Skip to content

Commit

Permalink
Scroll cursor and page together (neovim-like scrolling) (helix-editor…
Browse files Browse the repository at this point in the history
…#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 e490572.

* Revert "clear line annotations outside of move_vertically/_visual"

This reverts commit 1df3fef.

* 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
  • Loading branch information
AlexanderDickie authored and uek-1 committed Feb 24, 2024
1 parent e0e9d81 commit eaa31cc
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 29 deletions.
28 changes: 14 additions & 14 deletions book/src/keymap.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ Normal mode is the default mode when you launch helix. You can return to it from
| `End` | Move to the end of the line | `goto_line_end` |
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
| `Ctrl-u` | Move half page up | `half_page_up` |
| `Ctrl-d` | Move half page down | `half_page_down` |
| `Ctrl-u` | Move cursor and page half page up | `page_cursor_half_up` |
| `Ctrl-d` | Move cursor and page half page down | `page_cursor_half_down` |
| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` |
| `Ctrl-o` | Jump backward on the jumplist | `jump_backward` |
| `Ctrl-s` | Save the current selection to the jumplist | `save_selection` |
Expand Down Expand Up @@ -182,18 +182,18 @@ normal mode) is persistent and can be exited using the escape key. This is
useful when you're simply looking over text and not actively editing it.


| Key | Description | Command |
| ----- | ----------- | ------- |
| `z`, `c` | Vertically center the line | `align_view_center` |
| `t` | Align the line to the top of the screen | `align_view_top` |
| `b` | Align the line to the bottom of the screen | `align_view_bottom` |
| `m` | Align the line to the middle of the screen (horizontally) | `align_view_middle` |
| `j`, `down` | Scroll the view downwards | `scroll_down` |
| `k`, `up` | Scroll the view upwards | `scroll_up` |
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
| `Ctrl-d` | Move half page down | `half_page_down` |
| `Ctrl-u` | Move half page up | `half_page_up` |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `z`, `c` | Vertically center the line | `align_view_center` |
| `t` | Align the line to the top of the screen | `align_view_top` |
| `b` | Align the line to the bottom of the screen | `align_view_bottom` |
| `m` | Align the line to the middle of the screen (horizontally) | `align_view_middle` |
| `j`, `down` | Scroll the view downwards | `scroll_down` |
| `k`, `up` | Scroll the view upwards | `scroll_up` |
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
| `Ctrl-u` | Move cursor and page half page up | `page_cursor_half_up` |
| `Ctrl-d` | Move cursor and page half page down | `page_cursor_half_down` |

#### Goto mode

Expand Down
68 changes: 60 additions & 8 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -1609,7 +1613,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);
Expand All @@ -1629,7 +1633,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,
Expand All @@ -1639,6 +1643,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 => {
Expand Down Expand Up @@ -1689,25 +1717,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)]
Expand Down Expand Up @@ -4875,11 +4927,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) {
Expand Down
12 changes: 6 additions & 6 deletions helix-term/src/keymap/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit eaa31cc

Please sign in to comment.