mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
Cherry-pick of #55510 to preview ---- #53609 introduced a regression where Git Graph keybindings could take precedence over the search bar. As a result, typing characters like `j` or `k` in the search field could move the table selection instead of updating the search query. This PR fixes that regression by scoping Vim table navigation bindings away from the search bar. It also adds dedicated `tab` and `shift-tab` handling for Git Graph focus traversal, with the search bar and graph table participating as separate tab groups. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com>
This commit is contained in:
parent
cd6dd882e4
commit
c85e35c93c
6 changed files with 125 additions and 3 deletions
|
|
@ -1534,4 +1534,18 @@
|
||||||
"ctrl-shift-backspace": "worktree_picker::DeleteWorktree",
|
"ctrl-shift-backspace": "worktree_picker::DeleteWorktree",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraph",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraphSearchBar > Editor",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1626,4 +1626,18 @@
|
||||||
"escape": "notebook::EnterCommandMode",
|
"escape": "notebook::EnterCommandMode",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraph",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraphSearchBar > Editor",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1551,4 +1551,18 @@
|
||||||
"escape": "notebook::EnterCommandMode",
|
"escape": "notebook::EnterCommandMode",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraph",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraphSearchBar > Editor",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1035,6 +1035,20 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"context": "GitGraph",
|
"context": "GitGraph",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraphSearchBar > Editor",
|
||||||
|
"bindings": {
|
||||||
|
"tab": "git_graph::FocusNextTabStop",
|
||||||
|
"shift-tab": "git_graph::FocusPreviousTabStop",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraph && !GitGraphSearchBar",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"j": "vim::MenuSelectNext",
|
"j": "vim::MenuSelectNext",
|
||||||
"k": "vim::MenuSelectPrevious",
|
"k": "vim::MenuSelectPrevious",
|
||||||
|
|
|
||||||
|
|
@ -3526,6 +3526,10 @@ impl Editor {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn show_cursor(&mut self, cx: &mut Context<Self>) {
|
||||||
|
self.blink_manager.update(cx, BlinkManager::show_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cursor_shape(&self) -> CursorShape {
|
pub fn cursor_shape(&self) -> CursorShape {
|
||||||
self.cursor_shape
|
self.cursor_shape
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,10 @@ actions!(
|
||||||
OpenCommitView,
|
OpenCommitView,
|
||||||
/// Focuses the search field.
|
/// Focuses the search field.
|
||||||
FocusSearch,
|
FocusSearch,
|
||||||
|
/// Focuses the next git graph tab stop.
|
||||||
|
FocusNextTabStop,
|
||||||
|
/// Focuses the previous git graph tab stop.
|
||||||
|
FocusPreviousTabStop,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1105,7 +1109,11 @@ impl GitGraph {
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
let table_interaction_state = cx.new(|cx| TableInteractionState::new(cx));
|
let table_interaction_state = cx.new(|cx| {
|
||||||
|
let mut state = TableInteractionState::new(cx);
|
||||||
|
state.focus_handle = state.focus_handle.tab_index(1).tab_stop(true);
|
||||||
|
state
|
||||||
|
});
|
||||||
|
|
||||||
let column_widths = if matches!(log_source, LogSource::File(_)) {
|
let column_widths = if matches!(log_source, LogSource::File(_)) {
|
||||||
cx.new(|_cx| {
|
cx.new(|_cx| {
|
||||||
|
|
@ -1597,6 +1605,39 @@ impl GitGraph {
|
||||||
self.search(query, cx);
|
self.search(query, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn activate_search_editor_if_focused(&self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
self.search_state.editor.update(cx, |editor, cx| {
|
||||||
|
if editor.is_focused(window) {
|
||||||
|
editor.select_all(&Default::default(), window, cx);
|
||||||
|
editor.show_cursor(cx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn focus_next_tab_stop(
|
||||||
|
&mut self,
|
||||||
|
_: &FocusNextTabStop,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
window.focus_next(cx);
|
||||||
|
self.activate_search_editor_if_focused(window, cx);
|
||||||
|
cx.stop_propagation();
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn focus_previous_tab_stop(
|
||||||
|
&mut self,
|
||||||
|
_: &FocusPreviousTabStop,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
window.focus_prev(cx);
|
||||||
|
self.activate_search_editor_if_focused(window, cx);
|
||||||
|
cx.stop_propagation();
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
fn select_entry(
|
fn select_entry(
|
||||||
&mut self,
|
&mut self,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
|
|
@ -1778,7 +1819,12 @@ impl GitGraph {
|
||||||
|
|
||||||
fn render_search_bar(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render_search_bar(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let color = cx.theme().colors();
|
let color = cx.theme().colors();
|
||||||
let query_focus_handle = self.search_state.editor.focus_handle(cx);
|
let query_focus_handle = self
|
||||||
|
.search_state
|
||||||
|
.editor
|
||||||
|
.focus_handle(cx)
|
||||||
|
.tab_index(1)
|
||||||
|
.tab_stop(true);
|
||||||
let search_options = {
|
let search_options = {
|
||||||
let mut options = SearchOptions::NONE;
|
let mut options = SearchOptions::NONE;
|
||||||
options.set(
|
options.set(
|
||||||
|
|
@ -1789,6 +1835,10 @@ impl GitGraph {
|
||||||
};
|
};
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.key_context("GitGraphSearchBar")
|
||||||
|
.tab_index(1)
|
||||||
|
.tab_group()
|
||||||
|
.tab_stop(false)
|
||||||
.w_full()
|
.w_full()
|
||||||
.p_1p5()
|
.p_1p5()
|
||||||
.gap_1p5()
|
.gap_1p5()
|
||||||
|
|
@ -1801,6 +1851,7 @@ impl GitGraph {
|
||||||
.min_w_0()
|
.min_w_0()
|
||||||
.px_1p5()
|
.px_1p5()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
|
.track_focus(&query_focus_handle)
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(color.border_variant)
|
.border_color(color.border_variant)
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
|
|
@ -2806,6 +2857,8 @@ impl Render for GitGraph {
|
||||||
let hovered_entry_idx = self.hovered_entry_idx;
|
let hovered_entry_idx = self.hovered_entry_idx;
|
||||||
let weak_self = cx.weak_entity();
|
let weak_self = cx.weak_entity();
|
||||||
let focus_handle = self.focus_handle.clone();
|
let focus_handle = self.focus_handle.clone();
|
||||||
|
let table_focus_handle =
|
||||||
|
self.table_interaction_state.read(cx).focus_handle.clone();
|
||||||
|
|
||||||
let graph_canvas = div()
|
let graph_canvas = div()
|
||||||
.id("graph-canvas")
|
.id("graph-canvas")
|
||||||
|
|
@ -2834,7 +2887,9 @@ impl Render for GitGraph {
|
||||||
.map_row(move |(index, row), window, cx| {
|
.map_row(move |(index, row), window, cx| {
|
||||||
let is_selected = selected_entry_idx == Some(index);
|
let is_selected = selected_entry_idx == Some(index);
|
||||||
let is_hovered = hovered_entry_idx == Some(index);
|
let is_hovered = hovered_entry_idx == Some(index);
|
||||||
let is_focused = focus_handle.is_focused(window);
|
let table_focus_handle = table_focus_handle.clone();
|
||||||
|
let is_focused = focus_handle.is_focused(window)
|
||||||
|
|| table_focus_handle.is_focused(window);
|
||||||
let weak = weak_self.clone();
|
let weak = weak_self.clone();
|
||||||
let weak_for_hover = weak.clone();
|
let weak_for_hover = weak.clone();
|
||||||
|
|
||||||
|
|
@ -2866,6 +2921,7 @@ impl Render for GitGraph {
|
||||||
})
|
})
|
||||||
.on_click(move |event, window, cx| {
|
.on_click(move |event, window, cx| {
|
||||||
let click_count = event.click_count();
|
let click_count = event.click_count();
|
||||||
|
table_focus_handle.focus(window, cx);
|
||||||
weak.update(cx, |this, cx| {
|
weak.update(cx, |this, cx| {
|
||||||
this.select_entry(
|
this.select_entry(
|
||||||
index,
|
index,
|
||||||
|
|
@ -2907,6 +2963,9 @@ impl Render for GitGraph {
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
.tab_index(2)
|
||||||
|
.tab_group()
|
||||||
|
.tab_stop(false)
|
||||||
.w(DefiniteLength::Fraction(table_fraction))
|
.w(DefiniteLength::Fraction(table_fraction))
|
||||||
.h_full()
|
.h_full()
|
||||||
.min_w_0()
|
.min_w_0()
|
||||||
|
|
@ -2951,12 +3010,15 @@ impl Render for GitGraph {
|
||||||
this.search_state
|
this.search_state
|
||||||
.editor
|
.editor
|
||||||
.update(cx, |editor, cx| editor.focus_handle(cx).focus(window, cx));
|
.update(cx, |editor, cx| editor.focus_handle(cx).focus(window, cx));
|
||||||
|
this.activate_search_editor_if_focused(window, cx);
|
||||||
}))
|
}))
|
||||||
.on_action(cx.listener(Self::select_first))
|
.on_action(cx.listener(Self::select_first))
|
||||||
.on_action(cx.listener(Self::select_prev))
|
.on_action(cx.listener(Self::select_prev))
|
||||||
.on_action(cx.listener(Self::select_next))
|
.on_action(cx.listener(Self::select_next))
|
||||||
.on_action(cx.listener(Self::select_last))
|
.on_action(cx.listener(Self::select_last))
|
||||||
.on_action(cx.listener(Self::confirm))
|
.on_action(cx.listener(Self::confirm))
|
||||||
|
.on_action(cx.listener(Self::focus_next_tab_stop))
|
||||||
|
.on_action(cx.listener(Self::focus_previous_tab_stop))
|
||||||
.on_action(cx.listener(|this, _: &SelectNextMatch, _window, cx| {
|
.on_action(cx.listener(|this, _: &SelectNextMatch, _window, cx| {
|
||||||
this.select_next_match(cx);
|
this.select_next_match(cx);
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue