From 8f06f119fdeebaa5f589b8c639fb6780597fc75b Mon Sep 17 00:00:00 2001 From: oromate <7943950+oromate@users.noreply.github.com> Date: Mon, 8 Nov 2021 11:05:47 -0300 Subject: [PATCH] feat(scrolling): half-page scroll actions (#813) * Half-page scroll actions #794 * fix(performance): do not hang when resizing large line wraps (#814) * fix(performance): do not hang when resizing large line wraps * style(fmt): make rustfmt happy * style(clippy): make clippy happy * docs(changelog): scroll fix * fix(compatibility): home and end key fix (#815) * fix(compatibility): handle home/end keys properly from terminfo * style(fmt): make rustfmt happy * style(fmt): remove unused import * docs(changelog): home end key fix * docs(changelog): fix link * fix(typo): Correct typo from `occured` to `occurred` (#821) * docs(changelog): fix a typo * fix(docs): fix wrong arguments for `cargo make run` given in CONTRIBUTING.md (#819) * docs(changelog): update `cargo-make` for `v0.35.3` * fix(warning): Fix an unused import warning of std::fs on macos (#820) * docs(changelog): fix unused import on darwin * add: `WriteChars` action (#825) * Behaves like the `Write` action, but one can specify strings themselves instead of their bytecodes. Usage: WriteChars: "cargo make test", * docs(changelog): Add `WriteChars` action * fix(docs): Fix a typo and some grammatical errors in bug_report.md (#826) * docs(changelog): fix typo bug_report template * add: `rust-version` (msrv) field to `Cargo.toml` (#828) * specifies the minimum version the package can be compiled with, may be ignored with `--ignore-rust-version` option ref: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field * docs(changelog): add `rust-version` to `Cargo.toml` * fix(unix): forkpty => openpty (#830) * fix(unix): forkpty => openpty * style(fmt): make rustfmt happy * docs(changelog): forkpty => openpty * Fix: move `colors_transform` to `colorsys` (#832) * `colors_transform` is deprecated and superceded by `colorsys` ref: https://crates.io/crates/colors-transform * docs(changelog): `colors_transform` to `colorsys` * feat(ui): add right-click support to plugins * chore(docs): update changelog * chore(warnings): remove unused imports (#833) * rename var sroll_rows and review snapshots * style(fmt): make rustfmt happy Co-authored-by: Aram Drevekenin Co-authored-by: Ken Matsui <26405363+ken-matsui@users.noreply.github.com> Co-authored-by: a-kenji Co-authored-by: Tw Co-authored-by: Brooks Rady --- ...__e2e__cases__scrolling_inside_a_pane.snap | 2 +- zellij-server/src/route.rs | 12 +++++++ zellij-server/src/screen.rs | 20 +++++++++++ zellij-server/src/tab.rs | 33 ++++++++++++++++--- zellij-utils/assets/config/default.yaml | 4 +++ zellij-utils/src/errors.rs | 2 ++ zellij-utils/src/input/actions.rs | 4 +++ zellij-utils/src/input/mod.rs | 1 + 8 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane.snap index fdea92b7a..664e881b4 100644 --- a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane.snap +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane.snap @@ -26,4 +26,4 @@ expression: last_snapshot │ ││line19 00000000000000000000000000000000000000000000000000█│ └──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘ Ctrl + LOCK 

PANE  TAB  RESIZE  MOVE  SCROLL  SESSION  QUIT  - <↓↑> Scroll / Scroll Page / Select pane + <↓↑> Scroll / Scroll Page / Scroll Half Page / Select pane diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 444be5a08..457354916 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -183,6 +183,18 @@ fn route_action( .send_to_screen(ScreenInstruction::PageScrollDown(client_id)) .unwrap(); } + Action::HalfPageScrollUp => { + session + .senders + .send_to_screen(ScreenInstruction::HalfPageScrollUp(client_id)) + .unwrap(); + } + Action::HalfPageScrollDown => { + session + .senders + .send_to_screen(ScreenInstruction::HalfPageScrollDown(client_id)) + .unwrap(); + } Action::ToggleFocusFullscreen => { session .senders diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 2a8c54c6a..fb225f78a 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -59,6 +59,8 @@ pub(crate) enum ScreenInstruction { ScrollToBottom(ClientId), PageScrollUp(ClientId), PageScrollDown(ClientId), + HalfPageScrollUp(ClientId), + HalfPageScrollDown(ClientId), ClearScroll(ClientId), CloseFocusedPane(ClientId), ToggleActiveTerminalFullscreen(ClientId), @@ -123,6 +125,8 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::ScrollToBottom(..) => ScreenContext::ScrollToBottom, ScreenInstruction::PageScrollUp(..) => ScreenContext::PageScrollUp, ScreenInstruction::PageScrollDown(..) => ScreenContext::PageScrollDown, + ScreenInstruction::HalfPageScrollUp(..) => ScreenContext::HalfPageScrollUp, + ScreenInstruction::HalfPageScrollDown(..) => ScreenContext::HalfPageScrollDown, ScreenInstruction::ClearScroll(..) => ScreenContext::ClearScroll, ScreenInstruction::CloseFocusedPane(..) => ScreenContext::CloseFocusedPane, ScreenInstruction::ToggleActiveTerminalFullscreen(..) => { @@ -848,6 +852,22 @@ pub(crate) fn screen_thread_main( screen.render(); } + ScreenInstruction::HalfPageScrollUp(client_id) => { + screen + .get_active_tab_mut(client_id) + .unwrap() + .scroll_active_terminal_up_half_page(); + + screen.render(); + } + ScreenInstruction::HalfPageScrollDown(client_id) => { + screen + .get_active_tab_mut(client_id) + .unwrap() + .scroll_active_terminal_down_half_page(); + + screen.render(); + } ScreenInstruction::ClearScroll(client_id) => { screen .get_active_tab_mut(client_id) diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs index ffdf7e647..083984178 100644 --- a/zellij-server/src/tab.rs +++ b/zellij-server/src/tab.rs @@ -2899,8 +2899,8 @@ impl Tab { .get_mut(&PaneId::Terminal(active_terminal_id)) .unwrap(); // prevent overflow when row == 0 - let scroll_columns = active_terminal.rows().max(1) - 1; - active_terminal.scroll_up(scroll_columns); + let scroll_rows = active_terminal.rows().max(1) - 1; + active_terminal.scroll_up(scroll_rows); } } pub fn scroll_active_terminal_down_page(&mut self) { @@ -2910,8 +2910,33 @@ impl Tab { .get_mut(&PaneId::Terminal(active_terminal_id)) .unwrap(); // prevent overflow when row == 0 - let scroll_columns = active_terminal.rows().max(1) - 1; - active_terminal.scroll_down(scroll_columns); + let scroll_rows = active_terminal.rows().max(1) - 1; + active_terminal.scroll_down(scroll_rows); + if !active_terminal.is_scrolled() { + self.process_pending_vte_events(active_terminal_id); + } + } + } + pub fn scroll_active_terminal_up_half_page(&mut self) { + if let Some(active_terminal_id) = self.get_active_terminal_id() { + let active_terminal = self + .panes + .get_mut(&PaneId::Terminal(active_terminal_id)) + .unwrap(); + // prevent overflow when row == 0 + let scroll_rows = (active_terminal.rows().max(1) - 1) / 2; + active_terminal.scroll_up(scroll_rows); + } + } + pub fn scroll_active_terminal_down_half_page(&mut self) { + if let Some(active_terminal_id) = self.get_active_terminal_id() { + let active_terminal = self + .panes + .get_mut(&PaneId::Terminal(active_terminal_id)) + .unwrap(); + // prevent overflow when row == 0 + let scroll_rows = (active_terminal.rows().max(1) - 1) / 2; + active_terminal.scroll_down(scroll_rows); if !active_terminal.is_scrolled() { self.process_pending_vte_events(active_terminal_id); } diff --git a/zellij-utils/assets/config/default.yaml b/zellij-utils/assets/config/default.yaml index b1a1ad2e3..35dc2311d 100644 --- a/zellij-utils/assets/config/default.yaml +++ b/zellij-utils/assets/config/default.yaml @@ -265,6 +265,10 @@ keybinds: key: [Ctrl: 'f', PageDown, Right, Char: 'l',] - action: [PageScrollUp,] key: [Ctrl: 'b', PageUp, Left, Char: 'h',] + - action: [HalfPageScrollDown,] + key: [Char: 'd',] + - action: [HalfPageScrollUp,] + key: [Char: 'u',] - action: [NewPane: ,] key: [ Alt: 'n',] - action: [MoveFocus: Left,] diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs index 6dae0d1ac..7088c30ce 100644 --- a/zellij-utils/src/errors.rs +++ b/zellij-utils/src/errors.rs @@ -239,6 +239,8 @@ pub enum ScreenContext { ScrollToBottom, PageScrollUp, PageScrollDown, + HalfPageScrollUp, + HalfPageScrollDown, ClearScroll, CloseFocusedPane, ToggleActiveSyncTab, diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index 13d3566de..bd43206cf 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -68,6 +68,10 @@ pub enum Action { PageScrollUp, /// Scroll down one page in focus pane. PageScrollDown, + /// Scroll up half page in focus pane. + HalfPageScrollUp, + /// Scroll down half page in focus pane. + HalfPageScrollDown, /// Toggle between fullscreen focus pane and normal layout. ToggleFocusFullscreen, /// Toggle frames around panes in the UI diff --git a/zellij-utils/src/input/mod.rs b/zellij-utils/src/input/mod.rs index c0a0f1aee..613b8d172 100644 --- a/zellij-utils/src/input/mod.rs +++ b/zellij-utils/src/input/mod.rs @@ -51,6 +51,7 @@ pub fn get_mode_info( InputMode::Scroll => vec![ ("↓↑".to_string(), "Scroll".to_string()), ("PgUp/PgDn".to_string(), "Scroll Page".to_string()), + ("u/d".to_string(), "Scroll Half Page".to_string()), ], InputMode::RenameTab => vec![("Enter".to_string(), "when done".to_string())], InputMode::Session => vec![("d".to_string(), "Detach".to_string())],