Working change and delete in line mode

This commit is contained in:
Keith Simmons 2022-05-18 17:41:26 -07:00
parent d7d17b2148
commit f8f316cc64
7 changed files with 27 additions and 7 deletions

View File

@ -73,7 +73,7 @@
"vim::SwitchMode", "vim::SwitchMode",
"Visual" "Visual"
], ],
"V": [ "shift-V": [
"vim::SwitchMode", "vim::SwitchMode",
"VisualLine" "VisualLine"
] ]

View File

@ -488,7 +488,7 @@ impl EditorElement {
line_mode: bool, line_mode: bool,
cx: &mut PaintContext, cx: &mut PaintContext,
) { ) {
if range.start != range.end { if range.start != range.end || line_mode {
let row_range = if range.end.column() == 0 { let row_range = if range.end.column() == 0 {
cmp::max(range.start.row(), start_row)..cmp::min(range.end.row(), end_row) cmp::max(range.start.row(), start_row)..cmp::min(range.end.row(), end_row)
} else { } else {

View File

@ -38,7 +38,7 @@ impl SelectionsCollection {
display_map, display_map,
buffer, buffer,
next_selection_id: 1, next_selection_id: 1,
line_mode: true, line_mode: false,
disjoint: Arc::from([]), disjoint: Arc::from([]),
pending: Some(PendingSelection { pending: Some(PendingSelection {
selection: Selection { selection: Selection {

View File

@ -22,7 +22,7 @@ fn editor_focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppCont
vim.active_editor = Some(editor.downgrade()); vim.active_editor = Some(editor.downgrade());
vim.selection_subscription = Some(cx.subscribe(editor, |editor, event, cx| { vim.selection_subscription = Some(cx.subscribe(editor, |editor, event, cx| {
if let editor::Event::SelectionsChanged { local: true } = event { if let editor::Event::SelectionsChanged { local: true } = event {
let newest_empty = !editor.read(cx).selections.newest::<usize>(cx).is_empty(); let newest_empty = editor.read(cx).selections.newest::<usize>(cx).is_empty();
editor_local_selections_changed(newest_empty, cx); editor_local_selections_changed(newest_empty, cx);
} }
})); }));

View File

@ -46,6 +46,10 @@ impl VimState {
!matches!(self.mode, Mode::Insert) !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 { pub fn keymap_context_layer(&self) -> Context {
let mut context = Context::default(); let mut context = Context::default();
context.map.insert( context.map.insert(

View File

@ -128,14 +128,24 @@ impl Vim {
editor.set_cursor_shape(cursor_shape, cx); editor.set_cursor_shape(cursor_shape, cx);
editor.set_clip_at_line_ends(cursor_shape == CursorShape::Block, cx); editor.set_clip_at_line_ends(cursor_shape == CursorShape::Block, cx);
editor.set_input_enabled(!state.vim_controlled()); editor.set_input_enabled(!state.vim_controlled());
editor.selections.line_mode = state.mode == Mode::VisualLine;
let context_layer = state.keymap_context_layer(); let context_layer = state.keymap_context_layer();
editor.set_keymap_context_layer::<Self>(context_layer); editor.set_keymap_context_layer::<Self>(context_layer);
} else { } else {
editor.set_cursor_shape(CursorShape::Bar, cx); editor.set_cursor_shape(CursorShape::Bar, cx);
editor.set_clip_at_line_ends(false, cx); editor.set_clip_at_line_ends(false, cx);
editor.set_input_enabled(true); editor.set_input_enabled(true);
editor.selections.line_mode = false;
editor.remove_keymap_context_layer::<Self>(); editor.remove_keymap_context_layer::<Self>();
} }
if state.empty_selections_only() {
editor.change_selections(None, cx, |s| {
s.move_with(|_, selection| {
selection.collapse_to(selection.head(), selection.goal)
});
})
}
}); });
} }
} }

View File

@ -1,3 +1,4 @@
use collections::HashMap;
use editor::{Autoscroll, Bias}; use editor::{Autoscroll, Bias};
use gpui::{actions, MutableAppContext, ViewContext}; use gpui::{actions, MutableAppContext, ViewContext};
use workspace::Workspace; use workspace::Workspace;
@ -68,7 +69,7 @@ pub fn change(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext<Workspac
}); });
} }
pub fn change_line(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext<Workspace>) { pub fn change_line(_: &mut Workspace, _: &VisualLineChange, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.set_clip_at_line_ends(false, cx); editor.set_clip_at_line_ends(false, cx);
@ -114,13 +115,14 @@ pub fn delete(_: &mut Workspace, _: &VisualDelete, cx: &mut ViewContext<Workspac
}); });
} }
pub fn delete_line(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext<Workspace>) { pub fn delete_line(_: &mut Workspace, _: &VisualLineDelete, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(Mode::Normal, cx);
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.set_clip_at_line_ends(false, cx); editor.set_clip_at_line_ends(false, cx);
let mut original_columns: HashMap<_, _> = Default::default();
editor.change_selections(Some(Autoscroll::Fit), cx, |s| { editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
s.move_with(|map, selection| { 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; selection.start = map.prev_line_boundary(selection.start.to_point(map)).1;
if selection.end.row() < map.max_point().row() { if selection.end.row() < map.max_point().row() {
@ -143,11 +145,15 @@ pub fn delete_line(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext<Wor
editor.change_selections(Some(Autoscroll::Fit), cx, |s| { editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
s.move_with(|map, selection| { s.move_with(|map, selection| {
let mut cursor = selection.head(); let mut cursor = selection.head();
if let Some(column) = original_columns.get(&selection.id) {
*cursor.column_mut() = *column
}
cursor = map.clip_point(cursor, Bias::Left); cursor = map.clip_point(cursor, Bias::Left);
selection.collapse_to(cursor, selection.goal) selection.collapse_to(cursor, selection.goal)
}); });
}); });
}); });
vim.switch_mode(Mode::Normal, cx);
}); });
} }