Code review changes

Conrad Irwin created

Change summary

assets/keymaps/vim.json                       |   4 
crates/command_palette/src/command_palette.rs |   2 
crates/file_finder/src/file_finder.rs         |   9 -
crates/gpui/src/app/test_app_context.rs       |   2 
crates/terminal_view/src/terminal_view.rs     |   7 -
crates/vim/src/command.rs                     |  36 +++---
crates/vim/src/normal/search.rs               | 100 +++++++++++---------
crates/workspace/src/pane.rs                  |  92 +++++-------------
crates/workspace/src/workspace.rs             |  35 ++----
crates/zed/src/menus.rs                       |  18 ---
crates/zed/src/zed.rs                         |   9 -
11 files changed, 127 insertions(+), 187 deletions(-)

Detailed changes

assets/keymaps/vim.json πŸ”—

@@ -206,13 +206,13 @@
       "shift-z shift-q": [
         "pane::CloseActiveItem",
         {
-          "saveBehavior": "dontSave"
+          "saveIntent": "skip"
         }
       ],
       "shift-z shift-z": [
         "pane::CloseActiveItem",
         {
-          "saveBehavior": "promptOnConflict"
+          "saveIntent": "saveAll"
         }
       ],
       // Count support

crates/command_palette/src/command_palette.rs πŸ”—

@@ -297,7 +297,7 @@ impl PickerDelegate for CommandPaletteDelegate {
     }
 }
 
-pub fn humanize_action_name(name: &str) -> String {
+fn humanize_action_name(name: &str) -> String {
     let capacity = name.len() + name.chars().filter(|c| c.is_uppercase()).count();
     let mut result = String::with_capacity(capacity);
     for char in name.chars() {

crates/file_finder/src/file_finder.rs πŸ”—

@@ -1528,13 +1528,8 @@ mod tests {
         let active_pane = cx.read(|cx| workspace.read(cx).active_pane().clone());
         active_pane
             .update(cx, |pane, cx| {
-                pane.close_active_item(
-                    &workspace::CloseActiveItem {
-                        save_behavior: None,
-                    },
-                    cx,
-                )
-                .unwrap()
+                pane.close_active_item(&workspace::CloseActiveItem { save_intent: None }, cx)
+                    .unwrap()
             })
             .await
             .unwrap();

crates/gpui/src/app/test_app_context.rs πŸ”—

@@ -33,7 +33,7 @@ use super::{
 
 #[derive(Clone)]
 pub struct TestAppContext {
-    pub cx: Rc<RefCell<AppContext>>,
+    cx: Rc<RefCell<AppContext>>,
     foreground_platform: Rc<platform::test::ForegroundPlatform>,
     condition_duration: Option<Duration>,
     pub function_name: String,

crates/terminal_view/src/terminal_view.rs πŸ”—

@@ -284,12 +284,7 @@ impl TerminalView {
     pub fn deploy_context_menu(&mut self, position: Vector2F, cx: &mut ViewContext<Self>) {
         let menu_entries = vec![
             ContextMenuItem::action("Clear", Clear),
-            ContextMenuItem::action(
-                "Close",
-                pane::CloseActiveItem {
-                    save_behavior: None,
-                },
-            ),
+            ContextMenuItem::action("Close", pane::CloseActiveItem { save_intent: None }),
         ];
 
         self.context_menu.update(cx, |menu, cx| {

crates/vim/src/command.rs πŸ”—

@@ -50,119 +50,119 @@ pub fn command_interceptor(mut query: &str, _: &AppContext) -> Option<CommandInt
         "w" | "wr" | "wri" | "writ" | "write" => (
             "write",
             workspace::Save {
-                save_behavior: Some(SaveIntent::Save),
+                save_intent: Some(SaveIntent::Save),
             }
             .boxed_clone(),
         ),
         "w!" | "wr!" | "wri!" | "writ!" | "write!" => (
             "write!",
             workspace::Save {
-                save_behavior: Some(SaveIntent::Overwrite),
+                save_intent: Some(SaveIntent::Overwrite),
             }
             .boxed_clone(),
         ),
         "q" | "qu" | "qui" | "quit" => (
             "quit",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Close),
+                save_intent: Some(SaveIntent::Close),
             }
             .boxed_clone(),
         ),
         "q!" | "qu!" | "qui!" | "quit!" => (
             "quit!",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Skip),
+                save_intent: Some(SaveIntent::Skip),
             }
             .boxed_clone(),
         ),
         "wq" => (
             "wq",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Save),
+                save_intent: Some(SaveIntent::Save),
             }
             .boxed_clone(),
         ),
         "wq!" => (
             "wq!",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Overwrite),
+                save_intent: Some(SaveIntent::Overwrite),
             }
             .boxed_clone(),
         ),
         "x" | "xi" | "xit" | "exi" | "exit" => (
             "exit",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Save),
+                save_intent: Some(SaveIntent::SaveAll),
             }
             .boxed_clone(),
         ),
         "x!" | "xi!" | "xit!" | "exi!" | "exit!" => (
             "exit!",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Overwrite),
