refactor: centralize new terminal cwd selection

replaces contributions from Pitchfork-and-Torch
This commit is contained in:
Ogulcan Celik
2026-07-22 22:41:01 +03:00
parent 9524d0a3bc
commit a02c3a69bb
6 changed files with 43 additions and 70 deletions
+10 -5
View File
@@ -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 {
+1 -1
View File
@@ -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();
+26 -6
View File
@@ -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<PathBuf> {
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<PathBuf> {
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<PathBuf> {
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<PathBuf> {
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>) -> PathBuf {
+6 -2
View File
@@ -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,
-17
View File
@@ -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<TerminalId, TerminalState>,
terminal_runtimes: &TerminalRuntimeRegistry,
) -> Option<PathBuf> {
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())
})
}
}
-39
View File
@@ -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);
}