Fix task terminal split (#41218)

Re-lands https://github.com/zed-industries/zed/pull/40824

Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov
2025-10-26 10:01:40 +00:00
committed by GitHub
parent 003a39740a
commit 54a7da364c
4 changed files with 36 additions and 29 deletions
+9 -3
View File
@@ -410,14 +410,19 @@ impl Project {
terminal: &Entity<Terminal>,
cx: &mut Context<'_, Project>,
cwd: Option<PathBuf>,
) -> Result<Entity<Terminal>> {
) -> Task<Result<Entity<Terminal>>> {
// We cannot clone the task's terminal, as it will effectively re-spawn the task, which might not be desirable.
// For now, create a new shell instead.
if terminal.read(cx).task().is_some() {
return self.create_terminal_shell(cwd, cx);
}
let local_path = if self.is_via_remote_server() {
None
} else {
cwd
};
terminal
let new_terminal = terminal
.read(cx)
.clone_builder(cx, local_path)
.map(|builder| {
@@ -442,7 +447,8 @@ impl Project {
.detach();
terminal_handle
})
});
Task::ready(new_terminal)
}
pub fn terminal_settings<'a>(
+1 -1
View File
@@ -455,7 +455,7 @@ impl TerminalBuilder {
args: Option<Vec<String>>,
title_override: Option<String>,
) -> Self {
log::info!("Using {program} as shell");
log::debug!("Using {program} as shell");
Self {
program,
args,
+2 -2
View File
@@ -461,11 +461,11 @@ impl TerminalPanel {
cx.spawn_in(window, async move |panel, cx| {
let terminal = project
.update(cx, |project, cx| match terminal_view {
Some(view) => Task::ready(project.clone_terminal(
Some(view) => project.clone_terminal(
&view.read(cx).terminal.clone(),
cx,
working_directory,
)),
),
None => project.create_terminal_shell(working_directory, cx),
})
.ok()?
+24 -23
View File
@@ -38,7 +38,7 @@ use ui::{
prelude::*,
scrollbars::{self, GlobalSetting, ScrollbarVisibility},
};
use util::{ResultExt, maybe};
use util::ResultExt;
use workspace::{
CloseActiveItem, NewCenterTerminal, NewTerminal, ToolbarItemLocation, Workspace, WorkspaceId,
delete_unloaded_items,
@@ -1219,29 +1219,30 @@ impl Item for TerminalView {
window: &mut Window,
cx: &mut Context<Self>,
) -> Task<Option<Entity<Self>>> {
Task::ready(maybe!({
let terminal = self
.project
.update(cx, |project, cx| {
let cwd = project
.active_project_directory(cx)
.map(|it| it.to_path_buf());
project.clone_terminal(self.terminal(), cx, cwd)
})
.ok()?
.log_err()?;
let Some(terminal_task) = self
.project
.update(cx, |project, cx| {
let cwd = project
.active_project_directory(cx)
.map(|it| it.to_path_buf());
project.clone_terminal(self.terminal(), cx, cwd)
})
.ok()
else {
return Task::ready(None);
};
Some(cx.new(|cx| {
TerminalView::new(
terminal,
self.workspace.clone(),
workspace_id,
self.project.clone(),
window,
cx,
)
}))
}))
let workspace = self.workspace.clone();
let project = self.project.clone();
cx.spawn_in(window, async move |_, cx| {
let terminal = terminal_task.await.log_err()?;
cx.update(|window, cx| {
cx.new(|cx| {
TerminalView::new(terminal, workspace, workspace_id, project, window, cx)
})
})
.ok()
})
}
fn is_dirty(&self, cx: &gpui::App) -> bool {