+                save_intent: Some(SaveIntent::Overwrite),
             }
             .boxed_clone(),
         ),
         "up" | "upd" | "upda" | "updat" | "update" => (
             "update",
             workspace::Save {
-                save_behavior: Some(SaveIntent::SaveAll),
+                save_intent: Some(SaveIntent::SaveAll),
             }
             .boxed_clone(),
         ),
         "wa" | "wal" | "wall" => (
             "wall",
             workspace::SaveAll {
-                save_behavior: Some(SaveIntent::SaveAll),
+                save_intent: Some(SaveIntent::SaveAll),
             }
             .boxed_clone(),
         ),
         "wa!" | "wal!" | "wall!" => (
             "wall!",
             workspace::SaveAll {
-                save_behavior: Some(SaveIntent::Overwrite),
+                save_intent: Some(SaveIntent::Overwrite),
             }
             .boxed_clone(),
         ),
         "qa" | "qal" | "qall" | "quita" | "quital" | "quitall" => (
             "quitall",
             workspace::CloseAllItemsAndPanes {
-                save_behavior: Some(SaveIntent::Close),
+                save_intent: Some(SaveIntent::Close),
             }
             .boxed_clone(),
         ),
         "qa!" | "qal!" | "qall!" | "quita!" | "quital!" | "quitall!" => (
             "quitall!",
             workspace::CloseAllItemsAndPanes {
-                save_behavior: Some(SaveIntent::Skip),
+                save_intent: Some(SaveIntent::Skip),
             }
             .boxed_clone(),
         ),
         "xa" | "xal" | "xall" => (
             "xall",
             workspace::CloseAllItemsAndPanes {
-                save_behavior: Some(SaveIntent::SaveAll),
+                save_intent: Some(SaveIntent::SaveAll),
             }
             .boxed_clone(),
         ),
         "xa!" | "xal!" | "xall!" => (
             "xall!",
             workspace::CloseAllItemsAndPanes {
-                save_behavior: Some(SaveIntent::Overwrite),
+                save_intent: Some(SaveIntent::Overwrite),
             }
             .boxed_clone(),
         ),
         "wqa" | "wqal" | "wqall" => (
             "wqall",
             workspace::CloseAllItemsAndPanes {
-                save_behavior: Some(SaveIntent::SaveAll),
+                save_intent: Some(SaveIntent::SaveAll),
             }
             .boxed_clone(),
         ),
         "wqa!" | "wqal!" | "wqall!" => (
             "wqall!",
             workspace::CloseAllItemsAndPanes {
-                save_behavior: Some(SaveIntent::Overwrite),
+                save_intent: Some(SaveIntent::Overwrite),
             }
             .boxed_clone(),
         ),
@@ -197,7 +197,7 @@ pub fn command_interceptor(mut query: &str, _: &AppContext) -> Option<CommandInt
         "tabc" | "tabcl" | "tabclo" | "tabclos" | "tabclose" => (
             "tabclose",
             workspace::CloseActiveItem {
-                save_behavior: Some(SaveIntent::Close),
+                save_intent: Some(SaveIntent::Close),
             }
             .boxed_clone(),
         ),

crates/vim/src/normal/search.rs πŸ”—

