Git keyboard shortcuts (#26374)
Closes #26040 Release Notes: - git: Add keyboard shortcuts (when the panel is open) for fetch `ctrl-g ctrl-g`, pull `ctrl-g down`, push `ctrl-g up`, force-push `ctrl-g shift-up`, open diff `ctrl-g d`
This commit is contained in:
parent
b91e929086
commit
3891381d3e
4 changed files with 160 additions and 67 deletions
|
@ -731,14 +731,16 @@
|
||||||
"up": "menu::SelectPrevious",
|
"up": "menu::SelectPrevious",
|
||||||
"down": "menu::SelectNext",
|
"down": "menu::SelectNext",
|
||||||
"enter": "menu::Confirm",
|
"enter": "menu::Confirm",
|
||||||
|
"alt-y": "git::StageFile",
|
||||||
|
"alt-shift-y": "git::UnstageFile",
|
||||||
|
"ctrl-alt-y": "git::ToggleStaged",
|
||||||
"space": "git::ToggleStaged",
|
"space": "git::ToggleStaged",
|
||||||
"ctrl-space": "git::StageAll",
|
|
||||||
"ctrl-shift-space": "git::UnstageAll",
|
|
||||||
"tab": "git_panel::FocusEditor",
|
"tab": "git_panel::FocusEditor",
|
||||||
"shift-tab": "git_panel::FocusEditor",
|
"shift-tab": "git_panel::FocusEditor",
|
||||||
"escape": "git_panel::ToggleFocus",
|
"escape": "git_panel::ToggleFocus",
|
||||||
"ctrl-enter": "git::Commit",
|
"ctrl-enter": "git::Commit",
|
||||||
"alt-enter": "menu::SecondaryConfirm"
|
"alt-enter": "menu::SecondaryConfirm",
|
||||||
|
"backspace": "git::RestoreFile"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -749,10 +751,27 @@
|
||||||
"alt-l": "git::GenerateCommitMessage"
|
"alt-l": "git::GenerateCommitMessage"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "GitPanel",
|
||||||
|
"use_key_equivalents": true,
|
||||||
|
"bindings": {
|
||||||
|
"ctrl-g ctrl-g": "git::Fetch",
|
||||||
|
"ctrl-g up": "git::Push",
|
||||||
|
"ctrl-g down": "git::Pull",
|
||||||
|
"ctrl-g shift-up": "git::ForcePush",
|
||||||
|
"ctrl-g d": "git::Diff",
|
||||||
|
"ctrl-g backspace": "git::RestoreTrackedFiles",
|
||||||
|
"ctrl-g shift-backspace": "git::TrashUntrackedFiles",
|
||||||
|
"ctrl-space": "git::StageAll",
|
||||||
|
"ctrl-shift-space": "git::UnstageAll"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"context": "GitDiff > Editor",
|
"context": "GitDiff > Editor",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"ctrl-enter": "git::Commit"
|
"ctrl-enter": "git::Commit",
|
||||||
|
"ctrl-space": "git::StageAll",
|
||||||
|
"ctrl-shift-space": "git::UnstageAll"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -763,28 +763,25 @@
|
||||||
"cmd-up": "menu::SelectFirst",
|
"cmd-up": "menu::SelectFirst",
|
||||||
"cmd-down": "menu::SelectLast",
|
"cmd-down": "menu::SelectLast",
|
||||||
"enter": "menu::Confirm",
|
"enter": "menu::Confirm",
|
||||||
|
"cmd-alt-y": "git::ToggleStaged",
|
||||||
"space": "git::ToggleStaged",
|
"space": "git::ToggleStaged",
|
||||||
"cmd-shift-space": "git::StageAll",
|
"cmd-y": "git::StageFile",
|
||||||
"ctrl-shift-space": "git::UnstageAll",
|
"cmd-shift-y": "git::UnstageFile",
|
||||||
"alt-down": "git_panel::FocusEditor",
|
"alt-down": "git_panel::FocusEditor",
|
||||||
"tab": "git_panel::FocusEditor",
|
"tab": "git_panel::FocusEditor",
|
||||||
"shift-tab": "git_panel::FocusEditor",
|
"shift-tab": "git_panel::FocusEditor",
|
||||||
"escape": "git_panel::ToggleFocus",
|
"escape": "git_panel::ToggleFocus",
|
||||||
"cmd-enter": "git::Commit"
|
"cmd-enter": "git::Commit",
|
||||||
|
"backspace": "git::RestoreFile"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"context": "GitDiff > Editor",
|
"context": "GitDiff > Editor",
|
||||||
"use_key_equivalents": true,
|
"use_key_equivalents": true,
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"cmd-enter": "git::Commit"
|
"cmd-enter": "git::Commit",
|
||||||
}
|
"cmd-ctrl-y": "git::StageAll",
|
||||||
},
|
"cmd-ctrl-shift-y": "git::UnstageAll"
|
||||||
{
|
|
||||||
"context": "AskPass > Editor",
|
|
||||||
"use_key_equivalents": true,
|
|
||||||
"bindings": {
|
|
||||||
"enter": "menu::Confirm"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -800,6 +797,21 @@
|
||||||
"alt-tab": "git::GenerateCommitMessage"
|
"alt-tab": "git::GenerateCommitMessage"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "GitPanel",
|
||||||
|
"use_key_equivalents": true,
|
||||||
|
"bindings": {
|
||||||
|
"ctrl-g ctrl-g": "git::Fetch",
|
||||||
|
"ctrl-g up": "git::Push",
|
||||||
|
"ctrl-g down": "git::Pull",
|
||||||
|
"ctrl-g shift-up": "git::ForcePush",
|
||||||
|
"ctrl-g d": "git::Diff",
|
||||||
|
"ctrl-g backspace": "git::RestoreTrackedFiles",
|
||||||
|
"ctrl-g shift-backspace": "git::TrashUntrackedFiles",
|
||||||
|
"cmd-ctrl-y": "git::StageAll",
|
||||||
|
"cmd-ctrl-shift-y": "git::UnstageAll"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"context": "GitCommit > Editor",
|
"context": "GitCommit > Editor",
|
||||||
"use_key_equivalents": true,
|
"use_key_equivalents": true,
|
||||||
|
|
|
@ -102,9 +102,14 @@ enum TrashCancel {
|
||||||
Cancel,
|
Cancel,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn git_panel_context_menu(window: &mut Window, cx: &mut App) -> Entity<ContextMenu> {
|
fn git_panel_context_menu(
|
||||||
|
focus_handle: Option<FocusHandle>,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut App,
|
||||||
|
) -> Entity<ContextMenu> {
|
||||||
ContextMenu::build(window, cx, |context_menu, _, _| {
|
ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||||
context_menu
|
context_menu
|
||||||
|
.when_some(focus_handle, |el, focus_handle| el.context(focus_handle))
|
||||||
.action("Stage All", StageAll.boxed_clone())
|
.action("Stage All", StageAll.boxed_clone())
|
||||||
.action("Unstage All", UnstageAll.boxed_clone())
|
.action("Unstage All", UnstageAll.boxed_clone())
|
||||||
.separator()
|
.separator()
|
||||||
|
@ -1232,6 +1237,35 @@ impl GitPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stage_selected(&mut self, _: &git::StageFile, _window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
let Some(selected_entry) = self.get_selected_entry() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(status_entry) = selected_entry.status_entry() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if status_entry.staging != StageStatus::Staged {
|
||||||
|
self.change_file_stage(true, vec![status_entry.clone()], cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unstage_selected(
|
||||||
|
&mut self,
|
||||||
|
_: &git::UnstageFile,
|
||||||
|
_window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
let Some(selected_entry) = self.get_selected_entry() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(status_entry) = selected_entry.status_entry() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if status_entry.staging != StageStatus::Unstaged {
|
||||||
|
self.change_file_stage(false, vec![status_entry.clone()], cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
|
if self
|
||||||
.commit_editor
|
.commit_editor
|
||||||
|
@ -2425,8 +2459,12 @@ impl GitPanel {
|
||||||
|
|
||||||
self.panel_header_container(window, cx)
|
self.panel_header_container(window, cx)
|
||||||
.child(
|
.child(
|
||||||
Button::new("diff", "Open diff")
|
Button::new("diff", "Open Diff")
|
||||||
.tooltip(Tooltip::for_action_title("Open diff", &Diff))
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
|
"Open diff",
|
||||||
|
&Diff,
|
||||||
|
&self.focus_handle,
|
||||||
|
))
|
||||||
.on_click(|_, _, cx| {
|
.on_click(|_, _, cx| {
|
||||||
cx.defer(|cx| {
|
cx.defer(|cx| {
|
||||||
cx.dispatch_action(&Diff);
|
cx.dispatch_action(&Diff);
|
||||||
|
@ -2436,7 +2474,11 @@ impl GitPanel {
|
||||||
.child(div().flex_grow()) // spacer
|
.child(div().flex_grow()) // spacer
|
||||||
.child(
|
.child(
|
||||||
Button::new("stage-unstage-all", text)
|
Button::new("stage-unstage-all", text)
|
||||||
.tooltip(Tooltip::for_action_title(tooltip, action.as_ref()))
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
|
tooltip,
|
||||||
|
action.as_ref(),
|
||||||
|
&self.focus_handle,
|
||||||
|
))
|
||||||
.on_click(move |_, _, cx| {
|
.on_click(move |_, _, cx| {
|
||||||
let action = action.boxed_clone();
|
let action = action.boxed_clone();
|
||||||
cx.defer(move |cx| {
|
cx.defer(move |cx| {
|
||||||
|
@ -2886,6 +2928,7 @@ impl GitPanel {
|
||||||
};
|
};
|
||||||
let context_menu = ContextMenu::build(window, cx, |context_menu, _, _| {
|
let context_menu = ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||||
context_menu
|
context_menu
|
||||||
|
.context(self.focus_handle.clone())
|
||||||
.action(stage_title, ToggleStaged.boxed_clone())
|
.action(stage_title, ToggleStaged.boxed_clone())
|
||||||
.action(restore_title, git::RestoreFile.boxed_clone())
|
.action(restore_title, git::RestoreFile.boxed_clone())
|
||||||
.separator()
|
.separator()
|
||||||
|
@ -2902,7 +2945,7 @@ impl GitPanel {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let context_menu = git_panel_context_menu(window, cx);
|
let context_menu = git_panel_context_menu(Some(self.focus_handle.clone()), window, cx);
|
||||||
self.set_context_menu(context_menu, position, window, cx);
|
self.set_context_menu(context_menu, position, window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3169,10 +3212,16 @@ impl Render for GitPanel {
|
||||||
.track_focus(&self.focus_handle)
|
.track_focus(&self.focus_handle)
|
||||||
.on_modifiers_changed(cx.listener(Self::handle_modifiers_changed))
|
.on_modifiers_changed(cx.listener(Self::handle_modifiers_changed))
|
||||||
.when(has_write_access && !project.is_read_only(cx), |this| {
|
.when(has_write_access && !project.is_read_only(cx), |this| {
|
||||||
this.on_action(cx.listener(|this, &ToggleStaged, window, cx| {
|
this.on_action(cx.listener(Self::toggle_staged_for_selected))
|
||||||
this.toggle_staged_for_selected(&ToggleStaged, window, cx)
|
.on_action(cx.listener(GitPanel::commit))
|
||||||
}))
|
.on_action(cx.listener(Self::stage_all))
|
||||||
.on_action(cx.listener(GitPanel::commit))
|
.on_action(cx.listener(Self::unstage_all))
|
||||||
|
.on_action(cx.listener(Self::stage_selected))
|
||||||
|
.on_action(cx.listener(Self::unstage_selected))
|
||||||
|
.on_action(cx.listener(Self::restore_tracked_files))
|
||||||
|
.on_action(cx.listener(Self::revert_selected))
|
||||||
|
.on_action(cx.listener(Self::clean_all))
|
||||||
|
.on_action(cx.listener(Self::generate_commit_message_action))
|
||||||
})
|
})
|
||||||
.on_action(cx.listener(Self::select_first))
|
.on_action(cx.listener(Self::select_first))
|
||||||
.on_action(cx.listener(Self::select_next))
|
.on_action(cx.listener(Self::select_next))
|
||||||
|
@ -3181,16 +3230,9 @@ impl Render for GitPanel {
|
||||||
.on_action(cx.listener(Self::close_panel))
|
.on_action(cx.listener(Self::close_panel))
|
||||||
.on_action(cx.listener(Self::open_diff))
|
.on_action(cx.listener(Self::open_diff))
|
||||||
.on_action(cx.listener(Self::open_file))
|
.on_action(cx.listener(Self::open_file))
|
||||||
.on_action(cx.listener(Self::revert_selected))
|
|
||||||
.on_action(cx.listener(Self::focus_changes_list))
|
.on_action(cx.listener(Self::focus_changes_list))
|
||||||
.on_action(cx.listener(Self::focus_editor))
|
.on_action(cx.listener(Self::focus_editor))
|
||||||
.on_action(cx.listener(Self::toggle_staged_for_selected))
|
|
||||||
.on_action(cx.listener(Self::stage_all))
|
|
||||||
.on_action(cx.listener(Self::unstage_all))
|
|
||||||
.on_action(cx.listener(Self::restore_tracked_files))
|
|
||||||
.on_action(cx.listener(Self::clean_all))
|
|
||||||
.on_action(cx.listener(Self::expand_commit_editor))
|
.on_action(cx.listener(Self::expand_commit_editor))
|
||||||
.on_action(cx.listener(Self::generate_commit_message_action))
|
|
||||||
.when(has_write_access && has_co_authors, |git_panel| {
|
.when(has_write_access && has_co_authors, |git_panel| {
|
||||||
git_panel.on_action(cx.listener(Self::toggle_fill_co_authors))
|
git_panel.on_action(cx.listener(Self::toggle_fill_co_authors))
|
||||||
})
|
})
|
||||||
|
@ -3414,14 +3456,18 @@ impl PanelRepoFooter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_overflow_menu(&self, id: impl Into<ElementId>) -> impl IntoElement {
|
fn render_overflow_menu(&self, id: impl Into<ElementId>, cx: &App) -> impl IntoElement {
|
||||||
|
let focus_handle = self
|
||||||
|
.git_panel
|
||||||
|
.as_ref()
|
||||||
|
.map(|git_panel| git_panel.focus_handle(cx));
|
||||||
PopoverMenu::new(id.into())
|
PopoverMenu::new(id.into())
|
||||||
.trigger(
|
.trigger(
|
||||||
IconButton::new("overflow-menu-trigger", IconName::EllipsisVertical)
|
IconButton::new("overflow-menu-trigger", IconName::EllipsisVertical)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.icon_color(Color::Muted),
|
.icon_color(Color::Muted),
|
||||||
)
|
)
|
||||||
.menu(move |window, cx| Some(git_panel_context_menu(window, cx)))
|
.menu(move |window, cx| Some(git_panel_context_menu(focus_handle.clone(), window, cx)))
|
||||||
.anchor(Corner::TopRight)
|
.anchor(Corner::TopRight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3537,7 +3583,7 @@ impl RenderOnce for PanelRepoFooter {
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.children(spinner)
|
.children(spinner)
|
||||||
.child(self.render_overflow_menu(overflow_menu_id))
|
.child(self.render_overflow_menu(overflow_menu_id, cx))
|
||||||
.when_some(branch, |this, branch| {
|
.when_some(branch, |this, branch| {
|
||||||
let mut focus_handle = None;
|
let mut focus_handle = None;
|
||||||
if let Some(git_panel) = self.git_panel.as_ref() {
|
if let Some(git_panel) = self.git_panel.as_ref() {
|
||||||
|
|
|
@ -29,41 +29,43 @@ pub fn init(cx: &mut App) {
|
||||||
|
|
||||||
cx.observe_new(|workspace: &mut Workspace, _, cx| {
|
cx.observe_new(|workspace: &mut Workspace, _, cx| {
|
||||||
let project = workspace.project().read(cx);
|
let project = workspace.project().read(cx);
|
||||||
if project.is_via_collab() {
|
if project.is_read_only(cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
workspace.register_action(|workspace, _: &git::Fetch, window, cx| {
|
if !project.is_via_collab() {
|
||||||
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
workspace.register_action(|workspace, _: &git::Fetch, window, cx| {
|
||||||
return;
|
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
||||||
};
|
return;
|
||||||
panel.update(cx, |panel, cx| {
|
};
|
||||||
panel.fetch(window, cx);
|
panel.update(cx, |panel, cx| {
|
||||||
|
panel.fetch(window, cx);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
workspace.register_action(|workspace, _: &git::Push, window, cx| {
|
||||||
workspace.register_action(|workspace, _: &git::Push, window, cx| {
|
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
||||||
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
return;
|
||||||
return;
|
};
|
||||||
};
|
panel.update(cx, |panel, cx| {
|
||||||
panel.update(cx, |panel, cx| {
|
panel.push(false, window, cx);
|
||||||
panel.push(false, window, cx);
|
});
|
||||||
});
|
});
|
||||||
});
|
workspace.register_action(|workspace, _: &git::ForcePush, window, cx| {
|
||||||
workspace.register_action(|workspace, _: &git::ForcePush, window, cx| {
|
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
||||||
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
return;
|
||||||
return;
|
};
|
||||||
};
|
panel.update(cx, |panel, cx| {
|
||||||
panel.update(cx, |panel, cx| {
|
panel.push(true, window, cx);
|
||||||
panel.push(true, window, cx);
|
});
|
||||||
});
|
});
|
||||||
});
|
workspace.register_action(|workspace, _: &git::Pull, window, cx| {
|
||||||
workspace.register_action(|workspace, _: &git::Pull, window, cx| {
|
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
||||||
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
return;
|
||||||
return;
|
};
|
||||||
};
|
panel.update(cx, |panel, cx| {
|
||||||
panel.update(cx, |panel, cx| {
|
panel.pull(window, cx);
|
||||||
panel.pull(window, cx);
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
workspace.register_action(|workspace, action: &git::StageAll, window, cx| {
|
workspace.register_action(|workspace, action: &git::StageAll, window, cx| {
|
||||||
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
let Some(panel) = workspace.panel::<git_panel::GitPanel>(cx) else {
|
||||||
return;
|
return;
|
||||||
|
@ -173,6 +175,7 @@ mod remote_button {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
Some(IconName::ArrowCircle),
|
Some(IconName::ArrowCircle),
|
||||||
|
keybinding_target.clone(),
|
||||||
move |_, window, cx| {
|
move |_, window, cx| {
|
||||||
window.dispatch_action(Box::new(git::Fetch), cx);
|
window.dispatch_action(Box::new(git::Fetch), cx);
|
||||||
},
|
},
|
||||||
|
@ -200,6 +203,7 @@ mod remote_button {
|
||||||
ahead as usize,
|
ahead as usize,
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
keybinding_target.clone(),
|
||||||
move |_, window, cx| {
|
move |_, window, cx| {
|
||||||
window.dispatch_action(Box::new(git::Push), cx);
|
window.dispatch_action(Box::new(git::Push), cx);
|
||||||
},
|
},
|
||||||
|
@ -228,6 +232,7 @@ mod remote_button {
|
||||||
ahead as usize,
|
ahead as usize,
|
||||||
behind as usize,
|
behind as usize,
|
||||||
None,
|
None,
|
||||||
|
keybinding_target.clone(),
|
||||||
move |_, window, cx| {
|
move |_, window, cx| {
|
||||||
window.dispatch_action(Box::new(git::Pull), cx);
|
window.dispatch_action(Box::new(git::Pull), cx);
|
||||||
},
|
},
|
||||||
|
@ -254,6 +259,7 @@ mod remote_button {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
Some(IconName::ArrowUpFromLine),
|
Some(IconName::ArrowUpFromLine),
|
||||||
|
keybinding_target.clone(),
|
||||||
move |_, window, cx| {
|
move |_, window, cx| {
|
||||||
window.dispatch_action(Box::new(git::Push), cx);
|
window.dispatch_action(Box::new(git::Push), cx);
|
||||||
},
|
},
|
||||||
|
@ -280,6 +286,7 @@ mod remote_button {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
Some(IconName::ArrowUpFromLine),
|
Some(IconName::ArrowUpFromLine),
|
||||||
|
keybinding_target.clone(),
|
||||||
move |_, window, cx| {
|
move |_, window, cx| {
|
||||||
window.dispatch_action(Box::new(git::Push), cx);
|
window.dispatch_action(Box::new(git::Push), cx);
|
||||||
},
|
},
|
||||||
|
@ -321,7 +328,10 @@ mod remote_button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_git_action_menu(id: impl Into<ElementId>) -> impl IntoElement {
|
fn render_git_action_menu(
|
||||||
|
id: impl Into<ElementId>,
|
||||||
|
keybinding_target: Option<FocusHandle>,
|
||||||
|
) -> impl IntoElement {
|
||||||
PopoverMenu::new(id.into())
|
PopoverMenu::new(id.into())
|
||||||
.trigger(
|
.trigger(
|
||||||
ui::ButtonLike::new_rounded_right("split-button-right")
|
ui::ButtonLike::new_rounded_right("split-button-right")
|
||||||
|
@ -336,6 +346,9 @@ mod remote_button {
|
||||||
.menu(move |window, cx| {
|
.menu(move |window, cx| {
|
||||||
Some(ContextMenu::build(window, cx, |context_menu, _, _| {
|
Some(ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||||
context_menu
|
context_menu
|
||||||
|
.when_some(keybinding_target.clone(), |el, keybinding_target| {
|
||||||
|
el.context(keybinding_target.clone())
|
||||||
|
})
|
||||||
.action("Fetch", git::Fetch.boxed_clone())
|
.action("Fetch", git::Fetch.boxed_clone())
|
||||||
.action("Pull", git::Pull.boxed_clone())
|
.action("Pull", git::Pull.boxed_clone())
|
||||||
.separator()
|
.separator()
|
||||||
|
@ -353,12 +366,14 @@ mod remote_button {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SplitButton {
|
impl SplitButton {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn new(
|
fn new(
|
||||||
id: impl Into<SharedString>,
|
id: impl Into<SharedString>,
|
||||||
left_label: impl Into<SharedString>,
|
left_label: impl Into<SharedString>,
|
||||||
ahead_count: usize,
|
ahead_count: usize,
|
||||||
behind_count: usize,
|
behind_count: usize,
|
||||||
left_icon: Option<IconName>,
|
left_icon: Option<IconName>,
|
||||||
|
keybinding_target: Option<FocusHandle>,
|
||||||
left_on_click: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
|
left_on_click: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
|
||||||
tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static,
|
tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -416,9 +431,10 @@ mod remote_button {
|
||||||
.on_click(left_on_click)
|
.on_click(left_on_click)
|
||||||
.tooltip(tooltip);
|
.tooltip(tooltip);
|
||||||
|
|
||||||
let right = render_git_action_menu(ElementId::Name(
|
let right = render_git_action_menu(
|
||||||
format!("split-button-right-{}", id).into(),
|
ElementId::Name(format!("split-button-right-{}", id).into()),
|
||||||
))
|
keybinding_target,
|
||||||
|
)
|
||||||
.into_any_element();
|
.into_any_element();
|
||||||
|
|
||||||
Self { left, right }
|
Self { left, right }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue