diff options
author | Aram Drevekenin <aram@poor.dev> | 2021-08-12 14:50:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-12 14:50:00 +0200 |
commit | a37d3e5889476bbac209d20f89886daa3e9d3992 (patch) | |
tree | c02fbf779dda57b615a852fd6a43818b20722b19 /src | |
parent | 426cee728a3b8c84edbc2d02cbc22f4840fc6a28 (diff) |
feat(ui): pane frames (new pane UI) (#643)
* work
* resize working
* move focus working
* close pane working
* selection and fullscreen working
* pane title line
* titles and conditional scroll title
* whole tab resize working
* plugin frames working
* plugin splitting working
* truncate pane frame titles
* cleanup
* panes always draw their own borders - also fix gap
* toggle pane frames
* move toggle to screen and fix some bugs
* fix plugin frame toggle
* fix terminal window resize
* fix scrolling and fullscreen bugs
* unit tests passing
* e2e tests passing and new test for new frames added
* refactor: TerminalPane and PluginPane
* refactor: Tab
* refactor: moar Tab
* refactor: Boundaries
* only render and calculate boundaries when there are no pane frames
* refactor: Layout
* fix(grid): properly resize when coming back from alternative viewport
* style: remove commented code
* style: fmt
* style: fmt
* style: fmt + clippy
* docs(changelog): update change
Diffstat (limited to 'src')
17 files changed, 359 insertions, 245 deletions
diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index 8d41d44f9..d28ae2f76 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -221,26 +221,26 @@ pub fn scrolling_inside_a_pane() { let mut step_is_complete = false; if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() { // cursor is in the newly opened second pane - remote_terminal.send_key(&format!("{:0<57}", "line1 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line2 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line3 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line4 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line5 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line6 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line7 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line8 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line9 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line10 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line11 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line12 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line13 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line14 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line15 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line16 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line17 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line18 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line19 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<58}", "line20 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<56}", "line1 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line2 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line3 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line4 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line5 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line6 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line7 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line8 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line9 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line10 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line11 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line12 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line13 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line14 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line15 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line16 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line17 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line18 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line19 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<57}", "line20 ").as_bytes()); step_is_complete = true; } step_is_complete @@ -250,7 +250,7 @@ pub fn scrolling_inside_a_pane() { name: "Scroll up inside pane", instruction: |mut remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(119, 20) { + if remote_terminal.cursor_position_is(118, 20) { // all lines have been written to the pane remote_terminal.send_key(&SCROLL_MODE); remote_terminal.send_key(&SCROLL_UP_IN_SCROLL_MODE); @@ -263,7 +263,7 @@ pub fn scrolling_inside_a_pane() { name: "Wait for scroll to finish", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(119, 20) + if remote_terminal.cursor_position_is(118, 20) && remote_terminal.snapshot_contains("line1 ") { // scrolled up one line @@ -321,7 +321,7 @@ pub fn toggle_pane_fullscreen() { name: "Wait for pane to become fullscreen", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(2, 0) { + if remote_terminal.cursor_position_is(2, 2) { // cursor is in full screen pane now step_is_complete = true; } @@ -785,9 +785,9 @@ pub fn accepts_basic_layout() { name: "Wait for app to load", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(2, 0) - && remote_terminal.snapshot_contains("$ █ │$") - && remote_terminal.snapshot_contains("$ ") { + if remote_terminal.cursor_position_is(3, 1) + && remote_terminal.snapshot_contains("$ █ ││$") + && remote_terminal.snapshot_contains("$ ") { step_is_complete = true; } step_is_complete @@ -839,7 +839,7 @@ fn focus_pane_with_mouse() { name: "Wait for left pane to be focused", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(2, 2) && remote_terminal.tip_appears() { + if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() { // cursor is in the newly opened second pane step_is_complete = true; } @@ -884,26 +884,26 @@ pub fn scrolling_inside_a_pane_with_mouse() { let mut step_is_complete = false; if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() { // cursor is in the newly opened second pane - remote_terminal.send_key(&format!("{:0<57}", "line1 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line2 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line3 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line4 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line5 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line6 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line7 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line8 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line9 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line10 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line11 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line12 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line13 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line14 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line15 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line16 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line17 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line18 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<59}", "line19 ").as_bytes()); - remote_terminal.send_key(&format!("{:0<58}", "line20 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<56}", "line1 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line2 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line3 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line4 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line5 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line6 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line7 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line8 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line9 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line10 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line11 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line12 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line13 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line14 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line15 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line16 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line17 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line18 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<58}", "line19 ").as_bytes()); + remote_terminal.send_key(&format!("{:0<57}", "line20 ").as_bytes()); step_is_complete = true; } step_is_complete @@ -913,7 +913,7 @@ pub fn scrolling_inside_a_pane_with_mouse() { name: "Scroll up inside pane", instruction: |mut remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(119, 20) { + if remote_terminal.cursor_position_is(118, 20) { // all lines have been written to the pane remote_terminal.send_key(&normal_mouse_report(Position::new(2, 64), 64)); step_is_complete = true; @@ -925,7 +925,7 @@ pub fn scrolling_inside_a_pane_with_mouse() { name: "Wait for scroll to finish", instruction: |remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(119, 20) + if remote_terminal.cursor_position_is(118, 20) && remote_terminal.snapshot_contains("line1 ") { // scrolled up one line @@ -937,3 +937,45 @@ pub fn scrolling_inside_a_pane_with_mouse() { .run_all_steps(); assert_snapshot!(last_snapshot); } + +#[test] +#[ignore] +pub fn start_without_pane_frames() { + let fake_win_size = PositionAndSize { + cols: 120, + rows: 24, + x: 0, + y: 0, + ..Default::default() + }; + + let last_snapshot = RemoteRunner::new_without_frames("no_pane_frames", fake_win_size, None) + .add_step(Step { + name: "Split pane to the right", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() && remote_terminal.cursor_position_is(2, 1) + { + remote_terminal.send_key(&PANE_MODE); + remote_terminal.send_key(&SPLIT_RIGHT_IN_PANE_MODE); + // back to normal mode after split + remote_terminal.send_key(&ENTER); + step_is_complete = true; + } + step_is_complete + }, + }) + .add_step(Step { + name: "Wait for new pane to appear", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.cursor_position_is(62, 1) && remote_terminal.tip_appears() { + // cursor is in the newly opened second pane + step_is_complete = true; + } + step_is_complete + }, + }) + .run_all_steps(); + assert_snapshot!(last_snapshot); +} diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs index 053df477a..09ca8eae9 100644 --- a/src/tests/e2e/remote_runner.rs +++ b/src/tests/e2e/remote_runner.rs @@ -57,6 +57,13 @@ fn start_zellij(channel: &mut ssh2::Channel, session_name: Option<&String>) { channel.flush().unwrap(); } +fn start_zellij_without_frames(channel: &mut ssh2::Channel) { + channel + .write_all(format!("{} options --no-pane-frames\n", ZELLIJ_EXECUTABLE_LOCATION).as_bytes()) + .unwrap(); + channel.flush().unwrap(); +} + fn start_zellij_with_layout( channel: &mut ssh2::Channel, layout_path: &str, @@ -136,7 +143,8 @@ impl<'a> RemoteTerminal<'a> { self.current_snapshot.contains("Tip:") } pub fn status_bar_appears(&self) -> bool { - self.current_snapshot.contains("Ctrl +") && !self.current_snapshot.contains("─────") + self.current_snapshot.contains("Ctrl +") + // self.current_snapshot.contains("Ctrl +") && !self.current_snapshot.contains("─────") // this is a bug that happens because the app draws borders around the status bar momentarily on first render } pub fn snapshot_contains(&self, text: &str) -> bool { @@ -198,6 +206,7 @@ pub struct RemoteRunner { retries_left: usize, win_size: PositionAndSize, layout_file_name: Option<&'static str>, + without_frames: bool, } impl RemoteRunner { @@ -209,7 +218,7 @@ impl RemoteRunner { let sess = ssh_connect(); let mut channel = sess.channel_session().unwrap(); let vte_parser = vte::Parser::new(); - let terminal_output = TerminalPane::new(0, win_size, Palette::default()); + let terminal_output = TerminalPane::new(0, win_size, Palette::default(), 0); // 0 is the pane index setup_remote_environment(&mut channel, win_size); start_zellij(&mut channel, session_name.as_ref()); RemoteRunner { @@ -224,6 +233,33 @@ impl RemoteRunner { retries_left: 3, win_size, layout_file_name: None, + without_frames: false, + } + } + pub fn new_without_frames( + test_name: &'static str, + win_size: PositionAndSize, + session_name: Option<String>, + ) -> Self { + let sess = ssh_connect(); + let mut channel = sess.channel_session().unwrap(); + let vte_parser = vte::Parser::new(); + let terminal_output = TerminalPane::new(0, win_size, Palette::default(), 0); // 0 is the pane index + setup_remote_environment(&mut channel, win_size); + start_zellij_without_frames(&mut channel); + RemoteRunner { + steps: vec![], + channel, + terminal_output, + vte_parser, + session_name, + test_name, + currently_running_step: None, + current_step_index: 0, + retries_left: 3, + win_size, + layout_file_name: None, + without_frames: true, } } pub fn new_with_layout( @@ -232,12 +268,11 @@ impl RemoteRunner { layout_file_name: &'static str, session_name: Option<String>, ) -> Self { - // let layout_file_name = local_layout_path.file_name().unwrap(); - let remote_path = Path::new(ZELLIJ_LAYOUT_PATH).join(layout_file_name); // TODO: not hardcoded + let remote_path = Path::new(ZELLIJ_LAYOUT_PATH).join(layout_file_name); let sess = ssh_connect(); let mut channel = sess.channel_session().unwrap(); let vte_parser = vte::Parser::new(); - let terminal_output = TerminalPane::new(0, win_size, Palette::default()); + let terminal_output = TerminalPane::new(0, win_size, Palette::default(), 0); // 0 is the pane index setup_remote_environment(&mut channel, win_size); start_zellij_with_layout( &mut channel, @@ -256,6 +291,7 @@ impl RemoteRunner { retries_left: 3, win_size, layout_file_name: Some(layout_file_name), + without_frames: false, } } pub fn add_step(mut self, step: Step) -> Self { @@ -315,6 +351,13 @@ impl RemoteRunner { new_runner.replace_steps(self.steps.clone()); drop(std::mem::replace(self, new_runner)); self.run_all_steps() + } else if self.without_frames { + let mut new_runner = + RemoteRunner::new_without_frames(self.test_name, self.win_size, session_name); + new_runner.retries_left = self.retries_left - 1; + new_runner.replace_steps(self.steps.clone()); + drop(std::mem::replace(self, new_runner)); + self.run_all_steps() } else { let mut new_runner = RemoteRunner::new(self.test_name, self.win_size, session_name); new_runner.retries_left = self.retries_left - 1; diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__accepts_basic_layout.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__accepts_basic_layout.snap index 5556153a5..02ded6de5 100644 --- a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__accepts_basic_layout.snap +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__accepts_basic_layout.snap @@ -3,27 +3,27 @@ source: src/tests/e2e/cases.rs expression: last_snapshot --- -$ █ │$ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ - │ -───────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────── -$ - - - - +┌ Pane #1 ─────────────┐┌ Pane #2 ─────────────────────────────────────────────────────────────────────────────────────┐ +│$ █ ││$ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +└──────────────────────┘└──────────────────────────────────────────────────────────────────────────────────────────────┘ +┌ Pane #3 ────────────────────────────────────────────────────────────────── |