aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorAlexanderDickie2024-02-18 23:13:04 +0000
committerGitHub2024-02-18 23:13:04 +0000
commit9ab3f9d01a8ea4967f5a7e64a3f6c8f350674c18 (patch)
treef6b5fdbf1c7924584ecbc975591138def7ce16f8 /helix-term
parent64326698225999016300423c4b90f8a8c7b8f38b (diff)
Scroll cursor and page together (neovim-like scrolling) (#8015)
* neovim like scroll function * clear line annotations outside of move_vertically/_visual * add nvim scroll function to commands * assign nvim-scroll to C-d and C-u (half page scrolls) * dont remove backspace and space mapping * move non-softwrap logic to seperate function, call this in nvim-scroll fn * Revert "move non-softwrap logic to seperate function, call this in nvim-scroll fn" This reverts commit e4905729c338a2260e6981f1d8fac022897b4191. * Revert "clear line annotations outside of move_vertically/_visual" This reverts commit 1df3fefe55afc840d1ab5094b2116d1127fc363f. * add TODO for when inline diagnostics gets merged * move nvim-scroll logic into scroll(), dont respect scrolloff * run cargo fmt * run cargo clippy * update documenation for Ctrl-d and Ctrl-u remap
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs68
-rw-r--r--helix-term/src/keymap/default.rs12
-rw-r--r--helix-term/src/ui/editor.rs2
3 files changed, 67 insertions, 15 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index e46109c0..51a1ede9 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -277,6 +277,10 @@ impl MappableCommand {
page_down, "Move page down",
half_page_up, "Move half page up",
half_page_down, "Move half page down",
+ page_cursor_up, "Move page and cursor up",
+ page_cursor_down, "Move page and cursor down",
+ page_cursor_half_up, "Move page and cursor half up",
+ page_cursor_half_down, "Move page and cursor half down",
select_all, "Select whole document",
select_regex, "Select all regex matches inside selections",
split_selection, "Split selections on regex matches",
@@ -1608,7 +1612,7 @@ fn switch_to_lowercase(cx: &mut Context) {
});
}
-pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
+pub fn scroll(cx: &mut Context, offset: usize, direction: Direction, sync_cursor: bool) {
use Direction::*;
let config = cx.editor.config();
let (view, doc) = current!(cx.editor);
@@ -1628,7 +1632,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
let doc_text = doc.text().slice(..);
let viewport = view.inner_area(doc);
let text_fmt = doc.text_format(viewport.width, None);
- let annotations = view.text_annotations(doc, None);
+ let mut annotations = view.text_annotations(doc, None);
(view.offset.anchor, view.offset.vertical_offset) = char_idx_at_visual_offset(
doc_text,
view.offset.anchor,
@@ -1638,6 +1642,30 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
&annotations,
);
+ if sync_cursor {
+ let movement = match cx.editor.mode {
+ Mode::Select => Movement::Extend,
+ _ => Movement::Move,
+ };
+ // TODO: When inline diagnostics gets merged- 1. move_vertically_visual removes
+ // line annotations/diagnostics so the cursor may jump further than the view.
+ // 2. If the cursor lands on a complete line of virtual text, the cursor will
+ // jump a different distance than the view.
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ move_vertically_visual(
+ doc_text,
+ range,
+ direction,
+ offset.unsigned_abs(),
+ movement,
+ &text_fmt,
+ &mut annotations,
+ )
+ });
+ doc.set_selection(view.id, selection);
+ return;
+ }
+
let mut head;
match direction {
Forward => {
@@ -1688,25 +1716,49 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
fn page_up(cx: &mut Context) {
let view = view!(cx.editor);
let offset = view.inner_height();
- scroll(cx, offset, Direction::Backward);
+ scroll(cx, offset, Direction::Backward, false);
}
fn page_down(cx: &mut Context) {
let view = view!(cx.editor);
let offset = view.inner_height();
- scroll(cx, offset, Direction::Forward);
+ scroll(cx, offset, Direction::Forward, false);
}
fn half_page_up(cx: &mut Context) {
let view = view!(cx.editor);
let offset = view.inner_height() / 2;
- scroll(cx, offset, Direction::Backward);
+ scroll(cx, offset, Direction::Backward, false);
}
fn half_page_down(cx: &mut Context) {
let view = view!(cx.editor);
let offset = view.inner_height() / 2;
- scroll(cx, offset, Direction::Forward);
+ scroll(cx, offset, Direction::Forward, false);
+}
+
+fn page_cursor_up(cx: &mut Context) {
+ let view = view!(cx.editor);
+ let offset = view.inner_height();
+ scroll(cx, offset, Direction::Backward, true);
+}
+
+fn page_cursor_down(cx: &mut Context) {
+ let view = view!(cx.editor);
+ let offset = view.inner_height();
+ scroll(cx, offset, Direction::Forward, true);
+}
+
+fn page_cursor_half_up(cx: &mut Context) {
+ let view = view!(cx.editor);
+ let offset = view.inner_height() / 2;
+ scroll(cx, offset, Direction::Backward, true);
+}
+
+fn page_cursor_half_down(cx: &mut Context) {
+ let view = view!(cx.editor);
+ let offset = view.inner_height() / 2;
+ scroll(cx, offset, Direction::Forward, true);
}
#[allow(deprecated)]
@@ -4856,11 +4908,11 @@ fn align_view_middle(cx: &mut Context) {
}
fn scroll_up(cx: &mut Context) {
- scroll(cx, cx.count(), Direction::Backward);
+ scroll(cx, cx.count(), Direction::Backward, false);
}
fn scroll_down(cx: &mut Context) {
- scroll(cx, cx.count(), Direction::Forward);
+ scroll(cx, cx.count(), Direction::Forward, false);
}
fn goto_ts_object_impl(cx: &mut Context, object: &'static str, direction: Direction) {
diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs
index 763ed4ae..92d6b590 100644
--- a/helix-term/src/keymap/default.rs
+++ b/helix-term/src/keymap/default.rs
@@ -178,8 +178,8 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"esc" => normal_mode,
"C-b" | "pageup" => page_up,
"C-f" | "pagedown" => page_down,
- "C-u" => half_page_up,
- "C-d" => half_page_down,
+ "C-u" => page_cursor_half_up,
+ "C-d" => page_cursor_half_down,
"C-w" => { "Window"
"C-w" | "w" => rotate_view,
@@ -287,8 +287,8 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"j" | "down" => scroll_down,
"C-b" | "pageup" => page_up,
"C-f" | "pagedown" => page_down,
- "C-u" | "backspace" => half_page_up,
- "C-d" | "space" => half_page_down,
+ "C-u" | "backspace" => page_cursor_half_up,
+ "C-d" | "space" => page_cursor_half_down,
"/" => search,
"?" => rsearch,
@@ -304,8 +304,8 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"j" | "down" => scroll_down,
"C-b" | "pageup" => page_up,
"C-f" | "pagedown" => page_down,
- "C-u" | "backspace" => half_page_up,
- "C-d" | "space" => half_page_down,
+ "C-u" | "backspace" => page_cursor_half_up,
+ "C-d" | "space" => page_cursor_half_down,
"/" => search,
"?" => rsearch,
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index bb749d2e..a87e6cbc 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -1156,7 +1156,7 @@ impl EditorView {
}
let offset = config.scroll_lines.unsigned_abs();
- commands::scroll(cxt, offset, direction);
+ commands::scroll(cxt, offset, direction, false);
cxt.editor.tree.focus = current_view;
cxt.editor.ensure_cursor_in_view(current_view);