assets/settings/default.json 🔗
@@ -1296,6 +1296,7 @@
},
// Vim settings
"vim": {
+ "default_mode": "normal",
"toggle_relative_line_numbers": false,
"use_system_clipboard": "always",
"use_multiline_find": false,
Brandon Li and Marshall Bowers created
Closes #13881, and technically resolves #14927.
Release Notes:
- Added the ability to set the default Vim mode.
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
assets/settings/default.json | 1
crates/vim/src/vim.rs | 56 ++++++++++++++++++++++++++++++++++++-
docs/src/vim.md | 1
3 files changed, 56 insertions(+), 2 deletions(-)
@@ -1296,6 +1296,7 @@
},
// Vim settings
"vim": {
+ "default_mode": "normal",
"toggle_relative_line_numbers": false,
"use_system_clipboard": "always",
"use_multiline_find": false,
@@ -354,7 +354,7 @@ impl Vim {
let editor = cx.entity().clone();
cx.new(|cx| Vim {
- mode: Mode::Normal,
+ mode: VimSettings::get_global(cx).default_mode,
last_mode: Mode::Normal,
temp_mode: false,
exit_temporary_mode: false,
@@ -1643,6 +1643,7 @@ pub enum UseSystemClipboard {
#[derive(Deserialize)]
struct VimSettings {
+ pub default_mode: Mode,
pub toggle_relative_line_numbers: bool,
pub use_system_clipboard: UseSystemClipboard,
pub use_multiline_find: bool,
@@ -1653,6 +1654,7 @@ struct VimSettings {
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
struct VimSettingsContent {
+ pub default_mode: Option<ModeContent>,
pub toggle_relative_line_numbers: Option<bool>,
pub use_system_clipboard: Option<UseSystemClipboard>,
pub use_multiline_find: Option<bool>,
@@ -1661,12 +1663,62 @@ struct VimSettingsContent {
pub highlight_on_yank_duration: Option<u64>,
}
+#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
+#[serde(rename_all = "snake_case")]
+pub enum ModeContent {
+ #[default]
+ Normal,
+ Insert,
+ Replace,
+ Visual,
+ VisualLine,
+ VisualBlock,
+ HelixNormal,
+}
+
+impl From<ModeContent> for Mode {
+ fn from(mode: ModeContent) -> Self {
+ match mode {
+ ModeContent::Normal => Self::Normal,
+ ModeContent::Insert => Self::Insert,
+ ModeContent::Replace => Self::Replace,
+ ModeContent::Visual => Self::Visual,
+ ModeContent::VisualLine => Self::VisualLine,
+ ModeContent::VisualBlock => Self::VisualBlock,
+ ModeContent::HelixNormal => Self::HelixNormal,
+ }
+ }
+}
+
impl Settings for VimSettings {
const KEY: Option<&'static str> = Some("vim");
type FileContent = VimSettingsContent;
fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
- sources.json_merge()
+ let settings: VimSettingsContent = sources.json_merge()?;
+
+ Ok(Self {
+ default_mode: settings
+ .default_mode
+ .ok_or_else(Self::missing_default)?
+ .into(),
+ toggle_relative_line_numbers: settings
+ .toggle_relative_line_numbers
+ .ok_or_else(Self::missing_default)?,
+ use_system_clipboard: settings
+ .use_system_clipboard
+ .ok_or_else(Self::missing_default)?,
+ use_multiline_find: settings
+ .use_multiline_find
+ .ok_or_else(Self::missing_default)?,
+ use_smartcase_find: settings
+ .use_smartcase_find
+ .ok_or_else(Self::missing_default)?,
+ custom_digraphs: settings.custom_digraphs.ok_or_else(Self::missing_default)?,
+ highlight_on_yank_duration: settings
+ .highlight_on_yank_duration
+ .ok_or_else(Self::missing_default)?,
+ })
}
}
@@ -451,6 +451,7 @@ You can change the following settings to modify vim mode's behavior:
| Property | Description | Default Value |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
+| default_mode | The default mode to start in. One of "normal", "insert", "replace", "visual", "visual_line", "visual_block", "helix_normal". | "normal" |
| use_system_clipboard | Determines how system clipboard is used:<br><ul><li>"always": use for all operations</li><li>"never": only use when explicitly specified</li><li>"on_yank": use for yank operations</li></ul> | "always" |
| use_multiline_find | If `true`, `f` and `t` motions extend across multiple lines. | false |
| use_smartcase_find | If `true`, `f` and `t` motions are case-insensitive when the target letter is lowercase. | false |