@@ -220,53 +220,58 @@ fn replace_command(
     let replacement = parse_replace_all(&action.query);
     let pane = workspace.active_pane().clone();
     pane.update(cx, |pane, cx| {
-        if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
-            let search = search_bar.update(cx, |search_bar, cx| {
-                if !search_bar.show(cx) {
-                    return None;
-                }
+        let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() else {
+            return;
+        };
+        let search = search_bar.update(cx, |search_bar, cx| {
+            if !search_bar.show(cx) {
+                return None;
+            }
 
-                let mut options = SearchOptions::default();
-                if replacement.is_case_sensitive {
-                    options.set(SearchOptions::CASE_SENSITIVE, true)
-                }
-                let search = if replacement.search == "" {
-                    search_bar.query(cx)
-                } else {
-                    replacement.search
-                };
+            let mut options = SearchOptions::default();
+            if replacement.is_case_sensitive {
+                options.set(SearchOptions::CASE_SENSITIVE, true)
+            }
+            let search = if replacement.search == "" {
+                search_bar.query(cx)
+            } else {
+                replacement.search
+            };
 
-                search_bar.set_replacement(Some(&replacement.replacement), cx);
-                search_bar.activate_search_mode(SearchMode::Regex, cx);
-                Some(search_bar.search(&search, Some(options), cx))
-            });
-            let Some(search) = search else { return };
-            let search_bar = search_bar.downgrade();
-            cx.spawn(|_, mut cx| async move {
-                search.await?;
-                search_bar.update(&mut cx, |search_bar, cx| {
-                    if replacement.should_replace_all {
-                        search_bar.select_last_match(cx);
-                        search_bar.replace_all(&Default::default(), cx);
-                        Vim::update(cx, |vim, cx| {
-                            move_cursor(
-                                vim,
-                                Motion::StartOfLine {
-                                    display_lines: false,
-                                },
-                                None,
-                                cx,
-                            )
-                        })
-                    }
-                })?;
-                anyhow::Ok(())
-            })
-            .detach_and_log_err(cx);
-        }
+            search_bar.set_replacement(Some(&replacement.replacement), cx);
+            search_bar.activate_search_mode(SearchMode::Regex, cx);
+            Some(search_bar.search(&search, Some(options), cx))
+        });
+        let Some(search) = search else { return };
+        let search_bar = search_bar.downgrade();
+        cx.spawn(|_, mut cx| async move {
+            search.await?;
+            search_bar.update(&mut cx, |search_bar, cx| {
+                if replacement.should_replace_all {
+                    search_bar.select_last_match(cx);
+                    search_bar.replace_all(&Default::default(), cx);
+                    Vim::update(cx, |vim, cx| {
+                        move_cursor(
+                            vim,
+                            Motion::StartOfLine {
+                                display_lines: false,
+                            },
+                            None,
+                            cx,
+                        )
+                    })
+                }
+            })?;
+            anyhow::Ok(())
+        })
+        .detach_and_log_err(cx);
     })
 }
 
+// convert a vim query into something more usable by zed.
+// we don't attempt to fully convert between the two regex syntaxes,
+// but we do flip \( and \) to ( and ) (and vice-versa) in the pattern,
+// and convert \0..\9 to $0..$9 in the replacement so that common idioms work.
 fn parse_replace_all(query: &str) -> Replacement {
     let mut chars = query.chars();
     if Some('%') != chars.next() || Some('s') != chars.next() {
@@ -284,17 +289,18 @@ fn parse_replace_all(query: &str) -> Replacement {
     let mut buffer = &mut search;
 
     let mut escaped = false;
+    // 0 - parsing search
+    // 1 - parsing replacement
+    // 2 - parsing flags
     let mut phase = 0;
 
     for c in chars {
         if escaped {
             escaped = false;
             if phase == 1 && c.is_digit(10) {
-                // help vim users discover zed regex syntax
-                // (though we don't try and fix arbitrary patterns for them)
                 buffer.push('$')
+            // unescape escaped parens
             } else if phase == 0 && c == '(' || c == ')' {
-                // un-escape parens
             } else if c != delimeter {
                 buffer.push('\\')
             }
@@ -312,6 +318,10 @@ fn parse_replace_all(query: &str) -> Replacement {
                 break;
             }
         } else {
+            // escape unescaped parens
+            if phase == 0 && c == '(' || c == ')' {
+                buffer.push('\\')
+            }
             buffer.push(c)
         }
     }

crates/workspace/src/pane.rs πŸ”—

@@ -86,13 +86,13 @@ pub struct CloseItemsToTheRightById {
 #[derive(Clone, PartialEq, Debug, Deserialize, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct CloseActiveItem {
-    pub save_behavior: Option<SaveIntent>,
+    pub save_intent: Option<SaveIntent>,
 }
 
 #[derive(Clone, PartialEq, Debug, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct CloseAllItems {
-    pub save_behavior: Option<SaveIntent>,
+    pub save_intent: Option<SaveIntent>,
 }
 
 actions!(
@@ -734,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(SaveIntent::Close),
+            action.save_intent.unwrap_or(SaveIntent::Close),
             cx,
         ))
     }
