Solve an inconsistency between vim and helix
This commit is contained in:
parent
05bc741eaf
commit
309831ea9a
2 changed files with 70 additions and 1 deletions
|
@ -16,7 +16,7 @@ impl Vim {
|
||||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||||
editor.change_selections(Default::default(), window, cx, |s| {
|
editor.change_selections(Default::default(), window, cx, |s| {
|
||||||
s.move_with(|map, selection| {
|
s.move_with(|map, selection| {
|
||||||
let Some(range) = object.range(map, selection.clone(), around, None) else {
|
let Some(range) = object.helix_range(map, selection.clone(), around) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -714,6 +714,27 @@ impl Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the range the object spans if the cursor is over it.
|
||||||
|
/// Follows helix convention.
|
||||||
|
pub fn helix_range(
|
||||||
|
self,
|
||||||
|
map: &DisplaySnapshot,
|
||||||
|
selection: Selection<DisplayPoint>,
|
||||||
|
around: bool,
|
||||||
|
) -> Option<Range<DisplayPoint>> {
|
||||||
|
let relative_to = selection.head();
|
||||||
|
match self {
|
||||||
|
Object::Word { ignore_punctuation } => {
|
||||||
|
if around {
|
||||||
|
helix_around_word(map, relative_to, ignore_punctuation)
|
||||||
|
} else {
|
||||||
|
helix_in_word(map, relative_to, ignore_punctuation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => self.range(map, selection, around, None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expand_selection(
|
pub fn expand_selection(
|
||||||
self,
|
self,
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
|
@ -759,6 +780,42 @@ fn in_word(
|
||||||
Some(start..end)
|
Some(start..end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a range that surrounds the word `relative_to` is in.
|
||||||
|
///
|
||||||
|
/// If `relative_to` is between words, return `None`.
|
||||||
|
fn helix_in_word(
|
||||||
|
map: &DisplaySnapshot,
|
||||||
|
relative_to: DisplayPoint,
|
||||||
|
ignore_punctuation: bool,
|
||||||
|
) -> Option<Range<DisplayPoint>> {
|
||||||
|
// Use motion::right so that we consider the character under the cursor when looking for the start
|
||||||
|
let classifier = map
|
||||||
|
.buffer_snapshot
|
||||||
|
.char_classifier_at(relative_to.to_point(map))
|
||||||
|
.ignore_punctuation(ignore_punctuation);
|
||||||
|
let char = map
|
||||||
|
.buffer_chars_at(relative_to.to_offset(map, Bias::Left))
|
||||||
|
.next()?
|
||||||
|
.0;
|
||||||
|
|
||||||
|
if classifier.kind(char) == CharKind::Whitespace {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let start = movement::find_preceding_boundary_display_point(
|
||||||
|
map,
|
||||||
|
right(map, relative_to, 1),
|
||||||
|
movement::FindRange::SingleLine,
|
||||||
|
|left, right| classifier.kind(left) != classifier.kind(right),
|
||||||
|
);
|
||||||
|
|
||||||
|
let end = movement::find_boundary(map, relative_to, FindRange::SingleLine, |left, right| {
|
||||||
|
classifier.kind(left) != classifier.kind(right)
|
||||||
|
});
|
||||||
|
|
||||||
|
Some(start..end)
|
||||||
|
}
|
||||||
|
|
||||||
fn in_subword(
|
fn in_subword(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
relative_to: DisplayPoint,
|
relative_to: DisplayPoint,
|
||||||
|
@ -927,6 +984,18 @@ fn around_word(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the range of the word the cursor is over and all the whitespace on one side.
|
||||||
|
/// If there is whitespace after that is included, otherwise it's whitespace before the word if any.
|
||||||
|
fn helix_around_word(
|
||||||
|
map: &DisplaySnapshot,
|
||||||
|
relative_to: DisplayPoint,
|
||||||
|
ignore_punctuation: bool,
|
||||||
|
) -> Option<Range<DisplayPoint>> {
|
||||||
|
let word_range = helix_in_word(map, relative_to, ignore_punctuation)?;
|
||||||
|
|
||||||
|
Some(expand_to_include_whitespace(map, word_range, true))
|
||||||
|
}
|
||||||
|
|
||||||
fn around_subword(
|
fn around_subword(
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
relative_to: DisplayPoint,
|
relative_to: DisplayPoint,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue