From 5263f5143285f5bdf22340283b30826ac3669120 Mon Sep 17 00:00:00 2001 From: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com> Date: Mon, 6 Oct 2025 15:18:27 +0200 Subject: [PATCH] terminal: Fix terminal cloning on WSL (#39552) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should close #39428 The working directory of the `wsl.exe` program is set to a Linux path, which is invalid on the Windows side, causing the terminal to crash. The first spawn works because there is no active terminal view, allowing a new shell (which checks for the remote) to be created. I cannot explain why it works on SSH remote clients, but I may be missing something in the remote connection implementation. I don't have a Windows machine to test this, so I would appreciate someone testing it. 🙏🏼 Release Notes: - Fixed an issue where WSL terminals could not be splitted --------- Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com> --- crates/project/src/terminals.rs | 55 +++++++++++++--------- crates/terminal/src/terminal.rs | 8 +--- crates/terminal_view/src/terminal_panel.rs | 2 +- crates/terminal_view/src/terminal_view.rs | 2 +- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/crates/project/src/terminals.rs b/crates/project/src/terminals.rs index 1f75eacd4d9f167990b6ff596f19d04d3f927712..30090b26e146d0be6b7bc1c03b53235c22e478b2 100644 --- a/crates/project/src/terminals.rs +++ b/crates/project/src/terminals.rs @@ -404,31 +404,40 @@ impl Project { &mut self, terminal: &Entity, cx: &mut Context<'_, Project>, - cwd: impl FnOnce() -> Option, + cwd: Option, ) -> Result> { - terminal.read(cx).clone_builder(cx, cwd).map(|builder| { - let terminal_handle = cx.new(|cx| builder.subscribe(cx)); - - self.terminals - .local_handles - .push(terminal_handle.downgrade()); - - let id = terminal_handle.entity_id(); - cx.observe_release(&terminal_handle, move |project, _terminal, cx| { - let handles = &mut project.terminals.local_handles; - - if let Some(index) = handles - .iter() - .position(|terminal| terminal.entity_id() == id) - { - handles.remove(index); - cx.notify(); - } - }) - .detach(); + let local_path = if self.is_via_remote_server() { + None + } else { + cwd + }; - terminal_handle - }) + terminal + .read(cx) + .clone_builder(cx, local_path) + .map(|builder| { + let terminal_handle = cx.new(|cx| builder.subscribe(cx)); + + self.terminals + .local_handles + .push(terminal_handle.downgrade()); + + let id = terminal_handle.entity_id(); + cx.observe_release(&terminal_handle, move |project, _terminal, cx| { + let handles = &mut project.terminals.local_handles; + + if let Some(index) = handles + .iter() + .position(|terminal| terminal.entity_id() == id) + { + handles.remove(index); + cx.notify(); + } + }) + .detach(); + + terminal_handle + }) } pub fn terminal_settings<'a>( diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index f3cffe876a60c5695875b3bbbe91057233ccdeee..a4f2117a44e7ce95d63f451e9ce87b10a1baeee1 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -2135,12 +2135,8 @@ impl Terminal { self.vi_mode_enabled } - pub fn clone_builder( - &self, - cx: &App, - cwd: impl FnOnce() -> Option, - ) -> Result { - let working_directory = self.working_directory().or_else(cwd); + pub fn clone_builder(&self, cx: &App, cwd: Option) -> Result { + let working_directory = self.working_directory().or_else(|| cwd); TerminalBuilder::new( working_directory, None, diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index 93abc311549bcbca3d331bfbef1bcaabb6336372..7952eb51e8ce2abe53c9455bcc8225f052ddbfca 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -466,7 +466,7 @@ impl TerminalPanel { Some(view) => Task::ready(project.clone_terminal( &view.read(cx).terminal.clone(), cx, - || working_directory, + working_directory, )), None => project.create_terminal_shell(working_directory, cx), }) diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 16f4b7603e8390656e89923fac319a29b796423b..cbb3ad92c58ae980698f135b7fa10bb9f68a4dd1 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1225,7 +1225,7 @@ impl Item for TerminalView { let cwd = project .active_project_directory(cx) .map(|it| it.to_path_buf()); - project.clone_terminal(self.terminal(), cx, || cwd) + project.clone_terminal(self.terminal(), cx, cwd) }) .ok()? .log_err()?;