summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--zellij-server/src/route.rs6
-rw-r--r--zellij-server/src/screen.rs12
-rw-r--r--zellij-server/src/tab/mod.rs10
-rw-r--r--zellij-server/src/unit/screen_tests.rs47
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-2.snap16
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-3.snap6
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action.snap16
-rw-r--r--zellij-utils/src/cli.rs2
-rw-r--r--zellij-utils/src/errors.rs1
-rw-r--r--zellij-utils/src/input/actions.rs3
-rw-r--r--zellij-utils/src/kdl/mod.rs4
11 files changed, 123 insertions, 0 deletions
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 5b5e437ee..2ca58cc44 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -207,6 +207,12 @@ pub(crate) fn route_action(
.send_to_screen(ScreenInstruction::ScrollToBottom(client_id))
.with_context(err_context)?;
},
+ Action::ScrollToTop => {
+ session
+ .senders
+ .send_to_screen(ScreenInstruction::ScrollToTop(client_id))
+ .with_context(err_context)?;
+ },
Action::PageScrollUp => {
session
.senders
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index b2fdf4f80..fdca620d9 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -161,6 +161,7 @@ pub enum ScreenInstruction {
ScrollDown(ClientId),
ScrollDownAt(Position, ClientId),
ScrollToBottom(ClientId),
+ ScrollToTop(ClientId),
PageScrollUp(ClientId),
PageScrollDown(ClientId),
HalfPageScrollUp(ClientId),
@@ -294,6 +295,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::ScrollUp(..) => ScreenContext::ScrollUp,
ScreenInstruction::ScrollDown(..) => ScreenContext::ScrollDown,
ScreenInstruction::ScrollToBottom(..) => ScreenContext::ScrollToBottom,
+ ScreenInstruction::ScrollToTop(..) => ScreenContext::ScrollToTop,
ScreenInstruction::PageScrollUp(..) => ScreenContext::PageScrollUp,
ScreenInstruction::PageScrollDown(..) => ScreenContext::PageScrollDown,
ScreenInstruction::HalfPageScrollUp(..) => ScreenContext::HalfPageScrollUp,
@@ -1744,6 +1746,16 @@ pub(crate) fn screen_thread_main(
screen.render()?;
screen.unblock_input()?;
},
+ ScreenInstruction::ScrollToTop(client_id) => {
+ active_tab_and_connected_client_id!(
+ screen,
+ client_id,
+ |tab: &mut Tab, client_id: ClientId| tab
+ .scroll_active_terminal_to_top(client_id), ?
+ );
+ screen.render()?;
+ screen.unblock_input()?;
+ },
ScreenInstruction::PageScrollUp(client_id) => {
active_tab_and_connected_client_id!(
screen,
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index 093237eae..0dcd7ba58 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -2046,6 +2046,16 @@ impl Tab {
Ok(())
}
+ pub fn scroll_active_terminal_to_top(&mut self, client_id: ClientId) -> Result<()> {
+ if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
+ active_pane.clear_scroll();
+ if let Some(size) = active_pane.get_line_number() {
+ active_pane.scroll_up(size, client_id);
+ }
+ }
+ Ok(())
+ }
+
pub fn clear_active_terminal_scroll(&mut self, client_id: ClientId) -> Result<()> {
// TODO: is this a thing?
let err_context =
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index dd212c322..e9b399618 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -1521,6 +1521,53 @@ pub fn send_cli_scroll_to_bottom_action() {
}
#[test]
+pub fn send_cli_scroll_to_top_action() {
+ let size = Size { cols: 80, rows: 10 };
+ let client_id = 10; // fake client id should not appear in the screen's state
+ let mut initial_layout = PaneLayout::default();
+ initial_layout.children_split_direction = SplitDirection::Vertical;
+ initial_layout.children = vec![PaneLayout::default(), PaneLayout::default()];
+ let mut mock_screen = MockScreen::new(size);
+ let session_metadata = mock_screen.clone_session_metadata();
+ let screen_thread = mock_screen.run(Some(initial_layout));
+ let received_server_instructions = Arc::new(Mutex::new(vec![]));
+ let server_receiver = mock_screen.server_receiver.take().unwrap();
+ let server_instruction = log_actions_in_thread!(
+ received_server_instructions,
+ ServerInstruction::KillSession,
+ server_receiver
+ );
+ let scroll_to_top_action = CliAction::ScrollToTop;
+ let mut pane_contents = String::new();
+ for i in 0..20 {
+ pane_contents.push_str(&format!("fill pane up with something {}\n\r", i));
+ }
+ let _ = mock_screen.to_screen.send(ScreenInstruction::PtyBytes(
+ 0,
+ pane_contents.as_bytes().to_vec(),
+ ));
+ std::thread::sleep(std::time::Duration::from_millis(100));
+ // scroll to top
+ send_cli_action_to_server(
+ &session_metadata,
+ scroll_to_top_action.clone(),
+ &mut mock_screen,
+ client_id,
+ );
+ std::thread::sleep(std::time::Duration::from_millis(100));
+ mock_screen.teardown(vec![server_instruction, screen_thread]);
+ let snapshots = take_snapshots_and_cursor_coordinates_from_render_events(
+ received_server_instructions.lock().unwrap().iter(),
+ size,
+ );
+ let snapshot_count = snapshots.len();
+ for (_cursor_coordinates, snapshot) in snapshots {
+ assert_snapshot!(format!("{}", snapshot));
+ }
+ assert_snapshot!(format!("{}", snapshot_count));
+}
+
+#[test]
pub fn send_cli_page_scroll_up_action() {
let size = Size { cols: 80, rows: 10 };
let client_id = 10; // fake client id should not appear in the screen's state
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-2.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-2.snap
new file mode 100644
index 000000000..e0a5a3fd9
--- /dev/null
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-2.snap
@@ -0,0 +1,16 @@
+---
+source: zellij-server/src/./unit/screen_tests.rs
+assertion_line: 1565
+expression: "format!(\"{}\", snapshot)"
+---
+00 (C): ┌ Pane #1 ───────────── SCROLL: 13/13 ┐┌ Pane #2 ─────────────────────────────┐
+01 (C): │fill pane up with something 0 ││ │
+02 (C): │fill pane up with something 1 ││ │
+03 (C): │fill pane up with something 2 ││ │
+04 (C): │fill pane up with something 3 ││ │
+05 (C): │fill pane up with something 4 ││ │
+06 (C): │fill pane up with something 5 ││ │
+07 (C): │fill pane up with something 6 ││ │
+08 (C): │fill pane up with something 7 ││ │
+09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘
+
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-3.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-3.snap
new file mode 100644
index 000000000..526a865ca
--- /dev/null
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action-3.snap
@@ -0,0 +1,6 @@
+---
+source: zellij-server/src/./unit/screen_tests.rs
+assertion_line: 1567
+expression: "format!(\"{}\", snapshot_count)"
+---
+2
diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action.snap
new file mode 100644
index 000000000..0555f99f3
--- /dev/null
+++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_top_action.snap
@@ -0,0 +1,16 @@
+---
+source: zellij-server/src/./unit/screen_tests.rs
+assertion_line: 1565
+expression: "format!(\"{}\", snapshot)"
+---
+00 (C): ┌ Pane #1 ─────────────────────────────┐┌ Pane #2 ─────────────────────────────┐
+01 (C): │ ││ │
+02 (C): │ ││ │
+03 (C): │ ││ │
+04 (C): │ ││ │
+05 (C): │ ││ │
+06 (C): │ ││ │
+07 (C): │ ││ │
+08 (C): │ ││ │
+09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘
+
diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs
index 1d62e7d07..82c34eecd 100644
--- a/zellij-utils/src/cli.rs
+++ b/zellij-utils/src/cli.rs
@@ -216,6 +216,8 @@ pub enum CliAction {
ScrollDown,
/// Scroll down to bottom in focus pane.
ScrollToBottom,
+ /// Scroll up to top in focus pane.
+ ScrollToTop,
/// Scroll up one page in focus pane.
PageScrollUp,
/// Scroll down one page in focus pane.
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index b56bd79a1..50c8f9b28 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -261,6 +261,7 @@ pub enum ScreenContext {
ScrollDown,
ScrollDownAt,
ScrollToBottom,
+ ScrollToTop,
PageScrollUp,
PageScrollDown,
HalfPageScrollUp,
diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs
index 7bb13540c..1207023aa 100644
--- a/zellij-utils/src/input/actions.rs
+++ b/zellij-utils/src/input/actions.rs
@@ -128,6 +128,8 @@ pub enum Action {
ScrollDownAt(Position),
/// Scroll down to bottom in focus pane.
ScrollToBottom,
+ /// Scroll up to top in focus pane.
+ ScrollToTop,
/// Scroll up one page in focus pane.
PageScrollUp,
/// Scroll down one page in focus pane.
@@ -226,6 +228,7 @@ impl Action {
CliAction::ScrollUp => Ok(vec![Action::ScrollUp]),
CliAction::ScrollDown => Ok(vec![Action::ScrollDown]),
CliAction::ScrollToBottom => Ok(vec![Action::ScrollToBottom]),
+ CliAction::ScrollToTop => Ok(vec![Action::ScrollToTop]),
CliAction::PageScrollUp => Ok(vec![Action::PageScrollUp]),
CliAction::PageScrollDown => Ok(vec![Action::PageScrollDown]),
CliAction::HalfPageScrollUp => Ok(vec![Action::HalfPageScrollUp]),
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index db001fb5f..2a81300ca 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -43,6 +43,7 @@ macro_rules! parse_kdl_action_arguments {
"ScrollUp" => Ok(Action::ScrollUp),
"ScrollDown" => Ok(Action::ScrollDown),
"ScrollToBottom" => Ok(Action::ScrollToBottom),
+ "ScrollToTop" => Ok(Action::ScrollToTop),
"PageScrollUp" => Ok(Action::PageScrollUp),
"PageScrollDown" => Ok(Action::PageScrollDown),
"HalfPageScrollUp" => Ok(Action::HalfPageScrollUp),
@@ -636,6 +637,9 @@ impl TryFrom<&KdlNode> for Action {
"ScrollToBottom" => {
parse_kdl_action_arguments!(action_name, action_arguments, kdl_action)
},
+ "ScrollToTop" => {
+ parse_kdl_action_arguments!(action_name, action_arguments, kdl_action)
+ },
"PageScrollUp" => {
parse_kdl_action_arguments!(action_name, action_arguments, kdl_action)
},