diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index b875dfdacf..9ffc006687 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -41,7 +41,7 @@ use ui::{ IconSize, Indicator, Label, Tab, TabBar, TabPosition, Tooltip, }; use ui::{v_flex, ContextMenu}; -use util::{maybe, truncate_and_remove_front, ResultExt}; +use util::{debug_panic, maybe, truncate_and_remove_front, ResultExt}; #[derive(PartialEq, Clone, Copy, Deserialize, Debug)] #[serde(rename_all = "camelCase")] @@ -218,6 +218,7 @@ pub struct Pane { /// Otherwise, when `display_nav_history_buttons` is Some, it determines whether nav buttons should be displayed. display_nav_history_buttons: Option, double_click_dispatch_action: Box, + save_modals_spawned: HashSet, } pub struct ActivationHistoryEntry { @@ -401,6 +402,7 @@ impl Pane { ), _subscriptions: subscriptions, double_click_dispatch_action, + save_modals_spawned: HashSet::default(), } } @@ -1367,20 +1369,37 @@ impl Pane { ) && Self::can_autosave_item(item, cx) })?; if !will_autosave { - let 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, - None, - &["Save", "Don't Save", "Cancel"], - ) + let item_id = item.item_id(); + let answer_task = pane.update(cx, |pane, cx| { + if pane.save_modals_spawned.insert(item_id) { + pane.activate_item(item_ix, true, true, cx); + let prompt = dirty_message_for(item.project_path(cx)); + Some(cx.prompt( + PromptLevel::Warning, + &prompt, + None, + &["Save", "Don't Save", "Cancel"], + )) + } else { + None + } })?; - match answer.await { - Ok(0) => {} - Ok(1) => return Ok(true), // Don't save this file - _ => return Ok(false), // Cancel + if let Some(answer_task) = answer_task { + let answer = answer_task.await; + pane.update(cx, |pane, _| { + if !pane.save_modals_spawned.remove(&item_id) { + debug_panic!( + "save modal was not present in spawned modals after awaiting for its answer" + ) + } + })?; + match answer { + Ok(0) => {} + Ok(1) => return Ok(true), // Don't save this file + _ => return Ok(false), // Cancel + } + } else { + return Ok(false); } } }