diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index 836f76a73fe69aa5dfdacf3359be34946d8c3740..c273778ec3852788c8a6fef5b10f2bea7ebeefb0 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -1145,6 +1145,9 @@ impl RunningState { args, ..task.resolved.clone() }; + + Workspace::save_for_task(&weak_workspace, task_with_shell.save, cx).await; + let terminal = project .update(cx, |project, cx| { project.create_terminal_task( diff --git a/crates/workspace/src/tasks.rs b/crates/workspace/src/tasks.rs index 98421365532a8fdd4fc36f0f5c68e83b0814ae8e..3ea356788655537f1f7fe32b6c8fe006a23cc608 100644 --- a/crates/workspace/src/tasks.rs +++ b/crates/workspace/src/tasks.rs @@ -2,7 +2,7 @@ use std::process::ExitStatus; use anyhow::Result; use collections::HashSet; -use gpui::{AppContext, Context, Entity, Task}; +use gpui::{AppContext, AsyncWindowContext, Context, Entity, Task, WeakEntity}; use language::Buffer; use project::{TaskSourceKind, WorktreeId}; use remote::ConnectionState; @@ -78,26 +78,7 @@ impl Workspace { if self.terminal_provider.is_some() { let task = cx.spawn_in(window, async move |workspace, cx| { - let save_action = match spawn_in_terminal.save { - SaveStrategy::All => { - let save_all = workspace.update_in(cx, |workspace, window, cx| { - let task = workspace.save_all_internal(SaveIntent::SaveAll, window, cx); - // Match the type of the other arm by ignoring the bool value returned - cx.background_spawn(async { task.await.map(|_| ()) }) - }); - save_all.ok() - } - SaveStrategy::Current => { - let save_current = workspace.update_in(cx, |workspace, window, cx| { - workspace.save_active_item(SaveIntent::SaveAll, window, cx) - }); - save_current.ok() - } - SaveStrategy::None => None, - }; - if let Some(save_action) = save_action { - save_action.log_err().await; - } + Self::save_for_task(&workspace, spawn_in_terminal.save, cx).await; let spawn_task = workspace.update_in(cx, |workspace, window, cx| { workspace @@ -132,6 +113,32 @@ impl Workspace { } } + pub async fn save_for_task( + workspace: &WeakEntity, + save_strategy: SaveStrategy, + cx: &mut AsyncWindowContext, + ) { + let save_action = match save_strategy { + SaveStrategy::All => { + let save_all = workspace.update_in(cx, |workspace, window, cx| { + let task = workspace.save_all_internal(SaveIntent::SaveAll, window, cx); + cx.background_spawn(async { task.await.map(|_| ()) }) + }); + save_all.ok() + } + SaveStrategy::Current => { + let save_current = workspace.update_in(cx, |workspace, window, cx| { + workspace.save_active_item(SaveIntent::SaveAll, window, cx) + }); + save_current.ok() + } + SaveStrategy::None => None, + }; + if let Some(save_action) = save_action { + save_action.log_err().await; + } + } + pub fn start_debug_session( &mut self, scenario: DebugScenario, @@ -417,6 +424,69 @@ mod tests { item } + #[gpui::test] + async fn test_save_for_task_all(cx: &mut TestAppContext) { + let (fixture, cx) = create_fixture(cx, SaveStrategy::All).await; + let workspace = fixture.workspace.downgrade(); + cx.run_until_parked(); + + assert!(cx.read(|cx| fixture.item.read(cx).is_dirty)); + fixture.workspace.update_in(cx, |_workspace, window, cx| { + cx.spawn_in(window, { + let workspace = workspace.clone(); + async move |_this, cx| { + Workspace::save_for_task(&workspace, SaveStrategy::All, cx).await; + } + }) + .detach(); + }); + cx.run_until_parked(); + assert!(cx.read(|cx| !fixture.item.read(cx).is_dirty)); + } + + #[gpui::test] + async fn test_save_for_task_none(cx: &mut TestAppContext) { + let (fixture, cx) = create_fixture(cx, SaveStrategy::None).await; + let workspace = fixture.workspace.downgrade(); + cx.run_until_parked(); + + assert!(cx.read(|cx| fixture.item.read(cx).is_dirty)); + fixture.workspace.update_in(cx, |_workspace, window, cx| { + cx.spawn_in(window, { + let workspace = workspace.clone(); + async move |_this, cx| { + Workspace::save_for_task(&workspace, SaveStrategy::None, cx).await; + } + }) + .detach(); + }); + cx.run_until_parked(); + assert!(cx.read(|cx| fixture.item.read(cx).is_dirty)); + } + + #[gpui::test] + async fn test_save_for_task_current(cx: &mut TestAppContext) { + let (fixture, cx) = create_fixture(cx, SaveStrategy::Current).await; + let inactive = add_test_item(&fixture.workspace, "file2.txt", false, cx); + let workspace = fixture.workspace.downgrade(); + cx.run_until_parked(); + + assert!(cx.read(|cx| fixture.item.read(cx).is_dirty)); + assert!(cx.read(|cx| inactive.read(cx).is_dirty)); + fixture.workspace.update_in(cx, |_workspace, window, cx| { + cx.spawn_in(window, { + let workspace = workspace.clone(); + async move |_this, cx| { + Workspace::save_for_task(&workspace, SaveStrategy::Current, cx).await; + } + }) + .detach(); + }); + cx.run_until_parked(); + assert!(cx.read(|cx| !fixture.item.read(cx).is_dirty)); + assert!(cx.read(|cx| inactive.read(cx).is_dirty)); + } + struct TestTerminalProvider { item: Entity, dirty_before_spawn: Arc>>,