From 1086b282b87a878de71a727060112d55deb6739f Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 3 Mar 2025 20:49:29 -0700 Subject: [PATCH] git: New enter behaviour (#25986) Closes #25951 Release Notes: - git: Update "enter" in the list of changed files to preserve focus. If you want the old behaviour, hit enter twice. - git: Follow the cursor, not the scroll anchor, in the list. Although the scroll anchor was nice for passive scrolling, it broke if you had changed the overflow scroll settings. --- crates/editor/src/element.rs | 5 +++- crates/git_ui/src/git_panel.rs | 28 ++++++++++++++++++++-- crates/git_ui/src/project_diff.rs | 40 +++++++++++++++---------------- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index ef8de3037377550a281fb035b5f646412fd70e24..41e563cc19748cb718130d788785b42fe9253002 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -2722,7 +2722,10 @@ impl EditorElement { .shadow_md() .border_1() .map(|div| { - let border_color = if is_selected && is_folded { + let border_color = if is_selected + && is_folded + && focus_handle.contains_focused(window, cx) + { colors.border_focused } else { colors.border diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 331b496d4800be854a9cabcb5d9c113d43dc0393..8caed2fc11819c03cb411e4dc17e43bf979568a9 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -709,12 +709,31 @@ impl GitPanel { fn open_diff(&mut self, _: &menu::Confirm, window: &mut Window, cx: &mut Context) { maybe!({ let entry = self.entries.get(self.selected_entry?)?.status_entry()?; + let workspace = self.workspace.upgrade()?; + let git_repo = self.active_repository.as_ref()?; + + if let Some(project_diff) = workspace.read(cx).active_item_as::(cx) { + if let Some(project_path) = project_diff.read(cx).active_path(cx) { + if Some(&entry.repo_path) + == git_repo + .read(cx) + .project_path_to_repo_path(&project_path) + .as_ref() + { + project_diff.focus_handle(cx).focus(window); + return None; + } + } + }; self.workspace .update(cx, |workspace, cx| { ProjectDiff::deploy_at(workspace, Some(entry.clone()), window, cx); }) - .ok() + .ok(); + self.focus_handle.focus(window); + + Some(()) }); } @@ -2456,7 +2475,7 @@ impl GitPanel { ix: usize, entry: &GitStatusEntry, has_write_access: bool, - _: &Window, + window: &Window, cx: &Context, ) -> AnyElement { let display_name = entry @@ -2548,6 +2567,10 @@ impl GitPanel { .h(self.list_item_height()) .w_full() .items_center() + .border_1() + .when(selected && self.focus_handle.is_focused(window), |el| { + el.border_color(cx.theme().colors().border_focused) + }) .px(rems(0.75)) // ~12px .overflow_hidden() .flex_none() @@ -2563,6 +2586,7 @@ impl GitPanel { this.open_file(&Default::default(), window, cx) } else { this.open_diff(&Default::default(), window, cx); + this.focus_handle.focus(window); } }) }) diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index 2eced2cdb2f3c81f55b6cedfd8a256e27303f921..c61fefedfe31e52fec07e6f1b4b5a6681becb310 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -5,7 +5,7 @@ use collections::HashSet; use editor::{ actions::{GoToHunk, GoToPreviousHunk}, scroll::Autoscroll, - Editor, EditorEvent, ToPoint, + Editor, EditorEvent, }; use feature_flags::FeatureFlagViewExt; use futures::StreamExt; @@ -192,6 +192,19 @@ impl ProjectDiff { self.move_to_path(path_key, window, cx) } + pub fn active_path(&self, cx: &App) -> Option { + let editor = self.editor.read(cx); + let position = editor.selections.newest_anchor().head(); + let multi_buffer = editor.buffer().read(cx); + let (_, buffer, _) = multi_buffer.excerpt_containing(position, cx)?; + + let file = buffer.read(cx).file()?; + Some(ProjectPath { + worktree_id: file.worktree_id(cx), + path: file.path().clone(), + }) + } + fn move_to_path(&mut self, path_key: PathKey, window: &mut Window, cx: &mut Context) { if let Some(position) = self.multibuffer.read(cx).location_for_path(&path_key, cx) { self.editor.update(cx, |editor, cx| { @@ -271,41 +284,26 @@ impl ProjectDiff { fn handle_editor_event( &mut self, - editor: &Entity, + _: &Entity, event: &EditorEvent, window: &mut Window, cx: &mut Context, ) { match event { - EditorEvent::ScrollPositionChanged { .. } => editor.update(cx, |editor, cx| { - let anchor = editor.scroll_manager.anchor().anchor; - let multibuffer = self.multibuffer.read(cx); - let snapshot = multibuffer.snapshot(cx); - let mut point = anchor.to_point(&snapshot); - point.row = (point.row + 1).min(snapshot.max_row().0); - point.column = 0; - - let Some((_, buffer, _)) = self.multibuffer.read(cx).excerpt_containing(point, cx) - else { - return; - }; - let Some(project_path) = buffer - .read(cx) - .file() - .map(|file| (file.worktree_id(cx), file.path().clone())) - else { + EditorEvent::SelectionsChanged { local: true } => { + let Some(project_path) = self.active_path(cx) else { return; }; self.workspace .update(cx, |workspace, cx| { if let Some(git_panel) = workspace.panel::(cx) { git_panel.update(cx, |git_panel, cx| { - git_panel.select_entry_by_path(project_path.into(), window, cx) + git_panel.select_entry_by_path(project_path, window, cx) }) } }) .ok(); - }), + } _ => {} } }