From 616d17f5170c5d2e20b1db6faac899677afd8ed2 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Tue, 15 Apr 2025 13:30:02 +0530 Subject: [PATCH] git_ui: Force commit modal mode from command palette (#28745) Depending on `git::commit` or `git::amend` action triggered, commit modal opens up in appropriate mode, handling edge cases like if you are already in amend mode, etc. Release Notes: - N/A --- crates/git_ui/src/commit_modal.rs | 87 ++++++++++++------------------- crates/git_ui/src/git_panel.rs | 46 +++++++++------- 2 files changed, 59 insertions(+), 74 deletions(-) diff --git a/crates/git_ui/src/commit_modal.rs b/crates/git_ui/src/commit_modal.rs index d7a11e53ba38098d0ccb13535ffa536445d37e63..dd897eb46afc7dbbf833bc21372d73fca6249051 100644 --- a/crates/git_ui/src/commit_modal.rs +++ b/crates/git_ui/src/commit_modal.rs @@ -2,7 +2,6 @@ use crate::branch_picker::{self, BranchList}; use crate::git_panel::{GitPanel, commit_message_editor}; use git::repository::CommitOptions; use git::{Amend, Commit, GenerateCommitMessage}; -use language::Buffer; use panel::{panel_button, panel_editor_style, panel_filled_button}; use ui::{ ContextMenu, KeybindingHint, PopoverMenu, PopoverMenuHandle, SplitButton, Tooltip, prelude::*, @@ -100,22 +99,47 @@ struct RestoreDock { active_index: Option, } +pub enum ForceMode { + Amend, + Commit, +} + impl CommitModal { pub fn register(workspace: &mut Workspace) { workspace.register_action(|workspace, _: &Commit, window, cx| { - CommitModal::toggle(workspace, window, cx); + CommitModal::toggle(workspace, Some(ForceMode::Commit), window, cx); }); workspace.register_action(|workspace, _: &Amend, window, cx| { - CommitModal::toggle(workspace, window, cx); + CommitModal::toggle(workspace, Some(ForceMode::Amend), window, cx); }); } - pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context) { + pub fn toggle( + workspace: &mut Workspace, + force_mode: Option, + window: &mut Window, + cx: &mut Context, + ) { let Some(git_panel) = workspace.panel::(cx) else { return; }; git_panel.update(cx, |git_panel, cx| { + if let Some(force_mode) = force_mode { + match force_mode { + ForceMode::Amend => { + if !git_panel.amend_pending() { + git_panel.set_amend_pending(true, cx); + git_panel.load_last_commit_message_if_empty(cx); + } + } + ForceMode::Commit => { + if git_panel.amend_pending() { + git_panel.set_amend_pending(false, cx); + } + } + } + } git_panel.set_modal_open(true, cx); }); @@ -461,23 +485,12 @@ impl CommitModal { fn dismiss(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context) { if self.git_panel.read(cx).amend_pending() { self.git_panel - .update(cx, |git_panel, _| git_panel.set_amend_pending(false)); - cx.notify(); + .update(cx, |git_panel, cx| git_panel.set_amend_pending(false, cx)); } else { cx.emit(DismissEvent); } } - pub fn commit_message_buffer(&self, cx: &App) -> Entity { - self.commit_editor - .read(cx) - .buffer() - .read(cx) - .as_singleton() - .unwrap() - .clone() - } - fn commit(&mut self, _: &git::Commit, window: &mut Window, cx: &mut Context) { if self.git_panel.read(cx).amend_pending() { return; @@ -490,54 +503,20 @@ impl CommitModal { } fn amend(&mut self, _: &git::Amend, window: &mut Window, cx: &mut Context) { - let Some(active_repository) = self.git_panel.read(cx).active_repository.as_ref() else { - return; - }; - let Some(branch) = active_repository.read(cx).branch.as_ref() else { - return; - }; - let Some(recent_sha) = branch - .most_recent_commit - .as_ref() - .map(|commit| commit.sha.to_string()) - else { - return; - }; if self .commit_editor .focus_handle(cx) .contains_focused(window, cx) { if !self.git_panel.read(cx).amend_pending() { - self.git_panel.update(cx, |git_panel, _| { - git_panel.set_amend_pending(true); + self.git_panel.update(cx, |git_panel, cx| { + git_panel.set_amend_pending(true, cx); + git_panel.load_last_commit_message_if_empty(cx); }); - cx.notify(); - if self.commit_editor.read(cx).is_empty(cx) { - let detail_task = self.git_panel.update(cx, |git_panel, cx| { - git_panel.load_commit_details(recent_sha, cx) - }); - cx.spawn(async move |this, cx| { - if let Ok(message) = detail_task.await.map(|detail| detail.message) { - this.update(cx, |this, cx| { - this.commit_message_buffer(cx).update(cx, |buffer, cx| { - let insert_position = buffer.anchor_before(buffer.len()); - buffer.edit( - [(insert_position..insert_position, message)], - None, - cx, - ); - }); - }) - .log_err(); - } - }) - .detach(); - } } else { telemetry::event!("Git Amended", source = "Git Panel"); self.git_panel.update(cx, |git_panel, cx| { - git_panel.set_amend_pending(false); + git_panel.set_amend_pending(false, cx); git_panel.commit_changes(CommitOptions { amend: true }, window, cx); }); cx.emit(DismissEvent); diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 6a5c0fb372fcda5a318c34c0749abb425cc7687e..e8d27cd442c72ab94982e3ecf1ca5ce32ff0242d 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -167,7 +167,7 @@ pub fn register(workspace: &mut Workspace) { workspace.toggle_panel_focus::(window, cx); }); workspace.register_action(|workspace, _: &ExpandCommitEditor, window, cx| { - CommitModal::toggle(workspace, window, cx) + CommitModal::toggle(workspace, None, window, cx) }); } @@ -1434,7 +1434,10 @@ impl GitPanel { } } - fn amend(&mut self, _: &git::Amend, window: &mut Window, cx: &mut Context) { + pub fn load_last_commit_message_if_empty(&mut self, cx: &mut Context) { + if !self.commit_editor.read(cx).is_empty(cx) { + return; + } let Some(active_repository) = self.active_repository.as_ref() else { return; }; @@ -1448,6 +1451,23 @@ impl GitPanel { else { return; }; + let detail_task = self.load_commit_details(recent_sha, cx); + cx.spawn(async move |this, cx| { + if let Ok(message) = detail_task.await.map(|detail| detail.message) { + this.update(cx, |this, cx| { + this.commit_message_buffer(cx).update(cx, |buffer, cx| { + let start = buffer.anchor_before(0); + let end = buffer.anchor_after(buffer.len()); + buffer.edit([(start..end, message)], None, cx); + }); + }) + .log_err(); + } + }) + .detach(); + } + + fn amend(&mut self, _: &git::Amend, window: &mut Window, cx: &mut Context) { if self .commit_editor .focus_handle(cx) @@ -1456,22 +1476,7 @@ impl GitPanel { if !self.amend_pending { self.amend_pending = true; cx.notify(); - if self.commit_editor.read(cx).is_empty(cx) { - let detail_task = self.load_commit_details(recent_sha, cx); - cx.spawn(async move |this, cx| { - if let Ok(message) = detail_task.await.map(|detail| detail.message) { - this.update(cx, |this, cx| { - this.commit_message_buffer(cx).update(cx, |buffer, cx| { - let start = buffer.anchor_before(0); - let end = buffer.anchor_after(buffer.len()); - buffer.edit([(start..end, message)], None, cx); - }); - }) - .log_err(); - } - }) - .detach(); - } + self.load_last_commit_message_if_empty(cx); } else { telemetry::event!("Git Amended", source = "Git Panel"); self.amend_pending = false; @@ -2859,7 +2864,7 @@ impl GitPanel { window.defer(cx, move |window, cx| { workspace .update(cx, |workspace, cx| { - CommitModal::toggle(workspace, window, cx) + CommitModal::toggle(workspace, None, window, cx) }) .ok(); }) @@ -3997,8 +4002,9 @@ impl GitPanel { self.amend_pending } - pub fn set_amend_pending(&mut self, value: bool) { + pub fn set_amend_pending(&mut self, value: bool, cx: &mut Context) { self.amend_pending = value; + cx.notify(); } }