feat(ui): status bar redesign (#3475)

* work

* work

* working

* get default mode from server and some ui responsiveness

* work

* finish design and get tests to pass

* get e2e tests to pass

* add classic layout

* add classic layout assets

* fix e2e tests

* style(fmt): rustfmt

* fix plugin system test

* style(fmt): some cleanups
This commit is contained in:
Aram Drevekenin 2024-07-05 15:13:51 +02:00 committed by GitHub
parent 8e33b20559
commit a6d6c0e4ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
71 changed files with 2208 additions and 225 deletions

1
Cargo.lock generated
View file

@ -3811,6 +3811,7 @@ dependencies = [
"serde",
"serde_json",
"thiserror",
"unicode-width",
"zellij-tile",
"zellij-tile-utils",
]

View file

@ -13,6 +13,7 @@ rand = "0.8.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0.30"
unicode-width = "0.1.8"
zellij-tile = { path = "../../zellij-tile" }
zellij-tile-utils = { path = "../../zellij-tile-utils" }

View file

@ -8,14 +8,16 @@ use crate::{
};
use crate::{ColoredElements, LinePart};
struct KeyShortcut {
mode: KeyMode,
action: KeyAction,
key: Option<KeyWithModifier>,
#[derive(Debug)]
pub struct KeyShortcut {
pub mode: KeyMode,
pub action: KeyAction,
pub key: Option<KeyWithModifier>,
}
#[derive(PartialEq)]
enum KeyAction {
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum KeyAction {
Unlock,
Lock,
Pane,
Tab,
@ -27,7 +29,8 @@ enum KeyAction {
Tmux,
}
enum KeyMode {
#[derive(Debug, Copy, Clone)]
pub enum KeyMode {
Unselected,
UnselectedAlternate,
Selected,
@ -42,6 +45,7 @@ impl KeyShortcut {
pub fn full_text(&self) -> String {
match self.action {
KeyAction::Lock => String::from("LOCK"),
KeyAction::Unlock => String::from("UNLOCK"),
KeyAction::Pane => String::from("PANE"),
KeyAction::Tab => String::from("TAB"),
KeyAction::Resize => String::from("RESIZE"),
@ -82,6 +86,35 @@ impl KeyShortcut {
};
format!("{}", key)
}
pub fn get_key(&self) -> Option<KeyWithModifier> {
self.key.clone()
}
pub fn get_mode(&self) -> KeyMode {
self.mode
}
pub fn get_action(&self) -> KeyAction {
self.action
}
pub fn is_selected(&self) -> bool {
match self.mode {
KeyMode::Selected => true,
_ => false,
}
}
pub fn short_text(&self) -> String {
match self.action {
KeyAction::Lock => String::from("Lo"),
KeyAction::Unlock => String::from("Un"),
KeyAction::Pane => String::from("Pa"),
KeyAction::Tab => String::from("Ta"),
KeyAction::Resize => String::from("Re"),
KeyAction::Search => String::from("Se"),
KeyAction::Quit => String::from("Qu"),
KeyAction::Session => String::from("Se"),
KeyAction::Move => String::from("Mo"),
KeyAction::Tmux => String::from("Tm"),
}
}
}
/// Generate long mode shortcut tile.

View file

@ -1,4 +1,5 @@
mod first_line;
mod one_line_ui;
mod second_line;
mod tip;
@ -15,6 +16,7 @@ use zellij_tile::prelude::*;
use zellij_tile_utils::{palette_match, style};
use first_line::first_line;
use one_line_ui::one_line_ui;
use second_line::{
floating_panes_are_visible, fullscreen_panes_to_hide, keybinds,
locked_floating_panes_are_visible, locked_fullscreen_panes_to_hide, system_clipboard_error,
@ -35,6 +37,8 @@ struct State {
mode_info: ModeInfo,
text_copy_destination: Option<CopyDestination>,
display_system_clipboard_failure: bool,
classic_ui: bool,
base_mode_is_locked: bool,
}
register_plugin!(State);
@ -177,9 +181,13 @@ fn color_elements(palette: Palette, different_color_alternates: bool) -> Colored
}
impl ZellijPlugin for State {
fn load(&mut self, _configuration: BTreeMap<String, String>) {
fn load(&mut self, configuration: BTreeMap<String, String>) {
// TODO: Should be able to choose whether to use the cache through config.
self.tip_name = get_cached_tip_name();
self.classic_ui = configuration
.get("classic")
.map(|c| c == "true")
.unwrap_or(false);
set_selectable(false);
subscribe(&[
EventType::ModeUpdate,
@ -198,6 +206,7 @@ impl ZellijPlugin for State {
should_render = true;
}
self.mode_info = mode_info;
self.base_mode_is_locked = self.mode_info.base_mode == Some(InputMode::Locked);
},
Event::TabUpdate(tabs) => {
if self.tabs != tabs {
@ -244,6 +253,21 @@ impl ZellijPlugin for State {
""
};
if rows == 1 && !self.classic_ui {
let active_tab = self.tabs.iter().find(|t| t.active);
print!(
"{}",
one_line_ui(
&self.mode_info,
active_tab,
cols,
separator,
self.base_mode_is_locked
)
);
return;
}
let active_tab = self.tabs.iter().find(|t| t.active);
let first_line = first_line(&self.mode_info, active_tab, cols, separator);
let second_line = self.second_line(cols);
@ -418,10 +442,6 @@ pub fn style_key_with_modifier(
let common_modifiers = get_common_modifiers(keyvec.iter().collect());
// let modifier_str = match get_common_modifier(keyvec.iter().collect()) {
// Some(modifier) => modifier,
// None => "".to_string(),
// };
let no_common_modifier = common_modifiers.is_empty();
let modifier_str = common_modifiers
.iter()

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,14 @@
use ansi_term::ANSIStrings;
use ansi_term::{
Color::{Fixed, RGB},
Style,
};
use unicode_width::UnicodeWidthStr;
use crate::{LinePart, ARROW_SEPARATOR};
use zellij_tile::prelude::actions::Action;
use zellij_tile::prelude::*;
use zellij_tile_utils::style;
use zellij_tile_utils::{palette_match, style};
fn get_current_title_len(current_title: &[LinePart]) -> usize {
current_title.iter().map(|p| p.len).sum()
@ -224,6 +229,9 @@ pub fn tab_line(
palette: Palette,
capabilities: PluginCapabilities,
hide_session_name: bool,
tab_info: Option<&TabInfo>,
mode_info: &ModeInfo,
hide_swap_layout_indicator: bool,
) -> Vec<LinePart> {
let mut tabs_after_active = all_tabs.split_off(active_tab_index);
let mut tabs_before_active = all_tabs;
@ -236,10 +244,26 @@ pub fn tab_line(
true => tab_line_prefix(None, palette, cols),
false => tab_line_prefix(session_name, palette, cols),
};
let prefix_len = get_current_title_len(&prefix);
let mut swap_layout_indicator = if hide_swap_layout_indicator {
None
} else {
tab_info.and_then(|tab_info| {
swap_layout_status(
cols,
&tab_info.active_swap_layout_name,
tab_info.is_swap_layout_dirty,
mode_info,
!capabilities.arrow_fonts,
)
})
};
let non_tab_len =
get_current_title_len(&prefix) + swap_layout_indicator.as_ref().map(|s| s.len).unwrap_or(0);
// if active tab alone won't fit in cols, don't draw any tabs
if prefix_len + active_tab.len > cols {
if non_tab_len + active_tab.len > cols {
return prefix;
}
@ -249,10 +273,189 @@ pub fn tab_line(
&mut tabs_before_active,
&mut tabs_after_active,
&mut tabs_to_render,
cols.saturating_sub(prefix_len),
cols.saturating_sub(non_tab_len),
palette,
capabilities,
);
prefix.append(&mut tabs_to_render);
if let Some(mut swap_layout_indicator) = swap_layout_indicator.take() {
let remaining_space = cols
.saturating_sub(prefix.iter().fold(0, |len, part| len + part.len))
.saturating_sub(swap_layout_indicator.len);
let mut padding = String::new();
let mut padding_len = 0;
for _ in 0..remaining_space {
padding.push_str(" ");
padding_len += 1;
}
swap_layout_indicator.part = format!("{}{}", padding, swap_layout_indicator.part);
swap_layout_indicator.len += padding_len;
prefix.push(swap_layout_indicator);
}
prefix
}
fn swap_layout_status(
cols: usize,
swap_layout_name: &Option<String>,
is_swap_layout_dirty: bool,
mode_info: &ModeInfo,
supports_arrow_fonts: bool,
) -> Option<LinePart> {
match swap_layout_name {
Some(swap_layout_name) => {
let mode_keybinds = mode_info.get_mode_keybinds();
let prev_next_keys = action_key_group(
&mode_keybinds,
&[&[Action::PreviousSwapLayout], &[Action::NextSwapLayout]],
);
let mut text = style_key_with_modifier(&prev_next_keys, Some(0));
text.append(&ribbon_as_line_part(
&swap_layout_name.to_uppercase(),
!is_swap_layout_dirty,
supports_arrow_fonts,
));
Some(text)
},
None => None,
}
}
pub fn ribbon_as_line_part(text: &str, is_selected: bool, supports_arrow_fonts: bool) -> LinePart {
let ribbon_text = if is_selected {
Text::new(text).selected()
} else {
Text::new(text)
};
let part = serialize_ribbon(&ribbon_text);
let mut len = text.width() + 2;
if supports_arrow_fonts {
len += 2;
};
LinePart {
part,
len,
tab_index: None,
}
}
pub fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize>) -> LinePart {
if keyvec.is_empty() {
return LinePart::default();
}
let common_modifiers = get_common_modifiers(keyvec.iter().collect());
let no_common_modifier = common_modifiers.is_empty();
let modifier_str = common_modifiers
.iter()
.map(|m| m.to_string())
.collect::<Vec<_>>()
.join("-");
// Prints the keys
let key = keyvec
.iter()
.map(|key| {
if no_common_modifier || keyvec.len() == 1 {
format!("{}", key)
} else {
format!("{}", key.strip_common_modifiers(&common_modifiers))
}
})
.collect::<Vec<String>>();
// Special handling of some pre-defined keygroups
let key_string = key.join("");
let key_separator = match &key_string[..] {
"HJKL" => "",
"hjkl" => "",
"←↓↑→" => "",
"←→" => "",
"↓↑" => "",
"[]" => "",
_ => "|",
};
if no_common_modifier || key.len() == 1 {
let key_string_text = format!(" {} ", key.join(key_separator));
let text = if let Some(color_index) = color_index {
Text::new(&key_string_text).color_range(color_index, ..)
} else {
Text::new(&key_string_text)
};
LinePart {
part: serialize_text(&text),
len: key_string_text.width(),
..Default::default()
}
} else {
let key_string_without_modifier = format!("{}", key.join(key_separator));
let key_string_text = format!(" {} <{}> ", modifier_str, key_string_without_modifier);
let text = if let Some(color_index) = color_index {
Text::new(&key_string_text)
.color_range(color_index, ..modifier_str.width() + 1)
.color_range(
color_index,
modifier_str.width() + 3
..modifier_str.width() + 3 + key_string_without_modifier.width(),
)
} else {
Text::new(&key_string_text)
};
LinePart {
part: serialize_text(&text),
len: key_string_text.width(),
..Default::default()
}
}
}
pub fn get_common_modifiers(mut keyvec: Vec<&KeyWithModifier>) -> Vec<KeyModifier> {
if keyvec.is_empty() {
return vec![];
}
let mut common_modifiers = keyvec.pop().unwrap().key_modifiers.clone();
for key in keyvec {
common_modifiers = common_modifiers
.intersection(&key.key_modifiers)
.cloned()
.collect();
}
common_modifiers.into_iter().collect()
}
pub fn action_key_group(
keymap: &[(KeyWithModifier, Vec<Action>)],
actions: &[&[Action]],
) -> Vec<KeyWithModifier> {
let mut ret = vec![];
for action in actions {
ret.extend(action_key(keymap, action));
}
ret
}
pub fn action_key(
keymap: &[(KeyWithModifier, Vec<Action>)],
action: &[Action],
) -> Vec<KeyWithModifier> {
keymap
.iter()
.filter_map(|(key, acvec)| {
let matching = acvec
.iter()
.zip(action)
.filter(|(a, b)| a.shallow_eq(b))
.count();
if matching == acvec.len() && matching == action.len() {
Some(key.clone())
} else {
None
}
})
.collect::<Vec<KeyWithModifier>>()
}

View file

@ -18,12 +18,20 @@ pub struct LinePart {
tab_index: Option<usize>,
}
impl LinePart {
pub fn append(&mut self, to_append: &LinePart) {
self.part.push_str(&to_append.part);
self.len += to_append.len;
}
}
#[derive(Default)]
struct State {
tabs: Vec<TabInfo>,
active_tab_idx: usize,
mode_info: ModeInfo,
tab_line: Vec<LinePart>,
hide_swap_layout_indication: bool,
}
static ARROW_SEPARATOR: &str = "";
@ -31,7 +39,11 @@ static ARROW_SEPARATOR: &str = "";
register_plugin!(State);
impl ZellijPlugin for State {
fn load(&mut self, _configuration: BTreeMap<String, String>) {
fn load(&mut self, configuration: BTreeMap<String, String>) {
self.hide_swap_layout_indication = configuration
.get("hide_swap_layout_indication")
.map(|s| s == "true")
.unwrap_or(false);
set_selectable(false);
subscribe(&[
EventType::TabUpdate,
@ -120,6 +132,9 @@ impl ZellijPlugin for State {
self.mode_info.style.colors,
self.mode_info.capabilities,
self.mode_info.style.hide_session_name,
self.tabs.iter().find(|t| t.active),
&self.mode_info,
self.hide_swap_layout_indication,
);
let output = self

View file

@ -51,7 +51,7 @@ pub fn render_tab(
let right_separator = style!(background_color, foreground_color).paint(separator);
let tab_styled_text = if !focused_clients.is_empty() {
let (cursor_section, extra_length) = cursors(focused_clients, palette);
tab_text_len += extra_length;
tab_text_len += extra_length + 2; // 2 for cursor_beginning and cursor_end
let mut s = String::new();
let cursor_beginning = style!(foreground_color, background_color)
.bold()

View file

@ -100,7 +100,7 @@ fn account_for_races_in_snapshot(snapshot: String) -> String {
// to fix this, we should set plugins as unselectable in the layout (before they are loaded),
// once that happens, we should be able to remove this hack (and adjust the snapshots for the
// trailing spaces that we had to get rid of here)
let base_replace = Regex::new(r" BASE \s*\n").unwrap();
let base_replace = Regex::new(r"Alt <\[\]>  BASE \s*\n").unwrap();
let eol_arrow_replace = Regex::new(r"\s*\n").unwrap();
let snapshot = base_replace.replace_all(&snapshot, "\n").to_string();
let snapshot = eol_arrow_replace.replace_all(&snapshot, "\n").to_string();
@ -134,6 +134,7 @@ pub fn starts_with_one_terminal() {
},
});
if runner.test_timed_out && test_attempts > 0 {
test_attempts -= 1;
continue;
} else {
break last_snapshot;
@ -175,7 +176,8 @@ pub fn split_terminals_vertically() {
name: "Wait for new pane to appear",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
step_is_complete = true;
}
@ -219,12 +221,7 @@ pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
name: "Make sure only one pane appears",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
//two empty lines at the bottom to make sure there is no plugin output
&& remote_terminal
.current_snapshot()
.ends_with(" \n ")
{
if remote_terminal.cursor_position_is(3, 2) {
// ... is the truncated tip line
step_is_complete = true;
}
@ -272,7 +269,9 @@ pub fn scrolling_inside_a_pane() {
name: "Fill terminal with text",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.load_fixture("e2e/scrolling_inside_a_pane");
step_is_complete = true;
@ -284,7 +283,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(63, 20)
if remote_terminal.cursor_position_is(63, 21)
&& remote_terminal.snapshot_contains("line21")
{
// all lines have been written to the pane
@ -301,9 +300,9 @@ 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(63, 20)
if remote_terminal.cursor_position_is(63, 21)
&& remote_terminal.snapshot_contains("line3 ")
&& remote_terminal.snapshot_contains("SCROLL: 1/4")
&& remote_terminal.snapshot_contains("SCROLL: 1/3")
{
// keyboard scrolls up 1 line, scrollback is 4 lines: cat command + 2 extra lines from fixture + prompt
step_is_complete = true;
@ -352,7 +351,9 @@ pub fn toggle_pane_fullscreen() {
name: "Change newly opened pane to be fullscreen",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&PANE_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -415,7 +416,9 @@ pub fn open_new_tab() {
name: "Open new tab",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&TAB_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -431,7 +434,6 @@ pub fn open_new_tab() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2")
&& remote_terminal.status_bar_appears()
{
@ -482,7 +484,9 @@ pub fn close_tab() {
name: "Open new tab",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&TAB_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -497,7 +501,6 @@ pub fn close_tab() {
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2")
&& remote_terminal.status_bar_appears()
{
@ -675,7 +678,9 @@ pub fn close_pane() {
name: "Close pane",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&PANE_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -690,7 +695,8 @@ pub fn close_pane() {
name: "Wait for pane to close",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.status_bar_appears()
{
// cursor is in the original pane
step_is_complete = true;
}
@ -820,7 +826,9 @@ pub fn typing_exit_closes_pane() {
name: "Type exit",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
remote_terminal.send_key("e".as_bytes());
std::thread::sleep(std::time::Duration::from_millis(100));
remote_terminal.send_key("x".as_bytes());
@ -840,8 +848,8 @@ pub fn typing_exit_closes_pane() {
name: "Wait for pane to close",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
// if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.status_bar_appears()
{
// cursor is in the original pane
step_is_complete = true;
}
@ -889,7 +897,9 @@ pub fn resize_pane() {
name: "Resize pane",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&RESIZE_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -906,7 +916,8 @@ pub fn resize_pane() {
name: "Wait for pane to be resized",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(57, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(57, 2) && remote_terminal.status_bar_appears()
{
// pane has been resized
step_is_complete = true;
}
@ -952,7 +963,7 @@ pub fn lock_mode() {
name: "Send keys that should not be intercepted by the app",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.snapshot_contains("INTERFACE LOCKED") {
if !remote_terminal.snapshot_contains("PANE") {
remote_terminal.send_key(&TAB_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
remote_terminal.send_key(&NEW_TAB_IN_TAB_MODE);
@ -1017,7 +1028,9 @@ pub fn resize_terminal_window() {
name: "Change terminal window size",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// new pane has been opened and focused
remote_terminal.change_size(100, 24);
step_is_complete = true;
@ -1031,7 +1044,7 @@ pub fn resize_terminal_window() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(53, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.status_bar_appears()
&& remote_terminal.snapshot_contains("Ctrl +")
{
// size has been changed
@ -1081,7 +1094,9 @@ pub fn detach_and_attach_session() {
name: "Send some text to the active pane",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// new pane has been opened and focused
remote_terminal.send_key("I am some text".as_bytes());
step_is_complete = true;
@ -1275,7 +1290,9 @@ pub fn status_bar_loads_custom_keybindings() {
name: "Wait for app to load",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.snapshot_contains("LOCK")
{
step_is_complete = true;
}
step_is_complete
@ -1323,7 +1340,9 @@ fn focus_pane_with_mouse() {
name: "Click left pane",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
remote_terminal.send_key(&sgr_mouse_report(Position::new(5, 2), 0));
step_is_complete = true;
}
@ -1335,7 +1354,8 @@ 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(3, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
step_is_complete = true;
}
@ -1383,7 +1403,9 @@ pub fn scrolling_inside_a_pane_with_mouse() {
name: "Fill terminal with text",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
remote_terminal.load_fixture("e2e/scrolling_inside_a_pane");
step_is_complete = true;
}
@ -1394,7 +1416,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(63, 20)
if remote_terminal.cursor_position_is(63, 21)
&& remote_terminal.snapshot_contains("line21")
{
// all lines have been written to the pane
@ -1409,11 +1431,10 @@ 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(63, 20)
if remote_terminal.cursor_position_is(63, 21)
&& remote_terminal.snapshot_contains("line1 ")
&& remote_terminal.snapshot_contains("SCROLL: 3/4")
&& remote_terminal.snapshot_contains("SCROLL: 3/3")
{
// mouse wheel scrolls up 3 lines, scrollback is 4 lines: cat command + 2 extra lines from fixture + prompt
step_is_complete = true;
}
step_is_complete
@ -1460,7 +1481,8 @@ pub fn start_without_pane_frames() {
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() {
if remote_terminal.cursor_position_is(62, 1) && remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
step_is_complete = true;
}
@ -1529,7 +1551,9 @@ pub fn mirrored_sessions() {
name: "Open new tab (second user)",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&TAB_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -1544,7 +1568,6 @@ pub fn mirrored_sessions() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2")
&& remote_terminal.status_bar_appears()
{
@ -1559,7 +1582,7 @@ pub fn mirrored_sessions() {
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.status_bar_appears()
&& remote_terminal.snapshot_contains("Tab #2")
{
// cursor is in the newly opened second pane
@ -1584,7 +1607,7 @@ pub fn mirrored_sessions() {
});
second_runner.run_all_steps();
if first_runner.test_timed_out || second_runner.test_timed_out {
if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 {
test_attempts -= 1;
continue;
}
@ -1674,7 +1697,7 @@ pub fn multiple_users_in_same_pane_and_tab() {
});
second_runner.run_all_steps();
if first_runner.test_timed_out || second_runner.test_timed_out {
if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 {
test_attempts -= 1;
continue;
}
@ -1767,7 +1790,7 @@ pub fn multiple_users_in_different_panes_and_same_tab() {
});
second_runner.run_all_steps();
if first_runner.test_timed_out || second_runner.test_timed_out {
if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 {
test_attempts -= 1;
continue;
}
@ -1776,7 +1799,8 @@ pub fn multiple_users_in_different_panes_and_same_tab() {
name: "take snapshot after",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
step_is_complete = true;
}
@ -1790,6 +1814,7 @@ pub fn multiple_users_in_different_panes_and_same_tab() {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.snapshot_contains("││$")
&& remote_terminal.tab_bar_appears()
{
// cursor is back in the first tab
step_is_complete = true;
@ -1847,7 +1872,9 @@ pub fn multiple_users_in_different_tabs() {
name: "Open new tab",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
remote_terminal.send_key(&TAB_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
@ -1859,7 +1886,7 @@ pub fn multiple_users_in_different_tabs() {
});
second_runner.run_all_steps();
if first_runner.test_timed_out || second_runner.test_timed_out {
if (first_runner.test_timed_out || second_runner.test_timed_out) && test_attempts >= 0 {
test_attempts -= 1;
continue;
}
@ -1869,7 +1896,6 @@ pub fn multiple_users_in_different_tabs() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #1 [ ]")
&& remote_terminal.snapshot_contains("Tab #2")
&& remote_terminal.status_bar_appears()
@ -1887,7 +1913,6 @@ pub fn multiple_users_in_different_tabs() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(3, 2)
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2 [ ]")
&& remote_terminal.status_bar_appears()
{
@ -2006,9 +2031,7 @@ pub fn toggle_floating_panes() {
name: "Wait for new pane to appear",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(33, 7)
&& remote_terminal.snapshot_contains("FLOATING PANES VISIBLE")
{
if remote_terminal.cursor_position_is(33, 8) {
// cursor is in the newly opened second pane
step_is_complete = true;
}
@ -2057,7 +2080,8 @@ pub fn tmux_mode() {
name: "Wait for new pane to appear",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.status_bar_appears()
{
// cursor is in the newly opened second pane
step_is_complete = true;
}
@ -2163,7 +2187,7 @@ pub fn undo_rename_tab() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.snapshot_contains("Tab #1")
&& remote_terminal.snapshot_contains("Tip:")
&& remote_terminal.snapshot_contains("LOCK")
{
step_is_complete = true
}
@ -2220,7 +2244,7 @@ pub fn undo_rename_pane() {
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.snapshot_contains("Pane #1")
&& remote_terminal.snapshot_contains("Tip:")
&& remote_terminal.snapshot_contains("LOCK")
{
step_is_complete = true
}

View file

@ -351,10 +351,6 @@ impl RemoteTerminal {
pub fn cursor_position_is(&self, x: usize, y: usize) -> bool {
x == self.cursor_x && y == self.cursor_y
}
pub fn tip_appears(&self) -> bool {
let snapshot = self.last_snapshot.lock().unwrap();
snapshot.contains("Tip:") || snapshot.contains("QuickNav:")
}
pub fn status_bar_appears(&self) -> bool {
self.last_snapshot.lock().unwrap().contains("Ctrl +")
}

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1676
assertion_line: 1975
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 198
assertion_line: 243
expression: last_snapshot
---
Zellij
@ -20,6 +20,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────┘
Ctrl +

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 557
assertion_line: 707
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 975
assertion_line: 1138
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1071
assertion_line: 1352
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 836
assertion_line: 985
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <> PANE  <> TAB  <> RESIZE  <> MOVE  <> SEARCH  <> SESSION  <> QUIT 
-- INTERFACE LOCKED --
Ctrl + <g> LOCK 

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1354
assertion_line: 1625
expression: second_runner_snapshot
---
Zellij (mirrored_sessions)  Tab #1  Tab #2 
@ -24,6 +24,6 @@ expression: second_runner_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
<n> New / <←→> Move / <x> Close / <r> Rename / <s> Sync / <b> Break out / <[]> Break / <TAB> Toggle ...
Ctrl + <t> TAB   n  New  ←→  Move  x  Close  r  Rename  s  Sync  b  Break out  []  Break  ...

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1340
assertion_line: 1624
expression: first_runner_snapshot
---
Zellij (mirrored_sessions)  Tab #1  Tab #2 
@ -24,6 +24,6 @@ expression: first_runner_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 531
assertion_line: 558
expression: account_for_races_in_snapshot(last_snapshot)
---
Zellij (e2e-test)  Tab #1  Tab #3  Tab #2 
@ -24,6 +24,6 @@ expression: account_for_races_in_snapshot(last_snapshot)
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,5 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 620
expression: account_for_races_in_snapshot(last_snapshot)
---
Zellij (e2e-test)  Tab #2  Tab #1  Tab #3 
@ -23,6 +24,6 @@ expression: account_for_races_in_snapshot(last_snapshot)
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 624
assertion_line: 592
expression: account_for_races_in_snapshot(last_snapshot)
---
Zellij (e2e-test)  Tab #1  Tab #3  Tab #2 
@ -24,6 +24,6 @@ expression: account_for_races_in_snapshot(last_snapshot)
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,5 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 644
expression: account_for_races_in_snapshot(last_snapshot)
---
Zellij (e2e-test)  Tab #3  Tab #2  Tab #1 
@ -23,6 +24,6 @@ expression: account_for_races_in_snapshot(last_snapshot)
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1523
assertion_line: 1809
expression: second_runner_snapshot
---
Zellij (multiple_users_in_same_pane_and_tab)  Tab #1 [ ]
@ -24,6 +24,6 @@ expression: second_runner_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1522
assertion_line: 1808
expression: first_runner_snapshot
---
Zellij (multiple_users_in_same_pane_and_tab)  Tab #1 [ ]
@ -24,6 +24,6 @@ expression: first_runner_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1620
assertion_line: 1907
expression: second_runner_snapshot
---
Zellij (multiple_users_in_different_tabs)  Tab #1 [ ] Tab #2 
@ -24,6 +24,6 @@ expression: second_runner_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1619
assertion_line: 1906
expression: first_runner_snapshot
---
Zellij (multiple_users_in_different_tabs)  Tab #1  Tab #2 [ ]
@ -24,6 +24,6 @@ expression: first_runner_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1431
assertion_line: 1716
expression: second_runner_snapshot
---
Zellij (multiple_users_in_same_pane_and_tab)  Tab #1 [ ]
@ -24,6 +24,6 @@ expression: second_runner_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1430
assertion_line: 1718
expression: first_runner_snapshot
---
Zellij (multiple_users_in_same_pane_and_tab)  Tab #1 [ ]
@ -24,6 +24,6 @@ expression: first_runner_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 416
assertion_line: 452
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1  Tab #2 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1171
assertion_line: 1191
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1  Tab #2  Tab #3  Tab #4 
@ -25,5 +25,5 @@ expression: last_snapshot
│ └────────────────────────────────────────────────────────┘ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  BASE 
(FLOATING PANES VISIBLE): Press Ctrl p, <w> to hide.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1232
assertion_line: 1252
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1  Tab #2  Tab #3  Tab #4 
@ -25,5 +25,5 @@ expression: last_snapshot
│ └────────────────────────────────────────────────────────┘ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  BASE 
(FLOATING PANES VISIBLE): Press Ctrl p, <w> to hide.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 765
assertion_line: 923
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└────────────────────────────────────────────────────┘└────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 889
assertion_line: 1050
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└────────────────────────────────────────────────┘└────────────────────────────────────────────────┘
Ctrl + g  p  t  n  h  s  o  q  Alt + <[]>
QuickNav: Alt + <n> / Alt + <←↓↑→> or Alt + <hjkl> / Alt + <+|->
Ctrl + g  p  t  n  h  s  o  q  Alt +  <n> New Pane  <←↓↑→> Change Focus 

View file

@ -1,11 +1,12 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 305
assertion_line: 323
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────── SCROLL: 1/4 ┐
│$ ││line3 │
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────── SCROLL: 1/3 ┐
│$ ││line2 │
│ ││line3 │
│ ││line4 │
│ ││line5 │
│ ││line6 │
@ -25,5 +26,4 @@ expression: last_snapshot
│ ││line20 │
│ ││li█e21 │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
<s> Search / <↓↑> Scroll / <PgDn|PgUp> Scroll / <d|u> Scroll / <e> Edit / <ENTER> Select
Ctrl + <s> SEARCH   s  Search  ↓↑  Scroll  PgDn|PgUp  Scroll  d|u  Scroll  e  Edit  ENTER  Select 

View file

@ -1,11 +1,12 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1147
assertion_line: 1428
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────── SCROLL: 3/4 ┐
│$ ││line1 │
┌ Pane #1 ─────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────── SCROLL: 3/3 ┐
│$ ││$ cat /usr/src/zellij/fixtures/e2e/scrolling_inside_a_pane│
│ ││line1 │
│ ││line2 │
│ ││line3 │
│ ││line4 │
@ -26,4 +27,3 @@ expression: last_snapshot
│ ││li█e19 │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,9 +1,9 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 2175
assertion_line: 2349
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
Zellij (e2e-test)  Tab #1  Alt <[]>  VERTICAL 
┌ Pane #1 ────────────────────────────────────────────────────────────────┐┌ /usr/src/zellij/fixtures/append-echo-script.sh ─────────────────────────┐
│$ /usr/src/zellij/x86_64-unknown-linux-musl/release/zellij run -s -- "/us││foo │
│r/src/zellij/fixtures/append-echo-script.sh" ││foo │
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└─────────────────────────────────────────────────────────────────────────┘└ [ EXIT CODE: 0 ] <ENTER> re-run, <ESC> drop to shell, <Ctrl-c> exit ────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  Alt + <[]>  VERTICAL 
Tip: Alt + <n> => open new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate between panes. Alt + <+|-> => increase/decrease pane size.
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  Alt +  <n> New  <←↓↑→> Focus 

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 168
assertion_line: 194
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1326
assertion_line: 1476
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -25,5 +25,5 @@ $ │
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 120
assertion_line: 145
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1266
assertion_line: 1293
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
<F1> LOCK  <F2> PANE  <F3> TAB  <F4> RESIZE  <F5> MOVE  <F6> SEARCH  <Alt F7> SESSION  <Ctrl F8> QUIT 
Tip: UNBOUND => open new pane. UNBOUND => navigate between panes. UNBOUND => increase/decrease pane size.
F1  LOCK  F2  PANE  F3  TAB  F4  RESIZE  F5  MOVE  F6  SEARCH  Alt F7  SESSION  Ctrl F8  QUIT 

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1772
assertion_line: 2070
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ ││ │
│ ││ │
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└──────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,14 +1,15 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1984
assertion_line: 2027
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
Zellij (e2e-test)  Tab #1  Alt <[]>  STAGGERED 
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│$ │
│ │
│ │
│ │
│ │
│ ┌ Pane #2 ─────────────────────────────────────────────────┐ │
│ │$ █ │ │
│ │ │ │
@ -18,12 +19,11 @@ expression: last_snapshot
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
(FLOATING PANES VISIBLE): Press Ctrl p, <w> to hide.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 351
assertion_line: 386
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
(FULLSCREEN): + 1 hidden panes

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 702
assertion_line: 858
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1921
assertion_line: 2240
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -1,6 +1,6 @@
---
source: src/tests/e2e/cases.rs
assertion_line: 1871
assertion_line: 2183
expression: last_snapshot
---
Zellij (e2e-test)  Tab #1 
@ -24,6 +24,6 @@ expression: last_snapshot
│ │
│ │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.

View file

@ -9,7 +9,7 @@ pub fn new_tab() -> Step {
name: "Open new tab",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.tip_appears() && remote_terminal.status_bar_appears() {
if remote_terminal.status_bar_appears() {
remote_terminal.send_key(&TAB_MODE);
std::thread::sleep(std::time::Duration::from_millis(100));
remote_terminal.send_key(&NEW_TAB_IN_TAB_MODE);
@ -24,9 +24,7 @@ pub fn check_second_tab_opened() -> Step {
Step {
name: "Check second tab opened",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2")
remote_terminal.status_bar_appears() && remote_terminal.snapshot_contains("Tab #2")
},
}
}
@ -36,7 +34,7 @@ pub fn move_tab_left() -> Step {
name: "Move tab left",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.tip_appears() && remote_terminal.status_bar_appears() {
if remote_terminal.status_bar_appears() {
remote_terminal.send_key(&MOVE_TAB_LEFT);
std::thread::sleep(std::time::Duration::from_millis(100));
step_is_complete = true;
@ -51,7 +49,6 @@ pub fn check_third_tab_moved_left() -> Step {
name: "Check third tab is in the middle",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #1  Tab #3  Tab #2")
},
}
@ -62,7 +59,7 @@ pub fn type_second_tab_content() -> Step {
name: "Type second tab content",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.tip_appears() && remote_terminal.status_bar_appears() {
if remote_terminal.status_bar_appears() {
remote_terminal.send_key(&SECOND_TAB_CONTENT);
step_is_complete = true;
}
@ -75,9 +72,7 @@ pub fn check_third_tab_opened() -> Step {
Step {
name: "Check third tab opened",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #3")
remote_terminal.status_bar_appears() && remote_terminal.snapshot_contains("Tab #3")
},
}
}
@ -87,7 +82,7 @@ pub fn switch_focus_to_left_tab() -> Step {
name: "Move focus to tab on the left",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.tip_appears() && remote_terminal.status_bar_appears() {
if remote_terminal.status_bar_appears() {
remote_terminal.send_key(&MOVE_FOCUS_LEFT_IN_NORMAL_MODE);
step_is_complete = true;
}
@ -101,7 +96,6 @@ pub fn check_focus_on_second_tab() -> Step {
name: "Check focus is on the second tab",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2 content")
},
}
@ -112,7 +106,7 @@ pub fn move_tab_right() -> Step {
name: "Move tab right",
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.tip_appears() && remote_terminal.status_bar_appears() {
if remote_terminal.status_bar_appears() {
remote_terminal.send_key(&MOVE_TAB_RIGHT);
step_is_complete = true;
}
@ -126,7 +120,6 @@ pub fn check_third_tab_moved_to_beginning() -> Step {
name: "Check third tab moved to beginning",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #3  Tab #1  Tab #2")
},
}
@ -137,7 +130,6 @@ pub fn check_third_tab_is_left_wrapped() -> Step {
name: "Check third tab is in last position",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #2  Tab #1  Tab #3")
},
}
@ -148,7 +140,6 @@ pub fn check_third_tab_is_right_wrapped() -> Step {
name: "Check third tab is in last position",
instruction: |remote_terminal: RemoteTerminal| -> bool {
remote_terminal.status_bar_appears()
&& remote_terminal.tip_appears()
&& remote_terminal.snapshot_contains("Tab #3  Tab #2  Tab #1")
},
}

View file

@ -149,6 +149,7 @@ pub(crate) struct SessionMetaData {
pub config_options: Box<Options>,
pub client_keybinds: HashMap<ClientId, Keybinds>,
pub client_input_modes: HashMap<ClientId, InputMode>,
pub default_mode: InputMode,
screen_thread: Option<thread::JoinHandle<()>>,
pty_thread: Option<thread::JoinHandle<()>>,
plugin_thread: Option<thread::JoinHandle<()>>,
@ -565,7 +566,12 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
.send_to_plugin(PluginInstruction::AddClient(client_id))
.unwrap();
let default_mode = options.default_mode.unwrap_or_default();
let mode_info = get_mode_info(default_mode, &attrs, session_data.capabilities);
let mode_info = get_mode_info(
default_mode,
&attrs,
session_data.capabilities,
Some(default_mode),
);
session_data
.senders
.send_to_screen(ScreenInstruction::ChangeMode(mode_info.clone(), client_id))
@ -999,6 +1005,8 @@ fn init_session(
.clone()
.unwrap_or_else(|| get_default_shell());
let default_mode = config_options.default_mode.unwrap_or_default();
let pty_thread = thread::Builder::new()
.name("pty".to_string())
.spawn({
@ -1089,6 +1097,7 @@ fn init_session(
client_attributes,
default_shell,
plugin_aliases,
default_mode,
)
.fatal()
}
@ -1158,6 +1167,7 @@ fn init_session(
plugin_thread: Some(plugin_thread),
pty_writer_thread: Some(pty_writer_thread),
background_jobs_thread: Some(background_jobs_thread),
default_mode,
}
}

View file

@ -25,8 +25,8 @@ use wasm_bridge::WasmBridge;
use zellij_utils::{
async_std::{channel, future::timeout, task},
data::{
Event, EventType, MessageToPlugin, PermissionStatus, PermissionType, PipeMessage,
PipeSource, PluginCapabilities,
Event, EventType, InputMode, MessageToPlugin, PermissionStatus, PermissionType,
PipeMessage, PipeSource, PluginCapabilities,
},
errors::{prelude::*, ContextType, PluginContext},
input::{
@ -198,6 +198,7 @@ pub(crate) fn plugin_thread_main(
client_attributes: ClientAttributes,
default_shell: Option<TerminalAction>,
plugin_aliases: Box<PluginAliases>,
default_mode: InputMode,
) -> Result<()> {
info!("Wasm main thread starts");
let plugin_dir = data_dir.join("plugins/");
@ -219,6 +220,7 @@ pub(crate) fn plugin_thread_main(
default_shell,
layout.clone(),
layout_dir,
default_mode,
);
loop {

View file

@ -26,7 +26,7 @@ use crate::{
use zellij_utils::plugin_api::action::ProtobufPluginConfiguration;
use zellij_utils::{
consts::{ZELLIJ_CACHE_DIR, ZELLIJ_SESSION_CACHE_DIR, ZELLIJ_TMP_DIR},
data::PluginCapabilities,
data::{InputMode, PluginCapabilities},
errors::prelude::*,
input::command::TerminalAction,
input::layout::Layout,
@ -68,6 +68,7 @@ pub struct PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
}
impl<'a> PluginLoader<'a> {
@ -87,6 +88,7 @@ impl<'a> PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<()> {
let err_context = || format!("failed to reload plugin {plugin_id} from memory");
let mut connected_clients: Vec<ClientId> =
@ -112,6 +114,7 @@ impl<'a> PluginLoader<'a> {
default_shell,
default_layout,
layout_dir,
default_mode,
)?;
plugin_loader
.load_module_from_memory()
@ -148,6 +151,7 @@ impl<'a> PluginLoader<'a> {
default_layout: Box<Layout>,
skip_cache: bool,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<()> {
let err_context = || format!("failed to start plugin {plugin_id} for client {client_id}");
let mut plugin_loader = PluginLoader::new(
@ -168,6 +172,7 @@ impl<'a> PluginLoader<'a> {
default_shell,
default_layout,
layout_dir,
default_mode,
)?;
if skip_cache {
plugin_loader
@ -220,6 +225,7 @@ impl<'a> PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<()> {
let mut new_plugins = HashSet::new();
for plugin_id in plugin_map.lock().unwrap().plugin_ids() {
@ -242,6 +248,7 @@ impl<'a> PluginLoader<'a> {
default_shell.clone(),
default_layout.clone(),
layout_dir.clone(),
default_mode,
)?;
plugin_loader
.load_module_from_memory()
@ -270,6 +277,7 @@ impl<'a> PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<()> {
let err_context = || format!("failed to reload plugin id {plugin_id}");
@ -296,6 +304,7 @@ impl<'a> PluginLoader<'a> {
default_shell,
default_layout,
layout_dir,
default_mode,
)?;
plugin_loader
.compile_module()
@ -328,6 +337,7 @@ impl<'a> PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<Self> {
let plugin_own_data_dir = ZELLIJ_SESSION_CACHE_DIR
.join(Url::from(&plugin.location).to_string())
@ -355,6 +365,7 @@ impl<'a> PluginLoader<'a> {
default_shell,
default_layout,
layout_dir,
default_mode,
})
}
pub fn new_from_existing_plugin_attributes(
@ -373,6 +384,7 @@ impl<'a> PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<Self> {
let err_context = || "Failed to find existing plugin";
let (running_plugin, _subscriptions, _workers) = {
@ -407,6 +419,7 @@ impl<'a> PluginLoader<'a> {
default_shell,
default_layout,
layout_dir,
default_mode,
)
}
pub fn new_from_different_client_id(
@ -425,6 +438,7 @@ impl<'a> PluginLoader<'a> {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Result<Self> {
let err_context = || "Failed to find existing plugin";
let running_plugin = {
@ -460,6 +474,7 @@ impl<'a> PluginLoader<'a> {
default_shell,
default_layout,
layout_dir,
default_mode,
)
}
pub fn load_module_from_memory(&mut self) -> Result<Module> {
@ -715,6 +730,7 @@ impl<'a> PluginLoader<'a> {
self.default_shell.clone(),
self.default_layout.clone(),
self.layout_dir.clone(),
self.default_mode,
)?;
plugin_loader_for_client
.load_module_from_memory()
@ -814,6 +830,7 @@ impl<'a> PluginLoader<'a> {
input_pipes_to_unblock: Arc::new(Mutex::new(HashSet::new())),
input_pipes_to_block: Arc::new(Mutex::new(HashSet::new())),
layout_dir: self.layout_dir.clone(),
default_mode: self.default_mode.clone(),
subscriptions: Arc::new(Mutex::new(HashSet::new())),
stdin_pipe,
stdout_pipe,

View file

@ -19,6 +19,7 @@ use crate::{thread_bus::ThreadSenders, ClientId};
use zellij_utils::async_channel::Sender;
use zellij_utils::{
data::EventType,
data::InputMode,
data::PluginCapabilities,
input::command::TerminalAction,
input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginLocation},
@ -284,6 +285,7 @@ pub struct PluginEnv {
pub plugin_cwd: PathBuf,
pub input_pipes_to_unblock: Arc<Mutex<HashSet<String>>>,
pub input_pipes_to_block: Arc<Mutex<HashSet<String>>>,
pub default_mode: InputMode,
pub subscriptions: Arc<Mutex<Subscriptions>>,
pub stdin_pipe: Arc<Mutex<VecDeque<u8>>>,
pub stdout_pipe: Arc<Mutex<VecDeque<u8>>>,

View file

@ -7,7 +7,8 @@ use std::path::PathBuf;
use tempfile::tempdir;
use wasmtime::Engine;
use zellij_utils::data::{
BareKey, Event, KeyWithModifier, PermissionStatus, PermissionType, PluginCapabilities,
BareKey, Event, InputMode, KeyWithModifier, PermissionStatus, PermissionType,
PluginCapabilities,
};
use zellij_utils::errors::ErrorContext;
use zellij_utils::input::layout::{
@ -280,6 +281,7 @@ fn create_plugin_thread(
client_attributes,
default_shell_action,
Box::new(plugin_aliases),
InputMode::Normal,
)
.expect("TEST")
})
@ -359,6 +361,7 @@ fn create_plugin_thread_with_server_receiver(
client_attributes,
default_shell_action,
Box::new(PluginAliases::default()),
InputMode::Normal,
)
.expect("TEST");
})
@ -444,6 +447,7 @@ fn create_plugin_thread_with_pty_receiver(
client_attributes,
default_shell_action,
Box::new(PluginAliases::default()),
InputMode::Normal,
)
.expect("TEST")
})
@ -524,6 +528,7 @@ fn create_plugin_thread_with_background_jobs_receiver(
client_attributes,
default_shell_action,
Box::new(PluginAliases::default()),
InputMode::Normal,
)
.expect("TEST")
})

View file

@ -1,12 +1,15 @@
---
source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 455
assertion_line: 1043
expression: "format!(\"{:#?}\", switch_to_mode_event)"
---
Some(
ChangeMode(
ModeInfo {
mode: Tab,
base_mode: Some(
Normal,
),
keybinds: [],
style: Style {
colors: Palette {

View file

@ -19,7 +19,7 @@ use wasmtime::{Engine, Module};
use zellij_utils::async_channel::Sender;
use zellij_utils::async_std::task::{self, JoinHandle};
use zellij_utils::consts::ZELLIJ_CACHE_DIR;
use zellij_utils::data::{PermissionStatus, PermissionType, PipeMessage, PipeSource};
use zellij_utils::data::{InputMode, PermissionStatus, PermissionType, PipeMessage, PipeSource};
use zellij_utils::downloader::Downloader;
use zellij_utils::input::permission::PermissionCache;
use zellij_utils::notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap};
@ -102,6 +102,7 @@ pub struct WasmBridge {
HashMap<RunPluginLocation, HashMap<PluginUserConfiguration, Vec<(PluginId, ClientId)>>>,
pending_pipes: PendingPipes,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
}
impl WasmBridge {
@ -116,6 +117,7 @@ impl WasmBridge {
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
layout_dir: Option<PathBuf>,
default_mode: InputMode,
) -> Self {
let plugin_map = Arc::new(Mutex::new(PluginMap::default()));
let connected_clients: Arc<Mutex<Vec<ClientId>>> = Arc::new(Mutex::new(vec![]));
@ -146,6 +148,7 @@ impl WasmBridge {
cached_plugin_map: HashMap::new(),
pending_pipes: Default::default(),
layout_dir,
default_mode,
}
}
pub fn load_plugin(
@ -202,6 +205,7 @@ impl WasmBridge {
let default_shell = self.default_shell.clone();
let default_layout = self.default_layout.clone();
let layout_dir = self.layout_dir.clone();
let default_mode = self.default_mode;
async move {
let _ = senders.send_to_background_jobs(
BackgroundJob::AnimatePluginLoading(plugin_id),
@ -249,6 +253,7 @@ impl WasmBridge {
default_layout,
skip_cache,
layout_dir,
default_mode,
) {
Ok(_) => handle_plugin_successful_loading(&senders, plugin_id),
Err(e) => handle_plugin_loading_failure(
@ -340,6 +345,7 @@ impl WasmBridge {
let default_shell = self.default_shell.clone();
let default_layout = self.default_layout.clone();
let layout_dir = self.layout_dir.clone();
let default_mode = self.default_mode;
async move {
match PluginLoader::reload_plugin(
first_plugin_id,
@ -357,6 +363,7 @@ impl WasmBridge {
default_shell.clone(),
default_layout.clone(),
layout_dir.clone(),
default_mode,
) {
Ok(_) => {
handle_plugin_successful_loading(&senders, first_plugin_id);
@ -382,6 +389,7 @@ impl WasmBridge {
default_shell.clone(),
default_layout.clone(),
layout_dir.clone(),
default_mode,
) {
Ok(_) => handle_plugin_successful_loading(&senders, *plugin_id),
Err(e) => handle_plugin_loading_failure(
@ -434,6 +442,7 @@ impl WasmBridge {
self.default_shell.clone(),
self.default_layout.clone(),
self.layout_dir.clone(),
self.default_mode,
) {
Ok(_) => {
let _ = self

View file

@ -61,6 +61,7 @@ macro_rules! apply_action {
$env.default_shell.clone(),
$env.default_layout.clone(),
None,
$env.default_mode.clone(),
) {
log::error!("{}: {:?}", $error_message(), e);
}

View file

@ -13,7 +13,7 @@ use crate::{
use uuid::Uuid;
use zellij_utils::{
channels::SenderWithContext,
data::{Direction, Event, PluginCapabilities, ResizeStrategy},
data::{Direction, Event, InputMode, PluginCapabilities, ResizeStrategy},
errors::prelude::*,
input::{
actions::{Action, SearchDirection, SearchOption},
@ -38,6 +38,7 @@ pub(crate) fn route_action(
default_shell: Option<TerminalAction>,
default_layout: Box<Layout>,
mut seen_cli_pipes: Option<&mut HashSet<String>>,
default_mode: InputMode,
) -> Result<bool> {
let mut should_break = false;
let err_context = || format!("failed to route action for client {client_id}");
@ -98,7 +99,7 @@ pub(crate) fn route_action(
.send_to_plugin(PluginInstruction::Update(vec![(
None,
Some(client_id),
Event::ModeUpdate(get_mode_info(mode, attrs, capabilities)),
Event::ModeUpdate(get_mode_info(mode, attrs, capabilities, Some(default_mode))),
)]))
.with_context(err_context)?;
senders
@ -106,7 +107,7 @@ pub(crate) fn route_action(
.with_context(err_context)?;
senders
.send_to_screen(ScreenInstruction::ChangeMode(
get_mode_info(mode, attrs, capabilities),
get_mode_info(mode, attrs, capabilities, Some(default_mode)),
client_id,
))
.with_context(err_context)?;
@ -344,7 +345,12 @@ pub(crate) fn route_action(
.send_to_plugin(PluginInstruction::Update(vec![(
None,
None,
Event::ModeUpdate(get_mode_info(input_mode, attrs, capabilities)),
Event::ModeUpdate(get_mode_info(
input_mode,
attrs,
capabilities,
Some(default_mode),
)),
)]))
.with_context(err_context)?;
@ -357,6 +363,7 @@ pub(crate) fn route_action(
input_mode,
attrs,
capabilities,
Some(default_mode),
)))
.with_context(err_context)?;
},
@ -1018,6 +1025,7 @@ pub(crate) fn route_thread_main(
rlocked_sessions.default_shell.clone(),
rlocked_sessions.layout.clone(),
Some(&mut seen_cli_pipes),
rlocked_sessions.default_mode,
)? {
should_break = true;
}
@ -1042,6 +1050,7 @@ pub(crate) fn route_thread_main(
rlocked_sessions.default_shell.clone(),
rlocked_sessions.layout.clone(),
Some(&mut seen_cli_pipes),
rlocked_sessions.default_mode,
)? {
should_break = true;
}

View file

@ -2363,6 +2363,7 @@ pub(crate) fn screen_thread_main(
// ¯\_(ツ)_/¯
arrow_fonts: !arrow_fonts,
},
config_options.default_mode,
),
draw_pane_frames,
auto_layout,

View file

@ -114,6 +114,7 @@ fn send_cli_action_to_server(
let get_current_dir = || PathBuf::from(".");
let actions = Action::actions_from_cli(cli_action, Box::new(get_current_dir), None).unwrap();
let senders = session_metadata.senders.clone();
let default_mode = session_metadata.default_mode.clone();
let capabilities = PluginCapabilities::default();
let client_attributes = ClientAttributes::default();
let default_shell = None;
@ -129,6 +130,7 @@ fn send_cli_action_to_server(
default_shell.clone(),
default_layout.clone(),
None,
default_mode,
)
.unwrap();
}
@ -516,6 +518,7 @@ impl MockScreen {
layout,
client_input_modes: HashMap::new(),
client_keybinds: HashMap::new(),
default_mode: self.session_metadata.default_mode.clone(),
}
}
}
@ -575,6 +578,7 @@ impl MockScreen {
layout,
client_input_modes: HashMap::new(),
client_keybinds: HashMap::new(),
default_mode: InputMode::Normal,
};
let os_input = FakeInputOutput::default();

View file

@ -0,0 +1,13 @@
layout {
pane size=1 borderless=true {
plugin location="tab-bar" {
hide_swap_layout_indication true
}
}
pane
pane size=2 borderless=true {
plugin location="status-bar" {
classic true
}
}
}

View file

@ -0,0 +1,104 @@
tab_template name="ui" {
pane size=1 borderless=true {
plugin location="tab-bar" {
hide_swap_layout_indication true
}
}
children
pane size=2 borderless=true {
plugin location="status-bar" {
classic true
}
}
}
swap_tiled_layout name="vertical" {
ui max_panes=5 {
pane split_direction="vertical" {
pane
pane { children; }
}
}
ui max_panes=8 {
pane split_direction="vertical" {
pane { children; }
pane { pane; pane; pane; pane; }
}
}
ui max_panes=12 {
pane split_direction="vertical" {
pane { children; }
pane { pane; pane; pane; pane; }
pane { pane; pane; pane; pane; }
}
}
}
swap_tiled_layout name="horizontal" {
ui max_panes=5 {
pane
pane
}
ui max_panes=8 {
pane {
pane split_direction="vertical" { children; }
pane split_direction="vertical" { pane; pane; pane; pane; }
}
}
ui max_panes=12 {
pane {
pane split_direction="vertical" { children; }
pane split_direction="vertical" { pane; pane; pane; pane; }
pane split_direction="vertical" { pane; pane; pane; pane; }
}
}
}
swap_tiled_layout name="stacked" {
ui min_panes=5 {
pane split_direction="vertical" {
pane
pane stacked=true { children; }
}
}
}
swap_floating_layout name="staggered" {
floating_panes
}
swap_floating_layout name="enlarged" {
floating_panes max_panes=10 {
pane { x "5%"; y 1; width "90%"; height "90%"; }
pane { x "5%"; y 2; width "90%"; height "90%"; }
pane { x "5%"; y 3; width "90%"; height "90%"; }
pane { x "5%"; y 4; width "90%"; height "90%"; }
pane { x "5%"; y 5; width "90%"; height "90%"; }
pane { x "5%"; y 6; width "90%"; height "90%"; }
pane { x "5%"; y 7; width "90%"; height "90%"; }
pane { x "5%"; y 8; width "90%"; height "90%"; }
pane { x "5%"; y 9; width "90%"; height "90%"; }
pane focus=true { x 10; y 10; width "90%"; height "90%"; }
}
}
swap_floating_layout name="spread" {
floating_panes max_panes=1 {
pane {y "50%"; x "50%"; }
}
floating_panes max_panes=2 {
pane { x "1%"; y "25%"; width "45%"; }
pane { x "50%"; y "25%"; width "45%"; }
}
floating_panes max_panes=3 {
pane focus=true { y "55%"; width "45%"; height "45%"; }
pane { x "1%"; y "1%"; width "45%"; }
pane { x "50%"; y "1%"; width "45%"; }
}
floating_panes max_panes=4 {
pane { x "1%"; y "55%"; width "45%"; height "45%"; }
pane focus=true { x "50%"; y "55%"; width "45%"; height "45%"; }
pane { x "1%"; y "1%"; width "45%"; height "45%"; }
pane { x "50%"; y "1%"; width "45%"; height "45%"; }
}
}

View file

@ -3,7 +3,7 @@ layout {
plugin location="tab-bar"
}
pane
pane size=2 borderless=true {
pane size=1 borderless=true {
plugin location="status-bar"
}
}

View file

@ -3,7 +3,7 @@ tab_template name="ui" {
plugin location="tab-bar"
}
children
pane size=2 borderless=true {
pane size=1 borderless=true {
plugin location="status-bar"
}
}

View file

@ -293,6 +293,8 @@ pub struct ModeUpdatePayload {
pub arrow_fonts_support: bool,
#[prost(string, optional, tag = "5")]
pub session_name: ::core::option::Option<::prost::alloc::string::String>,
#[prost(enumeration = "super::input_mode::InputMode", optional, tag = "6")]
pub base_mode: ::core::option::Option<i32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]

View file

@ -1114,6 +1114,7 @@ pub type KeybindsVec = Vec<(InputMode, Vec<(KeyWithModifier, Vec<Action>)>)>;
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ModeInfo {
pub mode: InputMode,
pub base_mode: Option<InputMode>,
pub keybinds: KeybindsVec,
pub style: Style,
pub capabilities: PluginCapabilities,

View file

@ -709,6 +709,37 @@ impl Action {
CliAction::ListClients => Ok(vec![Action::ListClients]),
}
}
pub fn launches_plugin(&self, plugin_url: &str) -> bool {
match self {
Action::LaunchPlugin(run_plugin_or_alias, ..) => {
log::info!(
"1: {:?} == {:?}",
run_plugin_or_alias.location_string(),
plugin_url
);
eprintln!(
"1: {:?} == {:?}",
run_plugin_or_alias.location_string(),
plugin_url
);
&run_plugin_or_alias.location_string() == plugin_url
},
Action::LaunchOrFocusPlugin(run_plugin_or_alias, ..) => {
log::info!(
"2: {:?} == {:?}",
run_plugin_or_alias.location_string(),
plugin_url
);
eprintln!(
"2: {:?} == {:?}",
run_plugin_or_alias.location_string(),
plugin_url
);
&run_plugin_or_alias.location_string() == plugin_url
},
_ => false,
}
}
}
impl From<OnForceClose> for Action {

View file

@ -1121,6 +1121,7 @@ impl Layout {
available_layouts.push(LayoutInfo::BuiltIn("strider".to_owned()));
available_layouts.push(LayoutInfo::BuiltIn("disable-status-bar".to_owned()));
available_layouts.push(LayoutInfo::BuiltIn("compact".to_owned()));
available_layouts.push(LayoutInfo::BuiltIn("classic".to_owned()));
available_layouts.sort_by(|a, b| {
let a_name = a.name();
let b_name = b.name();
@ -1359,6 +1360,14 @@ impl Layout {
Self::stringified_compact_swap_from_assets()?,
)),
)),
Some("classic") => Ok((
"Classic layout".into(),
Self::stringified_classic_from_assets()?,
Some((
"Classiclayout swap".into(),
Self::stringified_classic_swap_from_assets()?,
)),
)),
Some("welcome") => Ok((
"Welcome screen layout".into(),
Self::stringified_welcome_from_assets()?,
@ -1395,6 +1404,14 @@ impl Layout {
Ok(String::from_utf8(setup::COMPACT_BAR_SWAP_LAYOUT.to_vec())?)
}
pub fn stringified_classic_from_assets() -> Result<String, ConfigError> {
Ok(String::from_utf8(setup::CLASSIC_LAYOUT.to_vec())?)
}
pub fn stringified_classic_swap_from_assets() -> Result<String, ConfigError> {
Ok(String::from_utf8(setup::CLASSIC_SWAP_LAYOUT.to_vec())?)
}
pub fn stringified_welcome_from_assets() -> Result<String, ConfigError> {
Ok(String::from_utf8(setup::WELCOME_LAYOUT.to_vec())?)
}

View file

@ -33,12 +33,14 @@ mod not_wasm {
mode: InputMode,
attributes: &ClientAttributes,
capabilities: PluginCapabilities,
base_mode: Option<InputMode>,
) -> ModeInfo {
let keybinds = attributes.keybinds.to_keybinds_vec();
let session_name = envs::get_session_name().ok();
ModeInfo {
mode,
base_mode,
keybinds,
style: attributes.style,
capabilities,

View file

@ -218,6 +218,7 @@ message ModeUpdatePayload {
style.Style style = 3;
bool arrow_fonts_support = 4;
optional string session_name = 5;
optional input_mode.InputMode base_mode = 6;
}
message InputModeKeybinds {

View file

@ -813,6 +813,9 @@ impl TryFrom<ProtobufModeUpdatePayload> for ModeInfo {
ProtobufInputMode::from_i32(protobuf_mode_update_payload.current_mode)
.ok_or("Malformed InputMode in the ModeUpdate Event")?
.try_into()?;
let base_mode: Option<InputMode> = protobuf_mode_update_payload
.base_mode
.and_then(|b_m| ProtobufInputMode::from_i32(b_m)?.try_into().ok());
let keybinds: Vec<(InputMode, Vec<(KeyWithModifier, Vec<Action>)>)> =
protobuf_mode_update_payload
.keybinds
@ -851,6 +854,7 @@ impl TryFrom<ProtobufModeUpdatePayload> for ModeInfo {
style,
capabilities,
session_name,
base_mode,
};
Ok(mode_info)
}
@ -860,6 +864,9 @@ impl TryFrom<ModeInfo> for ProtobufModeUpdatePayload {
type Error = &'static str;
fn try_from(mode_info: ModeInfo) -> Result<Self, &'static str> {
let current_mode: ProtobufInputMode = mode_info.mode.try_into()?;
let base_mode: Option<ProtobufInputMode> = mode_info
.base_mode
.and_then(|mode| ProtobufInputMode::try_from(mode).ok());
let style: ProtobufStyle = mode_info.style.try_into()?;
let arrow_fonts_support: bool = mode_info.capabilities.arrow_fonts;
let session_name = mode_info.session_name;
@ -893,6 +900,7 @@ impl TryFrom<ModeInfo> for ProtobufModeUpdatePayload {
keybinds: protobuf_input_mode_keybinds,
arrow_fonts_support,
session_name,
base_mode: base_mode.map(|b_m| b_m as i32),
})
}
}
@ -1112,6 +1120,7 @@ fn serialize_mode_update_event_with_non_default_values() {
},
capabilities: PluginCapabilities { arrow_fonts: false },
session_name: Some("my awesome test session".to_owned()),
base_mode: Some(InputMode::Locked),
});
let protobuf_event: ProtobufEvent = mode_update_event.clone().try_into().unwrap();
let serialized_protobuf_event = protobuf_event.encode_to_vec();

View file

@ -167,6 +167,18 @@ pub const COMPACT_BAR_SWAP_LAYOUT: &[u8] = include_bytes!(concat!(
"assets/layouts/compact.swap.kdl"
));
pub const CLASSIC_LAYOUT: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
"assets/layouts/classic.kdl"
));
pub const CLASSIC_SWAP_LAYOUT: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
"assets/layouts/classic.swap.kdl"
));
pub const WELCOME_LAYOUT: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
@ -230,6 +242,7 @@ pub fn dump_specified_layout(layout: &str) -> std::io::Result<()> {
"default" => dump_asset(DEFAULT_LAYOUT),
"compact" => dump_asset(COMPACT_BAR_LAYOUT),
"disable-status" => dump_asset(NO_STATUS_LAYOUT),
"classic" => dump_asset(CLASSIC_LAYOUT),
custom => {
info!("Dump {custom} layout");
let custom = add_layout_ext(custom);
@ -256,6 +269,7 @@ pub fn dump_specified_swap_layout(swap_layout: &str) -> std::io::Result<()> {
"strider" => dump_asset(STRIDER_SWAP_LAYOUT),
"default" => dump_asset(DEFAULT_SWAP_LAYOUT),
"compact" => dump_asset(COMPACT_BAR_SWAP_LAYOUT),
"classic" => dump_asset(CLASSIC_SWAP_LAYOUT),
not_found => Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Swap Layout not found for: {}", not_found),

View file

@ -1,6 +1,6 @@
---
source: zellij-utils/src/setup.rs
assertion_line: 699
assertion_line: 740
expression: "format!(\"{:#?}\", layout)"
---
Layout {
@ -69,7 +69,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -233,7 +233,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -455,7 +455,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -758,7 +758,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -903,7 +903,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -1125,7 +1125,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -1428,7 +1428,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(
@ -1592,7 +1592,7 @@ Layout {
children: [],
split_size: Some(
Fixed(
2,
1,
),
),
run: Some(