@@ -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>(
@@ -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,
@@ -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()?
@@ -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)
+ 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);
+ };
+
+ 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()?
- .log_err()?;
-
- Some(cx.new(|cx| {
- TerminalView::new(
- terminal,
- self.workspace.clone(),
- workspace_id,
- self.project.clone(),
- window,
- cx,
- )
- }))
- }))
+ })
+ .ok()
+ })
}
fn is_dirty(&self, cx: &gpui::App) -> bool {