diff options
author | Yves Biener <56591091+yves-biener@users.noreply.github.com> | 2023-01-24 13:51:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-24 21:51:11 +0900 |
commit | 650aeb12bed057572cb806e9324647dd35a05e98 (patch) | |
tree | 5da0d6d5176f2a9f457c630167d7eb11864c4d8c /zellij-server | |
parent | beddfb77a8ef8a5b90db084ad8030d1168f77352 (diff) |
feat: add ScrollToTop action (#2110)
Diffstat (limited to 'zellij-server')
7 files changed, 113 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): └──────────────────────────────────────┘└──────────────────────────────────────┘ + |