Update default vim substitute command behavior and add support for 'g' flag (#28138)

This Pull Request updates the default behavior of the substitute (`s`)
command in vim mode to only replace the next match by default, instead
of all, and replace all matches only when the `g` flag is provided,
making it more similar to NeoVim's behavior.

In order to achieve this, the following changes were introduced:

- Update `BufferSearchBar::replace_next` to be a public method, so it
can be called from `Vim::replace_command` .
- Update the `Replacement::parse` to set the `should_replace_all` field
to `false` by default, and only set it to `true` if the `'g'` flag is
present in the query.
- Add support for when the `Replacement.should_replace_all` is set to
`false` in `Vim::replace_command`, so as to have it only replace the
next occurrence instead of all occurrences in the line.
- Introduce `BufferSearchBar::select_first_match` so as to activate the
first match on the line under the cursor.

Closes #24450 

Release Notes:

- Improved vim's substitute command so as to only replace the first
match by default, and replace all matches if the `'g'` flag is provided

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Dino 2025-04-09 21:34:51 +01:00 committed by GitHub
parent 60c420a2da
commit af5318df98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 79 additions and 26 deletions

View file

@ -1231,6 +1231,8 @@ impl BufferSearchBar {
self.search_options.contains(SearchOptions::WHOLE_WORD),
self.search_options.contains(SearchOptions::CASE_SENSITIVE),
false,
self.search_options
.contains(SearchOptions::ONE_MATCH_PER_LINE),
Default::default(),
Default::default(),
None,

View file

@ -1053,6 +1053,8 @@ impl ProjectSearchView {
self.search_options.contains(SearchOptions::WHOLE_WORD),
self.search_options.contains(SearchOptions::CASE_SENSITIVE),
self.search_options.contains(SearchOptions::INCLUDE_IGNORED),
self.search_options
.contains(SearchOptions::ONE_MATCH_PER_LINE),
included_files,
excluded_files,
open_buffers,

View file

@ -48,6 +48,7 @@ bitflags! {
const CASE_SENSITIVE = 0b010;
const INCLUDE_IGNORED = 0b100;
const REGEX = 0b1000;
const ONE_MATCH_PER_LINE = 0b100000;
/// If set, reverse direction when finding the active match
const BACKWARDS = 0b10000;
}