From e3c0e93e464dc613d2eb9909ab5bba93f71b95a0 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 18 Aug 2023 10:38:06 -0600 Subject: [PATCH 1/3] Fix cursor adjustment on scroll Fixes: zed-industries/community#1929 Also preserves visual modes correctly. --- crates/editor/src/scroll.rs | 3 ++- crates/vim/src/normal/scroll.rs | 40 +++++++++++++++------------------ 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/crates/editor/src/scroll.rs b/crates/editor/src/scroll.rs index f5edb00d589f6e881b78e7327e53cdcba5ccde2f..d87bc0ae4fb7895ab24973d59c0b46815abaca79 100644 --- a/crates/editor/src/scroll.rs +++ b/crates/editor/src/scroll.rs @@ -29,6 +29,7 @@ use self::{ }; pub const SCROLL_EVENT_SEPARATION: Duration = Duration::from_millis(28); +pub const VERTICAL_SCROLL_MARGIN: f32 = 3.; const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1); #[derive(Default)] @@ -136,7 +137,7 @@ pub struct ScrollManager { impl ScrollManager { pub fn new() -> Self { ScrollManager { - vertical_scroll_margin: 3.0, + vertical_scroll_margin: VERTICAL_SCROLL_MARGIN, anchor: ScrollAnchor::new(), ongoing: OngoingScroll::new(), autoscroll_request: None, diff --git a/crates/vim/src/normal/scroll.rs b/crates/vim/src/normal/scroll.rs index 7b068cd7936d5215bcca75187f853ff5e933f8b7..a2bbab0478e304f59919663f61f828d77cf4906e 100644 --- a/crates/vim/src/normal/scroll.rs +++ b/crates/vim/src/normal/scroll.rs @@ -1,7 +1,9 @@ -use std::cmp::Ordering; - use crate::Vim; -use editor::{display_map::ToDisplayPoint, scroll::scroll_amount::ScrollAmount, Editor}; +use editor::{ + display_map::ToDisplayPoint, + scroll::{scroll_amount::ScrollAmount, VERTICAL_SCROLL_MARGIN}, + DisplayPoint, Editor, +}; use gpui::{actions, AppContext, ViewContext}; use language::Bias; use workspace::Workspace; @@ -53,13 +55,9 @@ fn scroll(cx: &mut ViewContext, by: fn(c: Option) -> ScrollAmoun fn scroll_editor(editor: &mut Editor, amount: &ScrollAmount, cx: &mut ViewContext) { let should_move_cursor = editor.newest_selection_on_screen(cx).is_eq(); + editor.scroll_screen(amount, cx); if should_move_cursor { - let selection_ordering = editor.newest_selection_on_screen(cx); - if selection_ordering.is_eq() { - return; - } - let visible_rows = if let Some(visible_rows) = editor.visible_line_count() { visible_rows as u32 } else { @@ -69,21 +67,19 @@ fn scroll_editor(editor: &mut Editor, amount: &ScrollAmount, cx: &mut ViewContex let top_anchor = editor.scroll_manager.anchor().anchor; editor.change_selections(None, cx, |s| { - s.replace_cursors_with(|snapshot| { - let mut new_point = top_anchor.to_display_point(&snapshot); - - match selection_ordering { - Ordering::Less => { - new_point = snapshot.clip_point(new_point, Bias::Right); - } - Ordering::Greater => { - *new_point.row_mut() += visible_rows - 1; - new_point = snapshot.clip_point(new_point, Bias::Left); - } - Ordering::Equal => unreachable!(), - } + s.move_heads_with(|map, head, goal| { + let top = top_anchor.to_display_point(map); + let min_row = top.row() + VERTICAL_SCROLL_MARGIN as u32; + let max_row = top.row() + visible_rows - VERTICAL_SCROLL_MARGIN as u32 - 1; - vec![new_point] + let new_head = if head.row() < min_row { + map.clip_point(DisplayPoint::new(min_row, head.column()), Bias::Left) + } else if head.row() > max_row { + map.clip_point(DisplayPoint::new(max_row, head.column()), Bias::Left) + } else { + head + }; + (new_head, goal) }) }); } From 5029587e3b65187e8a8addd7c564b696944834cd Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 18 Aug 2023 11:39:48 -0600 Subject: [PATCH 2/3] Add ctrl-q as an alias for ctrl-v Fixes: zed-industries/community#871 --- assets/keymaps/vim.json | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index a93d8aa3ec8fb88168da83df4fcda486c9ae2cbb..458232b9b098f0300b86982b8c99312de193a569 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -104,6 +104,7 @@ "v": "vim::ToggleVisual", "shift-v": "vim::ToggleVisualLine", "ctrl-v": "vim::ToggleVisualBlock", + "ctrl-q": "vim::ToggleVisualBlock", "*": "vim::MoveToNext", "#": "vim::MoveToPrev", "0": "vim::StartOfLine", // When no number operator present, use start of line motion From 93461d366c863ae7f7bf3a83eb14890d51d4bd93 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 18 Aug 2023 12:24:39 -0600 Subject: [PATCH 3/3] Fix to go to non-whitespace character Fixes: zed-industries/community#831 --- crates/vim/src/motion.rs | 13 ++++++++++++- crates/vim/test_data/test_next_line_start.json | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 crates/vim/test_data/test_next_line_start.json diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index 29a1ba7df8b0062470f4e20e64f2d1b3e5e3bdcc..13c22afdaa33eda5ae959f519751288375281273 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -651,7 +651,10 @@ fn find_backward( fn next_line_start(map: &DisplaySnapshot, point: DisplayPoint, times: usize) -> DisplayPoint { let new_row = (point.row() + times as u32).min(map.max_buffer_row()); - map.clip_point(DisplayPoint::new(new_row, 0), Bias::Left) + first_non_whitespace( + map, + map.clip_point(DisplayPoint::new(new_row, 0), Bias::Left), + ) } #[cfg(test)] @@ -799,4 +802,12 @@ mod test { cx.simulate_shared_keystrokes([","]).await; cx.assert_shared_state("one two thˇree four").await; } + + #[gpui::test] + async fn test_next_line_start(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + cx.set_shared_state("ˇone\n two\nthree").await; + cx.simulate_shared_keystrokes(["enter"]).await; + cx.assert_shared_state("one\n ˇtwo\nthree").await; + } } diff --git a/crates/vim/test_data/test_next_line_start.json b/crates/vim/test_data/test_next_line_start.json new file mode 100644 index 0000000000000000000000000000000000000000..90ed4a4f0384f15c0bbc92e68692ae3ceb150835 --- /dev/null +++ b/crates/vim/test_data/test_next_line_start.json @@ -0,0 +1,3 @@ +{"Put":{"state":"ˇone\n two\nthree"}} +{"Key":"enter"} +{"Get":{"state":"one\n ˇtwo\nthree","mode":"Normal"}}