vim: Add support for ap and ip paragraph text objects (#7687)

This PR adds support for `ap`/`ip` text objects in Vim mode and allows
users to perform paragraph-based operations.

Cases where compatibility with Neovim's behavior is checked, cases where
there are known differences in behavior with Neovim (cases where the
landing position is other than the beginning of the line), and cases
where the Neovim behavior in the test suite seems strange are separated
in the test code so that they can be identified.

Release Notes:

- Added support for `ap` and `ip` paragraph text objects in Vim mode
([#7359](https://github.com/zed-industries/zed/issues/7359)).
This commit is contained in:
Noritada Kobayashi 2024-03-05 08:39:02 +09:00 committed by GitHub
parent b742db65fe
commit d223fe446d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 1265 additions and 11 deletions

View file

@ -9,7 +9,7 @@ use editor::{
Bias, DisplayPoint, Editor,
};
use gpui::{actions, ViewContext, WindowContext};
use language::{Selection, SelectionGoal};
use language::{Point, Selection, SelectionGoal};
use workspace::Workspace;
use crate::{
@ -279,6 +279,25 @@ pub fn visual_object(object: Object, cx: &mut WindowContext) {
selection.end = range.end;
}
}
// In the visual selection result of a paragraph object, the cursor is
// placed at the start of the last line. And in the visual mode, the
// selection end is located after the end character. So, adjustment of
// selection end is needed.
//
// We don't do this adjustment for a one-line blank paragraph since the
// trailing newline is included in its selection from the beginning.
if object == Object::Paragraph && range.start != range.end {
let row_of_selection_end_line = selection.end.to_point(map).row;
let new_selection_end =
if map.buffer_snapshot.line_len(row_of_selection_end_line) == 0
{
Point::new(row_of_selection_end_line + 1, 0)
} else {
Point::new(row_of_selection_end_line, 1)
};
selection.end = new_selection_end.to_display_point(map);
}
}
});
});