diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 29be039cdd182d1d45b0f3189e676d293486089f..5149c01ebeb5e52c4eb093de0c1d10690b2a7035 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1107,6 +1107,9 @@ pub struct Editor { pending_rename: Option, searchable: bool, cursor_shape: CursorShape, + /// Whether the cursor is offset one character to the left when something is + /// selected (needed for vim visual mode) + cursor_offset_on_selection: bool, current_line_highlight: Option, pub collapse_matches: bool, autoindent_mode: Option, @@ -2281,6 +2284,7 @@ impl Editor { cursor_shape: EditorSettings::get_global(cx) .cursor_shape .unwrap_or_default(), + cursor_offset_on_selection: false, current_line_highlight: None, autoindent_mode: Some(AutoindentMode::EachLine), collapse_matches: false, @@ -3095,6 +3099,10 @@ impl Editor { self.cursor_shape } + pub fn set_cursor_offset_on_selection(&mut self, set_cursor_offset_on_selection: bool) { + self.cursor_offset_on_selection = set_cursor_offset_on_selection; + } + pub fn set_current_line_highlight( &mut self, current_line_highlight: Option, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 5a5b32e1755f5a026800f3af3c1cedaf6b11996d..ea619140dca36405f35521e316361942c72f644c 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -132,6 +132,7 @@ impl SelectionLayout { fn new( selection: Selection, line_mode: bool, + cursor_offset: bool, cursor_shape: CursorShape, map: &DisplaySnapshot, is_newest: bool, @@ -152,12 +153,9 @@ impl SelectionLayout { } // any vim visual mode (including line mode) - if (cursor_shape == CursorShape::Block || cursor_shape == CursorShape::Hollow) - && !range.is_empty() - && !selection.reversed - { + if cursor_offset && !range.is_empty() && !selection.reversed { if head.column() > 0 { - head = map.clip_point(DisplayPoint::new(head.row(), head.column() - 1), Bias::Left) + head = map.clip_point(DisplayPoint::new(head.row(), head.column() - 1), Bias::Left); } else if head.row().0 > 0 && head != map.max_point() { head = map.clip_point( DisplayPoint::new( @@ -1441,6 +1439,7 @@ impl EditorElement { let layout = SelectionLayout::new( selection, editor.selections.line_mode(), + editor.cursor_offset_on_selection, editor.cursor_shape, &snapshot.display_snapshot, is_newest, @@ -1487,6 +1486,7 @@ impl EditorElement { let drag_cursor_layout = SelectionLayout::new( drop_cursor.clone(), false, + editor.cursor_offset_on_selection, CursorShape::Bar, &snapshot.display_snapshot, false, @@ -1550,6 +1550,7 @@ impl EditorElement { .push(SelectionLayout::new( selection.selection, selection.line_mode, + editor.cursor_offset_on_selection, selection.cursor_shape, &snapshot.display_snapshot, false, @@ -1560,6 +1561,8 @@ impl EditorElement { selections.extend(remote_selections.into_values()); } else if !editor.is_focused(window) && editor.show_cursor_when_unfocused { + let cursor_offset_on_selection = editor.cursor_offset_on_selection; + let layouts = snapshot .buffer_snapshot() .selections_in_range(&(start_anchor..end_anchor), true) @@ -1567,6 +1570,7 @@ impl EditorElement { SelectionLayout::new( selection, line_mode, + cursor_offset_on_selection, cursor_shape, &snapshot.display_snapshot, false, @@ -3290,6 +3294,7 @@ impl EditorElement { SelectionLayout::new( newest, editor.selections.line_mode(), + editor.cursor_offset_on_selection, editor.cursor_shape, &snapshot.display_snapshot, true, @@ -11858,7 +11863,7 @@ mod tests { window .update(cx, |editor, window, cx| { - editor.cursor_shape = CursorShape::Block; + editor.cursor_offset_on_selection = true; editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| { s.select_ranges([ Point::new(0, 0)..Point::new(1, 0), diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 9a9a1a001c32fcf8b22892ce5300d8d2aec3dd37..26fec968fb261fbb80a9f84211357623147ca0f4 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -1943,6 +1943,7 @@ impl Vim { editor.set_collapse_matches(collapse_matches); editor.set_input_enabled(vim.editor_input_enabled()); editor.set_autoindent(vim.should_autoindent()); + editor.set_cursor_offset_on_selection(vim.mode.is_visual()); editor .selections .set_line_mode(matches!(vim.mode, Mode::VisualLine));