From f8f316cc64b9f2b7cbfe225c92fe7713c6020f84 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Wed, 18 May 2022 17:41:26 -0700 Subject: [PATCH] Working change and delete in line mode --- assets/keymaps/vim.json | 2 +- crates/editor/src/element.rs | 2 +- crates/editor/src/selections_collection.rs | 2 +- crates/vim/src/editor_events.rs | 2 +- crates/vim/src/state.rs | 4 ++++ crates/vim/src/vim.rs | 10 ++++++++++ crates/vim/src/visual.rs | 12 +++++++++--- 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index dd2e6a132a58ab4ac532e7bf899d2036a3274800..e5fdf44d3ea5238cade39d72107807854393fb9f 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -73,7 +73,7 @@ "vim::SwitchMode", "Visual" ], - "V": [ + "shift-V": [ "vim::SwitchMode", "VisualLine" ] diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 9893f942924c70f4f5232ddfe138096f409ff701..a794ac7edd9725d84c5fed4ca3aede5062f66fd7 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -488,7 +488,7 @@ impl EditorElement { line_mode: bool, cx: &mut PaintContext, ) { - if range.start != range.end { + if range.start != range.end || line_mode { let row_range = if range.end.column() == 0 { cmp::max(range.start.row(), start_row)..cmp::min(range.end.row(), end_row) } else { diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index 7d9ac8ed4025478192c4ab1e98ab6f19dff3caa3..dfed550777247fdf1ea73e6d69c82411b88cff64 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -38,7 +38,7 @@ impl SelectionsCollection { display_map, buffer, next_selection_id: 1, - line_mode: true, + line_mode: false, disjoint: Arc::from([]), pending: Some(PendingSelection { selection: Selection { diff --git a/crates/vim/src/editor_events.rs b/crates/vim/src/editor_events.rs index f3b6115c841d0fda9c6474c445d14248468b0768..1d477313846033fe2eed1d34a215a06c8e87fd68 100644 --- a/crates/vim/src/editor_events.rs +++ b/crates/vim/src/editor_events.rs @@ -22,7 +22,7 @@ fn editor_focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppCont vim.active_editor = Some(editor.downgrade()); vim.selection_subscription = Some(cx.subscribe(editor, |editor, event, cx| { if let editor::Event::SelectionsChanged { local: true } = event { - let newest_empty = !editor.read(cx).selections.newest::(cx).is_empty(); + let newest_empty = editor.read(cx).selections.newest::(cx).is_empty(); editor_local_selections_changed(newest_empty, cx); } })); diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index 31c2336f5e4721ce156bb71600719566fd0cb10e..a5ae5448fb73f8bda9692858ceff215ea460e95d 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -46,6 +46,10 @@ impl VimState { !matches!(self.mode, Mode::Insert) } + pub fn empty_selections_only(&self) -> bool { + self.mode != Mode::Visual && self.mode != Mode::VisualLine + } + pub fn keymap_context_layer(&self) -> Context { let mut context = Context::default(); context.map.insert( diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 115ef9ea38d1a8fb5b0737fee62404576a497bce..115536e6a5ad014f57bec88b50d2549241b49b7a 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -128,14 +128,24 @@ impl Vim { editor.set_cursor_shape(cursor_shape, cx); editor.set_clip_at_line_ends(cursor_shape == CursorShape::Block, cx); editor.set_input_enabled(!state.vim_controlled()); + editor.selections.line_mode = state.mode == Mode::VisualLine; let context_layer = state.keymap_context_layer(); editor.set_keymap_context_layer::(context_layer); } else { editor.set_cursor_shape(CursorShape::Bar, cx); editor.set_clip_at_line_ends(false, cx); editor.set_input_enabled(true); + editor.selections.line_mode = false; editor.remove_keymap_context_layer::(); } + + if state.empty_selections_only() { + editor.change_selections(None, cx, |s| { + s.move_with(|_, selection| { + selection.collapse_to(selection.head(), selection.goal) + }); + }) + } }); } } diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index da9bc04cb1e4bd0fb51d58871130e05665923d0b..0a7517bfb8078687a8b4a4db08582e967cdc15a7 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -1,3 +1,4 @@ +use collections::HashMap; use editor::{Autoscroll, Bias}; use gpui::{actions, MutableAppContext, ViewContext}; use workspace::Workspace; @@ -68,7 +69,7 @@ pub fn change(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext) { +pub fn change_line(_: &mut Workspace, _: &VisualLineChange, cx: &mut ViewContext) { Vim::update(cx, |vim, cx| { vim.update_active_editor(cx, |editor, cx| { editor.set_clip_at_line_ends(false, cx); @@ -114,13 +115,14 @@ pub fn delete(_: &mut Workspace, _: &VisualDelete, cx: &mut ViewContext) { +pub fn delete_line(_: &mut Workspace, _: &VisualLineDelete, cx: &mut ViewContext) { Vim::update(cx, |vim, cx| { - vim.switch_mode(Mode::Normal, cx); vim.update_active_editor(cx, |editor, cx| { editor.set_clip_at_line_ends(false, cx); + let mut original_columns: HashMap<_, _> = Default::default(); editor.change_selections(Some(Autoscroll::Fit), cx, |s| { s.move_with(|map, selection| { + original_columns.insert(selection.id, selection.head().column()); selection.start = map.prev_line_boundary(selection.start.to_point(map)).1; if selection.end.row() < map.max_point().row() { @@ -143,11 +145,15 @@ pub fn delete_line(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext