Detailed changes
@@ -2417,6 +2417,7 @@
"toggle_relative_line_numbers": false,
"use_system_clipboard": "always",
"use_smartcase_find": false,
+ "use_regex_search": true,
"gdefault": false,
"highlight_on_yank_duration": 200,
"custom_digraphs": {},
@@ -763,6 +763,7 @@ pub struct VimSettingsContent {
pub toggle_relative_line_numbers: Option<bool>,
pub use_system_clipboard: Option<UseSystemClipboard>,
pub use_smartcase_find: Option<bool>,
+ pub use_regex_search: Option<bool>,
/// When enabled, the `:substitute` command replaces all matches in a line
/// by default. The 'g' flag then toggles this behavior.,
pub gdefault: Option<bool>,
@@ -2447,7 +2447,7 @@ fn editor_page() -> SettingsPage {
]
}
- fn vim_settings_section() -> [SettingsPageItem; 12] {
+ fn vim_settings_section() -> [SettingsPageItem; 13] {
[
SettingsPageItem::SectionHeader("Vim"),
SettingsPageItem::SettingItem(SettingItem {
@@ -2556,6 +2556,24 @@ fn editor_page() -> SettingsPage {
metadata: None,
files: USER,
}),
+ SettingsPageItem::SettingItem(SettingItem {
+ title: "Regex Search",
+ description: "Use regex search by default in Vim search.",
+ field: Box::new(SettingField {
+ json_path: Some("vim.use_regex_search"),
+ pick: |settings_content| {
+ settings_content.vim.as_ref()?.use_regex_search.as_ref()
+ },
+ write: |settings_content, value| {
+ settings_content
+ .vim
+ .get_or_insert_default()
+ .use_regex_search = value;
+ },
+ }),
+ metadata: None,
+ files: USER,
+ }),
SettingsPageItem::SettingItem(SettingItem {
title: "Cursor Shape - Normal Mode",
description: "Cursor shape for normal mode.",
@@ -245,7 +245,7 @@ impl Vim {
search_bar.set_replacement(None, cx);
let mut options = SearchOptions::NONE;
- if action.regex {
+ if action.regex && VimSettings::get_global(cx).use_regex_search {
options |= SearchOptions::REGEX;
}
if action.backwards {
@@ -1446,4 +1446,66 @@ mod test {
// The cursor should be at the match location on line 3 (row 2).
cx.assert_state("hello world\nfoo bar\nhello Λagain\n", Mode::Normal);
}
+
+ #[gpui::test]
+ async fn test_vim_search_respects_search_settings(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, true).await;
+
+ cx.update_global(|store: &mut SettingsStore, cx| {
+ store.update_user_settings(cx, |settings| {
+ settings.vim.get_or_insert_default().use_regex_search = Some(false);
+ });
+ });
+
+ cx.set_state("Λcontent", Mode::Normal);
+ cx.simulate_keystrokes("/");
+ cx.run_until_parked();
+
+ // Verify search options are set from settings
+ let search_bar = cx.workspace(|workspace, _, cx| {
+ workspace
+ .active_pane()
+ .read(cx)
+ .toolbar()
+ .read(cx)
+ .item_of_type::<BufferSearchBar>()
+ .expect("Buffer search bar should be active")
+ });
+
+ cx.update_entity(search_bar, |bar, _window, _cx| {
+ assert!(
+ !bar.has_search_option(search::SearchOptions::REGEX),
+ "Vim search open without regex mode"
+ );
+ });
+
+ cx.simulate_keystrokes("escape");
+ cx.run_until_parked();
+
+ cx.update_global(|store: &mut SettingsStore, cx| {
+ store.update_user_settings(cx, |settings| {
+ settings.vim.get_or_insert_default().use_regex_search = Some(true);
+ });
+ });
+
+ cx.simulate_keystrokes("/");
+ cx.run_until_parked();
+
+ let search_bar = cx.workspace(|workspace, _, cx| {
+ workspace
+ .active_pane()
+ .read(cx)
+ .toolbar()
+ .read(cx)
+ .item_of_type::<BufferSearchBar>()
+ .expect("Buffer search bar should be active")
+ });
+
+ cx.update_entity(search_bar, |bar, _window, _cx| {
+ assert!(
+ bar.has_search_option(search::SearchOptions::REGEX),
+ "Vim search opens with regex mode"
+ );
+ });
+ }
}
@@ -2141,6 +2141,7 @@ struct VimSettings {
pub toggle_relative_line_numbers: bool,
pub use_system_clipboard: settings::UseSystemClipboard,
pub use_smartcase_find: bool,
+ pub use_regex_search: bool,
pub gdefault: bool,
pub custom_digraphs: HashMap<String, Arc<str>>,
pub highlight_on_yank_duration: u64,
@@ -2227,6 +2228,7 @@ impl Settings for VimSettings {
toggle_relative_line_numbers: vim.toggle_relative_line_numbers.unwrap(),
use_system_clipboard: vim.use_system_clipboard.unwrap(),
use_smartcase_find: vim.use_smartcase_find.unwrap(),
+ use_regex_search: vim.use_regex_search.unwrap(),
gdefault: vim.gdefault.unwrap(),
custom_digraphs: vim.custom_digraphs.unwrap(),
highlight_on_yank_duration: vim.highlight_on_yank_duration.unwrap(),
@@ -562,6 +562,7 @@ You can change the following settings to modify vim mode's behavior:
| 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 | deprecated |
| use_smartcase_find | If `true`, `f` and `t` motions are case-insensitive when the target letter is lowercase. | false |
+| use_regex_search | If `true`, then vim search will use regex mode | true |
| gdefault | If `true`, the `:substitute` command replaces all matches in a line by default (as if `g` flag was given). The `g` flag then toggles this, replacing only the first match. | false |
| toggle_relative_line_numbers | If `true`, line numbers are relative in normal mode and absolute in insert mode, giving you the best of both options. | false |
| custom_digraphs | An object that allows you to add custom digraphs. Read below for an example. | {} |
@@ -587,6 +588,7 @@ Here's an example of these settings changed:
"default_mode": "insert",
"use_system_clipboard": "never",
"use_smartcase_find": true,
+ "use_regex_search": true,
"gdefault": true,
"toggle_relative_line_numbers": true,
"highlight_on_yank_duration": 50,