summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2021-08-12 14:50:00 +0200
committerGitHub <noreply@github.com>2021-08-12 14:50:00 +0200
commita37d3e5889476bbac209d20f89886daa3e9d3992 (patch)
treec02fbf779dda57b615a852fd6a43818b20722b19
parent426cee728a3b8c84edbc2d02cbc22f4840fc6a28 (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
-rw-r--r--CHANGELOG.md1
-rw-r--r--default-plugins/status-bar/src/main.rs6
-rw-r--r--default-plugins/strider/src/state.rs6
-rw-r--r--default-plugins/tab-bar/src/line.rs6
-rw-r--r--src/tests/e2e/cases.rs140
-rw-r--r--src/tests/e2e/remote_runner.rs53
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__accepts_basic_layout.snap48
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__cannot_split_terminals_vertically_when_active_terminal_is_too_small.snap4
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__close_pane.snap4
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__detach_and_attach_session.snap44
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__focus_pane_with_mouse.snap42
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__lock_mode.snap4
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__open_new_tab.snap4
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__resize_pane.snap44
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__resize_terminal_window.snap44
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane.snap44
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__scrolling_inside_a_pane_with_mouse.snap42
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__split_terminals_vertically.snap44
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__start_without_pane_frames.snap29
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__starts_with_one_terminal.snap4
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__toggle_pane_fullscreen.snap10
-rw-r--r--zellij-server/src/panes/grid.rs88
-rw-r--r--zellij-server/src/panes/plugin_pane.rs195
-rw-r--r--zellij-server/src/panes/terminal_pane.rs201
-rw-r--r--zellij-server/src/panes/unit/grid_tests.rs4
-rw-r--r--zellij-server/src/panes/unit/terminal_pane_tests.rs2
-rw-r--r--zellij-server/src/route.rs6
-rw-r--r--zellij-server/src/screen.rs17
-rw-r--r--zellij-server/src/tab.rs868
-rw-r--r--zellij-server/src/ui/boundaries.rs159
-rw-r--r--zellij-server/src/ui/mod.rs1
-rw-r--r--zellij-server/src/ui/pane_boundaries_frame.rs277
-rw-r--r--zellij-server/src/ui/pane_resizer.rs64
-rw-r--r--zellij-server/src/ui/title_telescope.rs0
-rw-r--r--zellij-server/src/unit/screen_tests.rs9
-rw-r--r--zellij-server/src/unit/tab_tests.rs915
-rw-r--r--zellij-server/src/wasm_vm.rs16
-rw-r--r--zellij-utils/assets/config/default.yaml2
-rw-r--r--zellij-utils/assets/layouts/default.yaml2
-rw-r--r--zellij-utils/assets/layouts/disable-status-bar.yaml1
-rw-r--r--zellij-utils/assets/layouts/strider.yaml2
-rw-r--r--zellij-utils/src/errors.rs1
-rw-r--r--zellij-utils/src/input/actions.rs2
-rw-r--r--zellij-utils/src/input/layout.rs22
-rw-r--r--zellij-utils/src/input/mod.rs1
-rw-r--r--zellij-utils/src/input/options.rs5
-rw-r--r--zellij-utils/src/pane_size.rs14
-rw-r--r--zellij-utils/src/shared.rs2
48 files changed, 2420 insertions, 1079 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 97f68875b..fa985b353 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* Bound by default to `^c` in `scroll` mode, scrolls to bottom and exists the scroll mode
* Simplify deserialization slightly (https://github.com/zellij-org/zellij/pull/633)
* Fix update plugin attributes on inactive tab (https://github.com/zellij-org/zellij/pull/634)
+* New pane UI: draw pane frames - can be disabled with ctrl-p + z, or through configuration (https://github.com/zellij-org/zellij/pull/643)
## [0.15.0] - 2021-07-19
* Kill children properly (https://github.com/zellij-org/zellij/pull/601)
diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs
index 83eb50c9a..dba373f6b 100644
--- a/default-plugins/status-bar/src/main.rs
+++ b/default-plugins/status-bar/src/main.rs
@@ -154,7 +154,11 @@ impl ZellijPlugin for State {
let colored_elements = color_elements(self.mode_info.palette);
let superkey = superkey(colored_elements, separator);
- let ctrl_keys = ctrl_keys(&self.mode_info, cols - superkey.len, separator);
+ let ctrl_keys = ctrl_keys(
+ &self.mode_info,
+ cols.saturating_sub(superkey.len),
+ separator,
+ );
let first_line = format!("{}{}", superkey, ctrl_keys);
let second_line = keybinds(&self.mode_info, cols);
diff --git a/default-plugins/strider/src/state.rs b/default-plugins/strider/src/state.rs
index 0d96ae0b9..0ae84ab29 100644
--- a/default-plugins/strider/src/state.rs
+++ b/default-plugins/strider/src/state.rs
@@ -47,10 +47,10 @@ impl FsEntry {
FsEntry::Dir(_, s) => s.to_string(),
FsEntry::File(_, s) => pb::convert(*s as f64),
};
- let space = width - info.len();
+ let space = width.saturating_sub(info.len());
let name = self.name();
- if space - 1 < name.len() {
- [&name[..space - 2], &info].join("~ ")
+ if space.saturating_sub(1) < name.len() {
+ [&name[..space.saturating_sub(2)], &info].join("~ ")
} else {
let padding = " ".repeat(space - name.len());
[name, padding, info].concat()
diff --git a/default-plugins/tab-bar/src/line.rs b/default-plugins/tab-bar/src/line.rs
index 3ebeaac31..fc18abfd1 100644
--- a/default-plugins/tab-bar/src/line.rs
+++ b/default-plugins/tab-bar/src/line.rs
@@ -191,7 +191,7 @@ pub fn tab_line(
&mut tabs_before_active,
&mut tabs_after_active,
&mut tabs_to_render,
- cols - prefix.len,
+ cols.saturating_sub(prefix.len),
);
let mut tab_line: Vec<LinePart> = vec![];
@@ -200,7 +200,7 @@ pub fn tab_line(
&mut tabs_before_active,
&mut tabs_to_render,
&mut tab_line,
- cols - prefix.len,
+ cols.saturating_sub(prefix.len),
palette,
tab_separator(capabilities),
);
@@ -210,7 +210,7 @@ pub fn tab_line(
add_next_tabs_msg(
&mut tabs_after_active,
&mut tab_line,
- cols - prefix.len,
+ cols.saturating_sub(prefix.len),
palette,
tab_separator(capabilities),
);
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;
}