@@ -742,12 +742,10 @@ impl Pane {
     pub fn close_item_by_id(
         &mut self,
         item_id_to_close: usize,
-        save_behavior: SaveIntent,
+        save_intent: SaveIntent,
         cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>> {
-        self.close_items(cx, save_behavior, move |view_id| {
-            view_id == item_id_to_close
-        })
+        self.close_items(cx, save_intent, move |view_id| view_id == item_id_to_close)
     }
 
     pub fn close_inactive_items(
@@ -844,17 +842,17 @@ impl Pane {
             return None;
         }
 
-        Some(self.close_items(
-            cx,
-            action.save_behavior.unwrap_or(SaveIntent::Close),
-            |_| true,
-        ))
+        Some(
+            self.close_items(cx, action.save_intent.unwrap_or(SaveIntent::Close), |_| {
+                true
+            }),
+        )
     }
 
     pub fn close_items(
         &mut self,
         cx: &mut ViewContext<Pane>,
-        save_behavior: SaveIntent,
+        save_intent: SaveIntent,
         should_close: impl 'static + Fn(usize) -> bool,
     ) -> Task<Result<()>> {
         // Find the items to close.
@@ -912,7 +910,7 @@ impl Pane {
                         &pane,
                         item_ix,
                         &*item,
-                        save_behavior,
+                        save_intent,
                         &mut cx,
                     )
                     .await?
@@ -1010,14 +1008,14 @@ impl Pane {
         pane: &WeakViewHandle<Pane>,
         item_ix: usize,
         item: &dyn ItemHandle,
-        save_behavior: SaveIntent,
+        save_intent: SaveIntent,
         cx: &mut AsyncAppContext,
     ) -> 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 == SaveIntent::Skip {
+        if save_intent == SaveIntent::Skip {
             return Ok(true);
         }
 
@@ -1031,17 +1029,17 @@ impl Pane {
         });
 
         // when saving a single buffer, we ignore whether or not it's dirty.
-        if save_behavior == SaveIntent::Save {
+        if save_intent == SaveIntent::Save {
             is_dirty = true;
         }
 
-        if save_behavior == SaveIntent::SaveAs {
+        if save_intent == SaveIntent::SaveAs {
             is_dirty = true;
             has_conflict = false;
             can_save = false;
         }
 
-        if save_behavior == SaveIntent::Overwrite {
+        if save_intent == SaveIntent::Overwrite {
             has_conflict = false;
         }
 
@@ -1060,7 +1058,7 @@ impl Pane {
                 _ => return Ok(false),
             }
         } else if is_dirty && (can_save || can_save_as) {
-            if save_behavior == SaveIntent::Close {
+            if save_intent == SaveIntent::Close {
                 let will_autosave = cx.read(|cx| {
                     matches!(
                         settings::get::<WorkspaceSettings>(cx).autosave,
@@ -1188,9 +1186,7 @@ impl Pane {
                     vec![
                         ContextMenuItem::action(
                             "Close Active Item",
-                            CloseActiveItem {
-                                save_behavior: None,
-                            },
+                            CloseActiveItem { save_intent: None },
                         ),
                         ContextMenuItem::action("Close Inactive Items", CloseInactiveItems),
                         ContextMenuItem::action("Close Clean Items", CloseCleanItems),
@@ -1198,9 +1194,7 @@ impl Pane {
                         ContextMenuItem::action("Close Items To The Right", CloseItemsToTheRight),
                         ContextMenuItem::action(
                             "Close All Items",
-                            CloseAllItems {
-                                save_behavior: None,
-                            },
+                            CloseAllItems { save_intent: None },
                         ),
                     ]
                 } else {
@@ -1247,9 +1241,7 @@ impl Pane {
                         }),
                         ContextMenuItem::action(
                             "Close All Items",
-                            CloseAllItems {
-                                save_behavior: None,
-                            },
+                            CloseAllItems { save_intent: None },
                         ),
                     ]
                 },
@@ -2182,12 +2174,7 @@ mod tests {
 
         pane.update(cx, |pane, cx| {
             assert!(pane
-                .close_active_item(
-                    &CloseActiveItem {
-                        save_behavior: None
-                    },
-                    cx
-                )
+                .close_active_item(&CloseActiveItem { save_intent: None }, cx)
                 .is_none())
         });
     }
@@ -2439,12 +2426,7 @@ mod tests {
         assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx);
 
         pane.update(cx, |pane, cx| {
-            pane.close_active_item(
-                &CloseActiveItem {
-                    save_behavior: None,
-                },
-                cx,
-            )
+            pane.close_active_item(&CloseActiveItem { save_intent: None }, cx)
         })
         .unwrap()
         .await
@@ -2455,12 +2437,7 @@ mod tests {
         assert_item_labels(&pane, ["A", "B", "C", "D*"], cx);
 
         pane.update(cx, |pane, cx| {
-            pane.close_active_item(
-                &CloseActiveItem {
-                    save_behavior: None,
-                },
-                cx,
-            )
+            pane.close_active_item(&CloseActiveItem { save_intent: None }, cx)
         })
         .unwrap()
         .await
@@ -2468,12 +2445,7 @@ mod tests {
         assert_item_labels(&pane, ["A", "B*", "C"], cx);
 
         pane.update(cx, |pane, cx| {
-            pane.close_active_item(
-                &CloseActiveItem {
-                    save_behavior: None,
-                },
-                cx,
-            )
+            pane.close_active_item(&CloseActiveItem { save_intent: None }, cx)
         })
         .unwrap()
         .await
@@ -2481,12 +2453,7 @@ mod tests {
         assert_item_labels(&pane, ["A", "C*"], cx);
 
         pane.update(cx, |pane, cx| {
-            pane.close_active_item(
-                &CloseActiveItem {
-                    save_behavior: None,
-                },
-                cx,
-            )
+            pane.close_active_item(&CloseActiveItem { save_intent: None }, cx)
         })
         .unwrap()
         .await
@@ -2597,12 +2564,7 @@ mod tests {
         assert_item_labels(&pane, ["A", "B", "C*"], cx);
 
         pane.update(cx, |pane, cx| {
-            pane.close_all_items(
-                &CloseAllItems {
-                    save_behavior: None,
-                },
-                cx,
-            )
+            pane.close_all_items(&CloseAllItems { save_intent: None }, cx)
         })
         .unwrap()
         .await

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<SaveIntent>,
+    pub save_intent: Option<SaveIntent>,
 }
 
 #[derive(Clone, PartialEq, Debug, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct Save {
-    pub save_behavior: Option<SaveIntent>,
+    pub save_intent: Option<SaveIntent>,
 }
 
 #[derive(Clone, PartialEq, Debug, Deserialize, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct CloseAllItemsAndPanes {
-    pub save_behavior: Option<SaveIntent>,
+    pub save_intent: Option<SaveIntent>,
 }
 
 #[derive(Deserialize)]
@@ -294,7 +294,7 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
     cx.add_action(
         |workspace: &mut Workspace, action: &Save, cx: &mut ViewContext<Workspace>| {
             workspace
-                .save_active_item(action.save_behavior.unwrap_or(SaveIntent::Save), cx)
+                .save_active_item(action.save_intent.unwrap_or(SaveIntent::Save), cx)
                 .detach_and_log_err(cx);
         },
     );
@@ -1363,7 +1363,7 @@ impl Workspace {
         cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
         let save_all =
-            self.save_all_internal(action.save_behavior.unwrap_or(SaveIntent::SaveAll), cx);
+            self.save_all_internal(action.save_intent.unwrap_or(SaveIntent::SaveAll), cx);
         Some(cx.foreground().spawn(async move {
             save_all.await?;
             Ok(())
@@ -1372,7 +1372,7 @@ impl Workspace {
 
     fn save_all_internal(
         &mut self,
-        save_behaviour: SaveIntent,
+        save_intent: SaveIntent,
         cx: &mut ViewContext<Self>,
     ) -> Task<Result<bool>> {
         if self.project.read(cx).is_read_only() {
@@ -1407,7 +1407,7 @@ impl Workspace {
                             &pane,
                             ix,
                             &*item,
-                            save_behaviour,
+                            save_intent,
                             &mut cx,
                         )
                         .await?
@@ -1679,7 +1679,7 @@ impl Workspace {
 
     pub fn save_active_item(
         &mut self,
-        save_behavior: SaveIntent,
+        save_intent: SaveIntent,
         cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>> {
         let project = self.project.clone();
@@ -1690,16 +1690,9 @@ impl Workspace {
 
         cx.spawn(|_, mut cx| async move {
             if let Some(item) = item {
-                Pane::save_item(
-                    project,
-                    &pane,
-                    item_ix,
-                    item.as_ref(),
-                    save_behavior,
-                    &mut cx,
-                )
-                .await
-                .map(|_| ())
+                Pane::save_item(project, &pane, item_ix, item.as_ref(), save_intent, &mut cx)
+                    .await
+                    .map(|_| ())
             } else {
                 Ok(())
             }
@@ -1719,13 +1712,13 @@ impl Workspace {
         action: &CloseAllItemsAndPanes,
         cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        self.close_all_internal(false, action.save_behavior.unwrap_or(SaveIntent::Close), cx)
+        self.close_all_internal(false, action.save_intent.unwrap_or(SaveIntent::Close), cx)
     }
 
     fn close_all_internal(
         &mut self,
         retain_active_pane: bool,
-        save_behavior: SaveIntent,
+        save_intent: SaveIntent,
         cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
         let current_pane = self.active_pane();
@@ -1748,7 +1741,7 @@ impl Workspace {
             if let Some(close_pane_items) = pane.update(cx, |pane: &mut Pane, cx| {
                 pane.close_all_items(
                     &CloseAllItems {
-                        save_behavior: Some(save_behavior),
+                        save_intent: Some(save_intent),
                     },
                     cx,
                 )

crates/zed/src/menus.rs πŸ”—

@@ -38,24 +38,12 @@ pub fn menus() -> Vec<Menu<'static>> {
                 MenuItem::action("Open Recent...", recent_projects::OpenRecent),
                 MenuItem::separator(),
                 MenuItem::action("Add Folder to Project…", workspace::AddFolderToProject),
-                MenuItem::action(
-                    "Save",
-                    workspace::Save {
-                        save_behavior: None,
-                    },
-                ),
+                MenuItem::action("Save", workspace::Save { save_intent: None }),
                 MenuItem::action("Save As…", workspace::SaveAs),
-                MenuItem::action(
-                    "Save All",
-                    workspace::SaveAll {
-                        save_behavior: None,
-                    },
-                ),
+                MenuItem::action("Save All", workspace::SaveAll { save_intent: None }),
                 MenuItem::action(
                     "Close Editor",
-                    workspace::CloseActiveItem {
-                        save_behavior: None,
-                    },
+                    workspace::CloseActiveItem { save_intent: None },
                 ),
                 MenuItem::action("Close Window", workspace::CloseWindow),
             ],

crates/zed/src/zed.rs πŸ”—

@@ -1318,6 +1318,7 @@ mod tests {
         let save_task = workspace.update(cx, |workspace, cx| {
             workspace.save_active_item(SaveIntent::Save, cx)
         });
+        cx.foreground().run_until_parked();
         window.simulate_prompt_answer(0, cx);
         save_task.await.unwrap();
         editor.read_with(cx, |editor, cx| {
@@ -1522,9 +1523,7 @@ mod tests {
         });
         cx.dispatch_action(
             window.into(),
-            workspace::CloseActiveItem {
-                save_behavior: None,
-            },
+            workspace::CloseActiveItem { save_intent: None },
         );
 
         cx.foreground().run_until_parked();
@@ -1535,9 +1534,7 @@ mod tests {
 
         cx.dispatch_action(
             window.into(),
-            workspace::CloseActiveItem {
-                save_behavior: None,
-            },
+            workspace::CloseActiveItem { save_intent: None },
         );
         cx.foreground().run_until_parked();
         window.simulate_prompt_answer(1, cx);