Fix relative line numbers in vim visual mode

In visual mode when your selection ends with a newline we show the
cursor at the end of the previous line (not the start of the current
line). We had only been accounting for this if the cursor was on-screen.
This commit is contained in:
Conrad Irwin 2023-08-25 10:56:29 -06:00
parent 8d5dc266a3
commit f18cdcba54

View file

@ -1493,7 +1493,7 @@ impl EditorElement {
&self, &self,
rows: Range<u32>, rows: Range<u32>,
active_rows: &BTreeMap<u32, bool>, active_rows: &BTreeMap<u32, bool>,
newest_selection_head: Option<DisplayPoint>, newest_selection_head: DisplayPoint,
is_singleton: bool, is_singleton: bool,
snapshot: &EditorSnapshot, snapshot: &EditorSnapshot,
cx: &ViewContext<Editor>, cx: &ViewContext<Editor>,
@ -1508,7 +1508,7 @@ impl EditorElement {
let mut line_number = String::new(); let mut line_number = String::new();
let is_relative = settings::get::<EditorSettings>(cx).relative_line_numbers; let is_relative = settings::get::<EditorSettings>(cx).relative_line_numbers;
let relative_to = if is_relative { let relative_to = if is_relative {
newest_selection_head.map(|head| head.row()) Some(newest_selection_head.row())
} else { } else {
None None
}; };
@ -2357,10 +2357,22 @@ impl Element<Editor> for EditorElement {
}) })
.collect(); .collect();
let head_for_relative = newest_selection_head.unwrap_or_else(|| {
let newest = editor.selections.newest::<Point>(cx);
SelectionLayout::new(
newest,
editor.selections.line_mode,
editor.cursor_shape,
&snapshot.display_snapshot,
true,
)
.head
});
let (line_number_layouts, fold_statuses) = self.layout_line_numbers( let (line_number_layouts, fold_statuses) = self.layout_line_numbers(
start_row..end_row, start_row..end_row,
&active_rows, &active_rows,
newest_selection_head.or_else(|| Some(editor.selections.newest_display(cx).head())), head_for_relative,
is_singleton, is_singleton,
&snapshot, &snapshot,
cx, cx,
@ -3130,14 +3142,21 @@ mod tests {
let layouts = editor.update(cx, |editor, cx| { let layouts = editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx); let snapshot = editor.snapshot(cx);
element element
.layout_line_numbers(0..6, &Default::default(), None, false, &snapshot, cx) .layout_line_numbers(
0..6,
&Default::default(),
DisplayPoint::new(0, 0),
false,
&snapshot,
cx,
)
.0 .0
}); });
assert_eq!(layouts.len(), 6); assert_eq!(layouts.len(), 6);
let relative_rows = editor.update(cx, |editor, cx| { let relative_rows = editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx); let snapshot = editor.snapshot(cx);
element.calculate_relative_line_numbers(&snapshot, &(0..6), Some(3)) element.calculate_relative_line_numbers(&snapshot, &(0..6), 3)
}); });
assert_eq!(relative_rows[&0], 3); assert_eq!(relative_rows[&0], 3);
assert_eq!(relative_rows[&1], 2); assert_eq!(relative_rows[&1], 2);
@ -3150,7 +3169,7 @@ mod tests {
let relative_rows = editor.update(cx, |editor, cx| { let relative_rows = editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx); let snapshot = editor.snapshot(cx);
element.calculate_relative_line_numbers(&snapshot, &(3..6), Some(1)) element.calculate_relative_line_numbers(&snapshot, &(3..6), 1)
}); });
assert_eq!(relative_rows.len(), 3); assert_eq!(relative_rows.len(), 3);
assert_eq!(relative_rows[&3], 2); assert_eq!(relative_rows[&3], 2);
@ -3161,7 +3180,7 @@ mod tests {
let relative_rows = editor.update(cx, |editor, cx| { let relative_rows = editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx); let snapshot = editor.snapshot(cx);
element.calculate_relative_line_numbers(&snapshot, &(0..3), Some(6)) element.calculate_relative_line_numbers(&snapshot, &(0..3), 6)
}); });
assert_eq!(relative_rows.len(), 3); assert_eq!(relative_rows.len(), 3);
assert_eq!(relative_rows[&0], 5); assert_eq!(relative_rows[&0], 5);