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
This commit is contained in:
parent
e1c42315dc
commit
616d17f517
2 changed files with 59 additions and 74 deletions
|
@ -2,7 +2,6 @@ use crate::branch_picker::{self, BranchList};
|
||||||
use crate::git_panel::{GitPanel, commit_message_editor};
|
use crate::git_panel::{GitPanel, commit_message_editor};
|
||||||
use git::repository::CommitOptions;
|
use git::repository::CommitOptions;
|
||||||
use git::{Amend, Commit, GenerateCommitMessage};
|
use git::{Amend, Commit, GenerateCommitMessage};
|
||||||
use language::Buffer;
|
|
||||||
use panel::{panel_button, panel_editor_style, panel_filled_button};
|
use panel::{panel_button, panel_editor_style, panel_filled_button};
|
||||||
use ui::{
|
use ui::{
|
||||||
ContextMenu, KeybindingHint, PopoverMenu, PopoverMenuHandle, SplitButton, Tooltip, prelude::*,
|
ContextMenu, KeybindingHint, PopoverMenu, PopoverMenuHandle, SplitButton, Tooltip, prelude::*,
|
||||||
|
@ -100,22 +99,47 @@ struct RestoreDock {
|
||||||
active_index: Option<usize>,
|
active_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ForceMode {
|
||||||
|
Amend,
|
||||||
|
Commit,
|
||||||
|
}
|
||||||
|
|
||||||
impl CommitModal {
|
impl CommitModal {
|
||||||
pub fn register(workspace: &mut Workspace) {
|
pub fn register(workspace: &mut Workspace) {
|
||||||
workspace.register_action(|workspace, _: &Commit, window, cx| {
|
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| {
|
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<Workspace>) {
|
pub fn toggle(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
force_mode: Option<ForceMode>,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Workspace>,
|
||||||
|
) {
|
||||||
let Some(git_panel) = workspace.panel::<GitPanel>(cx) else {
|
let Some(git_panel) = workspace.panel::<GitPanel>(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
git_panel.update(cx, |git_panel, cx| {
|
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);
|
git_panel.set_modal_open(true, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -461,23 +485,12 @@ impl CommitModal {
|
||||||
fn dismiss(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
|
fn dismiss(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
if self.git_panel.read(cx).amend_pending() {
|
if self.git_panel.read(cx).amend_pending() {
|
||||||
self.git_panel
|
self.git_panel
|
||||||
.update(cx, |git_panel, _| git_panel.set_amend_pending(false));
|
.update(cx, |git_panel, cx| git_panel.set_amend_pending(false, cx));
|
||||||
cx.notify();
|
|
||||||
} else {
|
} else {
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit_message_buffer(&self, cx: &App) -> Entity<Buffer> {
|
|
||||||
self.commit_editor
|
|
||||||
.read(cx)
|
|
||||||
.buffer()
|
|
||||||
.read(cx)
|
|
||||||
.as_singleton()
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn commit(&mut self, _: &git::Commit, window: &mut Window, cx: &mut Context<Self>) {
|
fn commit(&mut self, _: &git::Commit, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
if self.git_panel.read(cx).amend_pending() {
|
if self.git_panel.read(cx).amend_pending() {
|
||||||
return;
|
return;
|
||||||
|
@ -490,54 +503,20 @@ impl CommitModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn amend(&mut self, _: &git::Amend, window: &mut Window, cx: &mut Context<Self>) {
|
fn amend(&mut self, _: &git::Amend, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
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
|
if self
|
||||||
.commit_editor
|
.commit_editor
|
||||||
.focus_handle(cx)
|
.focus_handle(cx)
|
||||||
.contains_focused(window, cx)
|
.contains_focused(window, cx)
|
||||||
{
|
{
|
||||||
if !self.git_panel.read(cx).amend_pending() {
|
if !self.git_panel.read(cx).amend_pending() {
|
||||||
self.git_panel.update(cx, |git_panel, _| {
|
self.git_panel.update(cx, |git_panel, cx| {
|
||||||
git_panel.set_amend_pending(true);
|
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 {
|
} else {
|
||||||
telemetry::event!("Git Amended", source = "Git Panel");
|
telemetry::event!("Git Amended", source = "Git Panel");
|
||||||
self.git_panel.update(cx, |git_panel, cx| {
|
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);
|
git_panel.commit_changes(CommitOptions { amend: true }, window, cx);
|
||||||
});
|
});
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
|
|
|
@ -167,7 +167,7 @@ pub fn register(workspace: &mut Workspace) {
|
||||||
workspace.toggle_panel_focus::<GitPanel>(window, cx);
|
workspace.toggle_panel_focus::<GitPanel>(window, cx);
|
||||||
});
|
});
|
||||||
workspace.register_action(|workspace, _: &ExpandCommitEditor, 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<Self>) {
|
pub fn load_last_commit_message_if_empty(&mut self, cx: &mut Context<Self>) {
|
||||||
|
if !self.commit_editor.read(cx).is_empty(cx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let Some(active_repository) = self.active_repository.as_ref() else {
|
let Some(active_repository) = self.active_repository.as_ref() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -1448,15 +1451,6 @@ impl GitPanel {
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if self
|
|
||||||
.commit_editor
|
|
||||||
.focus_handle(cx)
|
|
||||||
.contains_focused(window, cx)
|
|
||||||
{
|
|
||||||
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);
|
let detail_task = self.load_commit_details(recent_sha, cx);
|
||||||
cx.spawn(async move |this, cx| {
|
cx.spawn(async move |this, cx| {
|
||||||
if let Ok(message) = detail_task.await.map(|detail| detail.message) {
|
if let Ok(message) = detail_task.await.map(|detail| detail.message) {
|
||||||
|
@ -1472,6 +1466,17 @@ impl GitPanel {
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn amend(&mut self, _: &git::Amend, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
if self
|
||||||
|
.commit_editor
|
||||||
|
.focus_handle(cx)
|
||||||
|
.contains_focused(window, cx)
|
||||||
|
{
|
||||||
|
if !self.amend_pending {
|
||||||
|
self.amend_pending = true;
|
||||||
|
cx.notify();
|
||||||
|
self.load_last_commit_message_if_empty(cx);
|
||||||
} else {
|
} else {
|
||||||
telemetry::event!("Git Amended", source = "Git Panel");
|
telemetry::event!("Git Amended", source = "Git Panel");
|
||||||
self.amend_pending = false;
|
self.amend_pending = false;
|
||||||
|
@ -2859,7 +2864,7 @@ impl GitPanel {
|
||||||
window.defer(cx, move |window, cx| {
|
window.defer(cx, move |window, cx| {
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
CommitModal::toggle(workspace, window, cx)
|
CommitModal::toggle(workspace, None, window, cx)
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
})
|
})
|
||||||
|
@ -3997,8 +4002,9 @@ impl GitPanel {
|
||||||
self.amend_pending
|
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>) {
|
||||||
self.amend_pending = value;
|
self.amend_pending = value;
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue