diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-19 22:11:31 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-19 22:11:31 +0300 |
| commit | 08409d167deba8950495d9737fb54b0cc6634f4c (patch) | |
| tree | 25b73f6bbd759b45f22434b5e0ca0d90ff87a33e /src | |
| parent | a26a654351ee03b1a51d7b398f3bdff2c1ca920d (diff) | |
fix: show current workspace name in close confirmation
refs #1364
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui.rs | 4 | ||||
| -rw-r--r-- | src/ui/dialogs.rs | 112 |
2 files changed, 110 insertions, 6 deletions
@@ -435,7 +435,9 @@ pub fn render_with_runtime_registry( Mode::Prefix => render_prefix_overlay(app, frame, terminal_area), Mode::Copy => render_copy_mode_overlay(app, frame, terminal_area), Mode::Resize => render_resize_overlay(app, frame, terminal_area), - Mode::ConfirmClose => render_confirm_close_overlay(app, frame, terminal_area), + Mode::ConfirmClose => { + render_confirm_close_overlay(app, terminal_runtimes, frame, terminal_area) + } Mode::ContextMenu => { render_context_menu(app, frame); } diff --git a/src/ui/dialogs.rs b/src/ui/dialogs.rs index ff40693b..9575cfe9 100644 --- a/src/ui/dialogs.rs +++ b/src/ui/dialogs.rs @@ -12,6 +12,7 @@ use super::widgets::{ render_modal_header, render_modal_shell, render_panel_shell, ActionButtonSpec, }; use crate::app::{state::WorktreeOpenState, AppState, Mode}; +use crate::terminal::TerminalRuntimeRegistry; const NEW_LINKED_WORKTREE_POPUP_WIDTH: u16 = 68; const NEW_LINKED_WORKTREE_POPUP_HEIGHT: u16 = 12; @@ -596,11 +597,14 @@ fn render_open_worktree_search( frame.render_widget(Paragraph::new(Line::from(spans)), area); } -fn confirm_close_overlay_text(app: &AppState) -> (String, String) { +fn confirm_close_overlay_text( + app: &AppState, + terminal_runtimes: &TerminalRuntimeRegistry, +) -> (String, String) { let ws_name = app .workspaces .get(app.selected) - .map(|ws| ws.display_name()) + .map(|ws| ws.display_name_from(&app.terminals, terminal_runtimes)) .unwrap_or_else(|| "?".to_string()); let selected_space = app .workspaces @@ -659,8 +663,13 @@ fn confirm_close_overlay_text(app: &AppState) -> (String, String) { (title.to_string(), detail) } -pub(super) fn render_confirm_close_overlay(app: &AppState, frame: &mut Frame, area: Rect) { - let (title, detail) = confirm_close_overlay_text(app); +pub(super) fn render_confirm_close_overlay( + app: &AppState, + terminal_runtimes: &TerminalRuntimeRegistry, + frame: &mut Frame, + area: Rect, +) { + let (title, detail) = confirm_close_overlay_text(app, terminal_runtimes); super::dim_background(frame, area); @@ -766,6 +775,98 @@ mod tests { use super::{confirm_close_overlay_text, render_new_linked_worktree_overlay}; #[test] + fn confirm_close_text_uses_live_workspace_cwd_label() { + let mut app = AppState::test_new(); + let mut workspace = Workspace::test_new("initial"); + workspace.custom_name = None; + workspace.identity_cwd = "/projects/original".into(); + let root_pane = workspace.tabs[0].root_pane; + let terminal_id = workspace.tabs[0].panes[&root_pane] + .attached_terminal_id + .clone(); + app.workspaces = vec![workspace]; + app.ensure_test_terminals(); + app.terminals.get_mut(&terminal_id).unwrap().cwd = "/projects/current".into(); + app.selected = 0; + + let terminal_runtimes = crate::terminal::TerminalRuntimeRegistry::new(); + let (title, detail) = confirm_close_overlay_text(&app, &terminal_runtimes); + + assert_eq!(title, "Close workspace?"); + assert_eq!(detail, "current — 1 pane"); + } + + #[cfg(unix)] + #[tokio::test] + async fn confirm_close_text_prefers_live_runtime_cwd_over_stale_terminal_cwd() { + let root = std::env::temp_dir().join(format!( + "herdr-confirm-close-runtime-cwd-{}", + std::process::id() + )); + let stale_cwd = root.join("original"); + let live_cwd = root.join("current"); + std::fs::create_dir_all(&live_cwd).unwrap(); + + let mut app = AppState::test_new(); + let mut workspace = Workspace::test_new("initial"); + workspace.custom_name = None; + workspace.identity_cwd = stale_cwd.clone(); + let root_pane = workspace.tabs[0].root_pane; + let terminal_id = workspace.tabs[0].panes[&root_pane] + .attached_terminal_id + .clone(); + app.workspaces = vec![workspace]; + app.ensure_test_terminals(); + app.selected = 0; + + let (events, _) = tokio::sync::mpsc::channel(4); + let runtime = crate::terminal::TerminalRuntime::spawn( + root_pane, + 24, + 80, + live_cwd, + 0, + crate::terminal_theme::TerminalTheme::default(), + crate::pane::PaneShellConfig::new("/bin/sh", crate::config::ShellModeConfig::NonLogin), + &crate::pane::PaneLaunchEnv::default(), + events, + std::sync::Arc::new(tokio::sync::Notify::new()), + std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), + ) + .unwrap(); + let mut terminal_runtimes = crate::terminal::TerminalRuntimeRegistry::new(); + terminal_runtimes.insert(terminal_id, runtime); + + let (_, detail) = confirm_close_overlay_text(&app, &terminal_runtimes); + + assert_eq!(detail, "current — 1 pane"); + + drop(terminal_runtimes); + std::fs::remove_dir_all(root).unwrap(); + } + + #[test] + fn confirm_close_text_uses_selected_custom_name_instead_of_active_workspace_cwd() { + let mut app = AppState::test_new(); + let active = Workspace::test_new("active"); + let selected = Workspace::test_new("selected"); + let selected_root = selected.tabs[0].root_pane; + let selected_terminal_id = selected.tabs[0].panes[&selected_root] + .attached_terminal_id + .clone(); + app.workspaces = vec![active, selected]; + app.ensure_test_terminals(); + app.terminals.get_mut(&selected_terminal_id).unwrap().cwd = "/projects/current".into(); + app.active = Some(0); + app.selected = 1; + + let terminal_runtimes = crate::terminal::TerminalRuntimeRegistry::new(); + let (_, detail) = confirm_close_overlay_text(&app, &terminal_runtimes); + + assert_eq!(detail, "selected — 1 pane"); + } + + #[test] fn confirm_close_text_reports_parent_group_scope() { let mut app = AppState::test_new(); let mut parent = Workspace::test_new("main"); @@ -787,7 +888,8 @@ mod tests { app.workspaces = vec![parent, child]; app.selected = 0; - let (title, detail) = confirm_close_overlay_text(&app); + let terminal_runtimes = crate::terminal::TerminalRuntimeRegistry::new(); + let (title, detail) = confirm_close_overlay_text(&app, &terminal_runtimes); assert_eq!(title, "Close worktree group?"); assert_eq!(detail, "main — 2 workspaces, 2 panes"); |
