diff --git a/default-plugins/status-bar/src/first_line.rs b/default-plugins/status-bar/src/first_line.rs index 5bc5108686..cdb1deceee 100644 --- a/default-plugins/status-bar/src/first_line.rs +++ b/default-plugins/status-bar/src/first_line.rs @@ -279,7 +279,7 @@ pub fn ctrl_keys(help: &ModeInfo, max_len: usize, separator: &str) -> LinePart { colored_elements, separator, ), - InputMode::Pane => key_indicators( + InputMode::Pane | InputMode::RenamePane => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs index e27e9fc21e..205710f1dd 100644 --- a/src/tests/e2e/remote_runner.rs +++ b/src/tests/e2e/remote_runner.rs @@ -131,7 +131,8 @@ fn read_from_channel( let last_snapshot = last_snapshot.clone(); let cursor_coordinates = cursor_coordinates.clone(); let mut vte_parser = vte::Parser::new(); - let mut terminal_output = TerminalPane::new(0, *pane_geom, Palette::default(), 0); // 0 is the pane index + let mut terminal_output = + TerminalPane::new(0, *pane_geom, Palette::default(), 0, String::new()); // 0 is the pane index let mut retries_left = 3; move || { let mut should_sleep = false; diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 38ab302103..9bc8828aab 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -160,7 +160,7 @@ pub fn start_client( client_attributes, Box::new(opts), Box::new(config_options.clone()), - layout.unwrap(), + Box::new(layout.unwrap()), Some(config.plugins.clone()), ) } diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 6a94742ca3..c1f238edcc 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -58,7 +58,7 @@ pub enum ServerInstruction { ClientAttributes, Box, Box, - LayoutFromYaml, + Box, ClientId, Option, ), @@ -531,7 +531,7 @@ pub fn start_server(mut os_input: Box, socket_path: PathBuf) { pub struct SessionOptions { pub opts: Box, pub config_options: Box, - pub layout: LayoutFromYaml, + pub layout: Box, pub plugins: Option, } diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs index a9d5d3e5cc..46c5ed7a2a 100644 --- a/zellij-server/src/panes/plugin_pane.rs +++ b/zellij-server/src/panes/plugin_pane.rs @@ -12,7 +12,7 @@ use crate::ClientId; use zellij_utils::pane_size::Offset; use zellij_utils::position::Position; use zellij_utils::shared::ansi_len; -use zellij_utils::zellij_tile::prelude::{Event, Mouse, PaletteColor}; +use zellij_utils::zellij_tile::prelude::{Event, InputMode, Mouse, PaletteColor}; use zellij_utils::{ channels::SenderWithContext, pane_size::{Dimension, PaneGeom}, @@ -28,6 +28,7 @@ pub(crate) struct PluginPane { pub send_plugin_instructions: SenderWithContext, pub active_at: Instant, pub pane_title: String, + pub pane_name: String, frame: bool, borderless: bool, } @@ -38,6 +39,7 @@ impl PluginPane { position_and_size: PaneGeom, send_plugin_instructions: SenderWithContext, title: String, + pane_name: String, ) -> Self { Self { pid, @@ -51,6 +53,7 @@ impl PluginPane { content_offset: Offset::default(), pane_title: title, borderless: false, + pane_name, } } } @@ -209,14 +212,29 @@ impl Pane for PluginPane { None } } - fn render_frame(&mut self, _client_id: ClientId, frame_params: FrameParams) -> Option { + fn render_frame( + &mut self, + _client_id: ClientId, + frame_params: FrameParams, + input_mode: InputMode, + ) -> Option { // FIXME: This is a hack that assumes all fixed-size panes are borderless. This // will eventually need fixing! if self.frame && !(self.geom.rows.is_fixed() || self.geom.cols.is_fixed()) { + let pane_title = if self.pane_name.is_empty() + && input_mode == InputMode::RenamePane + && frame_params.is_main_client + { + String::from("Enter name...") + } else if self.pane_name.is_empty() { + self.pane_title.clone() + } else { + self.pane_name.clone() + }; let frame = PaneFrame::new( self.current_geom().into(), (0, 0), // scroll position - self.pane_title.clone(), + pane_title, frame_params, ); Some(frame.render()) @@ -231,6 +249,20 @@ impl Pane for PluginPane { ) -> Option { None } + fn update_name(&mut self, name: &str) { + match name { + "\0" => { + self.pane_name = String::new(); + } + "\u{007F}" | "\u{0008}" => { + //delete and backspace keys + self.pane_name.pop(); + } + c => { + self.pane_name.push_str(c); + } + } + } fn pid(&self) -> PaneId { PaneId::Plugin(self.pid) } diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index a6da76709b..284d6fe9b4 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -17,7 +17,7 @@ use zellij_utils::{ pane_size::{Dimension, PaneGeom}, position::Position, vte, - zellij_tile::data::{Palette, PaletteColor}, + zellij_tile::data::{InputMode, Palette, PaletteColor}, }; pub const SELECTION_SCROLL_INTERVAL_MS: u64 = 10; @@ -44,6 +44,7 @@ pub struct TerminalPane { selection_scrolled_at: time::Instant, content_offset: Offset, pane_title: String, + pane_name: String, frame: HashMap, borderless: bool, fake_cursor_locations: HashSet<(usize, usize)>, // (x, y) - these hold a record of previous fake cursors which we need to clear on render @@ -278,16 +279,31 @@ impl Pane for TerminalPane { None } } - fn render_frame(&mut self, client_id: ClientId, frame_params: FrameParams) -> Option { + fn render_frame( + &mut self, + client_id: ClientId, + frame_params: FrameParams, + input_mode: InputMode, + ) -> Option { // TODO: remove the cursor stuff from here let mut vte_output = None; - let frame = PaneFrame::new( - self.current_geom().into(), - self.grid.scrollback_position_and_length(), + let pane_title = if self.pane_name.is_empty() + && input_mode == InputMode::RenamePane + && frame_params.is_main_client + { + String::from("Enter name...") + } else if self.pane_name.is_empty() { self.grid .title .clone() - .unwrap_or_else(|| self.pane_title.clone()), + .unwrap_or_else(|| self.pane_title.clone()) + } else { + self.pane_name.clone() + }; + let frame = PaneFrame::new( + self.current_geom().into(), + self.grid.scrollback_position_and_length(), + pane_title, frame_params, ); match self.frame.get(&client_id) { @@ -336,6 +352,20 @@ impl Pane for TerminalPane { } vte_output } + fn update_name(&mut self, name: &str) { + match name { + "\0" => { + self.pane_name = String::new(); + } + "\u{007F}" | "\u{0008}" => { + //delete and backspace keys + self.pane_name.pop(); + } + c => { + self.pane_name.push_str(c); + } + } + } fn pid(&self) -> PaneId { PaneId::Terminal(self.pid) } @@ -475,6 +505,7 @@ impl TerminalPane { position_and_size: PaneGeom, palette: Palette, pane_index: usize, + pane_name: String, ) -> TerminalPane { let initial_pane_title = format!("Pane #{}", pane_index); let grid = Grid::new( @@ -495,6 +526,7 @@ impl TerminalPane { colors: palette, selection_scrolled_at: time::Instant::now(), pane_title: initial_pane_title, + pane_name, borderless: false, fake_cursor_locations: HashSet::new(), } diff --git a/zellij-server/src/panes/unit/terminal_pane_tests.rs b/zellij-server/src/panes/unit/terminal_pane_tests.rs index ef24a77f25..56ec2cf96d 100644 --- a/zellij-server/src/panes/unit/terminal_pane_tests.rs +++ b/zellij-server/src/panes/unit/terminal_pane_tests.rs @@ -14,7 +14,7 @@ pub fn scrolling_inside_a_pane() { let pid = 1; let palette = Palette::default(); - let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0); // 0 is the pane index + let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0, String::new()); // 0 is the pane index let mut text_to_fill_pane = String::new(); for i in 0..30 { writeln!(&mut text_to_fill_pane, "\rline {}", i + 1).unwrap(); diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index d7e2ad47b1..99f7e37568 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -74,7 +74,7 @@ pub(crate) struct Pty { use std::convert::TryFrom; -pub(crate) fn pty_thread_main(mut pty: Pty, layout: LayoutFromYaml) { +pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box) { loop { let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Pty((&event).into())); diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index e24d2d4f1e..4626bc5f10 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -226,6 +226,12 @@ fn route_action( }; session.senders.send_to_pty(pty_instr).unwrap(); } + Action::PaneNameInput(c) => { + session + .senders + .send_to_screen(ScreenInstruction::UpdatePaneName(c, client_id)) + .unwrap(); + } Action::Run(command) => { let run_cmd = Some(TerminalAction::RunCommand(command.clone().into())); let pty_instr = match command.direction { diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 1400235ea0..f5beade595 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -68,6 +68,7 @@ pub enum ScreenInstruction { TogglePaneFrames, SetSelectable(PaneId, bool, usize), ClosePane(PaneId, Option), + UpdatePaneName(Vec, ClientId), NewTab(Layout, Vec, ClientId), SwitchTabNext(ClientId), SwitchTabPrev(ClientId), @@ -140,6 +141,7 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::TogglePaneFrames => ScreenContext::TogglePaneFrames, ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable, ScreenInstruction::ClosePane(..) => ScreenContext::ClosePane, + ScreenInstruction::UpdatePaneName(..) => ScreenContext::UpdatePaneName, ScreenInstruction::NewTab(..) => ScreenContext::NewTab, ScreenInstruction::SwitchTabNext(..) => ScreenContext::SwitchTabNext, ScreenInstruction::SwitchTabPrev(..) => ScreenContext::SwitchTabPrev, @@ -975,6 +977,14 @@ pub(crate) fn screen_thread_main( } screen.update_tabs(); } + ScreenInstruction::UpdatePaneName(c, client_id) => { + screen + .get_active_tab_mut(client_id) + .unwrap() + .update_active_pane_name(c, client_id); + + screen.render(); + } ScreenInstruction::ToggleActiveTerminalFullscreen(client_id) => { screen .get_active_tab_mut(client_id) diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs index f684b99623..a0386a4564 100644 --- a/zellij-server/src/tab.rs +++ b/zellij-server/src/tab.rs @@ -23,8 +23,9 @@ use std::time::Instant; use std::{ cmp::Reverse, collections::{BTreeMap, HashMap, HashSet}, + str, }; -use zellij_tile::data::{Event, ModeInfo, Palette, PaletteColor}; +use zellij_tile::data::{Event, InputMode, ModeInfo, Palette, PaletteColor}; use zellij_utils::{ input::{ layout::{Direction, Layout, Run}, @@ -181,12 +182,18 @@ pub trait Pane { fn selectable(&self) -> bool; fn set_selectable(&mut self, selectable: bool); fn render(&mut self, client_id: Option) -> Option; - fn render_frame(&mut self, client_id: ClientId, frame_params: FrameParams) -> Option; + fn render_frame( + &mut self, + client_id: ClientId, + frame_params: FrameParams, + input_mode: InputMode, + ) -> Option; fn render_fake_cursor( &mut self, cursor_color: PaletteColor, text_color: PaletteColor, ) -> Option; + fn update_name(&mut self, name: &str); fn pid(&self) -> PaneId; fn reduce_height(&mut self, percent: f64); fn increase_height(&mut self, percent: f64); @@ -400,6 +407,7 @@ impl Tab { *position_and_size, self.senders.to_plugin.as_ref().unwrap().clone(), pane_title, + layout.pane_name.clone().unwrap_or_default(), ); new_plugin.set_borderless(layout.borderless); self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin)); @@ -412,6 +420,7 @@ impl Tab { *position_and_size, self.colors, next_terminal_position, + layout.pane_name.clone().unwrap_or_default(), ); new_pane.set_borderless(layout.borderless); self.panes @@ -588,6 +597,7 @@ impl Tab { bottom_winsize, self.colors, next_terminal_position, + String::new(), ); terminal_to_split.set_geom(top_winsize); self.panes.insert(pid, Box::new(new_terminal)); @@ -604,6 +614,7 @@ impl Tab { right_winsize, self.colors, next_terminal_position, + String::new(), ); terminal_to_split.set_geom(left_winsize); self.panes.insert(pid, Box::new(new_terminal)); @@ -647,6 +658,7 @@ impl Tab { bottom_winsize, self.colors, next_terminal_position, + String::new(), ); active_pane.set_geom(top_winsize); self.panes.insert(pid, Box::new(new_terminal)); @@ -684,8 +696,13 @@ impl Tab { } let terminal_ws = active_pane.position_and_size(); if let Some((left_winsize, right_winsize)) = split(Direction::Vertical, &terminal_ws) { - let new_terminal = - TerminalPane::new(term_pid, right_winsize, self.colors, next_terminal_position); + let new_terminal = TerminalPane::new( + term_pid, + right_winsize, + self.colors, + next_terminal_position, + String::new(), + ); active_pane.set_geom(left_winsize); self.panes.insert(pid, Box::new(new_terminal)); } @@ -3451,6 +3468,17 @@ impl Tab { .unwrap(); } } + + pub fn update_active_pane_name(&mut self, buf: Vec, client_id: ClientId) { + if let Some(active_terminal_id) = self.get_active_terminal_id(client_id) { + let s = str::from_utf8(&buf).unwrap(); + let active_terminal = self + .panes + .get_mut(&PaneId::Terminal(active_terminal_id)) + .unwrap(); + active_terminal.update_name(s); + } + } } #[allow(clippy::borrowed_box)] diff --git a/zellij-server/src/ui/pane_contents_and_ui.rs b/zellij-server/src/ui/pane_contents_and_ui.rs index f2742f17e8..25550fe9f9 100644 --- a/zellij-server/src/ui/pane_contents_and_ui.rs +++ b/zellij-server/src/ui/pane_contents_and_ui.rs @@ -132,7 +132,7 @@ impl<'a> PaneContentsAndUi<'a> { other_cursors_exist_in_session: self.multiple_users_exist_in_session, } }; - if let Some(vte_output) = self.pane.render_frame(client_id, frame_params) { + if let Some(vte_output) = self.pane.render_frame(client_id, frame_params, client_mode) { // FIXME: Use Termion for cursor and style clearing? self.output.push_to_client( client_id, diff --git a/zellij-tile/src/data.rs b/zellij-tile/src/data.rs index e43049a540..3e269af3b6 100644 --- a/zellij-tile/src/data.rs +++ b/zellij-tile/src/data.rs @@ -77,8 +77,12 @@ pub enum InputMode { /// `Scroll` mode allows scrolling up and down within a pane. #[serde(alias = "scroll")] Scroll, + /// `RenameTab` mode allows assigning a new name to a tab. #[serde(alias = "renametab")] RenameTab, + /// `RenamePane` mode allows assigning a new name to a pane. + #[serde(alias = "renamepane")] + RenamePane, /// `Session` mode allows detaching sessions #[serde(alias = "session")] Session, @@ -133,6 +137,7 @@ impl FromStr for InputMode { "session" => Ok(InputMode::Session), "move" => Ok(InputMode::Move), "prompt" => Ok(InputMode::Prompt), + "renamepane" => Ok(InputMode::RenamePane), e => Err(e.to_string().into()), } } diff --git a/zellij-utils/assets/config/default.yaml b/zellij-utils/assets/config/default.yaml index 0c06485a8e..4de2a92e49 100644 --- a/zellij-utils/assets/config/default.yaml +++ b/zellij-utils/assets/config/default.yaml @@ -135,6 +135,8 @@ keybinds: key: [ Alt: '[',] - action: [FocusNextPane,] key: [ Alt: ']',] + - action: [SwitchToMode: RenamePane, PaneNameInput: [0],] + key: [Char: 'c'] move: - action: [SwitchToMode: Locked,] key: [Ctrl: 'g'] @@ -304,6 +306,27 @@ keybinds: key: [ Alt: '[',] - action: [FocusNextPane,] key: [ Alt: ']',] + renamepane: + - action: [SwitchToMode: Normal,] + key: [Ctrl: 'c', Ctrl: 's', Char: ' ',] + - action: [SwitchToMode: Pane,] + key: [Char: "\n",] + - action: [PaneNameInput: [27] , SwitchToMode: Pane,] + key: [Esc,] + - action: [NewPane: ,] + key: [ Alt: 'n',] + - action: [MoveFocus: Left,] + key: [ Alt: 'h',] + - action: [MoveFocus: Right,] + key: [ Alt: 'l',] + - action: [MoveFocus: Down,] + key: [ Alt: 'j',] + - action: [MoveFocus: Up,] + key: [ Alt: 'k',] + - action: [FocusPreviousPane,] + key: [ Alt: '[',] + - action: [FocusNextPane,] + key: [ Alt: ']',] session: - action: [SwitchToMode: Locked,] key: [Ctrl: 'g'] diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs index f8b8def985..a546e6cc7f 100644 --- a/zellij-utils/src/errors.rs +++ b/zellij-utils/src/errors.rs @@ -251,6 +251,7 @@ pub enum ScreenContext { SetFixedHeight, SetFixedWidth, ClosePane, + UpdatePaneName, NewTab, SwitchTabNext, SwitchTabPrev, diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index c84ad285e4..d29799fbb1 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -83,6 +83,7 @@ pub enum Action { NewPane(Option), /// Close the focus pane. CloseFocus, + PaneNameInput(Vec), /// Create a new tab, optionally with a specified tab layout. NewTab(Option), /// Do nothing. diff --git a/zellij-utils/src/input/keybinds.rs b/zellij-utils/src/input/keybinds.rs index fcc2e4a874..47b7fc3e01 100644 --- a/zellij-utils/src/input/keybinds.rs +++ b/zellij-utils/src/input/keybinds.rs @@ -209,6 +209,7 @@ impl Keybinds { mode_keybind_or_action(Action::Write(raw_bytes)) } InputMode::RenameTab => mode_keybind_or_action(Action::TabNameInput(raw_bytes)), + InputMode::RenamePane => mode_keybind_or_action(Action::PaneNameInput(raw_bytes)), _ => mode_keybind_or_action(Action::NoOp), } } diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index 29b8de00fb..9fa6709c27 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -133,6 +133,8 @@ impl fmt::Display for RunPluginLocation { pub struct Layout { pub direction: Direction, #[serde(default)] + pub pane_name: Option, + #[serde(default)] pub parts: Vec, pub split_size: Option, pub run: Option, @@ -411,6 +413,8 @@ fn default_as_some_true() -> Option { pub struct LayoutTemplate { pub direction: Direction, #[serde(default)] + pub pane_name: Option, + #[serde(default)] pub borderless: bool, #[serde(default)] pub parts: Vec, @@ -454,6 +458,7 @@ impl LayoutTemplate { pub struct TabLayout { #[serde(default)] pub direction: Direction, + pub pane_name: Option, #[serde(default)] pub borderless: bool, #[serde(default)] @@ -703,6 +708,7 @@ impl TryFrom for Layout { fn try_from(tab: TabLayout) -> Result { Ok(Layout { direction: tab.direction, + pane_name: tab.pane_name, borderless: tab.borderless, parts: Self::from_vec_tab_layout(tab.parts)?, split_size: tab.split_size, @@ -715,6 +721,7 @@ impl From for LayoutTemplate { fn from(tab: TabLayout) -> Self { Self { direction: tab.direction, + pane_name: tab.pane_name, borderless: tab.borderless, parts: Self::from_vec_tab_layout(tab.parts), body: false, @@ -730,6 +737,7 @@ impl TryFrom for Layout { fn try_from(template: LayoutTemplate) -> Result { Ok(Layout { direction: template.direction, + pane_name: template.pane_name, borderless: template.borderless, parts: Self::from_vec_template_layout(template.parts)?, split_size: template.split_size, @@ -752,6 +760,7 @@ impl Default for TabLayout { split_size: None, run: None, name: String::new(), + pane_name: None, } } } @@ -760,10 +769,12 @@ impl Default for LayoutTemplate { fn default() -> Self { Self { direction: Direction::Horizontal, + pane_name: None, body: false, borderless: false, parts: vec![LayoutTemplate { direction: Direction::Horizontal, + pane_name: None, body: true, borderless: false, split_size: None, diff --git a/zellij-utils/src/input/mod.rs b/zellij-utils/src/input/mod.rs index a10ffa2cd7..34572ba794 100644 --- a/zellij-utils/src/input/mod.rs +++ b/zellij-utils/src/input/mod.rs @@ -40,6 +40,7 @@ pub fn get_mode_info( ("x".to_string(), "Close".to_string()), ("f".to_string(), "Fullscreen".to_string()), ("z".to_string(), "Frames".to_string()), + ("c".to_string(), "Rename".to_string()), ], InputMode::Tab => vec![ ("←↓↑→".to_string(), "Move focus".to_string()), @@ -55,6 +56,7 @@ pub fn get_mode_info( ("u/d".to_string(), "Scroll Half Page".to_string()), ], InputMode::RenameTab => vec![("Enter".to_string(), "when done".to_string())], + InputMode::RenamePane => vec![("Enter".to_string(), "when done".to_string())], InputMode::Session => vec![("d".to_string(), "Detach".to_string())], }; diff --git a/zellij-utils/src/input/unit/layout_test.rs b/zellij-utils/src/input/unit/layout_test.rs index 2ec66a2a00..aec34c458a 100644 --- a/zellij-utils/src/input/unit/layout_test.rs +++ b/zellij-utils/src/input/unit/layout_test.rs @@ -40,10 +40,12 @@ fn default_layout_merged_correctly() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: true, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -54,6 +56,7 @@ fn default_layout_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -61,6 +64,7 @@ fn default_layout_merged_correctly() { Layout { direction: Direction::Vertical, borderless: true, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -84,10 +88,12 @@ fn default_layout_new_tab_correct() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: true, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -98,6 +104,7 @@ fn default_layout_new_tab_correct() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -105,6 +112,7 @@ fn default_layout_new_tab_correct() { Layout { direction: Direction::Vertical, borderless: true, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -168,13 +176,16 @@ fn three_panes_with_tab_merged_correctly() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -182,10 +193,12 @@ fn three_panes_with_tab_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -193,6 +206,7 @@ fn three_panes_with_tab_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -220,9 +234,11 @@ fn three_panes_with_tab_new_tab_is_correct() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -260,10 +276,12 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -274,10 +292,12 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -285,10 +305,12 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -296,6 +318,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -311,6 +334,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -334,10 +358,12 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(1)), run: Some(Run::Plugin(RunPlugin { @@ -348,6 +374,7 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -355,6 +382,7 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Fixed(2)), run: Some(Run::Plugin(RunPlugin { @@ -396,14 +424,17 @@ fn deeply_nested_tab_merged_correctly() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(21.0)), run: None, @@ -411,10 +442,12 @@ fn deeply_nested_tab_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(22.0)), run: None, @@ -422,10 +455,12 @@ fn deeply_nested_tab_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(23.0)), run: None, @@ -433,6 +468,7 @@ fn deeply_nested_tab_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(24.0)), run: None, @@ -452,6 +488,7 @@ fn deeply_nested_tab_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(15.0)), run: None, @@ -459,6 +496,7 @@ fn deeply_nested_tab_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(15.0)), run: None, @@ -466,6 +504,7 @@ fn deeply_nested_tab_merged_correctly() { Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(15.0)), run: None, @@ -504,10 +543,12 @@ fn three_tabs_tab_one_merged_correctly() { let merged_layout = Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -515,6 +556,7 @@ fn three_tabs_tab_one_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -539,14 +581,17 @@ fn three_tabs_tab_two_merged_correctly() { let merged_layout = Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -554,6 +599,7 @@ fn three_tabs_tab_two_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -565,6 +611,7 @@ fn three_tabs_tab_two_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -589,14 +636,17 @@ fn three_tabs_tab_three_merged_correctly() { let merged_layout = Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![ Layout { direction: Direction::Vertical, borderless: false, + pane_name: None, parts: vec![], split_size: Some(SplitSize::Percent(50.0)), run: None, @@ -604,6 +654,7 @@ fn three_tabs_tab_three_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -615,6 +666,7 @@ fn three_tabs_tab_three_merged_correctly() { Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -650,9 +702,11 @@ fn no_tabs_merged_correctly() { let merged_layout = Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![Layout { direction: Direction::Horizontal, borderless: false, + pane_name: None, parts: vec![], split_size: None, run: None, @@ -699,6 +753,7 @@ fn no_layout_template_merged_correctly() { split_size: None, run: None, borderless: false, + pane_name: None, }, Layout { direction: Direction::Horizontal, @@ -706,15 +761,18 @@ fn no_layout_template_merged_correctly() { split_size: None, run: None, borderless: false, + pane_name: None, }, ], split_size: None, run: None, borderless: false, + pane_name: None, }], split_size: None, run: None, borderless: false, + pane_name: None, }; assert_eq!(merged_layout, tab_layout.try_into().unwrap()); diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs index b27a097a14..2716dd3cc0 100644 --- a/zellij-utils/src/ipc.rs +++ b/zellij-utils/src/ipc.rs @@ -62,7 +62,7 @@ pub enum ClientToServerMsg { ClientAttributes, Box, Box, - LayoutFromYaml, + Box, Option, ), AttachClient(ClientAttributes, Options),