Skip to content

Commit

Permalink
Maintain cursor to upper line in visual mode indent/outdent (#12582)
Browse files Browse the repository at this point in the history
Release Notes:

- vim: Fix indent via `<` and `>` not being repeatable with `.`.
[#12351](#12351)
  • Loading branch information
p-A-uLo authored Jun 6, 2024
1 parent fd39f20 commit 2f05778
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
43 changes: 41 additions & 2 deletions crates/vim/src/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) mod search;
pub mod substitute;
mod yank;

use std::collections::HashMap;
use std::sync::Arc;

use crate::{
Expand All @@ -21,8 +22,11 @@ use crate::{
Vim,
};
use collections::BTreeSet;
use editor::display_map::ToDisplayPoint;
use editor::scroll::Autoscroll;
use editor::Anchor;
use editor::Bias;
use editor::Editor;
use gpui::{actions, ViewContext, WindowContext};
use language::{Point, SelectionGoal};
use log::error;
Expand Down Expand Up @@ -143,7 +147,11 @@ pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
vim.update_active_editor(cx, |_, editor, cx| {
editor.transact(cx, |editor, cx| editor.indent(&Default::default(), cx))
editor.transact(cx, |editor, cx| {
let mut original_positions = save_selection_starts(editor, cx);
editor.indent(&Default::default(), cx);
restore_selection_cursors(editor, cx, &mut original_positions);
});
});
if vim.state().mode.is_visual() {
vim.switch_mode(Mode::Normal, false, cx)
Expand All @@ -155,7 +163,11 @@ pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace
Vim::update(cx, |vim, cx| {
vim.record_current_action(cx);
vim.update_active_editor(cx, |_, editor, cx| {
editor.transact(cx, |editor, cx| editor.outdent(&Default::default(), cx))
editor.transact(cx, |editor, cx| {
let mut original_positions = save_selection_starts(editor, cx);
editor.outdent(&Default::default(), cx);
restore_selection_cursors(editor, cx, &mut original_positions);
});
});
if vim.state().mode.is_visual() {
vim.switch_mode(Mode::Normal, false, cx)
Expand Down Expand Up @@ -390,6 +402,33 @@ fn yank_line(_: &mut Workspace, _: &YankLine, cx: &mut ViewContext<Workspace>) {
})
}

fn save_selection_starts(editor: &Editor, cx: &mut ViewContext<Editor>) -> HashMap<usize, Anchor> {
let (map, selections) = editor.selections.all_display(cx);
selections
.iter()
.map(|selection| {
(
selection.id,
map.display_point_to_anchor(selection.start, Bias::Right),
)
})
.collect::<HashMap<_, _>>()
}

fn restore_selection_cursors(
editor: &mut Editor,
cx: &mut ViewContext<Editor>,
positions: &mut HashMap<usize, Anchor>,
) {
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.move_with(|map, selection| {
if let Some(anchor) = positions.remove(&selection.id) {
selection.collapse_to(anchor.to_display_point(map), SelectionGoal::None);
}
});
});
}

pub(crate) fn normal_replace(text: Arc<str>, cx: &mut WindowContext) {
Vim::update(cx, |vim, cx| {
vim.stop_recording();
Expand Down
7 changes: 6 additions & 1 deletion crates/vim/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {

// works in visual mode
cx.simulate_keystrokes("shift-v down >");
cx.assert_editor_state("aa\n bb\n cˇc");
cx.assert_editor_state("aa\n bˇb\n cc");

// works as operator
cx.set_state("aa\nbˇb\ncc\n", Mode::Normal);
Expand All @@ -202,11 +202,16 @@ async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {
cx.simulate_keystrokes("> 2 k");
cx.assert_editor_state(" aa\n bb\n ˇcc\n");

// works with repeat
cx.set_state("a\nb\nccˇc\n", Mode::Normal);
cx.simulate_keystrokes("> 2 k");
cx.assert_editor_state(" a\n b\n ccˇc\n");
cx.simulate_keystrokes(".");
cx.assert_editor_state(" a\n b\n ccˇc\n");
cx.simulate_keystrokes("v k <");
cx.assert_editor_state(" a\n\n ccc\n");
cx.simulate_keystrokes(".");
cx.assert_editor_state(" a\n\nccc\n");
}

#[gpui::test]
Expand Down

0 comments on commit 2f05778

Please sign in to comment.