From c9db1b9a7bc272b26e436111ca0e38038c0b9ae4 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 25 Oct 2024 14:10:04 -0400 Subject: [PATCH] Add keybindings for accepting hunks (#19749) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I went with Cmd-Shift-Y on macOS (Ctrl-Shift-Y on Linux) for "yes accept this individual hunk" - both are currently unused. I went with Cmd-Shift-A on macOS (Ctrl-Alt-A on Linux) for "accept all hunks" - both are unused. (Ctrl-Shift-A on Linux was taken, as is Ctrl-Alt-Y, so although the pairing of Ctrl-Shift-Y and Ctrl-Alt-A isn't necessarily obvious, the letters seem intuitive - "yes" and "all" - and those key combinations don't conflict with anything.) Release Notes: - Added keybindings for applying hunks in Proposed Changes Screenshot 2024-10-25 at 12 47 00 PM --- assets/keymaps/default-linux.json | 7 +++++ assets/keymaps/default-macos.json | 7 +++++ crates/editor/src/actions.rs | 1 + crates/editor/src/element.rs | 1 + crates/editor/src/hunk_diff.rs | 14 ++++++--- crates/editor/src/proposed_changes_editor.rs | 33 ++++++++++++-------- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index fca38a45a436fc37bc3a8f60cac2c91394f9660b..9df8debb70ea98d9dea5a7fb40eadc5c1d3a05bf 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -505,6 +505,13 @@ "ctrl-enter": "assistant::InlineAssist" } }, + { + "context": "ProposedChangesEditor", + "bindings": { + "ctrl-shift-y": "editor::ApplyDiffHunk", + "ctrl-alt-a": "editor::ApplyAllDiffHunks" + } + }, { "context": "Editor && jupyter && !ContextEditor", "bindings": { diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index c39b7c06daed595a67af10f1cd8c97b08004f000..c0bad344ab621c9a3e6edc63d54057839b2ba92d 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -538,6 +538,13 @@ "ctrl-enter": "assistant::InlineAssist" } }, + { + "context": "ProposedChangesEditor", + "bindings": { + "cmd-shift-y": "editor::ApplyDiffHunk", + "cmd-shift-a": "editor::ApplyAllDiffHunks" + } + }, { "context": "PromptEditor", "bindings": { diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 5f866f9997297e71cfedac4cab6c44dcd47f68b7..b190283776eae2d48f5449cb7072128903e7cbf8 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -193,6 +193,7 @@ gpui::actions!( AcceptPartialInlineCompletion, AddSelectionAbove, AddSelectionBelow, + ApplyAllDiffHunks, ApplyDiffHunk, Backspace, Cancel, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 7402badc1e9923d1705f19925b68e1e827e78df2..12e9d74914aa43c14660d90991e36f58896723c7 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -444,6 +444,7 @@ impl EditorElement { register_action(view, cx, Editor::accept_inline_completion); register_action(view, cx, Editor::revert_file); register_action(view, cx, Editor::revert_selected_hunks); + register_action(view, cx, Editor::apply_all_diff_hunks); register_action(view, cx, Editor::apply_selected_diff_hunks); register_action(view, cx, Editor::open_active_item_in_terminal); register_action(view, cx, Editor::reload_file) diff --git a/crates/editor/src/hunk_diff.rs b/crates/editor/src/hunk_diff.rs index 9f66d27a644e501081ecdc4ff3f42cf52775398e..c55f36a9be4801aa61af92cf84de234606acb2dc 100644 --- a/crates/editor/src/hunk_diff.rs +++ b/crates/editor/src/hunk_diff.rs @@ -16,10 +16,10 @@ use util::RangeExt; use workspace::Item; use crate::{ - editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, ApplyDiffHunk, - BlockPlacement, BlockProperties, BlockStyle, CustomBlockId, DiffRowHighlight, DisplayRow, - DisplaySnapshot, Editor, EditorElement, ExpandAllHunkDiffs, GoToHunk, GoToPrevHunk, RevertFile, - RevertSelectedHunks, ToDisplayPoint, ToggleHunkDiff, + editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, ApplyAllDiffHunks, + ApplyDiffHunk, BlockPlacement, BlockProperties, BlockStyle, CustomBlockId, DiffRowHighlight, + DisplayRow, DisplaySnapshot, Editor, EditorElement, ExpandAllHunkDiffs, GoToHunk, GoToPrevHunk, + RevertFile, RevertSelectedHunks, ToDisplayPoint, ToggleHunkDiff, }; #[derive(Debug, Clone)] @@ -352,7 +352,11 @@ impl Editor { None } - pub(crate) fn apply_all_diff_hunks(&mut self, cx: &mut ViewContext) { + pub(crate) fn apply_all_diff_hunks( + &mut self, + _: &ApplyAllDiffHunks, + cx: &mut ViewContext, + ) { let buffers = self.buffer.read(cx).all_buffers(); for branch_buffer in buffers { branch_buffer.update(cx, |branch_buffer, cx| { diff --git a/crates/editor/src/proposed_changes_editor.rs b/crates/editor/src/proposed_changes_editor.rs index ae9f251a1f14db4b1f1d521c14aef109b1c1515f..ac97fe18da757d856da2843b45c568bc1e0a46a6 100644 --- a/crates/editor/src/proposed_changes_editor.rs +++ b/crates/editor/src/proposed_changes_editor.rs @@ -1,4 +1,4 @@ -use crate::{Editor, EditorEvent, SemanticsProvider}; +use crate::{ApplyAllDiffHunks, Editor, EditorEvent, SemanticsProvider}; use collections::HashSet; use futures::{channel::mpsc, future::join_all}; use gpui::{AppContext, EventEmitter, FocusableView, Model, Render, Subscription, Task, View}; @@ -8,7 +8,7 @@ use project::Project; use smol::stream::StreamExt; use std::{any::TypeId, ops::Range, rc::Rc, time::Duration}; use text::ToOffset; -use ui::prelude::*; +use ui::{prelude::*, ButtonLike, KeyBinding}; use workspace::{ searchable::SearchableItemHandle, Item, ItemHandle as _, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, @@ -232,7 +232,10 @@ impl ProposedChangesEditor { impl Render for ProposedChangesEditor { fn render(&mut self, _cx: &mut ViewContext) -> impl IntoElement { - self.editor.clone() + div() + .size_full() + .key_context("ProposedChangesEditor") + .child(self.editor.clone()) } } @@ -331,17 +334,21 @@ impl ProposedChangesEditorToolbar { } impl Render for ProposedChangesEditorToolbar { - fn render(&mut self, _cx: &mut ViewContext) -> impl IntoElement { - let editor = self.current_editor.clone(); - Button::new("apply-changes", "Apply All").on_click(move |_, cx| { - if let Some(editor) = &editor { - editor.update(cx, |editor, cx| { - editor.editor.update(cx, |editor, cx| { - editor.apply_all_diff_hunks(cx); - }) - }); + fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let button_like = ButtonLike::new("apply-changes").child(Label::new("Apply All")); + + match &self.current_editor { + Some(editor) => { + let focus_handle = editor.focus_handle(cx); + let keybinding = KeyBinding::for_action_in(&ApplyAllDiffHunks, &focus_handle, cx) + .map(|binding| binding.into_any_element()); + + button_like.children(keybinding).on_click({ + move |_event, cx| focus_handle.dispatch_action(&ApplyAllDiffHunks, cx) + }) } - }) + None => button_like.disabled(true), + } } }