vim: Fix relative motions (#2888)
This changes vim motions to be relative to fold lines, not display lines, to match the behaviour of vim. This is necessary for relative line numbers to make sense (as the most important thing is you can do `3j` to get th e line that is numbered 3). Release Notes: - vim: Fix handling of motions when `soft_wrap` is enabled in zed. Like in vim `j,k,up,down,$,^,0,home,end` will all now navigate in file coordinates not display coordinates. - vim: Add `g {j,k,up,down,$,^,0,home,end}` to navigate in display coordinates. - vim: Add `z o` and `z c` to open and close folds. - vim: Add `z f` in visual mode to fold selection. Note: this may be a jarring change if you're grown used to the current behaviour of `j` and `k`. You can make the issue less acute by setting `"soft_wrap":"none"` in your settings; or you can manually copy the bindings for `g j` to the binding for `j` (etc.) in your keymap.json to preserve the existing behaviour.
This commit is contained in:
commit
dd577074f2
13 changed files with 698 additions and 77 deletions
|
@ -30,6 +30,7 @@ pub use block_map::{
|
|||
BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock,
|
||||
};
|
||||
|
||||
pub use self::fold_map::FoldPoint;
|
||||
pub use self::inlay_map::{Inlay, InlayOffset, InlayPoint};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -310,7 +311,7 @@ impl DisplayMap {
|
|||
|
||||
pub struct DisplaySnapshot {
|
||||
pub buffer_snapshot: MultiBufferSnapshot,
|
||||
fold_snapshot: fold_map::FoldSnapshot,
|
||||
pub fold_snapshot: fold_map::FoldSnapshot,
|
||||
inlay_snapshot: inlay_map::InlaySnapshot,
|
||||
tab_snapshot: tab_map::TabSnapshot,
|
||||
wrap_snapshot: wrap_map::WrapSnapshot,
|
||||
|
@ -438,6 +439,20 @@ impl DisplaySnapshot {
|
|||
fold_point.to_inlay_point(&self.fold_snapshot)
|
||||
}
|
||||
|
||||
pub fn display_point_to_fold_point(&self, point: DisplayPoint, bias: Bias) -> FoldPoint {
|
||||
let block_point = point.0;
|
||||
let wrap_point = self.block_snapshot.to_wrap_point(block_point);
|
||||
let tab_point = self.wrap_snapshot.to_tab_point(wrap_point);
|
||||
self.tab_snapshot.to_fold_point(tab_point, bias).0
|
||||
}
|
||||
|
||||
pub fn fold_point_to_display_point(&self, fold_point: FoldPoint) -> DisplayPoint {
|
||||
let tab_point = self.tab_snapshot.to_tab_point(fold_point);
|
||||
let wrap_point = self.wrap_snapshot.tab_point_to_wrap_point(tab_point);
|
||||
let block_point = self.block_snapshot.to_block_point(wrap_point);
|
||||
DisplayPoint(block_point)
|
||||
}
|
||||
|
||||
pub fn max_point(&self) -> DisplayPoint {
|
||||
DisplayPoint(self.block_snapshot.max_point())
|
||||
}
|
||||
|
|
|
@ -7346,7 +7346,7 @@ impl Editor {
|
|||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
for selection in selections {
|
||||
let range = selection.range().sorted();
|
||||
let buffer_start_row = range.start.row;
|
||||
|
@ -7422,7 +7422,17 @@ impl Editor {
|
|||
|
||||
pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let ranges = selections.into_iter().map(|s| s.start..s.end);
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let line_mode = self.selections.line_mode;
|
||||
let ranges = selections.into_iter().map(|s| {
|
||||
if line_mode {
|
||||
let start = Point::new(s.start.row, 0);
|
||||
let end = Point::new(s.end.row, display_map.buffer_snapshot.line_len(s.end.row));
|
||||
start..end
|
||||
} else {
|
||||
s.start..s.end
|
||||
}
|
||||
});
|
||||
self.fold_ranges(ranges, true, cx);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue