mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-26 03:13:29 +04:00
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 commite4905729c3
. * Revert "clear line annotations outside of move_vertically/_visual" This reverts commit1df3fefe55
. * 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
This commit is contained in:
parent
6432669822
commit
9ab3f9d01a
@ -53,8 +53,8 @@ ### Movement
|
|||||||
| `End` | Move to the end of the line | `goto_line_end` |
|
| `End` | Move to the end of the line | `goto_line_end` |
|
||||||
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
|
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
|
||||||
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
|
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
|
||||||
| `Ctrl-u` | Move half page up | `half_page_up` |
|
| `Ctrl-u` | Move cursor and page half page up | `page_cursor_half_up` |
|
||||||
| `Ctrl-d` | Move half page down | `half_page_down` |
|
| `Ctrl-d` | Move cursor and page half page down | `page_cursor_half_down` |
|
||||||
| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` |
|
| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` |
|
||||||
| `Ctrl-o` | Jump backward on the jumplist | `jump_backward` |
|
| `Ctrl-o` | Jump backward on the jumplist | `jump_backward` |
|
||||||
| `Ctrl-s` | Save the current selection to the jumplist | `save_selection` |
|
| `Ctrl-s` | Save the current selection to the jumplist | `save_selection` |
|
||||||
@ -192,8 +192,8 @@ #### View mode
|
|||||||
| `k`, `up` | Scroll the view upwards | `scroll_up` |
|
| `k`, `up` | Scroll the view upwards | `scroll_up` |
|
||||||
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
|
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
|
||||||
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
|
| `Ctrl-b`, `PageUp` | Move page up | `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-u` | Move half page up | `half_page_up` |
|
| `Ctrl-d` | Move cursor and page half page down | `page_cursor_half_down` |
|
||||||
|
|
||||||
#### Goto mode
|
#### Goto mode
|
||||||
|
|
||||||
|
@ -277,6 +277,10 @@ pub fn doc(&self) -> &str {
|
|||||||
page_down, "Move page down",
|
page_down, "Move page down",
|
||||||
half_page_up, "Move half page up",
|
half_page_up, "Move half page up",
|
||||||
half_page_down, "Move half page down",
|
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_all, "Select whole document",
|
||||||
select_regex, "Select all regex matches inside selections",
|
select_regex, "Select all regex matches inside selections",
|
||||||
split_selection, "Split selections on regex matches",
|
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::*;
|
use Direction::*;
|
||||||
let config = cx.editor.config();
|
let config = cx.editor.config();
|
||||||
let (view, doc) = current!(cx.editor);
|
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 doc_text = doc.text().slice(..);
|
||||||
let viewport = view.inner_area(doc);
|
let viewport = view.inner_area(doc);
|
||||||
let text_fmt = doc.text_format(viewport.width, None);
|
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(
|
(view.offset.anchor, view.offset.vertical_offset) = char_idx_at_visual_offset(
|
||||||
doc_text,
|
doc_text,
|
||||||
view.offset.anchor,
|
view.offset.anchor,
|
||||||
@ -1638,6 +1642,30 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
|
|||||||
&annotations,
|
&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;
|
let mut head;
|
||||||
match direction {
|
match direction {
|
||||||
Forward => {
|
Forward => {
|
||||||
@ -1688,25 +1716,49 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
|
|||||||
fn page_up(cx: &mut Context) {
|
fn page_up(cx: &mut Context) {
|
||||||
let view = view!(cx.editor);
|
let view = view!(cx.editor);
|
||||||
let offset = view.inner_height();
|
let offset = view.inner_height();
|
||||||
scroll(cx, offset, Direction::Backward);
|
scroll(cx, offset, Direction::Backward, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_down(cx: &mut Context) {
|
fn page_down(cx: &mut Context) {
|
||||||
let view = view!(cx.editor);
|
let view = view!(cx.editor);
|
||||||
let offset = view.inner_height();
|
let offset = view.inner_height();
|
||||||
scroll(cx, offset, Direction::Forward);
|
scroll(cx, offset, Direction::Forward, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn half_page_up(cx: &mut Context) {
|
fn half_page_up(cx: &mut Context) {
|
||||||
let view = view!(cx.editor);
|
let view = view!(cx.editor);
|
||||||
let offset = view.inner_height() / 2;
|
let offset = view.inner_height() / 2;
|
||||||
scroll(cx, offset, Direction::Backward);
|
scroll(cx, offset, Direction::Backward, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn half_page_down(cx: &mut Context) {
|
fn half_page_down(cx: &mut Context) {
|
||||||
let view = view!(cx.editor);
|
let view = view!(cx.editor);
|
||||||
let offset = view.inner_height() / 2;
|
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)]
|
#[allow(deprecated)]
|
||||||
@ -4856,11 +4908,11 @@ fn align_view_middle(cx: &mut Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn scroll_up(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) {
|
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) {
|
fn goto_ts_object_impl(cx: &mut Context, object: &'static str, direction: Direction) {
|
||||||
|
@ -178,8 +178,8 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
|
|||||||
"esc" => normal_mode,
|
"esc" => normal_mode,
|
||||||
"C-b" | "pageup" => page_up,
|
"C-b" | "pageup" => page_up,
|
||||||
"C-f" | "pagedown" => page_down,
|
"C-f" | "pagedown" => page_down,
|
||||||
"C-u" => half_page_up,
|
"C-u" => page_cursor_half_up,
|
||||||
"C-d" => half_page_down,
|
"C-d" => page_cursor_half_down,
|
||||||
|
|
||||||
"C-w" => { "Window"
|
"C-w" => { "Window"
|
||||||
"C-w" | "w" => rotate_view,
|
"C-w" | "w" => rotate_view,
|
||||||
@ -287,8 +287,8 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
|
|||||||
"j" | "down" => scroll_down,
|
"j" | "down" => scroll_down,
|
||||||
"C-b" | "pageup" => page_up,
|
"C-b" | "pageup" => page_up,
|
||||||
"C-f" | "pagedown" => page_down,
|
"C-f" | "pagedown" => page_down,
|
||||||
"C-u" | "backspace" => half_page_up,
|
"C-u" | "backspace" => page_cursor_half_up,
|
||||||
"C-d" | "space" => half_page_down,
|
"C-d" | "space" => page_cursor_half_down,
|
||||||
|
|
||||||
"/" => search,
|
"/" => search,
|
||||||
"?" => rsearch,
|
"?" => rsearch,
|
||||||
@ -304,8 +304,8 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
|
|||||||
"j" | "down" => scroll_down,
|
"j" | "down" => scroll_down,
|
||||||
"C-b" | "pageup" => page_up,
|
"C-b" | "pageup" => page_up,
|
||||||
"C-f" | "pagedown" => page_down,
|
"C-f" | "pagedown" => page_down,
|
||||||
"C-u" | "backspace" => half_page_up,
|
"C-u" | "backspace" => page_cursor_half_up,
|
||||||
"C-d" | "space" => half_page_down,
|
"C-d" | "space" => page_cursor_half_down,
|
||||||
|
|
||||||
"/" => search,
|
"/" => search,
|
||||||
"?" => rsearch,
|
"?" => rsearch,
|
||||||
|
@ -1156,7 +1156,7 @@ fn handle_mouse_event(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let offset = config.scroll_lines.unsigned_abs();
|
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.tree.focus = current_view;
|
||||||
cxt.editor.ensure_cursor_in_view(current_view);
|
cxt.editor.ensure_cursor_in_view(current_view);
|
||||||
|
Loading…
Reference in New Issue
Block a user