feat: add ScrollToTop action (#2110)

This commit is contained in:
Yves Biener 2023-01-24 13:51:11 +01:00 committed by GitHub
parent beddfb77a8
commit 650aeb12be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 123 additions and 0 deletions

View File

@ -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

View File

@ -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,

View File

@ -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 =

View File

@ -1520,6 +1520,53 @@ pub fn send_cli_scroll_to_bottom_action() {
assert_snapshot!(format!("{}", snapshot_count));
}
#[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 };

View File

@ -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): └──────────────────────────────────────┘└──────────────────────────────────────┘

View File

@ -0,0 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 1567
expression: "format!(\"{}\", snapshot_count)"
---
2

View File

@ -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): └──────────────────────────────────────┘└──────────────────────────────────────┘

View File

@ -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.

View File

@ -261,6 +261,7 @@ pub enum ScreenContext {
ScrollDown,
ScrollDownAt,
ScrollToBottom,
ScrollToTop,
PageScrollUp,
PageScrollDown,
HalfPageScrollUp,

View File

@ -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]),

View File

@ -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)
},