vim: Prevent around word operations from selecting indentation (#24635)
Closes https://github.com/zed-industries/zed/issues/15323 Changes: Added check for first word on line Tested `v/c/d/y aw`. Matches standard neovim. |initial|old|new| |---|---|---| ||| Release Notes: - vim: Prevent around word operations from selecting indentation
This commit is contained in:
parent
7378ab9ba5
commit
0a146793ea
2 changed files with 74 additions and 2 deletions
|
@ -727,8 +727,25 @@ fn around_containing_word(
|
|||
relative_to: DisplayPoint,
|
||||
ignore_punctuation: bool,
|
||||
) -> Option<Range<DisplayPoint>> {
|
||||
in_word(map, relative_to, ignore_punctuation)
|
||||
.map(|range| expand_to_include_whitespace(map, range, true))
|
||||
in_word(map, relative_to, ignore_punctuation).map(|range| {
|
||||
let line_start = DisplayPoint::new(range.start.row(), 0);
|
||||
let is_first_word = map
|
||||
.buffer_chars_at(line_start.to_offset(map, Bias::Left))
|
||||
.take_while(|(ch, offset)| {
|
||||
offset < &range.start.to_offset(map, Bias::Left) && ch.is_whitespace()
|
||||
})
|
||||
.count()
|
||||
> 0;
|
||||
|
||||
if is_first_word {
|
||||
// For first word on line, trim indentation
|
||||
let mut expanded = expand_to_include_whitespace(map, range.clone(), true);
|
||||
expanded.start = range.start;
|
||||
expanded
|
||||
} else {
|
||||
expand_to_include_whitespace(map, range, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn around_next_word(
|
||||
|
@ -2455,4 +2472,36 @@ mod test {
|
|||
Mode::Visual,
|
||||
);
|
||||
}
|
||||
#[gpui::test]
|
||||
async fn test_around_containing_word_indent(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state(" ˇconst f = (x: unknown) => {")
|
||||
.await;
|
||||
cx.simulate_shared_keystrokes("v a w").await;
|
||||
cx.shared_state()
|
||||
.await
|
||||
.assert_eq(" «const ˇ»f = (x: unknown) => {");
|
||||
|
||||
cx.set_shared_state(" ˇconst f = (x: unknown) => {")
|
||||
.await;
|
||||
cx.simulate_shared_keystrokes("y a w").await;
|
||||
cx.shared_clipboard().await.assert_eq("const ");
|
||||
|
||||
cx.set_shared_state(" ˇconst f = (x: unknown) => {")
|
||||
.await;
|
||||
cx.simulate_shared_keystrokes("d a w").await;
|
||||
cx.shared_state()
|
||||
.await
|
||||
.assert_eq(" ˇf = (x: unknown) => {");
|
||||
cx.shared_clipboard().await.assert_eq("const ");
|
||||
|
||||
cx.set_shared_state(" ˇconst f = (x: unknown) => {")
|
||||
.await;
|
||||
cx.simulate_shared_keystrokes("c a w").await;
|
||||
cx.shared_state()
|
||||
.await
|
||||
.assert_eq(" ˇf = (x: unknown) => {");
|
||||
cx.shared_clipboard().await.assert_eq("const ");
|
||||
}
|
||||
}
|
||||
|
|
23
crates/vim/test_data/test_around_containing_word_indent.json
Normal file
23
crates/vim/test_data/test_around_containing_word_indent.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{"Put":{"state":" ˇconst f = (x: unknown) => {"}}
|
||||
{"Key":"v"}
|
||||
{"Key":"a"}
|
||||
{"Key":"w"}
|
||||
{"Get":{"state":" «const ˇ»f = (x: unknown) => {","mode":"Visual"}}
|
||||
{"Put":{"state":" ˇconst f = (x: unknown) => {"}}
|
||||
{"Key":"y"}
|
||||
{"Key":"a"}
|
||||
{"Key":"w"}
|
||||
{"Get":{"state":" ˇconst f = (x: unknown) => {","mode":"Normal"}}
|
||||
{"ReadRegister":{"name":"\"","value":"const "}}
|
||||
{"Put":{"state":" ˇconst f = (x: unknown) => {"}}
|
||||
{"Key":"d"}
|
||||
{"Key":"a"}
|
||||
{"Key":"w"}
|
||||
{"Get":{"state":" ˇf = (x: unknown) => {","mode":"Normal"}}
|
||||
{"ReadRegister":{"name":"\"","value":"const "}}
|
||||
{"Put":{"state":" ˇconst f = (x: unknown) => {"}}
|
||||
{"Key":"c"}
|
||||
{"Key":"a"}
|
||||
{"Key":"w"}
|
||||
{"Get":{"state":" ˇf = (x: unknown) => {","mode":"Insert"}}
|
||||
{"ReadRegister":{"name":"\"","value":"const "}}
|
Loading…
Add table
Add a link
Reference in a new issue