From 59daeba295f2fa04de0f81b87aa9772c6b8ea86c Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Thu, 7 May 2026 05:55:07 -0500 Subject: [PATCH] vim: Add setting to control whether edit predictions are shown in normal mode (#55956) Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #ISSUE Release Notes: - Added a setting [vim.show_edit_predictions_in_normal_mode](zed://settings/vim.show_edit_predictions_in_normal_mode) to control whether edit predictions are shown in normal mode. --- assets/settings/default.json | 3 +++ .../settings_content/src/settings_content.rs | 3 +++ crates/settings_ui/src/page_data.rs | 24 ++++++++++++++++++- crates/vim/src/state.rs | 4 ++++ crates/vim/src/vim.rs | 6 ++++- 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 64f97c451b00ea6fad4a11b0f2787ad53f408d78..d6d6feac644161b398df49e1e6638557784b37d9 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -2515,6 +2515,9 @@ "gdefault": false, "highlight_on_yank_duration": 200, "custom_digraphs": {}, + // When enabled, edit predictions are shown in Vim normal mode. + // By default, edit predictions are only shown in insert and replace modes. + "show_edit_predictions_in_normal_mode": false, // Cursor shape for each mode. // The shape can be one of the following: "block", "bar", "underline", "hollow". "cursor_shape": { diff --git a/crates/settings_content/src/settings_content.rs b/crates/settings_content/src/settings_content.rs index 1124e2ac94260536257b7a4078cbb504da2232f8..0bf14e2f4fffcf5284d85f00c4fdff41b202f430 100644 --- a/crates/settings_content/src/settings_content.rs +++ b/crates/settings_content/src/settings_content.rs @@ -864,6 +864,9 @@ pub struct VimSettingsContent { pub custom_digraphs: Option>>, pub highlight_on_yank_duration: Option, pub cursor_shape: Option, + /// When enabled, edit predictions are shown in Vim normal mode. + /// By default, edit predictions are only shown in insert and replace modes. + pub show_edit_predictions_in_normal_mode: Option, } #[derive( diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index ce0c53b3822e26277fe6480762491b4eae9b4662..acb9f53a67529726b3f05768cf9f232da67565f4 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -2573,7 +2573,7 @@ fn editor_page() -> SettingsPage { ] } - fn vim_settings_section() -> [SettingsPageItem; 13] { + fn vim_settings_section() -> [SettingsPageItem; 14] { [ SettingsPageItem::SectionHeader("Vim"), SettingsPageItem::SettingItem(SettingItem { @@ -2700,6 +2700,28 @@ fn editor_page() -> SettingsPage { metadata: None, files: USER, }), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Edit Predictions in Normal Mode", + description: "Whether edit predictions are shown in normal mode. By default, edit predictions are only shown in insert and replace modes.", + field: Box::new(SettingField { + json_path: Some("vim.show_edit_predictions_in_normal_mode"), + pick: |settings_content| { + settings_content + .vim + .as_ref()? + .show_edit_predictions_in_normal_mode + .as_ref() + }, + write: |settings_content, value, _| { + settings_content + .vim + .get_or_insert_default() + .show_edit_predictions_in_normal_mode = value; + }, + }), + metadata: None, + files: USER, + }), SettingsPageItem::SettingItem(SettingItem { title: "Cursor Shape - Normal Mode", description: "Cursor shape for normal mode.", diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index 0851604e1abcdfd2ec6631d6e96448037dd8b704..85bf84d887830b92ef3feecbe0fe6fa813d27f2d 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -79,6 +79,10 @@ impl Mode { pub fn is_helix(&self) -> bool { matches!(self, Self::HelixNormal | Self::HelixSelect) } + + pub fn is_normal(&self) -> bool { + matches!(self, Self::Normal | Self::HelixNormal) + } } #[derive(Clone, Debug, PartialEq)] diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 6c0c3d0201b49034020c7cdb981e80de4d7ac7e9..d247e24031075cbeb82b0a8a043b3e290a4334bd 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -2209,7 +2209,9 @@ impl Vim { autoindent: self.should_autoindent(), cursor_offset_on_selection: self.mode.is_visual() || self.mode.is_helix(), line_mode: matches!(self.mode, Mode::VisualLine), - hide_edit_predictions: !matches!(self.mode, Mode::Insert | Mode::Replace), + hide_edit_predictions: !matches!(self.mode, Mode::Insert | Mode::Replace) + && !(self.mode.is_normal() + && VimSettings::get_global(cx).show_edit_predictions_in_normal_mode), } } @@ -2259,6 +2261,7 @@ struct VimSettings { pub custom_digraphs: HashMap>, pub highlight_on_yank_duration: u64, pub cursor_shape: CursorShapeSettings, + pub show_edit_predictions_in_normal_mode: bool, } /// Cursor shape configuration for insert mode. @@ -2346,6 +2349,7 @@ impl Settings for VimSettings { custom_digraphs: vim.custom_digraphs.unwrap(), highlight_on_yank_duration: vim.highlight_on_yank_duration.unwrap(), cursor_shape: vim.cursor_shape.unwrap().into(), + show_edit_predictions_in_normal_mode: vim.show_edit_predictions_in_normal_mode.unwrap(), } } }