From 7a7ff4bb960faa05b5fadbd2cd9baf494685a949 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 20 Sep 2023 20:13:52 -0600 Subject: [PATCH] Fix save related tests, and refactor saves again --- crates/vim/src/command.rs | 43 ++++--- crates/workspace/src/item.rs | 6 +- crates/workspace/src/pane.rs | 195 +++++++++++++++--------------- crates/workspace/src/workspace.rs | 47 +++---- crates/zed/src/zed.rs | 28 +++-- 5 files changed, 156 insertions(+), 163 deletions(-) diff --git a/crates/vim/src/command.rs b/crates/vim/src/command.rs index 2ad8f0522eb84ac1a94348d4397f99259828e4d6..6bed7f5bb4b995df69bfb055b9b7a6acc64847ca 100644 --- a/crates/vim/src/command.rs +++ b/crates/vim/src/command.rs @@ -2,7 +2,7 @@ use command_palette::CommandInterceptResult; use editor::{SortLinesCaseInsensitive, SortLinesCaseSensitive}; use gpui::{impl_actions, Action, AppContext}; use serde_derive::Deserialize; -use workspace::{SaveBehavior, Workspace}; +use workspace::{SaveIntent, Workspace}; use crate::{ motion::{EndOfDocument, Motion}, @@ -50,112 +50,119 @@ pub fn command_interceptor(mut query: &str, _: &AppContext) -> Option ( "write", workspace::Save { - save_behavior: Some(SaveBehavior::PromptOnConflict), + save_behavior: Some(SaveIntent::Save), } .boxed_clone(), ), "w!" | "wr!" | "wri!" | "writ!" | "write!" => ( "write!", workspace::Save { - save_behavior: Some(SaveBehavior::SilentlyOverwrite), + save_behavior: Some(SaveIntent::Overwrite), } .boxed_clone(), ), "q" | "qu" | "qui" | "quit" => ( "quit", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::PromptOnWrite), + save_behavior: Some(SaveIntent::Close), } .boxed_clone(), ), "q!" | "qu!" | "qui!" | "quit!" => ( "quit!", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::DontSave), + save_behavior: Some(SaveIntent::Skip), } .boxed_clone(), ), "wq" => ( "wq", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::PromptOnConflict), + save_behavior: Some(SaveIntent::Save), } .boxed_clone(), ), "wq!" => ( "wq!", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::SilentlyOverwrite), + save_behavior: Some(SaveIntent::Overwrite), } .boxed_clone(), ), "x" | "xi" | "xit" | "exi" | "exit" => ( "exit", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::PromptOnConflict), + save_behavior: Some(SaveIntent::Save), } .boxed_clone(), ), "x!" | "xi!" | "xit!" | "exi!" | "exit!" => ( "exit!", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::SilentlyOverwrite), + save_behavior: Some(SaveIntent::Overwrite), + } + .boxed_clone(), + ), + "up" | "upd" | "upda" | "updat" | "update" => ( + "update", + workspace::Save { + save_behavior: Some(SaveIntent::SaveAll), } .boxed_clone(), ), "wa" | "wal" | "wall" => ( "wall", workspace::SaveAll { - save_behavior: Some(SaveBehavior::PromptOnConflict), + save_behavior: Some(SaveIntent::SaveAll), } .boxed_clone(), ), "wa!" | "wal!" | "wall!" => ( "wall!", workspace::SaveAll { - save_behavior: Some(SaveBehavior::SilentlyOverwrite), + save_behavior: Some(SaveIntent::Overwrite), } .boxed_clone(), ), "qa" | "qal" | "qall" | "quita" | "quital" | "quitall" => ( "quitall", workspace::CloseAllItemsAndPanes { - save_behavior: Some(SaveBehavior::PromptOnWrite), + save_behavior: Some(SaveIntent::Close), } .boxed_clone(), ), "qa!" | "qal!" | "qall!" | "quita!" | "quital!" | "quitall!" => ( "quitall!", workspace::CloseAllItemsAndPanes { - save_behavior: Some(SaveBehavior::DontSave), + save_behavior: Some(SaveIntent::Skip), } .boxed_clone(), ), "xa" | "xal" | "xall" => ( "xall", workspace::CloseAllItemsAndPanes { - save_behavior: Some(SaveBehavior::PromptOnConflict), + save_behavior: Some(SaveIntent::SaveAll), } .boxed_clone(), ), "xa!" | "xal!" | "xall!" => ( "xall!", workspace::CloseAllItemsAndPanes { - save_behavior: Some(SaveBehavior::SilentlyOverwrite), + save_behavior: Some(SaveIntent::Overwrite), } .boxed_clone(), ), "wqa" | "wqal" | "wqall" => ( "wqall", workspace::CloseAllItemsAndPanes { - save_behavior: Some(SaveBehavior::PromptOnConflict), + save_behavior: Some(SaveIntent::SaveAll), } .boxed_clone(), ), "wqa!" | "wqal!" | "wqall!" => ( "wqall!", workspace::CloseAllItemsAndPanes { - save_behavior: Some(SaveBehavior::SilentlyOverwrite), + save_behavior: Some(SaveIntent::Overwrite), } .boxed_clone(), ), @@ -190,7 +197,7 @@ pub fn command_interceptor(mut query: &str, _: &AppContext) -> Option ( "tabclose", workspace::CloseActiveItem { - save_behavior: Some(SaveBehavior::PromptOnWrite), + save_behavior: Some(SaveIntent::Close), } .boxed_clone(), ), diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index ea747b3a364720c653f91ce7b8bc609750509fe3..24bed4c8d1427f0497ca0151a16b14133abbb514 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -475,11 +475,7 @@ impl ItemHandle for ViewHandle { match item_event { ItemEvent::CloseItem => { pane.update(cx, |pane, cx| { - pane.close_item_by_id( - item.id(), - crate::SaveBehavior::PromptOnWrite, - cx, - ) + pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx) }) .detach_and_log_err(cx); return; diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 285cf1da603c64977c6942131105c0fe2462b263..40e6d36f3bea4419d69be1b6e7dd31b6435cabcd 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -45,17 +45,21 @@ use theme::{Theme, ThemeSettings}; #[derive(PartialEq, Clone, Copy, Deserialize, Debug)] #[serde(rename_all = "camelCase")] -pub enum SaveBehavior { - /// ask before overwriting conflicting files (used by default with cmd-s) - PromptOnConflict, - /// ask for a new path before writing (used with cmd-shift-s) - PromptForNewPath, - /// ask before writing any file that wouldn't be auto-saved (used by default with cmd-w) - PromptOnWrite, - /// never prompt, write on conflict (used with vim's :w!) - SilentlyOverwrite, - /// skip all save-related behaviour (used with vim's :q!) - DontSave, +pub enum SaveIntent { + /// write all files (even if unchanged) + /// prompt before overwriting on-disk changes + Save, + /// write any files that have local changes + /// prompt before overwriting on-disk changes + SaveAll, + /// always prompt for a new path + SaveAs, + /// prompt "you have unsaved changes" before writing + Close, + /// write all dirty files, don't prompt on conflict + Overwrite, + /// skip all save-related behavior + Skip, } #[derive(Clone, Deserialize, PartialEq)] @@ -82,13 +86,13 @@ pub struct CloseItemsToTheRightById { #[derive(Clone, PartialEq, Debug, Deserialize, Default)] #[serde(rename_all = "camelCase")] pub struct CloseActiveItem { - pub save_behavior: Option, + pub save_behavior: Option, } #[derive(Clone, PartialEq, Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CloseAllItems { - pub save_behavior: Option, + pub save_behavior: Option, } actions!( @@ -730,7 +734,7 @@ impl Pane { let active_item_id = self.items[self.active_item_index].id(); Some(self.close_item_by_id( active_item_id, - action.save_behavior.unwrap_or(SaveBehavior::PromptOnWrite), + action.save_behavior.unwrap_or(SaveIntent::Close), cx, )) } @@ -738,7 +742,7 @@ impl Pane { pub fn close_item_by_id( &mut self, item_id_to_close: usize, - save_behavior: SaveBehavior, + save_behavior: SaveIntent, cx: &mut ViewContext, ) -> Task> { self.close_items(cx, save_behavior, move |view_id| { @@ -756,11 +760,9 @@ impl Pane { } let active_item_id = self.items[self.active_item_index].id(); - Some( - self.close_items(cx, SaveBehavior::PromptOnWrite, move |item_id| { - item_id != active_item_id - }), - ) + Some(self.close_items(cx, SaveIntent::Close, move |item_id| { + item_id != active_item_id + })) } pub fn close_clean_items( @@ -773,11 +775,9 @@ impl Pane { .filter(|item| !item.is_dirty(cx)) .map(|item| item.id()) .collect(); - Some( - self.close_items(cx, SaveBehavior::PromptOnWrite, move |item_id| { - item_ids.contains(&item_id) - }), - ) + Some(self.close_items(cx, SaveIntent::Close, move |item_id| { + item_ids.contains(&item_id) + })) } pub fn close_items_to_the_left( @@ -802,7 +802,7 @@ impl Pane { .take_while(|item| item.id() != item_id) .map(|item| item.id()) .collect(); - self.close_items(cx, SaveBehavior::PromptOnWrite, move |item_id| { + self.close_items(cx, SaveIntent::Close, move |item_id| { item_ids.contains(&item_id) }) } @@ -830,7 +830,7 @@ impl Pane { .take_while(|item| item.id() != item_id) .map(|item| item.id()) .collect(); - self.close_items(cx, SaveBehavior::PromptOnWrite, move |item_id| { + self.close_items(cx, SaveIntent::Close, move |item_id| { item_ids.contains(&item_id) }) } @@ -846,7 +846,7 @@ impl Pane { Some(self.close_items( cx, - action.save_behavior.unwrap_or(SaveBehavior::PromptOnWrite), + action.save_behavior.unwrap_or(SaveIntent::Close), |_| true, )) } @@ -854,7 +854,7 @@ impl Pane { pub fn close_items( &mut self, cx: &mut ViewContext, - save_behavior: SaveBehavior, + save_behavior: SaveIntent, should_close: impl 'static + Fn(usize) -> bool, ) -> Task> { // Find the items to close. @@ -1010,18 +1010,18 @@ impl Pane { pane: &WeakViewHandle, item_ix: usize, item: &dyn ItemHandle, - save_behavior: SaveBehavior, + save_behavior: SaveIntent, cx: &mut AsyncAppContext, ) -> Result { const CONFLICT_MESSAGE: &str = "This file has changed on disk since you started editing it. Do you want to overwrite it?"; const DIRTY_MESSAGE: &str = "This file contains unsaved edits. Do you want to save it?"; - if save_behavior == SaveBehavior::DontSave { + if save_behavior == SaveIntent::Skip { return Ok(true); } - let (mut has_conflict, mut is_dirty, mut can_save, is_singleton) = cx.read(|cx| { + let (mut has_conflict, mut is_dirty, mut can_save, can_save_as) = cx.read(|cx| { ( item.has_conflict(cx), item.is_dirty(cx), @@ -1030,73 +1030,76 @@ impl Pane { ) }); - if save_behavior == SaveBehavior::PromptForNewPath { - has_conflict = false; + // when saving a single buffer, we ignore whether or not it's dirty. + if save_behavior == SaveIntent::Save { is_dirty = true; + } + + if save_behavior == SaveIntent::SaveAs { + is_dirty = true; + has_conflict = false; can_save = false; } + if save_behavior == SaveIntent::Overwrite { + has_conflict = false; + } + if has_conflict && can_save { - if save_behavior == SaveBehavior::SilentlyOverwrite { - pane.update(cx, |_, cx| item.save(project, cx))?.await?; - } else { - let mut answer = pane.update(cx, |pane, cx| { - pane.activate_item(item_ix, true, true, cx); - cx.prompt( - PromptLevel::Warning, - CONFLICT_MESSAGE, - &["Overwrite", "Discard", "Cancel"], - ) - })?; - match answer.next().await { - Some(0) => pane.update(cx, |_, cx| item.save(project, cx))?.await?, - Some(1) => pane.update(cx, |_, cx| item.reload(project, cx))?.await?, - _ => return Ok(false), - } + let mut answer = pane.update(cx, |pane, cx| { + pane.activate_item(item_ix, true, true, cx); + cx.prompt( + PromptLevel::Warning, + CONFLICT_MESSAGE, + &["Overwrite", "Discard", "Cancel"], + ) + })?; + match answer.next().await { + Some(0) => pane.update(cx, |_, cx| item.save(project, cx))?.await?, + Some(1) => pane.update(cx, |_, cx| item.reload(project, cx))?.await?, + _ => return Ok(false), } - } else if is_dirty && (can_save || is_singleton) { - let will_autosave = cx.read(|cx| { - matches!( - settings::get::(cx).autosave, - AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange - ) && Self::can_autosave_item(&*item, cx) - }); - let should_save = if save_behavior == SaveBehavior::PromptOnWrite && !will_autosave { - let mut answer = pane.update(cx, |pane, cx| { - pane.activate_item(item_ix, true, true, cx); - cx.prompt( - PromptLevel::Warning, - DIRTY_MESSAGE, - &["Save", "Don't Save", "Cancel"], - ) - })?; - match answer.next().await { - Some(0) => true, - Some(1) => false, - _ => return Ok(false), + } else if is_dirty && (can_save || can_save_as) { + if save_behavior == SaveIntent::Close { + let will_autosave = cx.read(|cx| { + matches!( + settings::get::(cx).autosave, + AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange + ) && Self::can_autosave_item(&*item, cx) + }); + if !will_autosave { + let mut answer = pane.update(cx, |pane, cx| { + pane.activate_item(item_ix, true, true, cx); + cx.prompt( + PromptLevel::Warning, + DIRTY_MESSAGE, + &["Save", "Don't Save", "Cancel"], + ) + })?; + match answer.next().await { + Some(0) => {} + Some(1) => return Ok(true), // Don't save this file + _ => return Ok(false), // Cancel + } } - } else { - true - }; + } - if should_save { - if can_save { - pane.update(cx, |_, cx| item.save(project, cx))?.await?; - } else if is_singleton { - let start_abs_path = project - .read_with(cx, |project, cx| { - let worktree = project.visible_worktrees(cx).next()?; - Some(worktree.read(cx).as_local()?.abs_path().to_path_buf()) - }) - .unwrap_or_else(|| Path::new("").into()); + if can_save { + pane.update(cx, |_, cx| item.save(project, cx))?.await?; + } else if can_save_as { + let start_abs_path = project + .read_with(cx, |project, cx| { + let worktree = project.visible_worktrees(cx).next()?; + Some(worktree.read(cx).as_local()?.abs_path().to_path_buf()) + }) + .unwrap_or_else(|| Path::new("").into()); - let mut abs_path = cx.update(|cx| cx.prompt_for_new_path(&start_abs_path)); - if let Some(abs_path) = abs_path.next().await.flatten() { - pane.update(cx, |_, cx| item.save_as(project, abs_path, cx))? - .await?; - } else { - return Ok(false); - } + let mut abs_path = cx.update(|cx| cx.prompt_for_new_path(&start_abs_path)); + if let Some(abs_path) = abs_path.next().await.flatten() { + pane.update(cx, |_, cx| item.save_as(project, abs_path, cx))? + .await?; + } else { + return Ok(false); } } } @@ -1210,7 +1213,7 @@ impl Pane { pane.update(cx, |pane, cx| { pane.close_item_by_id( target_item_id, - SaveBehavior::PromptOnWrite, + SaveIntent::Close, cx, ) .detach_and_log_err(cx); @@ -1367,12 +1370,8 @@ impl Pane { .on_click(MouseButton::Middle, { let item_id = item.id(); move |_, pane, cx| { - pane.close_item_by_id( - item_id, - SaveBehavior::PromptOnWrite, - cx, - ) - .detach_and_log_err(cx); + pane.close_item_by_id(item_id, SaveIntent::Close, cx) + .detach_and_log_err(cx); } }) .on_down( @@ -1580,7 +1579,7 @@ impl Pane { cx.window_context().defer(move |cx| { if let Some(pane) = pane.upgrade(cx) { pane.update(cx, |pane, cx| { - pane.close_item_by_id(item_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(item_id, SaveIntent::Close, cx) .detach_and_log_err(cx); }); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 6043b946214257642082194043395a75d7417138..a853691b7644028e570e7b7b78176d71d2f1aca2 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -163,19 +163,19 @@ pub struct NewFileInDirection(pub SplitDirection); #[derive(Clone, PartialEq, Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SaveAll { - pub save_behavior: Option, + pub save_behavior: Option, } #[derive(Clone, PartialEq, Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Save { - pub save_behavior: Option, + pub save_behavior: Option, } #[derive(Clone, PartialEq, Debug, Deserialize, Default)] #[serde(rename_all = "camelCase")] pub struct CloseAllItemsAndPanes { - pub save_behavior: Option, + pub save_behavior: Option, } #[derive(Deserialize)] @@ -294,19 +294,14 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { cx.add_action( |workspace: &mut Workspace, action: &Save, cx: &mut ViewContext| { workspace - .save_active_item( - action - .save_behavior - .unwrap_or(SaveBehavior::PromptOnConflict), - cx, - ) + .save_active_item(action.save_behavior.unwrap_or(SaveIntent::Save), cx) .detach_and_log_err(cx); }, ); cx.add_action( |workspace: &mut Workspace, _: &SaveAs, cx: &mut ViewContext| { workspace - .save_active_item(SaveBehavior::PromptForNewPath, cx) + .save_active_item(SaveIntent::SaveAs, cx) .detach_and_log_err(cx); }, ); @@ -1356,7 +1351,7 @@ impl Workspace { Ok(this .update(&mut cx, |this, cx| { - this.save_all_internal(SaveBehavior::PromptOnWrite, cx) + this.save_all_internal(SaveIntent::Close, cx) })? .await?) }) @@ -1367,12 +1362,8 @@ impl Workspace { action: &SaveAll, cx: &mut ViewContext, ) -> Option>> { - let save_all = self.save_all_internal( - action - .save_behavior - .unwrap_or(SaveBehavior::PromptOnConflict), - cx, - ); + let save_all = + self.save_all_internal(action.save_behavior.unwrap_or(SaveIntent::SaveAll), cx); Some(cx.foreground().spawn(async move { save_all.await?; Ok(()) @@ -1381,7 +1372,7 @@ impl Workspace { fn save_all_internal( &mut self, - save_behaviour: SaveBehavior, + save_behaviour: SaveIntent, cx: &mut ViewContext, ) -> Task> { if self.project.read(cx).is_read_only() { @@ -1688,7 +1679,7 @@ impl Workspace { pub fn save_active_item( &mut self, - save_behavior: SaveBehavior, + save_behavior: SaveIntent, cx: &mut ViewContext, ) -> Task> { let project = self.project.clone(); @@ -1720,7 +1711,7 @@ impl Workspace { _: &CloseInactiveTabsAndPanes, cx: &mut ViewContext, ) -> Option>> { - self.close_all_internal(true, SaveBehavior::PromptOnWrite, cx) + self.close_all_internal(true, SaveIntent::Close, cx) } pub fn close_all_items_and_panes( @@ -1728,17 +1719,13 @@ impl Workspace { action: &CloseAllItemsAndPanes, cx: &mut ViewContext, ) -> Option>> { - self.close_all_internal( - false, - action.save_behavior.unwrap_or(SaveBehavior::PromptOnWrite), - cx, - ) + self.close_all_internal(false, action.save_behavior.unwrap_or(SaveIntent::Close), cx) } fn close_all_internal( &mut self, retain_active_pane: bool, - save_behavior: SaveBehavior, + save_behavior: SaveIntent, cx: &mut ViewContext, ) -> Option>> { let current_pane = self.active_pane(); @@ -4433,7 +4420,7 @@ mod tests { let item1_id = item1.id(); let item3_id = item3.id(); let item4_id = item4.id(); - pane.close_items(cx, SaveBehavior::PromptOnWrite, move |id| { + pane.close_items(cx, SaveIntent::Close, move |id| { [item1_id, item3_id, item4_id].contains(&id) }) }); @@ -4571,7 +4558,7 @@ mod tests { // prompts, the task should complete. let close = left_pane.update(cx, |pane, cx| { - pane.close_items(cx, SaveBehavior::PromptOnWrite, move |_| true) + pane.close_items(cx, SaveIntent::Close, move |_| true) }); cx.foreground().run_until_parked(); left_pane.read_with(cx, |pane, cx| { @@ -4689,7 +4676,7 @@ mod tests { }); pane.update(cx, |pane, cx| { - pane.close_items(cx, SaveBehavior::PromptOnWrite, move |id| id == item_id) + pane.close_items(cx, SaveIntent::Close, move |id| id == item_id) }) .await .unwrap(); @@ -4712,7 +4699,7 @@ mod tests { // Ensure autosave is prevented for deleted files also when closing the buffer. let _close_items = pane.update(cx, |pane, cx| { - pane.close_items(cx, SaveBehavior::PromptOnWrite, move |id| id == item_id) + pane.close_items(cx, SaveIntent::Close, move |id| id == item_id) }); deterministic.run_until_parked(); assert!(window.has_pending_prompt(cx)); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 72804cb523ddb8d335339dda7c07622b4d3cf32e..5363262e3f610d5a5bd073132ee26df29feb5dae 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -744,7 +744,7 @@ mod tests { use theme::{ThemeRegistry, ThemeSettings}; use workspace::{ item::{Item, ItemHandle}, - open_new, open_paths, pane, NewFile, SaveBehavior, SplitDirection, WorkspaceHandle, + open_new, open_paths, pane, NewFile, SaveIntent, SplitDirection, WorkspaceHandle, }; #[gpui::test] @@ -945,12 +945,14 @@ mod tests { editor.update(cx, |editor, cx| { assert!(editor.text(cx).is_empty()); + assert!(!editor.is_dirty(cx)); }); let save_task = workspace.update(cx, |workspace, cx| { - workspace.save_active_item(SaveBehavior::PromptOnConflict, cx) + workspace.save_active_item(SaveIntent::Save, cx) }); app_state.fs.create_dir(Path::new("/root")).await.unwrap(); + cx.foreground().run_until_parked(); cx.simulate_new_path_selection(|_| Some(PathBuf::from("/root/the-new-name"))); save_task.await.unwrap(); editor.read_with(cx, |editor, cx| { @@ -1314,7 +1316,7 @@ mod tests { cx.read(|cx| assert!(editor.is_dirty(cx))); let save_task = workspace.update(cx, |workspace, cx| { - workspace.save_active_item(SaveBehavior::PromptOnConflict, cx) + workspace.save_active_item(SaveIntent::Save, cx) }); window.simulate_prompt_answer(0, cx); save_task.await.unwrap(); @@ -1358,8 +1360,9 @@ mod tests { // Save the buffer. This prompts for a filename. let save_task = workspace.update(cx, |workspace, cx| { - workspace.save_active_item(SaveBehavior::PromptOnConflict, cx) + workspace.save_active_item(SaveIntent::Save, cx) }); + cx.foreground().run_until_parked(); cx.simulate_new_path_selection(|parent_dir| { assert_eq!(parent_dir, Path::new("/root")); Some(parent_dir.join("the-new-name.rs")) @@ -1384,7 +1387,7 @@ mod tests { assert!(editor.is_dirty(cx)); }); let save_task = workspace.update(cx, |workspace, cx| { - workspace.save_active_item(SaveBehavior::PromptOnConflict, cx) + workspace.save_active_item(SaveIntent::Save, cx) }); save_task.await.unwrap(); assert!(!cx.did_prompt_for_new_path()); @@ -1453,8 +1456,9 @@ mod tests { // Save the buffer. This prompts for a filename. let save_task = workspace.update(cx, |workspace, cx| { - workspace.save_active_item(SaveBehavior::PromptOnConflict, cx) + workspace.save_active_item(SaveIntent::Save, cx) }); + cx.foreground().run_until_parked(); cx.simulate_new_path_selection(|_| Some(PathBuf::from("/root/the-new-name.rs"))); save_task.await.unwrap(); // The buffer is not dirty anymore and the language is assigned based on the path. @@ -1692,7 +1696,7 @@ mod tests { pane.update(cx, |pane, cx| { let editor3_id = editor3.id(); drop(editor3); - pane.close_item_by_id(editor3_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(editor3_id, SaveIntent::Close, cx) }) .await .unwrap(); @@ -1727,7 +1731,7 @@ mod tests { pane.update(cx, |pane, cx| { let editor2_id = editor2.id(); drop(editor2); - pane.close_item_by_id(editor2_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(editor2_id, SaveIntent::Close, cx) }) .await .unwrap(); @@ -1884,28 +1888,28 @@ mod tests { // Close all the pane items in some arbitrary order. pane.update(cx, |pane, cx| { - pane.close_item_by_id(file1_item_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(file1_item_id, SaveIntent::Close, cx) }) .await .unwrap(); assert_eq!(active_path(&workspace, cx), Some(file4.clone())); pane.update(cx, |pane, cx| { - pane.close_item_by_id(file4_item_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(file4_item_id, SaveIntent::Close, cx) }) .await .unwrap(); assert_eq!(active_path(&workspace, cx), Some(file3.clone())); pane.update(cx, |pane, cx| { - pane.close_item_by_id(file2_item_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(file2_item_id, SaveIntent::Close, cx) }) .await .unwrap(); assert_eq!(active_path(&workspace, cx), Some(file3.clone())); pane.update(cx, |pane, cx| { - pane.close_item_by_id(file3_item_id, SaveBehavior::PromptOnWrite, cx) + pane.close_item_by_id(file3_item_id, SaveIntent::Close, cx) }) .await .unwrap();