diff options
| author | akbash <akbash@herdr.dev> | 2026-08-04 23:03:16 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-04 23:03:16 +0300 |
| commit | 93e0086f383f000ada02be382230507d5bdf4d7e (patch) | |
| tree | 606b97e13e23ff2c61c8a4c7733d91a44f9ed4b5 /src/app | |
| parent | ee8429fb79ed0c53d2f23fa1b75b415e7f0cd377 (diff) | |
fix(ui): search single-tab names in navigator (#2320)
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/actions.rs | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/src/app/actions.rs b/src/app/actions.rs index 51f71877..51de049c 100644 --- a/src/app/actions.rs +++ b/src/app/actions.rs @@ -442,18 +442,25 @@ impl AppState { let multi_tab = ws.tabs.len() > 1; let mut rows = Vec::new(); for tab_idx in 0..ws.tabs.len() { - let mut tab_row = multi_tab.then(|| self.navigator_tab_row(ws_idx, tab_idx)); - let tab_matches = tab_row.as_ref().is_some_and(|row| match query_kind { + let mut tab_row = self.navigator_tab_row(ws_idx, tab_idx); + let tab_matches = match query_kind { NavigatorQueryKind::Empty => true, NavigatorQueryKind::State(filter) => { - navigator_state_filter_matches(filter, row.status, row.seen) + navigator_state_filter_matches(filter, tab_row.status, tab_row.seen) } - NavigatorQueryKind::Text => navigator_matches(query, &row.search_text), - }); - if let Some(tab_row) = tab_row.as_mut() { - tab_row.matched = tab_matches; - } - let mut pane_rows = self.navigator_pane_rows_for_tab(ws_idx, tab_idx, multi_tab); + NavigatorQueryKind::Text => navigator_matches( + query, + if multi_tab { + &tab_row.search_text + } else { + &tab_row.label + }, + ), + }; + tab_row.matched = tab_matches; + let show_tab_row = + multi_tab || (matches!(query_kind, NavigatorQueryKind::Text) && tab_matches); + let mut pane_rows = self.navigator_pane_rows_for_tab(ws_idx, tab_idx, show_tab_row); let filtered_panes = match query_kind { NavigatorQueryKind::Empty => pane_rows, NavigatorQueryKind::State(filter) => pane_rows @@ -474,10 +481,8 @@ impl AppState { .collect::<Vec<_>>(), }; - if let Some(tab_row) = tab_row { - if tab_matches || !filtered_panes.is_empty() { - rows.push(tab_row); - } + if show_tab_row && (tab_matches || !filtered_panes.is_empty()) { + rows.push(tab_row); } rows.extend(filtered_panes); } @@ -519,7 +524,7 @@ impl AppState { &self, ws_idx: usize, tab_idx: usize, - multi_tab: bool, + show_tab_row: bool, ) -> Vec<NavigatorRow> { let Some(ws) = self.workspaces.get(ws_idx) else { return Vec::new(); @@ -578,7 +583,7 @@ impl AppState { tab_idx, pane_id, }, - depth: if multi_tab { 2 } else { 1 }, + depth: if show_tab_row { 2 } else { 1 }, label, meta, status: state, @@ -3670,6 +3675,52 @@ mod tests { ))); } + #[test] + fn navigator_search_matches_named_tabs_in_single_tab_workspaces() { + let mut state = app_with_workspaces(&["multi", "single"]); + state.workspaces[0].tabs[0].custom_name = Some("Foo".into()); + state.workspaces[0].test_add_tab(Some("Bar")); + state.workspaces[1].tabs[0].custom_name = Some("Baz".into()); + state.ensure_test_terminals(); + + state.open_navigator(); + state.navigator.query = "foo".into(); + assert!(state.navigator_rows().iter().any(|row| { + row.matched + && matches!( + row.target, + crate::app::state::NavigatorTarget::Tab { + ws_idx: 0, + tab_idx: 0 + } + ) + })); + + state.navigator.query = "baz".into(); + state.select_first_navigator_match_from(&crate::terminal::TerminalRuntimeRegistry::new()); + let rows = state.navigator_rows(); + assert!(rows + .get(state.navigator.selected) + .is_some_and(|row| matches!( + row.target, + crate::app::state::NavigatorTarget::Tab { + ws_idx: 1, + tab_idx: 0 + } + ))); + assert!(!rows.iter().any(|row| matches!( + row.target, + crate::app::state::NavigatorTarget::Workspace { ws_idx: 0 } + | crate::app::state::NavigatorTarget::Tab { ws_idx: 0, .. } + | crate::app::state::NavigatorTarget::Pane { ws_idx: 0, .. } + ))); + + assert!(state.accept_navigator_selection()); + assert_eq!(state.active, Some(1)); + assert_eq!(state.workspaces[1].active_tab_index(), 0); + assert_eq!(state.mode, Mode::Terminal); + } + #[tokio::test] async fn navigator_rows_match_live_root_runtime_cwd_workspace_label() { let unique = format!( |
