Fix Vim 'e' Behavior When Boundary Is Last Point on Line (#7424)
This was originally just to fix https://github.com/zed-industries/zed/issues/4354, which I did by just returning the previous offset in `find_boundary`.. but `find_boundary` is used in the "insert mode" / normal editor too, so returning the previous boundary breaks existing functionality in that case. I was considering a new `find_boundary` function just for some of the vim motions like this, but I thought that this is straightforward enough and future Vim functions might need similar logic too. Release Notes: - Fixed https://github.com/zed-industries/zed/issues/4354
This commit is contained in:
parent
90cd3b5e87
commit
3aa4e0c90b
3 changed files with 48 additions and 20 deletions
|
@ -798,23 +798,14 @@ fn next_word_end(
|
|||
*point.row_mut() += 1;
|
||||
*point.column_mut() = 0;
|
||||
}
|
||||
point = movement::find_boundary(map, point, 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
|
||||
});
|
||||
point =
|
||||
movement::find_boundary_exclusive(map, point, 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);
|
||||
|
||||
// find_boundary clips, so if the character after the next character is a newline or at the end of the document, we know
|
||||
// we have backtracked already
|
||||
if !map
|
||||
.chars_at(point)
|
||||
.nth(1)
|
||||
.map(|(c, _)| c == '\n')
|
||||
.unwrap_or(true)
|
||||
{
|
||||
*point.column_mut() = point.column().saturating_sub(1);
|
||||
}
|
||||
left_kind != right_kind && left_kind != CharKind::Whitespace
|
||||
});
|
||||
point = map.clip_point(point, Bias::Left);
|
||||
}
|
||||
point
|
||||
|
@ -1285,6 +1276,15 @@ mod test {
|
|||
cx.assert_shared_state("one two thˇree four").await;
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_next_word_end_newline_last_char(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
let initial_state = indoc! {r"something(ˇfoo)"};
|
||||
cx.set_shared_state(initial_state).await;
|
||||
cx.simulate_shared_keystrokes(["}"]).await;
|
||||
cx.assert_shared_state(indoc! {r"something(fooˇ)"}).await;
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_next_line_start(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{"Put":{"state":"something(ˇfoo)"}}
|
||||
{"Key":"}"}
|
||||
{"Get":{"state":"something(fooˇ)","mode":"Normal"}}
|
Loading…
Add table
Add a link
Reference in a new issue