git_ui: Commit modal refinement (#25484)

Closes #ISSUE

Release Notes:

- N/A *or* Added/Fixed/Improved ...

---------

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
Nate Butler 2025-02-24 14:19:06 -05:00 committed by GitHub
parent ceb7fc2cb2
commit 30af8d0a81
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 510 additions and 146 deletions

View file

@ -184,6 +184,7 @@ pub struct GitPanel {
pending_remote_operations: RemoteOperations,
pub(crate) active_repository: Option<Entity<Repository>>,
commit_editor: Entity<Editor>,
suggested_commit_message: Option<String>,
conflicted_count: usize,
conflicted_staged_count: usize,
current_modifiers: Modifiers,
@ -308,6 +309,7 @@ impl GitPanel {
remote_operation_id: 0,
active_repository,
commit_editor,
suggested_commit_message: None,
conflicted_count: 0,
conflicted_staged_count: 0,
current_modifiers: window.modifiers(),
@ -1038,6 +1040,10 @@ impl GitPanel {
.detach();
}
pub fn total_staged_count(&self) -> usize {
self.tracked_staged_count + self.new_staged_count + self.conflicted_staged_count
}
pub fn commit_message_buffer(&self, cx: &App) -> Entity<Buffer> {
self.commit_editor
.read(cx)
@ -1200,6 +1206,57 @@ impl GitPanel {
self.pending_commit = Some(task);
}
/// Suggests a commit message based on the changed files and their statuses
pub fn suggest_commit_message(&self) -> Option<String> {
let entries = self
.entries
.iter()
.filter_map(|entry| {
if let GitListEntry::GitStatusEntry(status_entry) = entry {
Some(status_entry)
} else {
None
}
})
.collect::<Vec<&GitStatusEntry>>();
if entries.is_empty() {
None
} else if entries.len() == 1 {
let entry = &entries[0];
let file_name = entry
.repo_path
.file_name()
.unwrap_or_default()
.to_string_lossy();
if entry.status.is_deleted() {
Some(format!("Delete {}", file_name))
} else if entry.status.is_created() {
Some(format!("Create {}", file_name))
} else if entry.status.is_modified() {
Some(format!("Update {}", file_name))
} else {
None
}
} else {
None
}
}
fn update_editor_placeholder(&mut self, cx: &mut Context<Self>) {
let suggested_commit_message = self.suggest_commit_message();
self.suggested_commit_message = suggested_commit_message.clone();
if let Some(suggested_commit_message) = suggested_commit_message {
self.commit_editor.update(cx, |editor, cx| {
editor.set_placeholder_text(Arc::from(suggested_commit_message), cx)
});
}
cx.notify();
}
fn fetch(&mut self, _: &git::Fetch, _window: &mut Window, cx: &mut Context<Self>) {
let Some(repo) = self.active_repository.clone() else {
return;
@ -1444,6 +1501,7 @@ impl GitPanel {
git_panel.clear_pending();
}
git_panel.update_visible_entries(cx);
git_panel.update_editor_placeholder(cx);
})
.ok();
}