From a02c3a69bb5cea3832ef54e7cbe29425cc392eb3 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Wed, 22 Jul 2026 22:41:01 +0300 Subject: [PATCH] refactor: centralize new terminal cwd selection replaces contributions from Pitchfork-and-Torch --- src/app/api/layouts.rs | 15 ++++++++++----- src/app/api/panes.rs | 2 +- src/app/creation.rs | 32 ++++++++++++++++++++++++++------ src/app/input/mod.rs | 8 ++++++-- src/workspace/tab.rs | 17 ----------------- tests/api_ping.rs | 39 --------------------------------------- 6 files changed, 43 insertions(+), 70 deletions(-) diff --git a/src/app/api/layouts.rs b/src/app/api/layouts.rs index 0fdbaba0..34795474 100644 --- a/src/app/api/layouts.rs +++ b/src/app/api/layouts.rs @@ -339,10 +339,15 @@ impl App { return PathBuf::from(cwd); } let follow_cwd = replace_target.and_then(|(_, tab_idx)| { - let ws = self.state.workspaces.get(ws_idx)?; - let tab = ws.tabs.get(tab_idx)?; - let pane_id = tab.layout.focused(); - tab.follow_cwd_for_pane(pane_id, &self.state.terminals, &self.terminal_runtimes) + let pane_id = self + .state + .workspaces + .get(ws_idx)? + .tabs + .get(tab_idx)? + .layout + .focused(); + self.launch_cwd_for_pane_in_workspace(ws_idx, pane_id) }); self.resolve_new_terminal_cwd( follow_cwd.or_else(|| self.focused_pane_cwd_in_workspace(ws_idx)), @@ -396,7 +401,7 @@ impl App { .cwd .as_ref() .map(PathBuf::from) - .or_else(|| self.follow_cwd_for_pane_in_workspace(ws_idx, target_pane_id)); + .or_else(|| self.launch_cwd_for_pane_in_workspace(ws_idx, target_pane_id)); let extra_env = super::env::normalize_launch_env(pane.env.clone()) .map_err(|(_, message)| message.to_string())?; let direction = match direction { diff --git a/src/app/api/panes.rs b/src/app/api/panes.rs index 483d73a5..9947a3b8 100644 --- a/src/app/api/panes.rs +++ b/src/app/api/panes.rs @@ -51,7 +51,7 @@ impl App { }; let (rows, cols) = self.state.estimate_pane_size(); let split_cwd = params.cwd.map(std::path::PathBuf::from).or_else(|| { - let follow_cwd = self.follow_cwd_for_pane_in_workspace(ws_idx, target_pane_id); + let follow_cwd = self.launch_cwd_for_pane_in_workspace(ws_idx, target_pane_id); Some(self.resolve_new_terminal_cwd(follow_cwd)) }); let default_shell = self.state.default_shell.clone(); diff --git a/src/app/creation.rs b/src/app/creation.rs index 2e978ee9..fc01710e 100644 --- a/src/app/creation.rs +++ b/src/app/creation.rs @@ -30,6 +30,24 @@ pub(crate) fn resolve_new_terminal_cwd( } } +pub(super) fn launch_cwd_for_terminal( + terminal_id: &crate::terminal::TerminalId, + terminals: &std::collections::HashMap< + crate::terminal::TerminalId, + crate::terminal::TerminalState, + >, + terminal_runtimes: &crate::terminal::TerminalRuntimeRegistry, +) -> Option { + terminal_runtimes + .get(terminal_id) + .and_then(|runtime| runtime.follow_cwd()) + .or_else(|| { + terminals + .get(terminal_id) + .map(|terminal| terminal.cwd.clone()) + }) +} + impl App { pub(super) fn seed_cwd_from_workspace(&self, ws_idx: usize) -> Option { self.state @@ -38,15 +56,17 @@ impl App { .resolved_identity_cwd_from(&self.state.terminals, &self.terminal_runtimes) } - pub(super) fn follow_cwd_for_pane_in_workspace( + pub(super) fn launch_cwd_for_pane_in_workspace( &self, ws_idx: usize, pane_id: crate::layout::PaneId, ) -> Option { - let ws = self.state.workspaces.get(ws_idx)?; - let tab_idx = ws.find_tab_index_for_pane(pane_id)?; - ws.tabs.get(tab_idx)?.follow_cwd_for_pane( - pane_id, + let workspace = self.state.workspaces.get(ws_idx)?; + let tab = workspace + .tabs + .get(workspace.find_tab_index_for_pane(pane_id)?)?; + launch_cwd_for_terminal( + tab.terminal_id(pane_id)?, &self.state.terminals, &self.terminal_runtimes, ) @@ -54,7 +74,7 @@ impl App { pub(super) fn focused_pane_cwd_in_workspace(&self, ws_idx: usize) -> Option { let pane_id = self.state.workspaces.get(ws_idx)?.focused_pane_id()?; - self.follow_cwd_for_pane_in_workspace(ws_idx, pane_id) + self.launch_cwd_for_pane_in_workspace(ws_idx, pane_id) } pub(super) fn resolve_new_terminal_cwd(&self, follow_cwd: Option) -> PathBuf { diff --git a/src/app/input/mod.rs b/src/app/input/mod.rs index c9056109..5eee4250 100644 --- a/src/app/input/mod.rs +++ b/src/app/input/mod.rs @@ -652,8 +652,12 @@ impl AppState { .and_then(|i| self.workspaces.get(i)) .and_then(|ws| { let tab = ws.active_tab()?; - let pane_id = tab.layout.focused(); - tab.follow_cwd_for_pane(pane_id, &self.terminals, terminal_runtimes) + let terminal_id = tab.terminal_id(tab.layout.focused())?; + super::creation::launch_cwd_for_terminal( + terminal_id, + &self.terminals, + terminal_runtimes, + ) }); let cwd = Some(super::creation::resolve_new_terminal_cwd( &self.new_terminal_cwd, diff --git a/src/workspace/tab.rs b/src/workspace/tab.rs index 4c86a6e8..e2f82741 100644 --- a/src/workspace/tab.rs +++ b/src/workspace/tab.rs @@ -571,21 +571,4 @@ impl Tab { .get(terminal_id) .and_then(|rt| rt.foreground_cwd()) } - - pub fn follow_cwd_for_pane( - &self, - pane_id: PaneId, - terminals: &HashMap, - terminal_runtimes: &TerminalRuntimeRegistry, - ) -> Option { - let terminal_id = self.terminal_id(pane_id)?; - terminal_runtimes - .get(terminal_id) - .and_then(|runtime| runtime.follow_cwd()) - .or_else(|| { - terminals - .get(terminal_id) - .map(|terminal| terminal.cwd.clone()) - }) - } } diff --git a/tests/api_ping.rs b/tests/api_ping.rs index a31a5866..f63b93dd 100644 --- a/tests/api_ping.rs +++ b/tests/api_ping.rs @@ -740,10 +740,6 @@ fn pane_info_reports_foreground_cwd_without_changing_pane_cwd() { .as_str() .unwrap() .to_string(); - let workspace_id = created["result"]["workspace"]["workspace_id"] - .as_str() - .unwrap() - .to_string(); let command = format!( "/bin/sh -c 'cd {} && printf %s $$ > {} && touch {} && sleep 30; :'", foreground.display(), @@ -872,41 +868,6 @@ fn pane_info_reports_foreground_cwd_without_changing_pane_cwd() { foreground.display().to_string() ); - let tab = send_request( - &socket_path, - &serde_json::json!({ - "id": "fg_tab", - "method": "tab.create", - "params": { - "workspace_id": workspace_id, - "focus": false, - }, - }) - .to_string(), - ); - assert_eq!( - tab["result"]["root_pane"]["cwd"], - foreground.display().to_string() - ); - - let explicit_tab = send_request( - &socket_path, - &serde_json::json!({ - "id": "fg_explicit_tab", - "method": "tab.create", - "params": { - "workspace_id": workspace_id, - "cwd": base, - "focus": false, - }, - }) - .to_string(), - ); - assert_eq!( - explicit_tab["result"]["root_pane"]["cwd"], - base.display().to_string() - ); - cleanup_spawned_herdr(child, base); }