vim: subword motions (#8725)

Add subword motions to vim, inspired by
[nvim-spider](https://github.com/chrisgrieser/nvim-spider),
[CamelCaseMotion](https://github.com/bkad/CamelCaseMotion).


Release Notes:

- Added subword motions to vim
This commit is contained in:
Rom Grk 2024-03-07 21:36:12 -05:00 committed by GitHub
parent 467a179837
commit d247086b21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 491 additions and 93 deletions

View file

@ -1,15 +1,12 @@
use crate::{
motion::Motion,
motion::{self, Motion},
object::Object,
state::Mode,
utils::{coerce_punctuation, copy_selections_content},
utils::copy_selections_content,
Vim,
};
use editor::{
display_map::DisplaySnapshot,
movement::{self, FindRange, TextLayoutDetails},
scroll::Autoscroll,
DisplayPoint,
display_map::DisplaySnapshot, movement::TextLayoutDetails, scroll::Autoscroll, DisplayPoint,
};
use gpui::WindowContext;
use language::{char_kind, CharKind, Selection};
@ -39,6 +36,16 @@ pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &m
times,
ignore_punctuation,
&text_layout_details,
false,
)
} else if let Motion::NextSubwordStart { ignore_punctuation } = motion {
expand_changed_word_selection(
map,
selection,
times,
ignore_punctuation,
&text_layout_details,
true,
)
} else {
motion.expand_selection(map, selection, times, false, &text_layout_details)
@ -94,6 +101,7 @@ fn expand_changed_word_selection(
times: Option<usize>,
ignore_punctuation: bool,
text_layout_details: &TextLayoutDetails,
use_subword: bool,
) -> bool {
if times.is_none() || times.unwrap() == 1 {
let scope = map
@ -106,32 +114,30 @@ fn expand_changed_word_selection(
.unwrap_or_default();
if in_word {
selection.end =
movement::find_boundary(map, selection.end, FindRange::MultiLine, |left, right| {
let left_kind = coerce_punctuation(char_kind(&scope, left), ignore_punctuation);
let right_kind =
coerce_punctuation(char_kind(&scope, right), ignore_punctuation);
left_kind != right_kind && left_kind != CharKind::Whitespace
});
if !use_subword {
selection.end =
motion::next_word_end(map, selection.end, ignore_punctuation, 1, false);
} else {
selection.end =
motion::next_subword_end(map, selection.end, ignore_punctuation, 1, false);
}
selection.end = motion::next_char(map, selection.end, false);
true
} else {
Motion::NextWordStart { ignore_punctuation }.expand_selection(
map,
selection,
None,
false,
&text_layout_details,
)
let motion = if use_subword {
Motion::NextSubwordStart { ignore_punctuation }
} else {
Motion::NextWordStart { ignore_punctuation }
};
motion.expand_selection(map, selection, None, false, &text_layout_details)
}
} else {
Motion::NextWordStart { ignore_punctuation }.expand_selection(
map,
selection,
times,
false,
&text_layout_details,
)
let motion = if use_subword {
Motion::NextSubwordStart { ignore_punctuation }
} else {
Motion::NextWordStart { ignore_punctuation }
};
motion.expand_selection(map, selection, times, false, &text_layout_details)
}
}