@@ -42,7 +42,6 @@ use std::{
},
};
use theme::{Theme, ThemeSettings};
-use util::truncate_and_remove_front;
#[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
@@ -840,45 +839,10 @@ impl Pane {
Some(self.close_items(cx, SaveBehavior::PromptOnWrite, |_| true))
}
- pub(super) fn file_names_for_prompt(
- items: &mut dyn Iterator<Item = &Box<dyn ItemHandle>>,
- all_dirty_items: usize,
- cx: &AppContext,
- ) -> String {
- /// Quantity of item paths displayed in prompt prior to cutoff..
- const FILE_NAMES_CUTOFF_POINT: usize = 10;
- let mut file_names: Vec<_> = items
- .filter_map(|item| {
- item.project_path(cx).and_then(|project_path| {
- project_path
- .path
- .file_name()
- .and_then(|name| name.to_str().map(ToOwned::to_owned))
- })
- })
- .take(FILE_NAMES_CUTOFF_POINT)
- .collect();
- let should_display_followup_text =
- all_dirty_items > FILE_NAMES_CUTOFF_POINT || file_names.len() != all_dirty_items;
- if should_display_followup_text {
- let not_shown_files = all_dirty_items - file_names.len();
- if not_shown_files == 1 {
- file_names.push(".. 1 file not shown".into());
- } else {
- file_names.push(format!(".. {} files not shown", not_shown_files).into());
- }
- }
- let file_names = file_names.join("\n");
- format!(
- "Do you want to save changes to the following {} files?\n{file_names}",
- all_dirty_items
- )
- }
-
pub fn close_items(
&mut self,
cx: &mut ViewContext<Pane>,
- mut save_behavior: SaveBehavior,
+ save_behavior: SaveBehavior,
should_close: impl 'static + Fn(usize) -> bool,
) -> Task<Result<()>> {
// Find the items to close.
@@ -897,25 +861,6 @@ impl Pane {
let workspace = self.workspace.clone();
cx.spawn(|pane, mut cx| async move {
- if save_behavior == SaveBehavior::PromptOnWrite && items_to_close.len() > 1 {
- let mut answer = pane.update(&mut cx, |_, cx| {
- let prompt = Self::file_names_for_prompt(
- &mut items_to_close.iter(),
- items_to_close.len(),
- cx,
- );
- cx.prompt(
- PromptLevel::Warning,
- &prompt,
- &["Save all", "Discard all", "Cancel"],
- )
- })?;
- match answer.next().await {
- Some(0) => save_behavior = SaveBehavior::PromptOnConflict,
- Some(1) => save_behavior = SaveBehavior::DontSave,
- _ => {}
- }
- }
let mut saved_project_items_ids = HashSet::default();
for item in items_to_close.clone() {
// Find the item's current index and its set of project item models. Avoid
@@ -1058,6 +1003,7 @@ impl Pane {
) -> Result<bool> {
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 {
return Ok(true);
@@ -1100,10 +1046,9 @@ impl Pane {
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);
- let prompt = dirty_message_for(item.project_path(cx));
cx.prompt(
PromptLevel::Warning,
- &prompt,
+ DIRTY_MESSAGE,
&["Save", "Don't Save", "Cancel"],
)
})?;
@@ -2190,15 +2135,6 @@ impl<V: 'static> Element<V> for PaneBackdrop<V> {
}
}
-fn dirty_message_for(buffer_path: Option<ProjectPath>) -> String {
- let path = buffer_path
- .as_ref()
- .and_then(|p| p.path.to_str())
- .unwrap_or(&"Untitled buffer");
- let path = truncate_and_remove_front(path, 80);
- format!("{path} contains unsaved edits. Do you want to save it?")
-}
-
#[cfg(test)]
mod tests {
use super::*;
@@ -2543,14 +2479,12 @@ mod tests {
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
- let task = pane
- .update(cx, |pane, cx| {
- pane.close_inactive_items(&CloseInactiveItems, cx)
- })
- .unwrap();
- cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx);
- task.await.unwrap();
+ pane.update(cx, |pane, cx| {
+ pane.close_inactive_items(&CloseInactiveItems, cx)
+ })
+ .unwrap()
+ .await
+ .unwrap();
assert_item_labels(&pane, ["C*"], cx);
}
@@ -2571,12 +2505,10 @@ mod tests {
add_labeled_item(&pane, "E", false, cx);
assert_item_labels(&pane, ["A^", "B", "C^", "D", "E*"], cx);
- let task = pane
- .update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx))
+ pane.update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx))
+ .unwrap()
+ .await
.unwrap();
- cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx);
- task.await.unwrap();
assert_item_labels(&pane, ["A^", "C*^"], cx);
}
@@ -2592,14 +2524,12 @@ mod tests {
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
- let task = pane
- .update(cx, |pane, cx| {
- pane.close_items_to_the_left(&CloseItemsToTheLeft, cx)
- })
- .unwrap();
- cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx);
- task.await.unwrap();
+ pane.update(cx, |pane, cx| {
+ pane.close_items_to_the_left(&CloseItemsToTheLeft, cx)
+ })
+ .unwrap()
+ .await
+ .unwrap();
assert_item_labels(&pane, ["C*", "D", "E"], cx);
}
@@ -2615,14 +2545,12 @@ mod tests {
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
- let task = pane
- .update(cx, |pane, cx| {
- pane.close_items_to_the_right(&CloseItemsToTheRight, cx)
- })
- .unwrap();
- cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx);
- task.await.unwrap();
+ pane.update(cx, |pane, cx| {
+ pane.close_items_to_the_right(&CloseItemsToTheRight, cx)
+ })
+ .unwrap()
+ .await
+ .unwrap();
assert_item_labels(&pane, ["A", "B", "C*"], cx);
}
@@ -2641,12 +2569,10 @@ mod tests {
add_labeled_item(&pane, "C", false, cx);
assert_item_labels(&pane, ["A", "B", "C*"], cx);
- let t = pane
- .update(cx, |pane, cx| pane.close_all_items(&CloseAllItems, cx))
+ pane.update(cx, |pane, cx| pane.close_all_items(&CloseAllItems, cx))
+ .unwrap()
+ .await
.unwrap();
- cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx);
- t.await.unwrap();
assert_item_labels(&pane, [], cx);
}
@@ -1333,12 +1333,13 @@ impl Workspace {
fn save_all_internal(
&mut self,
- mut save_behaviour: SaveBehavior,
+ save_behaviour: SaveBehavior,
cx: &mut ViewContext<Self>,
) -> Task<Result<bool>> {
if self.project.read(cx).is_read_only() {
return Task::ready(Ok(true));
}
+
let dirty_items = self
.panes
.iter()
@@ -1354,27 +1355,7 @@ impl Workspace {
.collect::<Vec<_>>();
let project = self.project.clone();
- cx.spawn(|workspace, mut cx| async move {
- // Override save mode and display "Save all files" prompt
- if save_behaviour == SaveBehavior::PromptOnWrite && dirty_items.len() > 1 {
- let mut answer = workspace.update(&mut cx, |_, cx| {
- let prompt = Pane::file_names_for_prompt(
- &mut dirty_items.iter().map(|(_, handle)| handle),
- dirty_items.len(),
- cx,
- );
- cx.prompt(
- PromptLevel::Warning,
- &prompt,
- &["Save all", "Discard all", "Cancel"],
- )
- })?;
- match answer.next().await {
- Some(0) => save_behaviour = SaveBehavior::PromptOnConflict,
- Some(1) => save_behaviour = SaveBehavior::DontSave,
- _ => {}
- }
- }
+ cx.spawn(|_, mut cx| async move {
for (pane, item) in dirty_items {
let (singleton, project_entry_ids) =
cx.read(|cx| (item.is_singleton(cx), item.project_entry_ids(cx)));
@@ -4339,9 +4320,7 @@ mod tests {
});
let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx));
cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx); // cancel save all
- cx.foreground().run_until_parked();
- window.simulate_prompt_answer(2, cx); // cancel save all
+ window.simulate_prompt_answer(2, cx); // cancel
cx.foreground().run_until_parked();
assert!(!window.has_pending_prompt(cx));
assert!(!task.await.unwrap());
@@ -4399,15 +4378,13 @@ mod tests {
});
cx.foreground().run_until_parked();
- assert!(window.has_pending_prompt(cx));
- // Ignore "Save all" prompt
- window.simulate_prompt_answer(2, cx);
- cx.foreground().run_until_parked();
// There's a prompt to save item 1.
pane.read_with(cx, |pane, _| {
assert_eq!(pane.items_len(), 4);
assert_eq!(pane.active_item().unwrap().id(), item1.id());
});
+ assert!(window.has_pending_prompt(cx));
+
// Confirm saving item 1.
window.simulate_prompt_answer(0, cx);
cx.foreground().run_until_parked();
@@ -4535,10 +4512,6 @@ mod tests {
let close = left_pane.update(cx, |pane, cx| {
pane.close_items(cx, SaveBehavior::PromptOnWrite, move |_| true)
});
- cx.foreground().run_until_parked();
- // Discard "Save all" prompt
- window.simulate_prompt_answer(2, cx);
-
cx.foreground().run_until_parked();
left_pane.read_with(cx, |pane, cx| {
assert_eq!(