From 0b81c19fa144303eee8c91a4e2ba075012321ed4 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 14 Mar 2025 12:41:11 -0600 Subject: [PATCH] vim: Add zH/zL/zh/zl --- assets/keymaps/vim.json | 1 + crates/editor/src/element.rs | 7 ++++++- crates/editor/src/scroll.rs | 18 ++++++++++++++++++ crates/vim/src/normal/scroll.rs | 31 ++++++++++++++++++++++++++++++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index fe0613eac3..dc77e77483 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -155,6 +155,7 @@ "z +": ["workspace::SendKeystrokes", "shift-l j z t ^"], "z t": "editor::ScrollCursorTop", "z z": "editor::ScrollCursorCenter", + "z l": "vim::ScrollLeftHalfWay", "z .": ["workspace::SendKeystrokes", "z z ^"], "z b": "editor::ScrollCursorBottom", "z a": "editor::ToggleFold", diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 812cf3c143..f0b648f160 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -15,7 +15,7 @@ use crate::{ inlay_hint_settings, items::BufferSearchHighlights, mouse_context_menu::{self, MenuPosition, MouseContextMenu}, - scroll::{axis_pair, scroll_amount::ScrollAmount, AxisPair}, + scroll::{axis_pair, scroll_amount::ScrollAmount, AxisPair, HorizontalLayoutDetails}, BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayDiffHunk, DisplayPoint, DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, FocusedBlock, GoToHunk, GoToPreviousHunk, @@ -7031,6 +7031,11 @@ impl Element for EditorElement { ); self.editor.update(cx, |editor, cx| { + editor.scroll_manager.latest_horizontal_details = HorizontalLayoutDetails { + letter_width: letter_size.width.0, + editor_width: editor_width.0, + scroll_max: scroll_max.x, + }; let clamped = editor.scroll_manager.clamp_scroll_left(scroll_max.x); let autoscrolled = if autoscroll_horizontally { diff --git a/crates/editor/src/scroll.rs b/crates/editor/src/scroll.rs index 0ba1fde0ab..8cefd7f6fc 100644 --- a/crates/editor/src/scroll.rs +++ b/crates/editor/src/scroll.rs @@ -172,6 +172,13 @@ impl OngoingScroll { } } +#[derive(Default, Debug)] +pub struct HorizontalLayoutDetails { + pub letter_width: f32, + pub editor_width: f32, + pub scroll_max: f32, +} + pub struct ScrollManager { pub(crate) vertical_scroll_margin: f32, anchor: ScrollAnchor, @@ -183,6 +190,7 @@ pub struct ScrollManager { dragging_scrollbar: AxisPair, visible_line_count: Option, forbid_vertical_scroll: bool, + pub(crate) latest_horizontal_details: HorizontalLayoutDetails, } impl ScrollManager { @@ -198,6 +206,7 @@ impl ScrollManager { last_autoscroll: None, visible_line_count: None, forbid_vertical_scroll: false, + latest_horizontal_details: Default::default(), } } @@ -379,6 +388,15 @@ impl ScrollManager { cx.notify(); } + pub fn horizontal_scroll( + &mut self, + f: impl Fn(f32, &HorizontalLayoutDetails) -> f32, + cx: &mut Context, + ) { + self.anchor.offset.x = f(self.anchor.offset.x, &self.latest_horizontal_details); + cx.notify(); + } + pub fn clamp_scroll_left(&mut self, max: f32) -> bool { if max < self.anchor.offset.x { self.anchor.offset.x = max; diff --git a/crates/vim/src/normal/scroll.rs b/crates/vim/src/normal/scroll.rs index a7ae62741c..00f1db81c6 100644 --- a/crates/vim/src/normal/scroll.rs +++ b/crates/vim/src/normal/scroll.rs @@ -7,10 +7,20 @@ use editor::{ use gpui::{actions, Context, Window}; use language::Bias; use settings::Settings; +use ui::px; actions!( vim, - [LineUp, LineDown, ScrollUp, ScrollDown, PageUp, PageDown] + [ + LineUp, + LineDown, + ScrollUp, + ScrollDown, + PageUp, + PageDown, + ScrollLeftHalfWay, + ScrollRightHalfWay, + ] ); pub fn register(editor: &mut Editor, cx: &mut Context) { @@ -44,6 +54,25 @@ pub fn register(editor: &mut Editor, cx: &mut Context) { } }) }); + + Vim::action(editor, cx, |vim, _: &ScrollLeftHalfWay, window, cx| { + dbg!("here!"); + vim.update_editor(window, cx, |_, editor, window, cx| { + editor.scroll_manager.horizontal_scroll( + |current, details| (current + details.editor_width / 2.).min(details.scroll_max), + cx, + ); + }); + }); + // Vim::action(editor, cx, |vim, _: &ScrollRightHalfWay, window, cx| { + // vim.scroll_horizontal(window, cx, |c| { + // if let Some(c) = c { + // ScrollAmount::Line(-c) + // } else { + // ScrollAmount::Page(-0.5) + // } + // }) + // }); } impl Vim {