diff options
| author | Aram Drevekenin <aram@poor.dev> | 2025-10-31 20:15:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-31 20:15:32 +0100 |
| commit | 82f30e2cde5207e5b51301633686b2c7feac54f3 (patch) | |
| tree | 2bdc9a39be42b9e781619730fc6558afe0783838 | |
| parent | Feature: watcher clients (#4487) (diff) | |
| download | sl0ppij-82f30e2cde5207e5b51301633686b2c7feac54f3.tar.gz sl0ppij-82f30e2cde5207e5b51301633686b2c7feac54f3.tar.xz sl0ppij-82f30e2cde5207e5b51301633686b2c7feac54f3.zip | |
Improve CLI interface (add detach, switch session, blocking zellij run and more) (#4492)
* initial implementation
* fix tests
* move more ations
* screen adjustments (does not compile)
* plugin/pty adjustments (does not compile)
* more progress, tests not compiling
* fix tests
* more progress, does not compile
* more progress, compiles, tests failing
* tests passing
* rely on Drop for NotificationEnd
* atomicify some more actions
* fmt
* move unblock input to route
* don't pass hard-coded action names
* refactor: consolidate completion channel logic
* comment
* track last active client
* track cli clients explicitly
* use the last active client for cli commands when possible
* fix focus-next-pane for multiple clients
* various fixes for multi-client actions from the cli
* add detach action
* fix tests
* add switch session cli action
* fix switch session deadlock
* add and layout to switch-session cli action
* blocking zellij run: add NewBlockingPane variant
* blocking zellij run: wait forever mechanism
* blocking zellij run: thread NotificationEnd as needed until TerminalPane (tests not compiling)
* blocking zellij run: update cli
* blocking zellij run: add command
* blocking zellij run: finish implementation
* fix tests
* e2e test and close_on_exit fixes
* fmt
* fix e2e tests
* fix plugin tests
140 files changed, 3938 insertions, 1212 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6389b4d1..828f43c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * feat: allow plugins to read pane scrollback (https://github.com/zellij-org/zellij/pull/4465) * infra: migrate wasm runtime from wasmtime to wasmi (https://github.com/zellij-org/zellij/pull/4449) * feat: allow attaching to sessions as "read-only" (https://github.com/zellij-org/zellij/pull/4487) +* feat: improve cli interface (add detach, switch-session and more) (https://github.com/zellij-org/zellij/pull/4492) ## [0.43.1] - 2025-08-08 * fix: pane rename backspace regression (https://github.com/zellij-org/zellij/pull/4346) diff --git a/src/main.rs b/src/main.rs index 2b2e213a..f077c199 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ fn main() { height, pinned, stacked, + blocking, })) = opts.command { let cwd = cwd.or_else(|| std::env::current_dir().ok()); @@ -61,6 +62,7 @@ fn main() { height, pinned, stacked, + blocking, }; commands::send_action_to_session(command_cli_action, opts.session, config); std::process::exit(0); @@ -80,6 +82,7 @@ fn main() { { let cwd = None; let stacked = false; + let blocking = false; let command_cli_action = CliAction::NewPane { command: vec![], plugin: Some(url), @@ -98,6 +101,7 @@ fn main() { height, pinned, stacked, + blocking, }; commands::send_action_to_session(command_cli_action, opts.session, config); std::process::exit(0); diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index d2096cea..eab81039 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -2317,6 +2317,8 @@ pub fn send_command_through_the_cli() { fixture_folder )); std::thread::sleep(std::time::Duration::from_millis(100)); + remote_terminal.send_key(&ENTER); + std::thread::sleep(std::time::Duration::from_millis(100)); step_is_complete = true; } step_is_complete @@ -2396,6 +2398,102 @@ pub fn send_command_through_the_cli() { #[test] #[ignore] +pub fn send_blocking_command_through_the_cli() { + // here we test the following flow: + // - send a blocking command through the cli with --blocking --floating --close-on-exit + // - the command sleeps for 2 seconds (longer than the default 1s timeout) then exits with status 42 + // - verify that the CLI blocks for the full duration (we check after 2+ seconds) + // - verify that the floating pane appears while running and disappears after completion + // - verify that the exit status is properly propagated + let fake_win_size = Size { + cols: 150, + rows: 24, + }; + let mut test_attempts = 10; + let last_snapshot = loop { + RemoteRunner::kill_running_sessions(fake_win_size); + let mut runner = RemoteRunner::new(fake_win_size) + .add_step(Step { + name: "Run blocking command through the cli", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.status_bar_appears() + && remote_terminal.cursor_position_is(3, 2) + { + // Send a command that sleeps for 2 seconds then exits with status 42 + // Using bash -c with proper escaping + // remote_terminal.send_key("aaa\n".as_bytes()); + std::thread::sleep(std::time::Duration::from_millis(100)); + remote_terminal.send_blocking_command_through_the_cli( + // "lskdjlskdjf" + "bash -c 'sleep 2 && exit 42'", + ); + std::thread::sleep(std::time::Duration::from_millis(100)); + remote_terminal.send_key(&ENTER); + std::thread::sleep(std::time::Duration::from_millis(100)); + step_is_complete = true; + } + step_is_complete + }, + }) + .add_step(Step { + name: "Wait for floating pane to appear", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + // The floating pane should appear with the running command + if remote_terminal.snapshot_contains("PIN [ ]") { + std::thread::sleep(std::time::Duration::from_millis(2000)); // wait for + // command to + // end + step_is_complete = true + } + step_is_complete + }, + }) + .add_step(Step { + name: "Wait for command to complete and verify exit status", + instruction: |mut remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + // After 2+ seconds, the command should complete and the floating pane should close + // then we do echo $? to make sure we got back its exit status + if !remote_terminal.snapshot_contains("PIN [ ]") { + remote_terminal.send_key("echo $?".as_bytes()); + std::thread::sleep(std::time::Duration::from_millis(100)); + remote_terminal.send_key(&ENTER); + std::thread::sleep(std::time::Duration::from_millis(100)); + step_is_complete = true + } + step_is_complete + }, + }); + runner.run_all_steps(); + + let last_snapshot = runner.take_snapshot_after(Step { + name: "Verify CLI returned with proper exit status after command completed", + instruction: |remote_terminal: RemoteTerminal| -> bool { + let mut step_is_complete = false; + if remote_terminal.snapshot_contains("echo $?") + && remote_terminal.status_bar_appears() + { + step_is_complete = true + } + step_is_complete + }, + }); + + if runner.test_timed_out && test_attempts > 0 { + test_attempts -= 1; + continue; + } else { + break last_snapshot; + } + }; + let last_snapshot = account_for_races_in_snapshot(last_snapshot); + assert_snapshot!(last_snapshot); +} + +#[test] +#[ignore] pub fn load_plugins_in_background_on_startup() { let fake_win_size = Size { cols: 120, diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs index a9b345b7..377869f9 100644 --- a/src/tests/e2e/remote_runner.rs +++ b/src/tests/e2e/remote_runner.rs @@ -273,6 +273,7 @@ fn read_from_channel( arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index loop { if !should_keep_running.load(Ordering::SeqCst) { @@ -423,7 +424,20 @@ impl RemoteTerminal { channel .write_all( // note that this is run with the -s flag that suspends the command on startup - format!("{} run -s -- \"{}\"\n", ZELLIJ_EXECUTABLE_LOCATION, command).as_bytes(), + format!("{} run -s -- \"{}\"", ZELLIJ_EXECUTABLE_LOCATION, command).as_bytes(), + ) + .unwrap(); + channel.flush().unwrap(); + } + pub fn send_blocking_command_through_the_cli(&mut self, command: &str) { + let mut channel = self.channel.lock().unwrap(); + channel + .write_all( + format!( + "{} run --blocking --floating --close-on-exit -- {}", + ZELLIJ_EXECUTABLE_LOCATION, command + ) + .as_bytes(), ) .unwrap(); channel.flush().unwrap(); diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_blocking_command_through_the_cli.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_blocking_command_through_the_cli.snap new file mode 100644 index 00000000..0dce3a50 --- /dev/null +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_blocking_command_through_the_cli.snap @@ -0,0 +1,28 @@ +--- +source: src/tests/e2e/cases.rs +expression: last_snapshot +--- + Zellij (e2e-test) Tab #1 +┌ Pane #1 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│$ /usr/src/zellij/x86_64-unknown-linux-musl/release/zellij run --blocking --floating --close-on-exit -- bash -c 'sleep 2 && exit 42' │ +│$ │ +│$ echo $? │ +│42 │ +│$ │ +│$ █ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SEARCH <o> SESSION <q> QUIT Alt + <n> New Pane <f> Floating diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap index 1e1a014b..228407bd 100644 --- a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap +++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap @@ -7,7 +7,7 @@ expression: last_snapshot │$ /usr/src/zellij/x86_64-unknown-linux-musl/release/zellij run -s -- "/us││foo │ │r/src/zellij/fixtures/append-echo-script.sh" ││foo │ │$ ││█ │ -│ ││ │ +│$ ││ │ │ ││ │ │ ││ │ │ ││ │ diff --git a/zellij-client/src/cli_client.rs b/zellij-client/src/cli_client.rs index 29774994..a82e677e 100644 --- a/zellij-client/src/cli_client.rs +++ b/zellij-client/src/cli_client.rs @@ -121,6 +121,7 @@ fn pipe_client( }, terminal_id: pane_id, client_id: None, + is_cli_client: true, } }; let is_piped = !os_input.stdin_is_terminal(); @@ -208,6 +209,7 @@ fn individual_messages_client( action, terminal_id: pane_id, client_id: None, + is_cli_client: true, }; os_input.send_to_server(msg); loop { @@ -228,6 +230,9 @@ fn individual_messages_client( eprintln!("{}", e); process::exit(2); }, + ExitReason::CustomExitStatus(exit_status) => { + process::exit(exit_status); + }, _ => { break; }, diff --git a/zellij-client/src/input_handler.rs b/zellij-client/src/input_handler.rs index d2cee2e0..271eb33f 100644 --- a/zellij-client/src/input_handler.rs +++ b/zellij-client/src/input_handler.rs @@ -339,6 +339,7 @@ impl InputHandler { action, terminal_id: None, client_id, + is_cli_client: false, }); self.exit(ExitReason::Normal); should_break = true; @@ -348,6 +349,17 @@ impl InputHandler { action, terminal_id: None, client_id, + is_cli_client: false, + }); + self.exit(ExitReason::NormalDetached); + should_break = true; + }, + Action::SwitchSession { .. } => { + self.os_input.send_to_server(ClientToServerMsg::Action { + action, + terminal_id: None, + client_id, + is_cli_client: false, }); self.exit(ExitReason::NormalDetached); should_break = true; @@ -375,6 +387,7 @@ impl InputHandler { action, terminal_id: None, client_id, + is_cli_client: false, }); self.command_is_executing .wait_until_input_thread_is_unblocked(); @@ -392,6 +405,7 @@ impl InputHandler { action, terminal_id: None, client_id, + is_cli_client: false, }), } diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 42587b19..b66730cd 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -867,6 +867,7 @@ pub fn start_client( action: on_force_close.into(), terminal_id: None, client_id: None, + is_cli_client: false, }); } }), diff --git a/zellij-client/src/web_client/message_handlers.rs b/zellij-client/src/web_client/message_handlers.rs index 495ca003..a8257bc2 100644 --- a/zellij-client/src/web_client/message_handlers.rs +++ b/zellij-client/src/web_client/message_handlers.rs @@ -118,6 +118,7 @@ pub fn parse_stdin( action, terminal_id: None, client_id: None, + is_cli_client: false, }); }, InputEvent::Paste(pasted_text) => { @@ -129,6 +130,7 @@ pub fn parse_stdin( }, terminal_id: None, client_id: None, + is_cli_client: false, }); os_input.send_to_server(ClientToServerMsg::Action { action: Action::Write { @@ -138,6 +140,7 @@ pub fn parse_stdin( }, terminal_id: None, client_id: None, + is_cli_client: false, }); os_input.send_to_server(ClientToServerMsg::Action { action: Action::Write { @@ -147,6 +150,7 @@ pub fn parse_stdin( }, terminal_id: None, client_id: None, + is_cli_client: false, }); }, _ => { diff --git a/zellij-client/src/web_client/unit/web_client_tests.rs b/zellij-client/src/web_client/unit/web_client_tests.rs index ff87bc58..27e77996 100644 --- a/zellij-client/src/web_client/unit/web_client_tests.rs +++ b/zellij-client/src/web_client/unit/web_client_tests.rs @@ -440,6 +440,7 @@ mod web_client_tests { action: _, terminal_id: _, client_id: _, + is_cli_client: _, } => { found_terminal_input = true; }, diff --git a/zellij-server/src/global_async_runtime.rs b/zellij-server/src/global_async_runtime.rs new file mode 100644 index 00000000..3778786a --- /dev/null +++ b/zellij-server/src/global_async_runtime.rs @@ -0,0 +1,17 @@ +use once_cell::sync::OnceCell; +use tokio::runtime::Runtime; + +// Global tokio runtime for async I/O operations +// Shared between plugin downloads, timers, and action completion tracking +static TOKIO_RUNTIME: OnceCell<Runtime> = OnceCell::new(); + +pub fn get_tokio_runtime() -> &'static Runtime { + TOKIO_RUNTIME.get_or_init(|| { + tokio::runtime::Builder::new_multi_thread() + .worker_threads(4) + .thread_name("async-runtime") + .enable_all() + .build() + .expect("Failed to create tokio runtime") + }) +} diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 0266b062..1861fb68 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -4,6 +4,7 @@ pub mod panes; pub mod tab; mod background_jobs; +mod global_async_runtime; mod logging_pipe; mod pane_groups; mod plugins; @@ -43,7 +44,7 @@ use crate::{ screen::{screen_thread_main, ScreenInstruction}, thread_bus::{Bus, ThreadSenders}, }; -use route::route_thread_main; +use route::{route_thread_main, NotificationEnd}; use zellij_utils::{ channels::{self, ChannelWithContext, SenderWithContext}, consts::{ @@ -81,11 +82,11 @@ pub enum ServerInstruction { ), Render(Option<HashMap<ClientId, String>>), UnblockInputThread, - ClientExit(ClientId), + ClientExit(ClientId, Option<NotificationEnd>), RemoveClient(ClientId), Error(String), KillSession, - DetachSession(Vec<ClientId>), + DetachSession(Vec<ClientId>, Option<NotificationEnd>), AttachClient( CliAssets, Option<usize>, // tab position to focus @@ -95,9 +96,9 @@ pub enum ServerInstruction { ), AttachWatcherClient(ClientId, Size), ConnStatus(ClientId), - Log(Vec<String>, ClientId), - LogError(Vec<String>, ClientId), - SwitchSession(ConnectToSession, ClientId), + Log(Vec<String>, ClientId, Option<NotificationEnd>), + LogError(Vec<String>, ClientId, Option<NotificationEnd>), + SwitchSession(ConnectToSession, ClientId, Option<NotificationEnd>), UnblockCliPipeInput(String), // String -> Pipe name CliPipeOutput(String, String), // String -> Pipe name, String -> Output AssociatePipeWithClient { @@ -475,6 +476,7 @@ pub(crate) struct SessionState { clients: HashMap<ClientId, Option<(Size, bool)>>, // bool -> is_web_client pipes: HashMap<String, ClientId>, // String => pipe_id watchers: HashSet<ClientId>, // watcher clients (read-only observers) + last_active_client: Option<ClientId>, // last client that sent a Key message } impl SessionState { @@ -483,6 +485,7 @@ impl SessionState { clients: HashMap::new(), pipes: HashMap::new(), watchers: HashSet::new(), + last_active_client: None, } } pub fn new_client(&mut self) -> ClientId { @@ -510,6 +513,7 @@ impl SessionState { pub fn remove_client(&mut self, client_id: ClientId) { self.clients.remove(&client_id); self.pipes.retain(|_p_id, c_id| c_id != &client_id); + self.clear_last_active_client(client_id); } pub fn set_client_size(&mut self, client_id: ClientId, size: Size) { self.clients @@ -588,6 +592,17 @@ impl SessionState { pub fn remove_watcher(&mut self, client_id: ClientId) { self.watchers.remove(&client_id); } + pub fn set_last_active_client(&mut self, client_id: ClientId) { + self.last_active_client = Some(client_id); + } + pub fn get_last_active_client(&self) -> Option<ClientId> { + self.last_active_client + } + pub fn clear_last_active_client(&mut self, client_id: ClientId) { + if self.last_active_client == Some(client_id) { + self.last_active_client = None; + } + } } pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { @@ -771,6 +786,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { swap_layouts, should_focus_tab, (client_id, is_web_client), + None, )) .unwrap() }; @@ -909,7 +925,11 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { ); session_data .senders - .send_to_screen(ScreenInstruction::ChangeMode(mode_info.clone(), client_id)) + .send_to_screen(ScreenInstruction::ChangeMode( + mode_info.clone(), + client_id, + None, + )) .unwrap(); session_data .senders @@ -1014,7 +1034,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { }, } }, - ServerInstruction::ClientExit(client_id) => { + ServerInstruction::ClientExit(client_id, completion_tx) => { let _ = os_input.send_to_client( client_id, ServerToClientMsg::Exit { @@ -1039,6 +1059,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { } else { // Handle regular client removal remove_client!(client_id, os_input, session_state); + drop(completion_tx); // prevent deadlock with route thread if let Some(min_size) = session_state.read().unwrap().min_client_terminal_size() { session_data @@ -1193,15 +1214,21 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { remove_client!(client_id, os_input, session_state); } }, - ServerInstruction::DetachSession(client_ids) => { - for client_id in client_ids { + ServerInstruction::DetachSession(client_ids, completion_tx) => { + for client_id in &client_ids { let _ = os_input.send_to_client( - client_id, + *client_id, ServerToClientMsg::Exit { exit_reason: ExitReason::Normal, }, ); - remove_client!(client_id, os_input, session_state); + remove_client!(*client_id, os_input, session_state); + } + drop(completion_tx); // we do this here explicitly to signal that the clients have + // already disconnected and to prevent a deadlock below caused + // by us having to wait for session_data to send cleanup + // signals to the various threads + for client_id in client_ids { if let Some(min_size) = session_state.read().unwrap().min_client_terminal_size() { session_data @@ -1295,7 +1322,12 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { let _ = os_input.send_to_client(client_id, ServerToClientMsg::Connected); remove_client!(client_id, os_input, session_state); }, - ServerInstruction::Log(lines_to_log, client_id) => { + ServerInstruction::Log( + lines_to_log, + client_id, + _completion_tx, // the action ends here, dropping this will release anything waiting + // for it + ) => { send_to_client!( client_id, os_input, @@ -1305,7 +1337,12 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { session_state ); }, - ServerInstruction::LogError(lines_to_log, client_id) => { + ServerInstruction::LogError( + lines_to_log, + client_id, + _completion_tx, // the action ends here, dropping this will release anything waiting + // for it + ) => { send_to_client!( client_id, os_input, @@ -1315,7 +1352,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { session_state ); }, - ServerInstruction::SwitchSession(mut connect_to_session, client_id) => { + ServerInstruction::SwitchSession(mut connect_to_session, client_id, completion_tx) => { let current_session_name = envs::get_session_name(); if connect_to_session.name == current_session_name.ok() { log::error!("Cannot attach to same session"); @@ -1333,6 +1370,16 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { if let Some(layout_dir) = layout_dir { connect_to_session.apply_layout_dir(&layout_dir); } + + send_to_client!( + client_id, + os_input, + ServerToClientMsg::SwitchSession { connect_to_session }, + session_state + ); + remove_client!(client_id, os_input, session_state); + drop(completion_tx); // do not deadlock with route thread + if let Some(min_size) = session_state.read().unwrap().min_client_terminal_size() { session_data @@ -1360,13 +1407,6 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { .senders .send_to_plugin(PluginInstruction::RemoveClient(client_id)) .unwrap(); - send_to_client!( - client_id, - os_input, - ServerToClientMsg::SwitchSession { connect_to_session }, - session_state - ); - remove_client!(client_id, os_input, session_state); } }, ServerInstruction::AssociatePipeWithClient { pipe_id, client_id } => { diff --git a/zellij-server/src/pane_groups.rs b/zellij-server/src/pane_groups.rs index e1ab97ab..8f27c37a 100644 --- a/zellij-server/src/pane_groups.rs +++ b/zellij-server/src/pane_groups.rs @@ -182,6 +182,7 @@ impl PaneGroups { cwd, should_focus_plugin, Some(floating_pane_coordinates), + None, )); } } diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index 21cdd64e..1c5667a5 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -6,6 +6,7 @@ use crate::panes::{ terminal_character::{render_first_run_banner, TerminalCharacter, EMPTY_TERMINAL_CHARACTER}, }; use crate::pty::VteBytes; +use crate::route::NotificationEnd; use crate::tab::{AdjustedInput, Pane}; use crate::ClientId; use std::cell::RefCell; @@ -141,6 +142,7 @@ pub struct TerminalPane { invoked_with: Option<Run>, #[allow(dead_code)] arrow_fonts: bool, + notification_end: Option<NotificationEnd>, } impl Pane for TerminalPane { @@ -735,6 +737,11 @@ impl Pane for TerminalPane { fn hold(&mut self, exit_status: Option<i32>, is_first_run: bool, run_command: RunCommand) { self.invoked_with = Some(Run::Command(run_command.clone())); self.is_held = Some((exit_status, is_first_run, run_command)); + if let Some(notification_end) = self.notification_end.as_mut() { + if let Some(exit_status) = exit_status { + notification_end.set_exit_status(exit_status); + } + } if is_first_run { self.render_first_run_banner(); } @@ -889,6 +896,11 @@ impl Pane for TerminalPane { ) -> PaneContents { self.grid.pane_contents(get_full_scrollback) } + fn update_exit_status(&mut self, exit_status: i32) { + if let Some(notification_end) = self.notification_end.as_mut() { + notification_end.set_exit_status(exit_status); + } + } } impl TerminalPane { @@ -910,6 +922,7 @@ impl TerminalPane { arrow_fonts: bool, styled_underlines: bool, explicitly_disable_keyboard_protocol: bool, + notification_end: Option<NotificationEnd>, ) -> TerminalPane { let initial_pane_title = initial_pane_title.unwrap_or_else(|| format!("Pane #{}", pane_index)); @@ -951,6 +964,7 @@ impl TerminalPane { pane_frame_color_override: None, invoked_with, arrow_fonts, + notification_end, } } pub fn get_x(&self) -> usize { diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs index d2cbb0c3..fb73a90d 100644 --- a/zellij-server/src/panes/tiled_panes/mod.rs +++ b/zellij-server/src/panes/tiled_panes/mod.rs @@ -1713,8 +1713,6 @@ impl TiledPanes { } pub fn focus_next_pane(&mut self, client_id: ClientId) { - let connected_clients: Vec<ClientId> = - { self.connected_clients.borrow().iter().copied().collect() }; let active_pane_id = self.get_active_pane_id(client_id).unwrap(); let next_active_pane_id = { let pane_grid = TiledPaneGrid::new( @@ -1736,16 +1734,12 @@ impl TiledPanes { self.reapply_pane_frames(); } - for client_id in connected_clients { - self.active_panes - .insert(client_id, next_active_pane_id, &mut self.panes); - } + self.active_panes + .insert(client_id, next_active_pane_id, &mut self.panes); self.set_pane_active_at(next_active_pane_id); self.reset_boundaries(); } pub fn focus_previous_pane(&mut self, client_id: ClientId) { - let connected_clients: Vec<ClientId> = - { self.connected_clients.borrow().iter().copied().collect() }; let active_pane_id = self.get_active_pane_id(client_id).unwrap(); let next_active_pane_id = { let pane_grid = TiledPaneGrid::new( @@ -1767,10 +1761,8 @@ impl TiledPanes { .expand_pane(&next_active_pane_id); self.reapply_pane_frames(); } - for client_id in connected_clients { - self.active_panes - .insert(client_id, next_active_pane_id, &mut self.panes); - } + self.active_panes + .insert(client_id, next_active_pane_id, &mut self.panes); self.set_pane_active_at(next_active_pane_id); self.reset_boundaries(); } diff --git a/zellij-server/src/panes/unit/search_in_pane_tests.rs b/zellij-server/src/panes/unit/search_in_pane_tests.rs index 3ab06501..aebaa5d7 100644 --- a/zellij-server/src/panes/unit/search_in_pane_tests.rs +++ b/zellij-server/src/panes/unit/search_in_pane_tests.rs @@ -49,6 +49,7 @@ fn create_pane() -> TerminalPane { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let content = read_fixture(); terminal_pane.handle_pty_bytes(content); diff --git a/zellij-server/src/panes/unit/terminal_pane_tests.rs b/zellij-server/src/panes/unit/terminal_pane_tests.rs index b568d164..01515f73 100644 --- a/zellij-server/src/panes/unit/terminal_pane_tests.rs +++ b/zellij-server/src/panes/unit/terminal_pane_tests.rs @@ -57,6 +57,7 @@ pub fn scrolling_inside_a_pane() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let mut text_to_fill_pane = String::new(); for i in 0..30 { @@ -107,6 +108,7 @@ pub fn sixel_image_inside_terminal_pane() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let sixel_image_bytes = "\u{1b}Pq #0;2;0;0;0#1;2;100;100;0#2;2;0;100;0 @@ -157,6 +159,7 @@ pub fn partial_sixel_image_inside_terminal_pane() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let pane_content = read_fixture("sixel-image-500px.six"); terminal_pane.handle_pty_bytes(pane_content); @@ -201,6 +204,7 @@ pub fn overflowing_sixel_image_inside_terminal_pane() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let pane_content = read_fixture("sixel-image-500px.six"); terminal_pane.handle_pty_bytes(pane_content); @@ -244,6 +248,7 @@ pub fn scrolling_through_a_sixel_image() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let mut text_to_fill_pane = String::new(); for i in 0..30 { @@ -298,6 +303,7 @@ pub fn multiple_sixel_images_in_pane() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let mut text_to_fill_pane = String::new(); for i in 0..5 { @@ -350,6 +356,7 @@ pub fn resizing_pane_with_sixel_images() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let mut text_to_fill_pane = String::new(); for i in 0..5 { @@ -405,6 +412,7 @@ pub fn changing_character_cell_size_with_sixel_images() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let mut text_to_fill_pane = String::new(); for i in 0..5 { @@ -465,6 +473,7 @@ pub fn keep_working_after_corrupted_sixel_image() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index let sixel_image_bytes = "\u{1b}PI AM CORRUPTED BWAHAHAq @@ -523,6 +532,7 @@ pub fn pane_with_frame_position_is_on_frame() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index terminal_pane.set_content_offset(Offset::frame(1)); @@ -617,6 +627,7 @@ pub fn pane_with_bottom_and_right_borders_position_is_on_frame() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index terminal_pane.set_content_offset(Offset::shift(1, 1)); @@ -711,6 +722,7 @@ pub fn frameless_pane_position_is_on_frame() { arrow_fonts, styled_underlines, explicitly_disable_kitty_keyboard_protocol, + None, ); // 0 is the pane index terminal_pane.set_content_offset(Offset::default()); diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index 126ec356..cede7901 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -18,6 +18,7 @@ use std::{ use wasmi::Engine; use crate::panes::PaneId; +use crate::route::NotificationEnd; use crate::screen::ScreenInstruction; use crate::session_layout_metadata::SessionLayoutMetadata; use crate::{pty::PtyInstruction, thread_bus::Bus, ClientId, ServerInstruction}; @@ -63,6 +64,7 @@ pub enum PluginInstruction { bool, // skip cache Option<bool>, // should focus plugin Option<FloatingPaneCoordinates>, + Option<NotificationEnd>, // completion signal ), LoadBackgroundPlugin(RunPluginOrAlias, ClientId), Update(Vec<(Option<PluginId>, Option<ClientId>, Event)>), // Focused plugin / broadcast, client_id, event data @@ -73,6 +75,7 @@ pub enum PluginInstruction { RunPluginOrAlias, usize, // tab index Size, + Option<NotificationEnd>, ), ReloadPluginWithId(u32), Resize(PluginId, usize, usize), // plugin_id, columns, rows @@ -83,9 +86,10 @@ pub enum PluginInstruction { Option<TerminalAction>, Option<TiledPaneLayout>, Vec<FloatingPaneLayout>, - usize, // tab_index - bool, // should change focus to new tab - (ClientId, bool), // bool -> is_web_client + usize, // tab_index + bool, // should change focus to new tab + (ClientId, bool), // bool -> is_web_client + Option<NotificationEnd>, // completion signal ), ApplyCachedEvents { plugin_ids: Vec<PluginId>, @@ -115,8 +119,8 @@ pub enum PluginInstruction { PermissionStatus, Option<PathBuf>, ), - DumpLayout(SessionLayoutMetadata, ClientId), - ListClientsMetadata(SessionLayoutMetadata, ClientId), + DumpLayout(SessionLayoutMetadata, ClientId, Option<NotificationEnd>), + ListClientsMetadata(SessionLayoutMetadata, ClientId, Option<NotificationEnd>), DumpLayoutToPlugin(SessionLayoutMetadata, PluginId), LogLayoutToHd(SessionLayoutMetadata), CliPipe { @@ -298,6 +302,7 @@ pub(crate) fn plugin_thread_main( skip_cache, should_focus_plugin, floating_pane_coordinates, + completion_tx, ) => { run_plugin_or_alias.populate_run_plugin_if_needed(&plugin_aliases); let cwd = run_plugin_or_alias.get_initial_cwd().or(cwd).or_else(|| { @@ -331,6 +336,7 @@ pub(crate) fn plugin_thread_main( floating_pane_coordinates, should_focus_plugin, Some(client_id), + completion_tx, ))); drop(bus.senders.send_to_pty(PtyInstruction::ReportPluginCwd( @@ -364,6 +370,7 @@ pub(crate) fn plugin_thread_main( mut run_plugin_or_alias, tab_index, size, + completion_tx, ) => { run_plugin_or_alias.populate_run_plugin_if_needed(&plugin_aliases); match run_plugin_or_alias.get_run_plugin() { @@ -408,6 +415,7 @@ pub(crate) fn plugin_thread_main( None, None, None, + completion_tx, ), )); }, @@ -423,7 +431,7 @@ pub(crate) fn plugin_thread_main( } }, None => { - log::error!("Failed to find plugin info for: {:?}", run_plugin_or_alias) + log::error!("Failed to find plugin info for: {:?}", run_plugin_or_alias); }, } }, @@ -447,6 +455,7 @@ pub(crate) fn plugin_thread_main( tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + completion_tx, ) => { // prefer connected clients so as to avoid opening plugins in the background for // CLI clients unless no-one else is connected @@ -518,6 +527,7 @@ pub(crate) fn plugin_thread_main( plugin_ids, should_change_focus_to_new_tab, (client_id, is_web_client), + completion_tx, ))); }, PluginInstruction::ApplyCachedEvents { @@ -588,7 +598,11 @@ pub(crate) fn plugin_thread_main( shutdown_send.clone(), )?; }, - PluginInstruction::DumpLayout(mut session_layout_metadata, client_id) => { + PluginInstruction::DumpLayout( + mut session_layout_metadata, + client_id, + completion_tx, + ) => { populate_session_layout_metadata( &mut session_layout_metadata, &wasm_bridge, @@ -597,9 +611,14 @@ pub(crate) fn plugin_thread_main( drop(bus.senders.send_to_pty(PtyInstruction::DumpLayout( session_layout_metadata, client_id, + completion_tx, ))); }, - PluginInstruction::ListClientsMetadata(mut session_layout_metadata, client_id) => { + PluginInstruction::ListClientsMetadata( + mut session_layout_metadata, + client_id, + completion_tx, + ) => { populate_session_layout_metadata( &mut session_layout_metadata, &wasm_bridge, @@ -608,6 +627,7 @@ pub(crate) fn plugin_thread_main( drop(bus.senders.send_to_pty(PtyInstruction::ListClientsMetadata( session_layout_metadata, client_id, + completion_tx, ))); }, PluginInstruction::DumpLayoutToPlugin(mut session_layout_metadata, plugin_id) => { @@ -1096,6 +1116,7 @@ fn pipe_to_specific_plugins( let _ = bus.senders.send_to_server(ServerInstruction::LogError( vec![format!("Failed to parse plugin url: {}", e)], cli_client_id, + None, )); }, None => { @@ -1144,6 +1165,7 @@ fn load_background_plugin( None, None, Some(client_id), + None, ))); }, Err(e) => { diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs index 9631da91..5f90ebbe 100644 --- a/zellij-server/src/plugins/unit/plugin_tests.rs +++ b/zellij-server/src/plugins/unit/plugin_tests.rs @@ -729,6 +729,7 @@ pub fn load_new_plugin_from_hd() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -812,6 +813,7 @@ pub fn load_new_plugin_with_plugin_alias() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -891,6 +893,7 @@ pub fn plugin_workers() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); // we send a SystemClipboardFailure to trigger the custom handler in the fixture plugin that @@ -974,6 +977,7 @@ pub fn plugin_workers_persist_state() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); // we send a SystemClipboardFailure to trigger the custom handler in the fixture plugin that @@ -1067,6 +1071,7 @@ pub fn can_subscribe_to_hd_events() { false, None, None, + None, )); // extra long time because we only start the fs watcher on plugin load std::thread::sleep(std::time::Duration::from_millis(5000)); @@ -1148,6 +1153,7 @@ pub fn switch_to_mode_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1223,6 +1229,7 @@ pub fn switch_to_mode_plugin_command_permission_denied() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1298,6 +1305,7 @@ pub fn new_tabs_with_layout_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1387,6 +1395,7 @@ pub fn new_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1462,6 +1471,7 @@ pub fn go_to_next_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1536,6 +1546,7 @@ pub fn go_to_previous_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1610,6 +1621,7 @@ pub fn resize_focused_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1684,6 +1696,7 @@ pub fn resize_focused_pane_with_direction_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1758,6 +1771,7 @@ pub fn focus_next_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1832,6 +1846,7 @@ pub fn focus_previous_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1906,6 +1921,7 @@ pub fn move_focus_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -1980,6 +1996,7 @@ pub fn move_focus_or_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2054,6 +2071,7 @@ pub fn edit_scrollback_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2128,6 +2146,7 @@ pub fn write_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2202,6 +2221,7 @@ pub fn write_chars_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2276,6 +2296,7 @@ pub fn toggle_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2350,6 +2371,7 @@ pub fn move_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2424,6 +2446,7 @@ pub fn move_pane_with_direction_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2499,6 +2522,7 @@ pub fn clear_screen_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2574,6 +2598,7 @@ pub fn scroll_up_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2648,6 +2673,7 @@ pub fn scroll_down_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2722,6 +2748,7 @@ pub fn scroll_to_top_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2796,6 +2823,7 @@ pub fn scroll_to_bottom_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2870,6 +2898,7 @@ pub fn page_scroll_up_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -2944,6 +2973,7 @@ pub fn page_scroll_down_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3018,6 +3048,7 @@ pub fn toggle_focus_fullscreen_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3066,7 +3097,7 @@ pub fn toggle_pane_frames_plugin_command() { rows: 20, }; let received_screen_instructions = Arc::new(Mutex::new(vec![])); - let screen_thread = grant_permissions_and_log_actions_in_thread_naked_variant!( + let screen_thread = grant_permissions_and_log_actions_in_thread!( received_screen_instructions, ScreenInstruction::TogglePaneFrames, screen_receiver, @@ -3092,6 +3123,7 @@ pub fn toggle_pane_frames_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3106,7 +3138,7 @@ pub fn toggle_pane_frames_plugin_command() { .unwrap() .iter() .find_map(|i| { - if let ScreenInstruction::TogglePaneFrames = i { + if let ScreenInstruction::TogglePaneFrames(..) = i { Some(i.clone()) } else { None @@ -3166,6 +3198,7 @@ pub fn toggle_pane_embed_or_eject_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3240,6 +3273,7 @@ pub fn undo_rename_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3314,6 +3348,7 @@ pub fn close_focus_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3388,6 +3423,7 @@ pub fn toggle_active_tab_sync_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3462,6 +3498,7 @@ pub fn close_focused_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3536,6 +3573,7 @@ pub fn undo_rename_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3610,6 +3648,7 @@ pub fn previous_swap_layout_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3684,6 +3723,7 @@ pub fn next_swap_layout_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3758,6 +3798,7 @@ pub fn go_to_tab_name_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3832,6 +3873,7 @@ pub fn focus_or_create_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3906,6 +3948,7 @@ pub fn go_to_tab() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -3980,6 +4023,7 @@ pub fn start_or_reload_plugin() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4061,6 +4105,7 @@ pub fn quit_zellij_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4142,6 +4187,7 @@ pub fn detach_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4223,6 +4269,7 @@ pub fn open_file_floating_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4308,6 +4355,7 @@ pub fn open_file_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4394,6 +4442,7 @@ pub fn open_file_with_line_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4479,6 +4528,7 @@ pub fn open_file_with_line_floating_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4564,6 +4614,7 @@ pub fn open_terminal_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4645,6 +4696,7 @@ pub fn open_terminal_floating_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4726,6 +4778,7 @@ pub fn open_command_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4807,6 +4860,7 @@ pub fn open_command_pane_floating_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4881,6 +4935,7 @@ pub fn switch_to_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -4955,6 +5010,7 @@ pub fn hide_self_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5028,6 +5084,7 @@ pub fn show_self_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5102,6 +5159,7 @@ pub fn close_terminal_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5176,6 +5234,7 @@ pub fn close_plugin_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5250,6 +5309,7 @@ pub fn focus_terminal_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5324,6 +5384,7 @@ pub fn focus_plugin_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5398,6 +5459,7 @@ pub fn rename_terminal_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5472,6 +5534,7 @@ pub fn rename_plugin_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5546,6 +5609,7 @@ pub fn rename_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5629,6 +5693,7 @@ pub fn send_configuration_to_plugins() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5700,6 +5765,7 @@ pub fn request_plugin_permissions() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5795,6 +5861,7 @@ pub fn granted_permission_request_result() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5889,6 +5956,7 @@ pub fn denied_permission_request_result() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -5963,6 +6031,7 @@ pub fn run_command_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -6044,6 +6113,7 @@ pub fn run_command_with_env_vars_and_cwd_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -6125,6 +6195,7 @@ pub fn web_request_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -6199,6 +6270,7 @@ pub fn unblock_input_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6284,6 +6356,7 @@ pub fn block_input_plugin_command() { false, None, None, + None, )); // extra long time because we only start the fs watcher on plugin load std::thread::sleep(std::time::Duration::from_millis(5000)); @@ -6377,6 +6450,7 @@ pub fn pipe_output_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6463,6 +6537,7 @@ pub fn pipe_message_to_plugin_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::CliPipe { @@ -6560,6 +6635,7 @@ pub fn switch_session_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6644,6 +6720,7 @@ pub fn switch_session_with_layout_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6728,6 +6805,7 @@ pub fn switch_session_with_layout_and_cwd_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6812,6 +6890,7 @@ pub fn disconnect_other_clients_plugins_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6896,6 +6975,7 @@ pub fn reconfigure_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -6984,6 +7064,7 @@ pub fn run_plugin_in_specific_cwd() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -7061,6 +7142,7 @@ pub fn hide_pane_with_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7135,6 +7217,7 @@ pub fn show_pane_with_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7216,6 +7299,7 @@ pub fn open_command_pane_background_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7294,6 +7378,7 @@ pub fn rerun_command_pane_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7368,6 +7453,7 @@ pub fn resize_pane_with_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7442,6 +7528,7 @@ pub fn edit_scrollback_for_pane_with_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7516,6 +7603,7 @@ pub fn write_to_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7590,6 +7678,7 @@ pub fn write_chars_to_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7664,6 +7753,7 @@ pub fn move_pane_with_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7738,6 +7828,7 @@ pub fn move_pane_with_pane_id_in_direction_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7812,6 +7903,7 @@ pub fn clear_screen_for_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7886,6 +7978,7 @@ pub fn scroll_up_in_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -7960,6 +8053,7 @@ pub fn scroll_down_in_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8034,6 +8128,7 @@ pub fn scroll_to_top_in_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8108,6 +8203,7 @@ pub fn scroll_to_bottom_in_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8182,6 +8278,7 @@ pub fn page_scroll_up_in_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8256,6 +8353,7 @@ pub fn page_scroll_down_in_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8330,6 +8428,7 @@ pub fn toggle_pane_id_fullscreen_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8404,6 +8503,7 @@ pub fn toggle_pane_embed_or_eject_for_pane_id_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8478,6 +8578,7 @@ pub fn close_tab_with_index_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8552,6 +8653,7 @@ pub fn break_panes_to_new_tab_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8626,6 +8728,7 @@ pub fn break_panes_to_tab_with_index_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8700,6 +8803,7 @@ pub fn reload_plugin_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8774,6 +8878,7 @@ pub fn load_new_plugin_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -8855,6 +8960,7 @@ pub fn rebind_keys_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); @@ -8932,6 +9038,7 @@ pub fn list_clients_plugin_command() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(500)); let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( @@ -9006,6 +9113,7 @@ pub fn before_close_plugin_event() { false, None, None, + None, )); std::thread::sleep(std::time::Duration::from_millis(5000)); // here we send an unload to plugin id 0 (the first plugin id, presumably this plugin) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__clear_screen_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__clear_screen_plugin_command.snap index 07eaf0e5..975e20a3 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__clear_screen_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__clear_screen_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1387 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ClearScreen( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focus_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focus_plugin_command.snap index 78bf48eb..133b23ff 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focus_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focus_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2010 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( CloseFocusedPane( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focused_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focused_tab_plugin_command.snap index 3904a121..cdaa2362 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focused_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_focused_tab_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2118 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( CloseTab( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap index 269986f1..cbf3c8c2 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_plugin_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3789 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -9,5 +8,12 @@ Some( 1, ), None, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap index 778d07b9..1041e20f 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__close_terminal_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3729 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -9,5 +8,12 @@ Some( 1, ), None, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__detach_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__detach_plugin_command.snap index 779f8cd7..ea71beac 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__detach_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__detach_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2685 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -8,5 +7,11 @@ Some( [ 1, ], + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_for_pane_with_id_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_for_pane_with_id_plugin_command.snap index 47285b57..7c22e80f 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_for_pane_with_id_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_for_pane_with_id_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 7127 expression: "format!(\"{:#?}\", rerun_command_pane_event)" --- Some( @@ -8,5 +7,6 @@ Some( Terminal( 2, ), + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_plugin_command.snap index dca337fa..cc572e0c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__edit_scrollback_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1063 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( EditScrollback( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_next_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_next_pane_plugin_command.snap index 22832bb0..f8cf4623 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_next_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_next_pane_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 847 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( FocusNextPane( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_or_create_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_or_create_tab_plugin_command.snap index 16ed8498..305eb5a5 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_or_create_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_or_create_tab_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2388 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -15,5 +14,11 @@ Some( Some( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap index d830391e..6b98856a 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_plugin_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3909 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -10,5 +9,11 @@ Some( ), false, 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_previous_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_previous_pane_plugin_command.snap index 4b2712e5..0b37d318 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_previous_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_previous_pane_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 901 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( FocusPreviousPane( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_terminal_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_terminal_pane_plugin_command.snap index 38685b01..345f0479 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_terminal_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__focus_terminal_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3849 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -10,5 +9,11 @@ Some( ), false, 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_next_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_next_tab_plugin_command.snap index cb87f071..ca2edc5f 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_next_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_next_tab_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 632 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( SwitchTabNext( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_previous_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_previous_tab_plugin_command.snap index a6fd094e..1451fa50 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_previous_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_previous_tab_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 687 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( SwitchTabPrev( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab.snap index 8e2a7570..13bbdb4a 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3306 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -9,5 +8,11 @@ Some( Some( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab_name_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab_name_plugin_command.snap index a66449c6..3fd2e40f 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab_name_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__go_to_tab_name_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2709 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -15,5 +14,11 @@ Some( Some( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_or_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_or_tab_plugin_command.snap index a04c4a72..c3b1d5f2 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_or_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_or_tab_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1009 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( MoveFocusLeftOrPreviousTab( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_plugin_command.snap index 10182cac..72b7dc15 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_focus_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 955 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( MoveFocusLeft( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_plugin_command.snap index 97488981..b9306571 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1279 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( MovePane( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_with_direction_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_with_direction_plugin_command.snap index 48be5c2a..9da82855 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_with_direction_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__move_pane_with_direction_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1333 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( MovePaneLeft( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tab_plugin_command.snap index ccff2ac2..1213308e 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tab_plugin_command.snap @@ -22,5 +22,11 @@ Some( 1, false, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command-2.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command-2.snap index 56b2221f..bc4faa99 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command-2.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command-2.snap @@ -68,5 +68,11 @@ Some( 1, false, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command.snap index 75a2d011..2ba4de2a 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__new_tabs_with_layout_plugin_command.snap @@ -68,5 +68,11 @@ Some( 1, false, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__next_swap_layout_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__next_swap_layout_plugin_command.snap index e83e1d93..21c4257c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__next_swap_layout_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__next_swap_layout_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2280 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( NextSwapLayout( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_background_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_background_plugin_command.snap index cf0e8b03..37624741 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_background_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_background_plugin_command.snap @@ -34,5 +34,7 @@ Some( ClientId( 1, ), + None, + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap index caff93e5..ac0838cc 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap @@ -34,5 +34,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap index d1a7fb5e..ca751a22 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap @@ -34,5 +34,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_floating_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_floating_plugin_command.snap index 82d7c861..eb598cf0 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_floating_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_floating_plugin_command.snap @@ -32,5 +32,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_plugin_command.snap index 8ff9d6d0..d235c416 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_plugin_command.snap @@ -32,5 +32,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_floating_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_floating_plugin_command.snap index 1909e504..cde191a5 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_floating_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_floating_plugin_command.snap @@ -34,5 +34,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_plugin_command.snap index 88597b2b..89986fd2 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_file_with_line_plugin_command.snap @@ -34,5 +34,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap index f32a0d71..b2f0f9ae 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap @@ -27,5 +27,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap index ec793a8c..5cc2ce7c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap @@ -27,5 +27,12 @@ Some( ClientId( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + false, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_down_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_down_plugin_command.snap index dc06b3d5..d85ffc61 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_down_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_down_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1711 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( PageScrollDown( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_up_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_up_plugin_command.snap index 5f0b7ab3..014ac3d3 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_up_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__page_scroll_up_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1657 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( PageScrollUp( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers.snap index 91417b76..5219678c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 250 expression: "format!(\"{:#?}\", plugin_bytes_event)" --- Some( diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers_persist_state.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers_persist_state.snap index 51693505..b9f4c3f7 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers_persist_state.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__plugin_workers_persist_state.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 319 expression: "format!(\"{:#?}\", plugin_bytes_event)" --- Some( diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__previous_swap_layout_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__previous_swap_layout_plugin_command.snap index 34eff5ad..b35b3b0b 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__previous_swap_layout_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__previous_swap_layout_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2226 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( PreviousSwapLayout( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__quit_zellij_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__quit_zellij_plugin_command.snap index aa600320..d00a7663 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__quit_zellij_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__quit_zellij_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2631 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ClientExit( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_plugin_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_plugin_pane_plugin_command.snap index cda7d3c4..5816c283 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_plugin_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_plugin_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4029 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -30,5 +29,11 @@ Some( 109, 101, ], + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_tab_plugin_command.snap index 21fe9260..9450f7c0 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_tab_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4089 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -20,5 +19,11 @@ Some( 109, 101, ], + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_terminal_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_terminal_pane_plugin_command.snap index 64fdf4a9..f23a792c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_terminal_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rename_terminal_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3969 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -32,5 +31,11 @@ Some( 109, 101, ], + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rerun_command_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rerun_command_pane_plugin_command.snap index 38dbfa3f..0f98c797 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rerun_command_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__rerun_command_pane_plugin_command.snap @@ -1,10 +1,10 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 6951 expression: "format!(\"{:#?}\", rerun_command_pane_event)" --- Some( RerunCommandPane( 1, + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_plugin_command.snap index f260c361..37275f43 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 742 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -11,5 +10,11 @@ Some( direction: None, invert_on_boundaries: true, }, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_with_direction_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_with_direction_plugin_command.snap index 4e5c8ea4..d9fa542d 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_with_direction_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__resize_focused_pane_with_direction_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 793 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -13,5 +12,11 @@ Some( ), invert_on_boundaries: true, }, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_down_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_down_plugin_command.snap index 338f315e..c8605a1c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_down_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_down_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1495 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ScrollDown( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_bottom_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_bottom_plugin_command.snap index 08b41ce3..410902d5 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_bottom_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_bottom_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1603 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ScrollToBottom( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_top_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_top_plugin_command.snap index eb852c7b..9f2effac 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_top_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_to_top_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1549 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ScrollToTop( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_up_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_up_plugin_command.snap index 9700c556..acc0d6a6 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_up_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__scroll_up_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1441 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ScrollUp( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__send_configuration_to_plugins.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__send_configuration_to_plugins.snap index cfc94db2..aa9592c2 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__send_configuration_to_plugins.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__send_configuration_to_plugins.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4225 expression: "format!(\"{:#?}\", go_to_tab_event)" --- Some( @@ -15,5 +14,11 @@ Some( Some( 1, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_pane_with_id_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_pane_with_id_plugin_command.snap index f13aded1..24f6c12f 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_pane_with_id_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_pane_with_id_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 6798 expression: "format!(\"{:#?}\", focus_pane_event)" --- Some( @@ -10,5 +9,6 @@ Some( ), true, 1, + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_self_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_self_plugin_command.snap index b42e5db1..a99b0230 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_self_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_self_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3673 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -10,5 +9,11 @@ Some( ), false, 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap index 4c444a1f..290247c0 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3749 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -18,5 +17,11 @@ Some( }, ), None, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_plugin_command.snap index db02121d..b9528696 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 6236 expression: "format!(\"{:#?}\", switch_session_event)" --- Some( @@ -15,5 +14,6 @@ Some( cwd: None, }, 1, + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_and_cwd_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_and_cwd_plugin_command.snap index 16c19ce5..a29aa181 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_and_cwd_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_and_cwd_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 6398 expression: "format!(\"{:#?}\", switch_session_event)" --- Some( @@ -21,5 +20,6 @@ Some( ), }, 1, + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_plugin_command.snap index 1f2ff843..ba0d9639 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_session_with_layout_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 6317 expression: "format!(\"{:#?}\", switch_session_event)" --- Some( @@ -19,5 +18,6 @@ Some( cwd: None, }, 1, + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_mode_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_mode_plugin_command.snap index 10b3a900..6df0b5df 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_mode_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_mode_plugin_command.snap @@ -326,5 +326,11 @@ Some( web_server_capability: None, }, 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_tab_plugin_command.snap index b785c27e..6cab10ad 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__switch_to_tab_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3252 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -9,5 +8,6 @@ Some( Some( 1, ), + None, ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_active_tab_sync_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_active_tab_sync_plugin_command.snap index 4ff349b3..f8959104 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_active_tab_sync_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_active_tab_sync_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2064 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ToggleActiveSyncTab( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_focus_fullscreen_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_focus_fullscreen_plugin_command.snap index c906b8df..34e96dae 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_focus_fullscreen_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_focus_fullscreen_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1765 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ToggleActiveTerminalFullscreen( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_embed_or_eject_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_embed_or_eject_plugin_command.snap index 1f249d1a..8f375b9c 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_embed_or_eject_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_embed_or_eject_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1902 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( TogglePaneEmbedOrFloating( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_frames_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_frames_plugin_command.snap index 535eff30..e1bded4d 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_frames_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_pane_frames_plugin_command.snap @@ -1,8 +1,14 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1848 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( - TogglePaneFrames, + TogglePaneFrames( + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), + ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_tab_plugin_command.snap index 45f70576..e088770b 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__toggle_tab_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1225 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( ToggleTab( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_pane_plugin_command.snap index 8f8b8c4f..6c500286 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_pane_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1956 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( UndoRenamePane( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_tab_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_tab_plugin_command.snap index c9b3e09f..54566d68 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_tab_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__undo_rename_tab_plugin_command.snap @@ -1,10 +1,15 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2172 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( UndoRenameTab( 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_chars_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_chars_plugin_command.snap index 50edf7ad..8bb05ce1 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_chars_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_chars_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 2047 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -13,5 +12,11 @@ Some( ], false, 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_plugin_command.snap index 1075fffe..8bb05ce1 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__write_plugin_command.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 1976 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -13,5 +12,11 @@ Some( ], false, 1, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index 647e72ec..5dd78d13 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -1,4 +1,5 @@ use super::{PinnedExecutor, PluginId, PluginInstruction}; +use crate::global_async_runtime::get_tokio_runtime; use crate::plugins::pipes::{ apply_pipe_message_to_plugin, pipes_to_block_or_unblock, PendingPipes, PipeStateChange, }; @@ -12,14 +13,12 @@ use async_channel::Sender; use highway::{HighwayHash, PortableHash}; use log::info; use notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap}; -use once_cell::sync::OnceCell; use std::{ collections::{BTreeMap, HashMap, HashSet}, path::PathBuf, str::FromStr, sync::{Arc, Mutex}, }; -use tokio::runtime::Runtime; use url::Url; use wasmi::{Engine, Module}; use zellij_utils::consts::{ZELLIJ_CACHE_DIR, ZELLIJ_SESSION_CACHE_DIR, ZELLIJ_TMP_DIR}; @@ -51,20 +50,6 @@ use zellij_utils::{ pane_size::Size, }; -// Global tokio runtime for async I/O operations (plugin downloads, timers) -static TOKIO_RUNTIME: OnceCell<Runtime> = OnceCell::new(); - -pub fn get_tokio_runtime() -> &'static Runtime { - TOKIO_RUNTIME.get_or_init(|| { - tokio::runtime::Builder::new_multi_thread() - .worker_threads(2) // Small pool for I/O only - .thread_name("tokio-plugin-io") - .enable_all() - .build() - .expect("Failed to create tokio runtime") - }) -} - #[derive(Debug, Clone)] pub enum EventOrPipeMessage { Event(Event), @@ -1133,7 +1118,6 @@ impl WasmBridge { } // Execute directly on pinned thread (no async I/O needed for pipe message processing) plugin_executor.execute_for_plugin(*plugin_id, { - // let senders = senders.clone(); let running_plugin = running_plugin.clone(); let pipe_message = pipe_message.clone(); let plugin_id = *plugin_id; @@ -1780,6 +1764,7 @@ impl WasmBridge { floating_pane_coordinates, Some(should_focus), Some(client_id), + None, ))); vec![(plugin_id, Some(client_id))] }, @@ -1789,6 +1774,7 @@ impl WasmBridge { let _ = self.senders.send_to_server(ServerInstruction::LogError( vec![format!("Failed to log plugin: {e}")], cli_client_id, + None, )); } vec![] @@ -1886,6 +1872,7 @@ fn handle_plugin_loading_failure( let _ = senders.send_to_server(ServerInstruction::LogError( vec![format!("{:?}", error)], client_id, + None, )); } } diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs index 2b4ac7e1..526b4bcb 100644 --- a/zellij-server/src/plugins/zellij_exports.rs +++ b/zellij-server/src/plugins/zellij_exports.rs @@ -1,8 +1,9 @@ use super::PluginInstruction; use crate::background_jobs::BackgroundJob; +use crate::global_async_runtime::get_tokio_runtime; use crate::plugins::plugin_map::PluginEnv; -use crate::plugins::wasm_bridge::{get_tokio_runtime, handle_plugin_crash}; -use crate::pty::{ClientTabIndexOrPaneId, NewPanePlacement, PtyInstruction}; +use crate::plugins::wasm_bridge::handle_plugin_crash; +use crate::pty::{ClientTabIndexOrPaneId, PtyInstruction}; use crate::route::route_action; use crate::ServerInstruction; use interprocess::local_socket::LocalSocketStream; @@ -20,8 +21,8 @@ use std::{ use wasmi::{Caller, Linker}; use zellij_utils::data::{ CommandType, ConnectToSession, FloatingPaneCoordinates, HttpVerb, KeyWithModifier, LayoutInfo, - MessageToPlugin, OriginatingPlugin, PaneScrollbackResponse, PermissionStatus, PermissionType, - PluginPermission, + MessageToPlugin, NewPanePlacement, OriginatingPlugin, PaneScrollbackResponse, PermissionStatus, + PermissionType, PluginPermission, }; use zellij_utils::input::permission::PermissionCache; use zellij_utils::ipc::{ClientToServerMsg, IpcSenderWithContext}; @@ -65,6 +66,7 @@ macro_rules! apply_action { if let Err(e) = route_action( $action, $env.client_id, + None, Some(PaneId::Plugin($env.plugin_id)), $env.senders.clone(), $env.capabilities.clone(), @@ -74,6 +76,7 @@ macro_rules! apply_action { None, $env.keybinds.clone(), $env.default_mode.clone(), + None, ) { log::error!("{}: {:?}", $error_message(), e); } @@ -760,6 +763,8 @@ fn open_file_near_plugin( NewPanePlacement::default(), start_suppressed, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls + false, // set_blocking ); let _ = env.senders.send_to_pty(pty_instr); } @@ -788,6 +793,8 @@ fn open_file_floating_near_plugin( NewPanePlacement::Floating(floating_pane_coordinates), start_suppressed, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls + false, // set_blocking ); let _ = env.senders.send_to_pty(pty_instr); } @@ -814,6 +821,7 @@ fn open_file_in_place_of_plugin( Some(title), close_plugin_after_replace, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls ); let _ = env.senders.send_to_pty(pty_instr); } @@ -858,6 +866,8 @@ fn open_terminal_near_plugin(env: &PluginEnv, cwd: PathBuf) { NewPanePlacement::Tiled(None), false, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls + false, // set_blocking )); } @@ -909,6 +919,8 @@ fn open_terminal_floating_near_plugin( NewPanePlacement::Floating(floating_pane_coordinates), false, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls + false, // set_blocking )); } @@ -956,6 +968,7 @@ fn open_terminal_in_place_of_plugin( name, close_plugin_after_replace, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls )); } @@ -995,6 +1008,7 @@ fn open_command_pane_in_place_of_plugin( name, close_plugin_after_replace, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls )); } @@ -1068,6 +1082,8 @@ fn open_command_pane_near_plugin( NewPanePlacement::Tiled(None), false, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls + false, // set_blocking )); } @@ -1143,6 +1159,8 @@ fn open_command_pane_floating_near_plugin( NewPanePlacement::Floating(floating_pane_coordinates), false, ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)), + None, // no completion signal needed for plugin calls + false, // set_blocking )); } @@ -1219,18 +1237,24 @@ fn open_command_pane_background( NewPanePlacement::default(), start_suppressed, ClientTabIndexOrPaneId::ClientId(env.client_id), + None, // no completion signal needed for plugin calls + false, // set_blocking )); } fn rerun_command_pane(env: &PluginEnv, terminal_pane_id: u32) { let _ = env .senders - .send_to_screen(ScreenInstruction::RerunCommandPane(terminal_pane_id)); + .send_to_screen(ScreenInstruction::RerunCommandPane(terminal_pane_id, None)); } fn switch_tab_to(env: &PluginEnv, tab_idx: u32) { env.senders - .send_to_screen(ScreenInstruction::GoToTab(tab_idx, Some(env.client_id))) + .send_to_screen(ScreenInstruction::GoToTab( + tab_idx, + Some(env.client_id), + None, + )) .with_context(|| { format!( "failed to switch to tab {tab_idx} from plugin {}", @@ -1406,6 +1430,7 @@ fn show_pane_with_id(env: &PluginEnv, pane_id: PaneId, should_float_if_hidden: b pane_id, should_float_if_hidden, env.client_id, + None, )); } @@ -1414,6 +1439,8 @@ fn close_self(env: &PluginEnv) { .send_to_screen(ScreenInstruction::ClosePane( PaneId::Plugin(env.plugin_id), None, + None, + None, )) .with_context(|| format!("failed to close self")) .non_fatal(); @@ -1637,6 +1664,7 @@ fn switch_session( .send_to_server(ServerInstruction::SwitchSession( connect_to_session, client_id, + None, )) .with_context(err_context)?; } @@ -1892,9 +1920,10 @@ fn close_terminal_pane(env: &PluginEnv, terminal_pane_id: u32) { }; apply_action!(action, error_msg, env); env.senders - .send_to_pty(PtyInstruction::ClosePane(PaneId::Terminal( - terminal_pane_id, - ))) + .send_to_pty(PtyInstruction::ClosePane( + PaneId::Terminal(terminal_pane_id), + None, + )) .non_fatal(); } @@ -2033,9 +2062,9 @@ fn set_floating_pane_pinned(env: &PluginEnv, pane_id: PaneId, should_be_pinned: } fn stack_panes(env: &PluginEnv, pane_ids: Vec<PaneId>) { - let _ = env - .senders - .send_to_screen(ScreenInstruction::StackPanes(pane_ids, env.client_id)); + let _ = + env.senders + .send_to_screen(ScreenInstruction::StackPanes(pane_ids, env.client_id, None)); } fn change_floating_panes_coordinates( @@ -2046,6 +2075,7 @@ fn change_floating_panes_coordinates( .senders .send_to_screen(ScreenInstruction::ChangeFloatingPanesCoordinates( pane_ids_and_coordinates, + None, )); } @@ -2125,7 +2155,9 @@ fn resize_pane_with_id(env: &PluginEnv, resize: ResizeStrategy, pane_id: PaneId) fn edit_scrollback_for_pane_with_id(env: &PluginEnv, pane_id: PaneId) { let _ = env .senders - .send_to_screen(ScreenInstruction::EditScrollbackForPaneWithId(pane_id)); + .send_to_screen(ScreenInstruction::EditScrollbackForPaneWithId( + pane_id, None, + )); } fn get_pane_scrollback(env: &PluginEnv, pane_id: PaneId, get_full_scrollback: bool) { @@ -2377,6 +2409,7 @@ fn load_new_plugin( skip_cache, None, None, + None, )); }, Err(e) => { diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index 88bfee7d..39bf4668 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -1,4 +1,5 @@ use crate::background_jobs::BackgroundJob; +use crate::route::NotificationEnd; use crate::terminal_bytes::TerminalBytes; use crate::{ panes::PaneId, @@ -16,7 +17,7 @@ use nix::unistd::Pid; use std::sync::Arc; use std::{collections::HashMap, os::unix::io::RawFd, path::PathBuf}; use zellij_utils::{ - data::{Direction, Event, FloatingPaneCoordinates, OriginatingPlugin}, + data::{Direction, Event, FloatingPaneCoordinates, NewPanePlacement, OriginatingPlugin}, errors::prelude::*, errors::{ContextType, PtyContext}, input::{ @@ -37,83 +38,6 @@ pub enum ClientTabIndexOrPaneId { PaneId(PaneId), } -// TODO: move elsewhere -#[derive(Clone, Debug)] -pub enum NewPanePlacement { - NoPreference, - Tiled(Option<Direction>), - Floating(Option<FloatingPaneCoordinates>), - InPlace { - pane_id_to_replace: Option<PaneId>, - close_replaced_pane: bool, - }, - Stacked(Option<PaneId>), -} - -impl Default for NewPanePlacement { - fn default() -> Self { - NewPanePlacement::NoPreference - } -} - -impl NewPanePlacement { - pub fn with_floating_pane_coordinates( - floating_pane_coordinates: Option<FloatingPaneCoordinates>, - ) -> Self { - NewPanePlacement::Floating(floating_pane_coordinates) - } - pub fn with_should_be_in_place( - self, - should_be_in_place: bool, - close_replaced_pane: bool, - ) -> Self { - if should_be_in_place { - NewPanePlacement::InPlace { - pane_id_to_replace: None, - close_replaced_pane, - } - } else { - self - } - } - pub fn with_pane_id_to_replace( - pane_id_to_replace: Option<PaneId>, - close_replaced_pane: bool, - ) -> Self { - NewPanePlacement::InPlace { - pane_id_to_replace, - close_replaced_pane, - } - } - pub fn should_float(&self) -> Option<bool> { - match self { - NewPanePlacement::Floating(_) => Some(true), - NewPanePlacement::Tiled(_) => Some(false), - _ => None, - } - } - pub fn floating_pane_coordinates(&self) -> Option<FloatingPaneCoordinates> { - match self { - NewPanePlacement::Floating(floating_pane_coordinates) => { - floating_pane_coordinates.clone() - }, - _ => None, - } - } - pub fn should_stack(&self) -> bool { - match self { - NewPanePlacement::Stacked(_) => true, - _ => false, - } - } - pub fn id_of_stack_root(&self) -> Option<PaneId> { - match self { - NewPanePlacement::Stacked(id) => *id, - _ => None, - } - } -} - /// Instructions related to PTYs (pseudoterminals). #[derive(Clone, Debug)] pub enum PtyInstruction { @@ -123,9 +47,16 @@ pub enum PtyInstruction { NewPanePlacement, bool, // start suppressed ClientTabIndexOrPaneId, + Option<NotificationEnd>, // completion signal + bool, // set_blocking ), // bool (if Some) is // should_float, String is an optional pane name - OpenInPlaceEditor(PathBuf, Option<usize>, ClientTabIndexOrPaneId), // Option<usize> is the optional line number + OpenInPlaceEditor( + PathBuf, + Option<usize>, + ClientTabIndexOrPaneId, + Option<NotificationEnd>, + ), // Option<usize> is the optional line number UpdateActivePane(Option<PaneId>, ClientId), GoToTab(TabIndex, ClientId), NewTab( @@ -137,22 +68,25 @@ pub enum PtyInstruction { HashMap<RunPluginOrAlias, Vec<u32>>, // plugin_ids bool, // should change focus to new tab (ClientId, bool), // bool -> is_web_client + Option<NotificationEnd>, // completion signal ), // the String is the tab name - ClosePane(PaneId), + ClosePane(PaneId, Option<NotificationEnd>), CloseTab(Vec<PaneId>), - ReRunCommandInPane(PaneId, RunCommand), + ReRunCommandInPane(PaneId, RunCommand, Option<NotificationEnd>), DropToShellInPane { pane_id: PaneId, shell: Option<PathBuf>, working_dir: Option<PathBuf>, + completion_tx: Option<NotificationEnd>, }, SpawnInPlaceTerminal( Option<TerminalAction>, Option<String>, bool, // close replaced pane ClientTabIndexOrPaneId, + Option<NotificationEnd>, // completion signal ), // String is an optional pane name - DumpLayout(SessionLayoutMetadata, ClientId), + DumpLayout(SessionLayoutMetadata, ClientId, Option<NotificationEnd>), DumpLayoutToPlugin(SessionLayoutMetadata, PluginId), LogLayoutToHd(SessionLayoutMetadata), FillPluginCwd( @@ -168,8 +102,9 @@ pub enum PtyInstruction { Option<PathBuf>, // if Some, will not fill cwd but just forward the message Option<bool>, // should focus plugin Option<FloatingPaneCoordinates>, + Option<NotificationEnd>, ), - ListClientsMetadata(SessionLayoutMetadata, ClientId), + ListClientsMetadata(SessionLayoutMetadata, ClientId, Option<NotificationEnd>), Reconfigure { client_id: ClientId, default_editor: Option<PathBuf>, @@ -187,7 +122,7 @@ impl From<&PtyInstruction> for PtyContext { PtyInstruction::OpenInPlaceEditor(..) => PtyContext::OpenInPlaceEditor, PtyInstruction::UpdateActivePane(..) => PtyContext::UpdateActivePane, PtyInstruction::GoToTab(..) => PtyContext::GoToTab, - PtyInstruction::ClosePane(_) => PtyContext::ClosePane, + PtyInstruction::ClosePane(..) => PtyContext::ClosePane, PtyInstruction::CloseTab(_) => PtyContext::CloseTab, PtyInstruction::NewTab(..) => PtyContext::NewTab, PtyInstruction::ReRunCommandInPane(..) => PtyContext::ReRunCommandInPane, @@ -229,6 +164,8 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { new_pane_placement, start_suppressed, client_or_tab_index, + completion_tx, + set_blocking, ) => { let err_context = || format!("failed to spawn terminal for {:?}", client_or_tab_index); @@ -315,6 +252,8 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { new_pane_placement, start_suppressed, client_or_tab_index, + completion_tx, + set_blocking, )) .with_context(err_context)?; }, @@ -332,6 +271,8 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { new_pane_placement, start_suppressed, client_or_tab_index, + completion_tx, + set_blocking, )) .with_context(err_context)?; if let Some(run_command) = run_command { @@ -357,6 +298,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { name, close_replaced_pane, client_id_tab_index_or_pane_id, + completion_tx, ) => { let err_context = || { format!( @@ -402,6 +344,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { invoked_with, close_replaced_pane, client_id_tab_index_or_pane_id, + completion_tx, )) .with_context(err_context)?; }, @@ -418,6 +361,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { invoked_with, close_replaced_pane, client_id_tab_index_or_pane_id, + completion_tx, )) .with_context(err_context)?; if let Some(run_command) = run_command { @@ -442,6 +386,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { temp_file, line_number, client_tab_index_or_pane_id, + _completion_tx, ) => { let err_context = || format!("failed to open in-place editor for client"); @@ -473,7 +418,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { PtyInstruction::GoToTab(tab_index, client_id) => { pty.bus .senders - .send_to_screen(ScreenInstruction::GoToTab(tab_index, Some(client_id))) + .send_to_screen(ScreenInstruction::GoToTab(tab_index, Some(client_id), None)) .with_context(|| { format!("failed to move client {} to tab {}", client_id, tab_index) })?; @@ -487,6 +432,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { plugin_ids, should_change_focus_to_new_tab, client_id_and_is_web_client, + completion_tx, ) => { let err_context = || "failed to open new tab"; @@ -504,10 +450,11 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { tab_index, should_change_focus_to_new_tab, client_id_and_is_web_client, + completion_tx, ) .with_context(err_context)?; }, - PtyInstruction::ClosePane(id) => { + PtyInstruction::ClosePane(id, _completion_tx) => { pty.close_pane(id) .and_then(|_| { pty.bus @@ -525,7 +472,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { }) .context("failed to close tabs")?; }, - PtyInstruction::ReRunCommandInPane(pane_id, run_command) => { + PtyInstruction::ReRunCommandInPane(pane_id, run_command, _completion_tx) => { let err_context = || format!("failed to rerun command in pane {:?}", pane_id); match pty @@ -566,6 +513,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { pane_id, shell, working_dir, + completion_tx: _completion_tx, } => { let err_context = || format!("failed to rerun command in pane {:?}", pane_id); @@ -613,7 +561,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { }, } }, - PtyInstruction::DumpLayout(mut session_layout_metadata, client_id) => { + PtyInstruction::DumpLayout(mut session_layout_metadata, client_id, completion_tx) => { let err_context = || format!("Failed to dump layout"); pty.populate_session_layout_metadata(&mut session_layout_metadata); match session_serialization::serialize_session_layout( @@ -622,20 +570,32 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { Ok((kdl_layout, _pane_contents)) => { pty.bus .senders - .send_to_server(ServerInstruction::Log(vec![kdl_layout], client_id)) + .send_to_server(ServerInstruction::Log( + vec![kdl_layout], + client_id, + completion_tx, + )) .with_context(err_context) .non_fatal(); }, Err(e) => { pty.bus .senders - .send_to_server(ServerInstruction::Log(vec![e.to_owned()], client_id)) + .send_to_server(ServerInstruction::Log( + vec![e.to_owned()], + client_id, + completion_tx, + )) .with_context(err_context) .non_fatal(); }, } }, - PtyInstruction::ListClientsMetadata(mut session_layout_metadata, client_id) => { + PtyInstruction::ListClientsMetadata( + mut session_layout_metadata, + client_id, + completion_tx, + ) => { let err_context = || format!("Failed to dump layout"); pty.populate_session_layout_metadata(&mut session_layout_metadata); pty.bus @@ -643,9 +603,10 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { .send_to_server(ServerInstruction::Log( vec![format!( "{}", - session_layout_metadata.list_clients_metadata() + session_layout_metadata.list_clients_metadata(), )], client_id, + completion_tx, )) .with_context(err_context) .non_fatal(); @@ -716,6 +677,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { cwd, should_focus_plugin, floating_pane_coordinates, + completion_tx, ) => { pty.fill_plugin_cwd( should_float, @@ -730,6 +692,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { cwd, should_focus_plugin, floating_pane_coordinates, + completion_tx, )?; }, PtyInstruction::Reconfigure { @@ -934,7 +897,12 @@ impl Pty { command, )); } else { - let _ = senders.send_to_screen(ScreenInstruction::ClosePane(pane_id, None)); + let _ = senders.send_to_screen(ScreenInstruction::ClosePane( + pane_id, + None, + None, + exit_status, + )); } } }); @@ -983,6 +951,7 @@ impl Pty { tab_index: usize, should_change_focus_to_new_tab: bool, client_id_and_is_web_client: (ClientId, bool), + completion_tx: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to spawn terminals for layout for"); @@ -1049,6 +1018,7 @@ impl Pty { tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + completion_tx, )) .with_context(err_context)?; let mut terminals_to_start = vec![]; @@ -1121,8 +1091,13 @@ impl Pty { let err_context = || format!("failed to apply run instruction"); let quit_cb = Box::new({ let senders = self.bus.senders.clone(); - move |pane_id, _exit_status, _command| { - let _ = senders.send_to_screen(ScreenInstruction::ClosePane(pane_id, None)); + move |pane_id, exit_status, _command| { + let _ = senders.send_to_screen(ScreenInstruction::ClosePane( + pane_id, + None, + None, + exit_status, + )); } }); match run_instruction { @@ -1139,8 +1114,12 @@ impl Pty { command, )); } else { - let _ = - senders.send_to_screen(ScreenInstruction::ClosePane(pane_id, None)); + let _ = senders.send_to_screen(ScreenInstruction::ClosePane( + pane_id, + None, + None, + exit_status, + )); } } }); @@ -1369,8 +1348,12 @@ impl Pty { command, )); } else { - let _ = - senders.send_to_screen(ScreenInstruction::ClosePane(pane_id, None)); + let _ = senders.send_to_screen(ScreenInstruction::ClosePane( + pane_id, + None, + None, + exit_status, + )); } } }); @@ -1486,6 +1469,7 @@ impl Pty { cwd: Option<PathBuf>, should_focus_plugin: Option<bool>, floating_pane_coordinates: Option<FloatingPaneCoordinates>, + completion_tx: Option<NotificationEnd>, ) -> Result<()> { let get_focused_cwd = || { self.active_panes @@ -1528,6 +1512,7 @@ impl Pty { skip_cache, should_focus_plugin, floating_pane_coordinates, + completion_tx, ))?; Ok(()) } diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index a336e3d9..7d11ba65 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -1,12 +1,14 @@ use std::collections::{BTreeMap, HashSet, VecDeque}; use std::sync::{Arc, RwLock}; +use tokio::sync::oneshot; +use crate::global_async_runtime::get_tokio_runtime; use crate::thread_bus::ThreadSenders; use crate::{ os_input_output::ServerOsApi, panes::PaneId, plugins::PluginInstruction, - pty::{ClientTabIndexOrPaneId, NewPanePlacement, PtyInstruction}, + pty::{ClientTabIndexOrPaneId, PtyInstruction}, screen::ScreenInstruction, ServerInstruction, SessionMetaData, SessionState, }; @@ -15,7 +17,11 @@ use std::time::Duration; use uuid::Uuid; use zellij_utils::{ channels::SenderWithContext, - data::{BareKey, Direction, Event, InputMode, KeyModifier, PluginCapabilities, ResizeStrategy}, + data::{ + BareKey, ConnectToSession, Direction, Event, InputMode, KeyModifier, NewPanePlacement, + PluginCapabilities, ResizeStrategy, + }, + envs, errors::prelude::*, input::{ actions::{Action, SearchDirection, SearchOption}, @@ -31,9 +37,90 @@ use zellij_utils::{ use crate::ClientId; +const ACTION_COMPLETION_TIMEOUT: Duration = Duration::from_secs(1); + +fn wait_for_action_completion( + receiver: oneshot::Receiver<Option<i32>>, // currently i32 signals an exit status, can be expanded as + // needed + action_name: &str, + wait_forever: bool, +) -> Option<i32> { + let runtime = get_tokio_runtime(); + if wait_forever { + runtime.block_on(async { + match receiver.await { + Ok(Some(payload)) => Some(payload), + Ok(None) => None, + Err(e) => { + log::error!("Failed to wait for action {}: {}", action_name, e); + None + }, + } + }) + } else { + match runtime + .block_on(async { tokio::time::timeout(ACTION_COMPLETION_TIMEOUT, receiver).await }) + { + Ok(Ok(Some(payload))) => Some(payload), + Ok(Ok(None)) => None, + Err(_) | Ok(Err(_)) => { + log::error!( + "Action {} did not complete within {:?} timeout", + action_name, + ACTION_COMPLETION_TIMEOUT + ); + None + }, + } + } +} + +// This is used to wait for actions that span multiple threads until they logically end +// dropping this struct sends a notification through the oneshot channel to the receiver, letting +// it know the action is ended and thus releasing it +// +// Note: Cloning this struct DOES NOT clone that internal receiver, it only implements Clone so +// that it can be included in various other larger structs - DO NOT RELY ON CLONING IT! +#[derive(Debug)] +pub struct NotificationEnd { + channel: Option<oneshot::Sender<Option<i32>>>, + exit_status: Option<i32>, +} + +impl Clone for NotificationEnd { + fn clone(&self) -> Self { + // Always clone as None - only the original holder should signal completion + NotificationEnd { + channel: None, + exit_status: self.exit_status, + } + } +} + +impl NotificationEnd { + pub fn new(sender: oneshot::Sender<Option<i32>>) -> Self { + NotificationEnd { + channel: Some(sender), + exit_status: None, + } + } + pub fn set_exit_status(&mut self, exit_status: i32) { + self.exit_status = Some(exit_status); + } +} + +impl Drop for NotificationEnd { + fn drop(&mut self) { + if let Some(tx) = self.channel.take() { + let _ = tx.send(self.exit_status); + } + } +} + pub(crate) fn route_action( action: Action, client_id: ClientId, + cli_client_id: Option<ClientId>, pane_id: Option<PaneId>, senders: ThreadSenders, capabilities: PluginCapabilities, @@ -43,9 +130,11 @@ pub(crate) fn route_action( mut seen_cli_pipes: Option<&mut HashSet<String>>, client_keybinds: Keybinds, default_mode: InputMode, + os_input: Option<Box<dyn ServerOsApi>>, ) -> Result<bool> { let mut should_break = false; let err_context = || format!("failed to route action for client {client_id}"); + let action_name = action.to_string(); if !action.is_mouse_action() { // mouse actions should only send InputReceived to plugins @@ -59,10 +148,22 @@ pub(crate) fn route_action( .with_context(err_context)?; } + // we use this oneshot channel to wait for an action to be "logically" + // done, meaning that it traveled through all the threads it needed to travel through and the + // app has confirmed that it is complete. Once this happens, we get a signal through the + // wait_for_action_completion call below (or timeout after 1 second) and release this thread, + // allowing the client to produce another action without risking races + let (completion_tx, completion_rx) = oneshot::channel(); + + let mut wait_forever = false; + match action { Action::ToggleTab => { senders - .send_to_screen(ScreenInstruction::ToggleTab(client_id)) + .send_to_screen(ScreenInstruction::ToggleTab( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::Write { @@ -79,6 +180,7 @@ pub(crate) fn route_action( raw_bytes, is_kitty_keyboard_protocol, client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -89,7 +191,11 @@ pub(crate) fn route_action( let chars = chars.into_bytes(); senders .send_to_screen(ScreenInstruction::WriteCharacter( - None, chars, false, client_id, + None, + chars, + false, + client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -108,6 +214,7 @@ pub(crate) fn route_action( Some(default_mode), ), client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; senders @@ -115,56 +222,84 @@ pub(crate) fn route_action( .with_context(err_context)?; }, Action::Resize { resize, direction } => { - let screen_instr = - ScreenInstruction::Resize(client_id, ResizeStrategy::new(resize, direction)); + let screen_instr = ScreenInstruction::Resize( + client_id, + ResizeStrategy::new(resize, direction), + Some(NotificationEnd::new(completion_tx)), + ); senders .send_to_screen(screen_instr) .with_context(err_context)?; }, Action::SwitchFocus => { senders - .send_to_screen(ScreenInstruction::SwitchFocus(client_id)) + .send_to_screen(ScreenInstruction::SwitchFocus( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::FocusNextPane => { senders - .send_to_screen(ScreenInstruction::FocusNextPane(client_id)) + .send_to_screen(ScreenInstruction::FocusNextPane( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::FocusPreviousPane => { senders - .send_to_screen(ScreenInstruction::FocusPreviousPane(client_id)) + .send_to_screen(ScreenInstruction::FocusPreviousPane( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::MoveFocus { direction } => { + let notification_end = Some(NotificationEnd::new(completion_tx)); + let screen_instr = match direction { - Direction::Left => ScreenInstruction::MoveFocusLeft(client_id), - Direction::Right => ScreenInstruction::MoveFocusRight(client_id), - Direction::Up => ScreenInstruction::MoveFocusUp(client_id), - Direction::Down => ScreenInstruction::MoveFocusDown(client_id), + Direction::Left => ScreenInstruction::MoveFocusLeft(client_id, notification_end), + Direction::Right => ScreenInstruction::MoveFocusRight(client_id, notification_end), + Direction::Up => ScreenInstruction::MoveFocusUp(client_id, notification_end), + Direction::Down => ScreenInstruction::MoveFocusDown(client_id, notification_end), }; senders .send_to_screen(screen_instr) .with_context(err_context)?; }, Action::MoveFocusOrTab { direction } => { + let notification_end = Some(NotificationEnd::new(completion_tx)); + let screen_instr = match direction { - Direction::Left => ScreenInstruction::MoveFocusLeftOrPreviousTab(client_id), - Direction::Right => ScreenInstruction::MoveFocusRightOrNextTab(client_id), - Direction::Up => ScreenInstruction::SwitchTabNext(client_id), - Direction::Down => ScreenInstruction::SwitchTabPrev(client_id), + Direction::Left => { + ScreenInstruction::MoveFocusLeftOrPreviousTab(client_id, notification_end) + }, + Direction::Right => { + ScreenInstruction::MoveFocusRightOrNextTab(client_id, notification_end) + }, + Direction::Up => ScreenInstruction::SwitchTabNext(client_id, notification_end), + Direction::Down => ScreenInstruction::SwitchTabPrev(client_id, notification_end), }; senders .send_to_screen(screen_instr) .with_context(err_context)?; }, Action::MovePane { direction } => { + let notification_end = Some(NotificationEnd::new(completion_tx)); + let screen_instr = match direction { - Some(Direction::Left) => ScreenInstruction::MovePaneLeft(client_id), - Some(Direction::Right) => ScreenInstruction::MovePaneRight(client_id), - Some(Direction::Up) => ScreenInstruction::MovePaneUp(client_id), - Some(Direction::Down) => ScreenInstruction::MovePaneDown(client_id), - None => ScreenInstruction::MovePane(client_id), + Some(Direction::Left) => { + ScreenInstruction::MovePaneLeft(client_id, notification_end) + }, + Some(Direction::Right) => { + ScreenInstruction::MovePaneRight(client_id, notification_end) + }, + Some(Direction::Up) => ScreenInstruction::MovePaneUp(client_id, notification_end), + Some(Direction::Down) => { + ScreenInstruction::MovePaneDown(client_id, notification_end) + }, + None => ScreenInstruction::MovePane(client_id, notification_end), }; senders .send_to_screen(screen_instr) @@ -172,12 +307,18 @@ pub(crate) fn route_action( }, Action::MovePaneBackwards => { senders - .send_to_screen(ScreenInstruction::MovePaneBackwards(client_id)) + .send_to_screen(ScreenInstruction::MovePaneBackwards( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ClearScreen => { senders - .send_to_screen(ScreenInstruction::ClearScreen(client_id)) + .send_to_screen(ScreenInstruction::ClearScreen( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::DumpScreen { @@ -189,6 +330,7 @@ pub(crate) fn route_action( file_path, client_id, include_scrollback, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -198,72 +340,118 @@ pub(crate) fn route_action( _ => None, }; senders - .send_to_screen(ScreenInstruction::DumpLayout(default_shell, client_id)) + .send_to_screen(ScreenInstruction::DumpLayout( + default_shell, + cli_client_id.unwrap_or(client_id), // we prefer the cli client here because + // this is a cli query and we want to print + // it there + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::EditScrollback => { senders - .send_to_screen(ScreenInstruction::EditScrollback(client_id)) + .send_to_screen(ScreenInstruction::EditScrollback( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ScrollUp => { senders - .send_to_screen(ScreenInstruction::ScrollUp(client_id)) + .send_to_screen(ScreenInstruction::ScrollUp( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ScrollUpAt { position } => { senders - .send_to_screen(ScreenInstruction::ScrollUpAt(position, client_id)) + .send_to_screen(ScreenInstruction::ScrollUpAt( + position, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ScrollDown => { senders - .send_to_screen(ScreenInstruction::ScrollDown(client_id)) + .send_to_screen(ScreenInstruction::ScrollDown( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ScrollDownAt { position } => { senders - .send_to_screen(ScreenInstruction::ScrollDownAt(position, client_id)) + .send_to_screen(ScreenInstruction::ScrollDownAt( + position, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ScrollToBottom => { senders - .send_to_screen(ScreenInstruction::ScrollToBottom(client_id)) + .send_to_screen(ScreenInstruction::ScrollToBottom( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ScrollToTop => { senders - .send_to_screen(ScreenInstruction::ScrollToTop(client_id)) + .send_to_screen(ScreenInstruction::ScrollToTop( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::PageScrollUp => { senders - .send_to_screen(ScreenInstruction::PageScrollUp(client_id)) + .send_to_screen(ScreenInstruction::PageScrollUp( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::PageScrollDown => { senders - .send_to_screen(ScreenInstruction::PageScrollDown(client_id)) + .send_to_screen(ScreenInstruction::PageScrollDown( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::HalfPageScrollUp => { senders - .send_to_screen(ScreenInstruction::HalfPageScrollUp(client_id)) + .send_to_screen(ScreenInstruction::HalfPageScrollUp( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::HalfPageScrollDown => { senders - .send_to_screen(ScreenInstruction::HalfPageScrollDown(client_id)) + .send_to_screen(ScreenInstruction::HalfPageScrollDown( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ToggleFocusFullscreen => { senders - .send_to_screen(ScreenInstruction::ToggleActiveTerminalFullscreen(client_id)) + .send_to_screen(ScreenInstruction::ToggleActiveTerminalFullscreen( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::TogglePaneFrames => { senders - .send_to_screen(ScreenInstruction::TogglePaneFrames) + .send_to_screen(ScreenInstruction::TogglePaneFrames(Some( + NotificationEnd::new(completion_tx), + ))) .with_context(err_context)?; }, Action::NewPane { @@ -276,13 +464,39 @@ pub(crate) fn route_action( Some(direction) => NewPanePlacement::Tiled(Some(direction)), None => NewPanePlacement::NoPreference, }; - let _ = senders.send_to_pty(PtyInstruction::SpawnTerminal( - shell, - pane_name, - new_pane_placement, - start_suppressed, - ClientTabIndexOrPaneId::ClientId(client_id), - )); + senders + .send_to_pty(PtyInstruction::SpawnTerminal( + shell, + pane_name, + new_pane_placement, + start_suppressed, + ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking + )) + .with_context(err_context)?; + }, + Action::NewBlockingPane { + placement, + pane_name, + command, + } => { + let command = command + .map(|cmd| TerminalAction::RunCommand(cmd.into())) + .or_else(|| default_shell.clone()); + let set_pane_blocking = true; + senders + .send_to_pty(PtyInstruction::SpawnTerminal( + command, + pane_name, + placement, + false, + ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + set_pane_blocking, + )) + .with_context(err_context)?; + wait_forever = true; }, Action::EditFile { payload: open_file_payload, @@ -301,12 +515,14 @@ pub(crate) fn route_action( Some(title), false, ClientTabIndexOrPaneId::PaneId(pane_id), + Some(NotificationEnd::new(completion_tx)), ), None => PtyInstruction::SpawnInPlaceTerminal( Some(open_file), Some(title), false, ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), ), } } else { @@ -320,6 +536,8 @@ pub(crate) fn route_action( }, start_suppressed, ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking ) }; senders.send_to_pty(pty_instr).with_context(err_context)?; @@ -345,13 +563,16 @@ pub(crate) fn route_action( .with_context(err_context)?; senders - .send_to_screen(ScreenInstruction::ChangeModeForAllClients(get_mode_info( - input_mode, - attrs, - capabilities, - &client_keybinds, - Some(default_mode), - ))) + .send_to_screen(ScreenInstruction::ChangeModeForAllClients( + get_mode_info( + input_mode, + attrs, + capabilities, + &client_keybinds, + Some(default_mode), + ), + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::NewFloatingPane { @@ -369,6 +590,8 @@ pub(crate) fn route_action( NewPanePlacement::Floating(floating_pane_coordinates), false, ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking )) .with_context(err_context)?; }, @@ -387,6 +610,7 @@ pub(crate) fn route_action( name, false, ClientTabIndexOrPaneId::PaneId(pane_id), + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -397,6 +621,7 @@ pub(crate) fn route_action( name, false, ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -415,9 +640,11 @@ pub(crate) fn route_action( .send_to_pty(PtyInstruction::SpawnTerminal( run_cmd, name, - NewPanePlacement::Stacked(Some(pane_id)), + NewPanePlacement::Stacked(Some(pane_id.into())), false, ClientTabIndexOrPaneId::PaneId(pane_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking )) .with_context(err_context)?; }, @@ -429,6 +656,8 @@ pub(crate) fn route_action( NewPanePlacement::Stacked(None), false, ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking )) .with_context(err_context)?; }, @@ -442,17 +671,24 @@ pub(crate) fn route_action( let run_cmd = run_command .map(|cmd| TerminalAction::RunCommand(cmd.into())) .or_else(|| default_shell.clone()); - let _ = senders.send_to_pty(PtyInstruction::SpawnTerminal( - run_cmd, - name, - NewPanePlacement::Tiled(direction), - false, - ClientTabIndexOrPaneId::ClientId(client_id), - )); + senders + .send_to_pty(PtyInstruction::SpawnTerminal( + run_cmd, + name, + NewPanePlacement::Tiled(direction), + false, + ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking + )) + .with_context(err_context)?; }, Action::TogglePaneEmbedOrFloating => { senders - .send_to_screen(ScreenInstruction::TogglePaneEmbedOrFloating(client_id)) + .send_to_screen(ScreenInstruction::TogglePaneEmbedOrFloating( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ToggleFloatingPanes => { @@ -460,32 +696,47 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::ToggleFloatingPanes( client_id, default_shell.clone(), + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, Action::PaneNameInput { input } => { senders - .send_to_screen(ScreenInstruction::UpdatePaneName(input, client_id)) + .send_to_screen(ScreenInstruction::UpdatePaneName( + input, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::UndoRenamePane => { senders - .send_to_screen(ScreenInstruction::UndoRenamePane(client_id)) + .send_to_screen(ScreenInstruction::UndoRenamePane( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::Run { command } => { let run_cmd = Some(TerminalAction::RunCommand(command.clone().into())); - let _ = senders.send_to_pty(PtyInstruction::SpawnTerminal( - run_cmd, - None, - NewPanePlacement::Tiled(command.direction), - false, - ClientTabIndexOrPaneId::ClientId(client_id), - )); + senders + .send_to_pty(PtyInstruction::SpawnTerminal( + run_cmd, + None, + NewPanePlacement::Tiled(command.direction), + false, + ClientTabIndexOrPaneId::ClientId(client_id), + Some(NotificationEnd::new(completion_tx)), + false, // set_blocking + )) + .with_context(err_context)?; }, Action::CloseFocus => { senders - .send_to_screen(ScreenInstruction::CloseFocusedPane(client_id)) + .send_to_screen(ScreenInstruction::CloseFocusedPane( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::NewTab { @@ -503,6 +754,7 @@ pub(crate) fn route_action( let swap_floating_layouts = swap_floating_layouts .unwrap_or_else(|| default_layout.swap_floating_layouts.clone()); let is_web_client = false; // actions cannot be initiated directly from the web + senders .send_to_screen(ScreenInstruction::NewTab( cwd, @@ -513,32 +765,49 @@ pub(crate) fn route_action( (swap_tiled_layouts, swap_floating_layouts), should_change_focus_to_new_tab, (client_id, is_web_client), + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, Action::GoToNextTab => { senders - .send_to_screen(ScreenInstruction::SwitchTabNext(client_id)) + .send_to_screen(ScreenInstruction::SwitchTabNext( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::GoToPreviousTab => { senders - .send_to_screen(ScreenInstruction::SwitchTabPrev(client_id)) + .send_to_screen(ScreenInstruction::SwitchTabPrev( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ToggleActiveSyncTab => { senders - .send_to_screen(ScreenInstruction::ToggleActiveSyncTab(client_id)) + .send_to_screen(ScreenInstruction::ToggleActiveSyncTab( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::CloseTab => { senders - .send_to_screen(ScreenInstruction::CloseTab(client_id)) + .send_to_screen(ScreenInstruction::CloseTab( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::GoToTab { index } => { senders - .send_to_screen(ScreenInstruction::GoToTab(index, Some(client_id))) + .send_to_screen(ScreenInstruction::GoToTab( + index, + Some(client_id), + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::GoToTabName { name, create } => { @@ -552,24 +821,37 @@ pub(crate) fn route_action( shell, create, Some(client_id), + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, Action::TabNameInput { input } => { senders - .send_to_screen(ScreenInstruction::UpdateTabName(input, client_id)) + .send_to_screen(ScreenInstruction::UpdateTabName( + input, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::UndoRenameTab => { senders - .send_to_screen(ScreenInstruction::UndoRenameTab(client_id)) + .send_to_screen(ScreenInstruction::UndoRenameTab( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::MoveTab { direction } => { let screen_instr = match direction { - Direction::Left => ScreenInstruction::MoveTabLeft(client_id), - Direction::Right => ScreenInstruction::MoveTabRight(client_id), - _ => return Ok(false), + Direction::Left | Direction::Up => ScreenInstruction::MoveTabLeft( + client_id, + Some(NotificationEnd::new(completion_tx)), + ), + Direction::Right | Direction::Down => ScreenInstruction::MoveTabRight( + client_id, + Some(NotificationEnd::new(completion_tx)), + ), }; senders .send_to_screen(screen_instr) @@ -577,68 +859,130 @@ pub(crate) fn route_action( }, Action::Quit => { senders - .send_to_server(ServerInstruction::ClientExit(client_id)) + .send_to_server(ServerInstruction::ClientExit( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; should_break = true; }, Action::Detach => { senders - .send_to_server(ServerInstruction::DetachSession(vec![client_id])) + .send_to_server(ServerInstruction::DetachSession( + vec![client_id], + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; should_break = true; }, + Action::SwitchSession { + name, + tab_position, + pane_id, + layout, + cwd, + } => { + let current_session_name = envs::get_session_name().unwrap_or_else(|_| String::new()); + if name != current_session_name { + let connect_to_session = ConnectToSession { + name: Some(name.clone()), + tab_position: tab_position.clone(), + pane_id: pane_id.clone(), + layout: layout.clone(), + cwd: cwd.clone(), + }; + senders + .send_to_server(ServerInstruction::SwitchSession( + connect_to_session, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) + .with_context(err_context)?; + should_break = true; + } else { + drop(completion_tx); // no need to wait, this is a no-op + } + }, Action::MouseEvent { event } => { senders - .send_to_screen(ScreenInstruction::MouseEvent(event, client_id)) + .send_to_screen(ScreenInstruction::MouseEvent( + event, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::Copy => { senders - .send_to_screen(ScreenInstruction::Copy(client_id)) + .send_to_screen(ScreenInstruction::Copy( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::Confirm => { senders - .send_to_screen(ScreenInstruction::ConfirmPrompt(client_id)) + .send_to_screen(ScreenInstruction::ConfirmPrompt( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::Deny => { senders - .send_to_screen(ScreenInstruction::DenyPrompt(client_id)) + .send_to_screen(ScreenInstruction::DenyPrompt( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, #[allow(clippy::single_match)] Action::SkipConfirm { action } => match *action { Action::Quit => { + drop(completion_tx); senders - .send_to_server(ServerInstruction::ClientExit(client_id)) + .send_to_server(ServerInstruction::ClientExit(client_id, None)) .with_context(err_context)?; should_break = true; }, _ => {}, }, - Action::NoOp => {}, + Action::NoOp => { + drop(completion_tx); + }, Action::SearchInput { input } => { senders - .send_to_screen(ScreenInstruction::UpdateSearch(input, client_id)) + .send_to_screen(ScreenInstruction::UpdateSearch( + input, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::Search { direction } => { + let notification_end = Some(NotificationEnd::new(completion_tx)); + let instruction = match direction { - SearchDirection::Down => ScreenInstruction::SearchDown(client_id), - SearchDirection::Up => ScreenInstruction::SearchUp(client_id), + SearchDirection::Down => ScreenInstruction::SearchDown(client_id, notification_end), + SearchDirection::Up => ScreenInstruction::SearchUp(client_id, notification_end), }; senders .send_to_screen(instruction) .with_context(err_context)?; }, Action::SearchToggleOption { option } => { + let notification_end = Some(NotificationEnd::new(completion_tx)); + let instruction = match option { SearchOption::CaseSensitivity => { - ScreenInstruction::SearchToggleCaseSensitivity(client_id) + ScreenInstruction::SearchToggleCaseSensitivity(client_id, notification_end) + }, + SearchOption::WholeWord => { + ScreenInstruction::SearchToggleWholeWord(client_id, notification_end) + }, + SearchOption::Wrap => { + ScreenInstruction::SearchToggleWrap(client_id, notification_end) }, - SearchOption::WholeWord => ScreenInstruction::SearchToggleWholeWord(client_id), - SearchOption::Wrap => ScreenInstruction::SearchToggleWrap(client_id), }; senders .send_to_screen(instruction) @@ -647,17 +991,26 @@ pub(crate) fn route_action( Action::ToggleMouseMode => {}, // Handled client side Action::PreviousSwapLayout => { senders - .send_to_screen(ScreenInstruction::PreviousSwapLayout(client_id)) + .send_to_screen(ScreenInstruction::PreviousSwapLayout( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::NextSwapLayout => { senders - .send_to_screen(ScreenInstruction::NextSwapLayout(client_id)) + .send_to_screen(ScreenInstruction::NextSwapLayout( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::QueryTabNames => { senders - .send_to_screen(ScreenInstruction::QueryTabNames(client_id)) + .send_to_screen(ScreenInstruction::QueryTabNames( + cli_client_id.unwrap_or(client_id), + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::NewTiledPluginPane { @@ -668,7 +1021,12 @@ pub(crate) fn route_action( } => { senders .send_to_screen(ScreenInstruction::NewTiledPluginPane( - run_plugin, name, skip_cache, cwd, client_id, + run_plugin, + name, + skip_cache, + cwd, + client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -687,6 +1045,7 @@ pub(crate) fn route_action( cwd, floating_pane_coordinates, client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -698,7 +1057,12 @@ pub(crate) fn route_action( if let Some(pane_id) = pane_id { senders .send_to_screen(ScreenInstruction::NewInPlacePluginPane( - run_plugin, name, pane_id, skip_cache, client_id, + run_plugin, + name, + pane_id, + skip_cache, + client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; } else { @@ -707,7 +1071,11 @@ pub(crate) fn route_action( }, Action::StartOrReloadPlugin { plugin: run_plugin } => { senders - .send_to_screen(ScreenInstruction::StartOrReloadPluginPane(run_plugin, None)) + .send_to_screen(ScreenInstruction::StartOrReloadPluginPane( + run_plugin, + None, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::LaunchOrFocusPlugin { @@ -726,6 +1094,7 @@ pub(crate) fn route_action( pane_id, skip_cache, client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -745,6 +1114,7 @@ pub(crate) fn route_action( skip_cache, cwd, client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -755,7 +1125,9 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::ClosePane( PaneId::Terminal(terminal_pane_id), None, // we send None here so that the terminal pane would be closed anywhere - // in the app, not just in the client's tab + // in the app, not just in the client's tab + Some(NotificationEnd::new(completion_tx)), + None, )) .with_context(err_context)?; }, @@ -766,7 +1138,9 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::ClosePane( PaneId::Plugin(plugin_pane_id), None, // we send None here so that the terminal pane would be closed anywhere - // in the app, not just in the client's tab + // in the app, not just in the client's tab + Some(NotificationEnd::new(completion_tx)), + None, )) .with_context(err_context)?; }, @@ -779,6 +1153,7 @@ pub(crate) fn route_action( PaneId::Terminal(pane_id), should_float_if_hidden, client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -791,6 +1166,7 @@ pub(crate) fn route_action( PaneId::Plugin(pane_id), should_float_if_hidden, client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -802,6 +1178,7 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::RenamePane( PaneId::Terminal(pane_id), name_bytes, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -813,6 +1190,7 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::RenamePane( PaneId::Plugin(pane_id), name_bytes, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -824,6 +1202,7 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::RenameTab( tab_position as usize, name_bytes, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -833,22 +1212,33 @@ pub(crate) fn route_action( default_layout.clone(), default_shell.clone(), client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, Action::BreakPaneRight => { senders - .send_to_screen(ScreenInstruction::BreakPaneRight(client_id)) + .send_to_screen(ScreenInstruction::BreakPaneRight( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::BreakPaneLeft => { senders - .send_to_screen(ScreenInstruction::BreakPaneLeft(client_id)) + .send_to_screen(ScreenInstruction::BreakPaneLeft( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::RenameSession { name } => { senders - .send_to_screen(ScreenInstruction::RenameSession(name, client_id)) + .send_to_screen(ScreenInstruction::RenameSession( + name, + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::CliPipe { @@ -865,13 +1255,15 @@ pub(crate) fn route_action( pane_title, .. } => { + drop(completion_tx); // releasing pipes is handled by the plugins, so we don't want + // this to block additionallu if let Some(seen_cli_pipes) = seen_cli_pipes.as_mut() { if !seen_cli_pipes.contains(&pipe_id) { seen_cli_pipes.insert(pipe_id.clone()); senders .send_to_server(ServerInstruction::AssociatePipeWithClient { pipe_id: pipe_id.clone(), - client_id, + client_id: cli_client_id.unwrap_or(client_id), }) .with_context(err_context)?; } @@ -895,7 +1287,7 @@ pub(crate) fn route_action( cwd, pane_title, skip_cache, - cli_client_id: client_id, + cli_client_id: cli_client_id.unwrap_or(client_id), }) .with_context(err_context)?; } else { @@ -954,13 +1346,19 @@ pub(crate) fn route_action( senders .send_to_screen(ScreenInstruction::ListClientsMetadata( default_shell, - client_id, + cli_client_id.unwrap_or(client_id), // we prefer the cli client here because + // this is a cli query and we want to print + // it there + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, Action::TogglePanePinned => { senders - .send_to_screen(ScreenInstruction::TogglePanePinned(client_id)) + .send_to_screen(ScreenInstruction::TogglePanePinned( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::StackPanes { @@ -970,6 +1368,7 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::StackPanes( pane_ids_to_stack.iter().map(|p| PaneId::from(*p)).collect(), client_id, + Some(NotificationEnd::new(completion_tx)), )) .with_context(err_context)?; }, @@ -978,23 +1377,42 @@ pub(crate) fn route_action( coordinates, } => { senders - .send_to_screen(ScreenInstruction::ChangeFloatingPanesCoordinates(vec![( - pane_id.into(), - coordinates, - )])) + .send_to_screen(ScreenInstruction::ChangeFloatingPanesCoordinates( + vec![(pane_id.into(), coordinates)], + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::TogglePaneInGroup => { senders - .send_to_screen(ScreenInstruction::TogglePaneInGroup(client_id)) + .send_to_screen(ScreenInstruction::TogglePaneInGroup( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, Action::ToggleGroupMarking => { senders - .send_to_screen(ScreenInstruction::ToggleGroupMarking(client_id)) + .send_to_screen(ScreenInstruction::ToggleGroupMarking( + client_id, + Some(NotificationEnd::new(completion_tx)), + )) .with_context(err_context)?; }, } + let exit_status = wait_for_action_completion(completion_rx, &action_name, wait_forever); + if let Some(exit_status) = exit_status { + if let Some(cli_client_id) = cli_client_id { + if let Some(os_input) = os_input { + let _ = os_input.send_to_client( + cli_client_id, + ServerToClientMsg::Exit { + exit_reason: ExitReason::CustomExitStatus(exit_status), + }, + ); + } + } + } Ok(should_break) } @@ -1090,6 +1508,12 @@ pub(crate) fn route_thread_main( raw_bytes, is_kitty_keyboard_protocol, } => { + // Track this as the last active client + session_state + .write() + .unwrap() + .set_last_active_client(client_id); + if let Some(rlocked_sessions) = rlocked_sessions.as_ref() { match rlocked_sessions.get_client_keybinds_and_mode(&client_id) { Some((keybinds, input_mode, default_input_mode)) => { @@ -1106,6 +1530,7 @@ pub(crate) fn route_thread_main( action, client_id, None, + None, rlocked_sessions.senders.clone(), rlocked_sessions.capabilities.clone(), rlocked_sessions.client_attributes.clone(), @@ -1120,6 +1545,7 @@ pub(crate) fn route_thread_main( .default_mode .unwrap_or(InputMode::Normal) .clone(), + Some(os_input.clone()), )? { should_break = true; } @@ -1135,12 +1561,30 @@ pub(crate) fn route_thread_main( action, terminal_id: maybe_pane_id, client_id: maybe_client_id, + is_cli_client, } => { - let client_id = maybe_client_id.unwrap_or(client_id); + let cli_client_id = client_id; + let client_id = if is_cli_client { + // for cli clients, we want to default to the last active client + // (i.e. the last client to have issued a keystroke) this is to + // interpret actions that require a client_id (such as move focus, + // detach, etc.) for which using the cli client id will not be + // doing the right thing - using the last_active_client is almost + // certainly correct in almost all cases + session_state + .read() + .unwrap() + .get_last_active_client() + .or(maybe_client_id) + .unwrap_or(client_id) + } else { + maybe_client_id.unwrap_or(client_id) + }; if let Some(rlocked_sessions) = rlocked_sessions.as_ref() { if route_action( action, client_id, + Some(cli_client_id), maybe_pane_id.map(|p| PaneId::Terminal(p)), rlocked_sessions.senders.clone(), rlocked_sessions.capabilities.clone(), @@ -1159,6 +1603,7 @@ pub(crate) fn route_thread_main( .default_mode .unwrap_or(InputMode::Normal) .clone(), + Some(os_input.clone()), )? { should_break = true; } @@ -1296,6 +1741,7 @@ pub(crate) fn route_thread_main( let _ = to_server.send(ServerInstruction::LogError( vec![error.to_owned()], client_id, + None, )); let _ = to_server .send(ServerInstruction::SendWebClientsForbidden(client_id)); @@ -1309,8 +1755,6 @@ pub(crate) fn route_thread_main( .with_context(err_context)?; }, ClientToServerMsg::ClientExited => { - // we don't unwrap this because we don't really care if there's an error here (eg. - // if the main server thread exited before this router thread did) let _ = to_server.send(ServerInstruction::RemoveClient(client_id)); return Ok(true); }, @@ -1324,7 +1768,8 @@ pub(crate) fn route_thread_main( should_break = true; }, ClientToServerMsg::DetachSession { client_ids } => { - let _ = to_server.send(ServerInstruction::DetachSession(client_ids)); + let _ = + to_server.send(ServerInstruction::DetachSession(client_ids, None)); should_break = true; }, ClientToServerMsg::WebServerStarted { base_url } => { @@ -1370,6 +1815,13 @@ pub(crate) fn route_thread_main( } }, } + + // signal to the client that the action has finished processing and it can either exit (if + // it's a cli client) or allow the user to perform another action (if it's an actively + // connected user) + let _ = os_input.send_to_client(client_id, ServerToClientMsg::UnblockInputThread); } + // route thread exited, make sure we clean up + let _ = to_server.send(ServerInstruction::RemoveClient(client_id)); Ok(()) } diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 4a957941..3c83d6b0 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -8,11 +8,13 @@ use std::rc::Rc; use std::str; use std::time::{Duration, Instant}; +use crate::route::NotificationEnd; + use log::{debug, warn}; use zellij_utils::data::{ - Direction, FloatingPaneCoordinates, KeyWithModifier, PaneContents, PaneManifest, - PaneScrollbackResponse, PluginPermission, Resize, ResizeStrategy, SessionInfo, Styling, - WebSharing, + Direction, FloatingPaneCoordinates, KeyWithModifier, NewPanePlacement, PaneContents, + PaneManifest, PaneScrollbackResponse, PluginPermission, Resize, ResizeStrategy, SessionInfo, + Styling, WebSharing, }; use zellij_utils::errors::prelude::*; use zellij_utils::input::command::RunCommand; @@ -46,7 +48,7 @@ use crate::{ panes::sixel::SixelImageStore, panes::PaneId, plugins::{PluginId, PluginInstruction, PluginRenderAsset}, - pty::{get_default_shell, ClientTabIndexOrPaneId, NewPanePlacement, PtyInstruction, VteBytes}, + pty::{get_default_shell, ClientTabIndexOrPaneId, PtyInstruction, VteBytes}, tab::{SuppressedPanes, Tab}, thread_bus::Bus, ui::{ @@ -158,62 +160,74 @@ pub enum ScreenInstruction { NewPanePlacement, bool, // start suppressed ClientTabIndexOrPaneId, + Option<NotificationEnd>, // completion signal + bool, // set_blocking ), OpenInPlaceEditor(PaneId, ClientTabIndexOrPaneId), - TogglePaneEmbedOrFloating(ClientId), - ToggleFloatingPanes(ClientId, Option<TerminalAction>), - HorizontalSplit(PaneId, Option<InitialTitle>, HoldForCommand, ClientId), - VerticalSplit(PaneId, Option<InitialTitle>, HoldForCommand, ClientId), - WriteCharacter(Option<KeyWithModifier>, Vec<u8>, bool, ClientId), // bool -> + TogglePaneEmbedOrFloating(ClientId, Option<NotificationEnd>), + ToggleFloatingPanes(ClientId, Option<TerminalAction>, Option<NotificationEnd>), + WriteCharacter( + Option<KeyWithModifier>, + Vec<u8>, + bool, + ClientId, + Option<NotificationEnd>, + ), // bool -> // is_kitty_keyboard_protocol - Resize(ClientId, ResizeStrategy), - SwitchFocus(ClientId), - FocusNextPane(ClientId), - FocusPreviousPane(ClientId), - MoveFocusLeft(ClientId), - MoveFocusLeftOrPreviousTab(ClientId), - MoveFocusDown(ClientId), - MoveFocusUp(ClientId), - MoveFocusRight(ClientId), - MoveFocusRightOrNextTab(ClientId), - MovePane(ClientId), - MovePaneBackwards(ClientId), - MovePaneUp(ClientId), - MovePaneDown(ClientId), - MovePaneRight(ClientId), - MovePaneLeft(ClientId), + Resize(ClientId, ResizeStrategy, Option<NotificationEnd>), + SwitchFocus(ClientId, Option<NotificationEnd>), + FocusNextPane(ClientId, Option<NotificationEnd>), + FocusPreviousPane(ClientId, Option<NotificationEnd>), + MoveFocusLeft(ClientId, Option<NotificationEnd>), + MoveFocusLeftOrPreviousTab(ClientId, Option<NotificationEnd>), + MoveFocusDown(ClientId, Option<NotificationEnd>), + MoveFocusUp(ClientId, Option<NotificationEnd>), + MoveFocusRight(ClientId, Option<NotificationEnd>), + MoveFocusRightOrNextTab(ClientId, Option<NotificationEnd>), + MovePane(ClientId, Option<NotificationEnd>), + MovePaneBackwards(ClientId, Option<NotificationEnd>), + MovePaneUp(ClientId, Option<NotificationEnd>), + MovePaneDown(ClientId, Option<NotificationEnd>), + MovePaneRight(ClientId, Option<NotificationEnd>), + MovePaneLeft(ClientId, Option<NotificationEnd>), Exit, - ClearScreen(ClientId), - DumpScreen(String, ClientId, bool), - DumpLayout(Option<PathBuf>, ClientId), // PathBuf is the default configured + ClearScreen(ClientId, Option<NotificationEnd>), + DumpScreen(String, ClientId, bool, Option<NotificationEnd>), + DumpLayout(Option<PathBuf>, ClientId, Option<NotificationEnd>), // PathBuf is the default configured // shell DumpLayoutToPlugin(PluginId), - EditScrollback(ClientId), + EditScrollback(ClientId, Option<NotificationEnd>), GetPaneScrollback { pane_id: PaneId, client_id: ClientId, get_full_scrollback: bool, response_channel: crossbeam::channel::Sender<PaneScrollbackResponse>, }, - ScrollUp(ClientId), - ScrollUpAt(Position, ClientId), - ScrollDown(ClientId), - ScrollDownAt(Position, ClientId), - ScrollToBottom(ClientId), - ScrollToTop(ClientId), - PageScrollUp(ClientId), - PageScrollDown(ClientId), - HalfPageScrollUp(ClientId), - HalfPageScrollDown(ClientId), + ScrollUp(ClientId, Option<NotificationEnd>), + ScrollUpAt(Position, ClientId, Option<NotificationEnd>), + ScrollDown(ClientId, Option<NotificationEnd>), + ScrollDownAt(Position, ClientId, Option<NotificationEnd>), + ScrollToBottom(ClientId, Option<NotificationEnd>), + ScrollToTop(ClientId, Option<NotificationEnd>), + PageScrollUp(ClientId, Option<NotificationEnd>), + PageScrollDown(ClientId, Option<NotificationEnd>), + HalfPageScrollUp(ClientId, Option<NotificationEnd>), + HalfPageScrollDown(ClientId, Option<NotificationEnd>), ClearScroll(ClientId), - CloseFocusedPane(ClientId), - ToggleActiveTerminalFullscreen(ClientId), - TogglePaneFrames, + CloseFocusedPane(ClientId, Option<NotificationEnd>), + ToggleActiveTerminalFullscreen(ClientId, Option<NotificationEnd>), + TogglePaneFrames(Option<NotificationEnd>), SetSelectable(PaneId, bool), - ClosePane(PaneId, Option<ClientId>), + ClosePane( + PaneId, + Option<ClientId>, + Option<NotificationEnd>, + Option<i32>, + ), // i32 -> optional exit + // status HoldPane(PaneId, Option<i32>, RunCommand), - UpdatePaneName(Vec<u8>, ClientId), - UndoRenamePane(ClientId), + UpdatePaneName(Vec<u8>, ClientId, Option<NotificationEnd>), + UndoRenamePane(ClientId, Option<NotificationEnd>), NewTab( Option<PathBuf>, Option<TerminalAction>, @@ -223,6 +237,7 @@ pub enum ScreenInstruction { (Vec<SwapTiledLayout>, Vec<SwapFloatingLayout>), // swap layouts bool, // should_change_focus_to_new_tab (ClientId, bool), // bool -> is_web_client + Option<NotificationEnd>, // completion signal ), ApplyLayout( TiledPaneLayout, @@ -230,36 +245,38 @@ pub enum ScreenInstruction { Vec<(u32, HoldForCommand)>, // new pane pids Vec<(u32, HoldForCommand)>, // new floating pane pids HashMap<RunPluginOrAlias, Vec<u32>>, - usize, // tab_index - bool, // should change focus to new tab - (ClientId, bool), // bool -> is_web_client + usize, // tab_index + bool, // should change focus to new tab + (ClientId, bool), // bool -> is_web_client + Option<NotificationEnd>, // completion signal ), - SwitchTabNext(ClientId), - SwitchTabPrev(ClientId), - ToggleActiveSyncTab(ClientId), - CloseTab(ClientId), - GoToTab(u32, Option<ClientId>), // this Option is a hacky workaround, please do not copy this behaviour + SwitchTabNext(ClientId, Option<NotificationEnd>), + SwitchTabPrev(ClientId, Option<NotificationEnd>), + ToggleActiveSyncTab(ClientId, Option<NotificationEnd>), + CloseTab(ClientId, Option<NotificationEnd>), + GoToTab(u32, Option<ClientId>, Option<NotificationEnd>), // this Option is a hacky workaround, please do not copy this behaviour GoToTabName( String, (Vec<SwapTiledLayout>, Vec<SwapFloatingLayout>), // swap layouts Option<TerminalAction>, // default_shell bool, Option<ClientId>, + Option<NotificationEnd>, ), - ToggleTab(ClientId), - UpdateTabName(Vec<u8>, ClientId), - UndoRenameTab(ClientId), - MoveTabLeft(ClientId), - MoveTabRight(ClientId), + ToggleTab(ClientId, Option<NotificationEnd>), + UpdateTabName(Vec<u8>, ClientId, Option<NotificationEnd>), + UndoRenameTab(ClientId, Option<NotificationEnd>), + MoveTabLeft(ClientId, Option<NotificationEnd>), + MoveTabRight(ClientId, Option<NotificationEnd>), TerminalResize(Size), TerminalPixelDimensions(PixelDimensions), TerminalBackgroundColor(String), TerminalForegroundColor(String), TerminalColorRegisters(Vec<(usize, String)>), - ChangeMode(ModeInfo, ClientId), - ChangeModeForAllClients(ModeInfo), - MouseEvent(MouseEvent, ClientId), - Copy(ClientId), + ChangeMode(ModeInfo, ClientId, Option<NotificationEnd>), + ChangeModeForAllClients(ModeInfo, Option<NotificationEnd>), + MouseEvent(MouseEvent, ClientId, Option<NotificationEnd>), + Copy(ClientId, Option<NotificationEnd>), AddClient( ClientId, bool, // is_web_client @@ -269,25 +286,26 @@ pub enum ScreenInstruction { RemoveClient(ClientId), AddOverlay(Overlay, ClientId), RemoveOverlay(ClientId), - ConfirmPrompt(ClientId), - DenyPrompt(ClientId), - UpdateSearch(Vec<u8>, ClientId), - SearchDown(ClientId), - SearchUp(ClientId), - SearchToggleCaseSensitivity(ClientId), - SearchToggleWholeWord(ClientId), - SearchToggleWrap(ClientId), + ConfirmPrompt(ClientId, Option<NotificationEnd>), + DenyPrompt(ClientId, Option<NotificationEnd>), + UpdateSearch(Vec<u8>, ClientId, Option<NotificationEnd>), + SearchDown(ClientId, Option<NotificationEnd>), + SearchUp(ClientId, Option<NotificationEnd>), + SearchToggleCaseSensitivity(ClientId, Option<NotificationEnd>), + SearchToggleWholeWord(ClientId, Option<NotificationEnd>), + SearchToggleWrap(ClientId, Option<NotificationEnd>), AddRedPaneFrameColorOverride(Vec<PaneId>, Option<String>), // Option<String> => optional error text ClearPaneFrameColorOverride(Vec<PaneId>), - PreviousSwapLayout(ClientId), - NextSwapLayout(ClientId), - QueryTabNames(ClientId), + PreviousSwapLayout(ClientId, Option<NotificationEnd>), + NextSwapLayout(ClientId, Option<NotificationEnd>), + QueryTabNames(ClientId, Option<NotificationEnd>), NewTiledPluginPane( RunPluginOrAlias, Option<String>, bool, Option<PathBuf>, ClientId, + Option<NotificationEnd>, ), // Option<String> is // optional pane title, bool is skip cache, Option<PathBuf> is an optional cwd NewFloatingPluginPane( @@ -297,12 +315,20 @@ pub enum ScreenInstruction { Option<PathBuf>, Option<FloatingPaneCoordinates>, ClientId, + Option<NotificationEnd>, ), // Option<String> is an // optional pane title, bool // is skip cache, Option<PathBuf> is an optional cwd - NewInPlacePluginPane(RunPluginOrAlias, Option<String>, PaneId, bool, ClientId), // Option<String> is an + NewInPlacePluginPane( + RunPluginOrAlias, + Option<String>, + PaneId, + bool, + ClientId, + Option<NotificationEnd>, + ), // Option<String> is an // optional pane title, bool is skip cache - StartOrReloadPluginPane(RunPluginOrAlias, Option<String>), + StartOrReloadPluginPane(RunPluginOrAlias, Option<String>, Option<NotificationEnd>), AddPlugin( Option<bool>, // should_float bool, // should be opened in place @@ -316,6 +342,7 @@ pub enum ScreenInstruction { Option<FloatingPaneCoordinates>, Option<bool>, // should focus plugin Option<ClientId>, + Option<NotificationEnd>, // completion signal ), UpdatePluginLoadingStage(u32, LoadingIndication), // u32 - plugin_id StartPluginLoadingIndication(u32, LoadingIndication), // u32 - plugin_id @@ -329,6 +356,7 @@ pub enum ScreenInstruction { Option<PaneId>, bool, ClientId, + Option<NotificationEnd>, ), // bools are: should_float, move_to_focused_tab, should_open_in_place, Option<PaneId> is the pane id to replace, bool following it is skip_cache LaunchPlugin( RunPluginOrAlias, @@ -338,18 +366,24 @@ pub enum ScreenInstruction { bool, Option<PathBuf>, ClientId, + Option<NotificationEnd>, ), // bools are: should_float, should_open_in_place Option<PaneId> is the pane id to replace, Option<PathBuf> is an optional cwd, bool after is skip_cache - SuppressPane(PaneId, ClientId), // bool is should_float - FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float - RenamePane(PaneId, Vec<u8>), - RenameTab(usize, Vec<u8>), + SuppressPane(PaneId, ClientId), // bool is should_float + FocusPaneWithId(PaneId, bool, ClientId, Option<NotificationEnd>), // bool is should_float + RenamePane(PaneId, Vec<u8>, Option<NotificationEnd>), + RenameTab(usize, Vec<u8>, Option<NotificationEnd>), RequestPluginPermissions( u32, // u32 - plugin_id PluginPermission, ), - BreakPane(Box<Layout>, Option<TerminalAction>, ClientId), - BreakPaneRight(ClientId), - BreakPaneLeft(ClientId), + BreakPane( + Box<Layout>, + Option<TerminalAction>, + ClientId, + Option<NotificationEnd>, + ), + BreakPaneRight(ClientId, Option<NotificationEnd>), + BreakPaneLeft(ClientId, Option<NotificationEnd>), UpdateSessionInfos( BTreeMap<String, SessionInfo>, // String is the session name BTreeMap<String, Duration>, // resurrectable sessions - <name, created> @@ -361,10 +395,11 @@ pub enum ScreenInstruction { Option<Run>, bool, // close replaced pane ClientTabIndexOrPaneId, + Option<NotificationEnd>, // completion signal ), SerializeLayoutForResurrection, - RenameSession(String, ClientId), // String -> new name - ListClientsMetadata(Option<PathBuf>, ClientId), // Option<PathBuf> - default shell + RenameSession(String, ClientId, Option<NotificationEnd>), // String -> new name + ListClientsMetadata(Option<PathBuf>, ClientId, Option<NotificationEnd>), // Option<PathBuf> - default shell Reconfigure { client_id: ClientId, keybinds: Keybinds, @@ -383,9 +418,9 @@ pub enum ScreenInstruction { default_editor: Option<PathBuf>, advanced_mouse_actions: bool, }, - RerunCommandPane(u32), // u32 - terminal pane id + RerunCommandPane(u32, Option<NotificationEnd>), // u32 - terminal pane id ResizePaneWithId(ResizeStrategy, PaneId), - EditScrollbackForPaneWithId(PaneId), + EditScrollbackForPaneWithId(PaneId, Option<NotificationEnd>), WriteToPaneId(Vec<u8>, PaneId), MovePaneWithPaneId(PaneId), MovePaneWithPaneIdInDirection(PaneId, Direction), @@ -413,18 +448,21 @@ pub enum ScreenInstruction { client_id: ClientId, }, ListClientsToPlugin(PluginId, ClientId), - TogglePanePinned(ClientId), + TogglePanePinned(ClientId, Option<NotificationEnd>), SetFloatingPanePinned(PaneId, bool), - StackPanes(Vec<PaneId>, ClientId), - ChangeFloatingPanesCoordinates(Vec<(PaneId, FloatingPaneCoordinates)>), + StackPanes(Vec<PaneId>, ClientId, Option<NotificationEnd>), + ChangeFloatingPanesCoordinates( + Vec<(PaneId, FloatingPaneCoordinates)>, + Option<NotificationEnd>, + ), AddHighlightPaneFrameColorOverride(Vec<PaneId>, Option<String>), // Option<String> => optional // message GroupAndUngroupPanes(Vec<PaneId>, Vec<PaneId>, bool, ClientId), // panes_to_group, panes_to_ungroup, bool -> for all clients HighlightAndUnhighlightPanes(Vec<PaneId>, Vec<PaneId>, ClientId), // panes_to_highlight, panes_to_unhighlight FloatMultiplePanes(Vec<PaneId>, ClientId), EmbedMultiplePanes(Vec<PaneId>, ClientId), - TogglePaneInGroup(ClientId), - ToggleGroupMarking(ClientId), + TogglePaneInGroup(ClientId, Option<NotificationEnd>), + ToggleGroupMarking(ClientId, Option<NotificationEnd>), SessionSharingStatusChange(bool), SetMouseSelectionSupport(PaneId, bool), InterceptKeyPresses(PluginId, ClientId), @@ -449,10 +487,8 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenContext::TogglePaneEmbedOrFloating }, ScreenInstruction::ToggleFloatingPanes(..) => ScreenContext::ToggleFloatingPanes, - ScreenInstruction::HorizontalSplit(..) => ScreenContext::HorizontalSplit, - ScreenInstruction::VerticalSplit(..) => ScreenContext::VerticalSplit, ScreenInstruction::WriteCharacter(..) => ScreenContext::WriteCharacter, - ScreenInstruction::Resize(.., strategy) => match strategy { + ScreenInstruction::Resize(.., strategy, _) => match strategy { ResizeStrategy { resize: Resize::Increase, direction, @@ -515,7 +551,7 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::ToggleActiveTerminalFullscreen(..) => { ScreenContext::ToggleActiveTerminalFullscreen }, - ScreenInstruction::TogglePaneFrames => ScreenContext::TogglePaneFrames, + ScreenInstruction::TogglePaneFrames(..) => ScreenContext::TogglePaneFrames, ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable, ScreenInstruction::ClosePane(..) => ScreenContext::ClosePane, ScreenInstruction::HoldPane(..) => ScreenContext::HoldPane, @@ -2544,11 +2580,15 @@ impl Screen { }; Ok(()) } - pub fn rerun_command_pane_with_id(&mut self, terminal_pane_id: u32) { + pub fn rerun_command_pane_with_id( + &mut self, + terminal_pane_id: u32, + completion_tx: Option<NotificationEnd>, + ) { let mut found = false; for tab in self.tabs.values_mut() { if tab.has_pane_with_pid(&PaneId::Terminal(terminal_pane_id)) { - tab.rerun_terminal_pane_with_id(terminal_pane_id); + tab.rerun_terminal_pane_with_id(terminal_pane_id, completion_tx); found = true; break; } @@ -2628,6 +2668,7 @@ impl Screen { tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + None, ))?; } else { let active_pane_id = active_tab @@ -2640,7 +2681,6 @@ impl Screen { "Cannot break single pane out!".into(), )) .with_context(err_context)?; - self.unblock_input()?; } Ok(()) } @@ -2704,6 +2744,7 @@ impl Screen { tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + None, ))?; Ok(()) } @@ -2760,7 +2801,6 @@ impl Screen { )) .with_context(err_context)?; } - self.unblock_input()?; self.render(None)?; Ok(()) } @@ -2847,6 +2887,7 @@ impl Screen { new_pane_id, close_replaced_pane, run, + None, ); if let Some(pane_title) = pane_title { let _ = tab.rename_pane(pane_title.as_bytes().to_vec(), new_pane_id); @@ -2937,6 +2978,7 @@ impl Screen { tab.1.close_pane_and_replace_with_other_pane( pane_id_to_replace, extracted_pane_from_other_tab, + None, ); } let _ = self.log_and_report_session_state(); @@ -3027,7 +3069,6 @@ impl Screen { tab.toggle_pane_pinned(client_id); } ); - self.unblock_input().non_fatal(); } pub fn set_floating_pane_pinned(&mut self, pane_id: PaneId, should_be_pinned: bool) { let mut found = false; @@ -3210,12 +3251,6 @@ impl Screen { } Ok(()) } - fn unblock_input(&self) -> Result<()> { - self.bus - .senders - .send_to_server(ServerInstruction::UnblockInputThread) - .context("failed to unblock input") - } fn get_layout_metadata(&self, default_shell: Option<PathBuf>) -> SessionLayoutMetadata { let mut session_layout_metadata = SessionLayoutMetadata::new(self.default_layout.clone()); if let Some(default_shell) = default_shell { @@ -3657,7 +3692,11 @@ pub(crate) fn screen_thread_main( new_pane_placement, start_suppressed, client_or_tab_index, + completion_tx, + set_blocking, ) => { + let blocking_notification = if set_blocking { completion_tx } else { None }; + match client_or_tab_index { ClientTabIndexOrPaneId::ClientId(client_id) => { active_tab_and_connected_client_id!(screen, client_id, |tab: &mut Tab, client_id: ClientId| { @@ -3667,7 +3706,8 @@ pub(crate) fn screen_thread_main( start_suppressed, true, new_pane_placement, - Some(client_id) + Some(client_id), + blocking_notification ) }, ?); if let Some(hold_for_command) = hold_for_command { @@ -3694,6 +3734,7 @@ pub(crate) fn screen_thread_main( true, new_pane_placement, None, + blocking_notification, )?; if let Some(hold_for_command) = hold_for_command { let is_first_run = true; @@ -3716,6 +3757,7 @@ pub(crate) fn screen_thread_main( true, new_pane_placement, None, + blocking_notification, // TODO: is this correct? )?; if let Some(hold_for_command) = hold_for_command { let is_first_run = true; @@ -3733,7 +3775,6 @@ pub(crate) fn screen_thread_main( } }, }; - screen.unblock_input()?; screen.log_and_report_session_state()?; screen.render(None)?; @@ -3743,7 +3784,6 @@ pub(crate) fn screen_thread_main( ClientTabIndexOrPaneId::ClientId(client_id) => { active_tab!(screen, client_id, |tab: &mut Tab| tab .replace_active_pane_with_editor_pane(pid, client_id), ?); - screen.unblock_input()?; screen.log_and_report_session_state()?; }, ClientTabIndexOrPaneId::TabIndex(_tab_index) => { @@ -3771,84 +3811,30 @@ pub(crate) fn screen_thread_main( screen.render(None)?; }, - ScreenInstruction::TogglePaneEmbedOrFloating(client_id) => { + ScreenInstruction::TogglePaneEmbedOrFloating( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!(screen, client_id, |tab: &mut Tab, client_id: ClientId| tab .toggle_pane_embed_or_floating(client_id), ?); - screen.unblock_input()?; screen.log_and_report_session_state()?; screen.render(None)?; }, - ScreenInstruction::ToggleFloatingPanes(client_id, default_shell) => { + ScreenInstruction::ToggleFloatingPanes(client_id, default_shell, completion_tx) => { active_tab_and_connected_client_id!(screen, client_id, |tab: &mut Tab, client_id: ClientId| tab - .toggle_floating_panes(Some(client_id), default_shell), ?); - screen.unblock_input()?; + .toggle_floating_panes(Some(client_id), default_shell, completion_tx), ?); screen.log_and_report_session_state()?; screen.render(None)?; }, - ScreenInstruction::HorizontalSplit( - pid, - initial_pane_title, - hold_for_command, - client_id, - ) => { - active_tab_and_connected_client_id!( - screen, - client_id, - |tab: &mut Tab, client_id: ClientId| tab.horizontal_split(pid, initial_pane_title, client_id), - ? - ); - if let Some(hold_for_command) = hold_for_command { - let is_first_run = true; - active_tab_and_connected_client_id!( - screen, - client_id, - |tab: &mut Tab, _client_id: ClientId| tab.hold_pane( - pid, - None, - is_first_run, - hold_for_command - ) - ); - } - screen.unblock_input()?; - screen.log_and_report_session_state()?; - screen.render(None)?; - }, - ScreenInstruction::VerticalSplit( - pid, - initial_pane_title, - hold_for_command, - client_id, - ) => { - active_tab_and_connected_client_id!( - screen, - client_id, - |tab: &mut Tab, client_id: ClientId| tab.vertical_split(pid, initial_pane_title, client_id), - ? - ); - if let Some(hold_for_command) = hold_for_command { - let is_first_run = true; - active_tab_and_connected_client_id!( - screen, - client_id, - |tab: &mut Tab, _client_id: ClientId| tab.hold_pane( - pid, - None, - is_first_run, - hold_for_command - ) - ); - } - screen.unblock_input()?; - screen.log_and_report_session_state()?; - screen.render(None)?; - }, ScreenInstruction::WriteCharacter( key_with_modifier, raw_bytes, is_kitty_keyboard_protocol, client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it ) => { if let Some(plugin_id) = keybind_intercepts.get(&client_id) { if let Some(key_with_modifier) = key_with_modifier { @@ -3930,49 +3916,66 @@ pub(crate) fn screen_thread_main( if state_changed { screen.log_and_report_session_state()?; } - screen.unblock_input()?; + screen.render(None)?; }, - ScreenInstruction::Resize(client_id, strategy) => { + ScreenInstruction::Resize( + client_id, + strategy, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.resize(client_id, strategy), ? ); - screen.unblock_input()?; screen.render(None)?; screen.log_and_report_session_state()?; }, - ScreenInstruction::SwitchFocus(client_id) => { + ScreenInstruction::SwitchFocus( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.focus_next_pane(client_id) ); - screen.unblock_input()?; screen.render(None)?; screen.log_and_report_session_state()?; }, - ScreenInstruction::FocusNextPane(client_id) => { + ScreenInstruction::FocusNextPane( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.focus_next_pane(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::FocusPreviousPane(client_id) => { + ScreenInstruction::FocusPreviousPane( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.focus_previous_pane(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MoveFocusLeft(client_id) => { + ScreenInstruction::MoveFocusLeft( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -3981,17 +3984,23 @@ pub(crate) fn screen_thread_main( ); screen.add_active_pane_to_group_if_marking(&client_id); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MoveFocusLeftOrPreviousTab(client_id) => { + ScreenInstruction::MoveFocusLeftOrPreviousTab( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.move_focus_left_or_previous_tab(client_id)?; screen.add_active_pane_to_group_if_marking(&client_id); - screen.unblock_input()?; screen.render(None)?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MoveFocusDown(client_id) => { + ScreenInstruction::MoveFocusDown( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4000,10 +4009,13 @@ pub(crate) fn screen_thread_main( ); screen.add_active_pane_to_group_if_marking(&client_id); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MoveFocusRight(client_id) => { + ScreenInstruction::MoveFocusRight( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4012,17 +4024,23 @@ pub(crate) fn screen_thread_main( ); screen.add_active_pane_to_group_if_marking(&client_id); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MoveFocusRightOrNextTab(client_id) => { + ScreenInstruction::MoveFocusRightOrNextTab( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.move_focus_right_or_next_tab(client_id)?; screen.add_active_pane_to_group_if_marking(&client_id); - screen.unblock_input()?; screen.render(None)?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MoveFocusUp(client_id) => { + ScreenInstruction::MoveFocusUp( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4031,10 +4049,13 @@ pub(crate) fn screen_thread_main( ); screen.add_active_pane_to_group_if_marking(&client_id); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::ClearScreen(client_id) => { + ScreenInstruction::ClearScreen( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4044,9 +4065,14 @@ pub(crate) fn screen_thread_main( ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::DumpScreen(file, client_id, full) => { + ScreenInstruction::DumpScreen( + file, + client_id, + full, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4058,9 +4084,8 @@ pub(crate) fn screen_thread_main( ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::DumpLayout(default_shell, client_id) => { + ScreenInstruction::DumpLayout(default_shell, client_id, completion_tx) => { let err_context = || format!("Failed to dump layout"); let session_layout_metadata = screen.get_layout_metadata(default_shell); screen @@ -4069,10 +4094,11 @@ pub(crate) fn screen_thread_main( .send_to_plugin(PluginInstruction::DumpLayout( session_layout_metadata, client_id, + completion_tx, )) .with_context(err_context)?; }, - ScreenInstruction::ListClientsMetadata(default_shell, client_id) => { + ScreenInstruction::ListClientsMetadata(default_shell, client_id, completion_tx) => { let err_context = || format!("Failed to dump layout"); let session_layout_metadata = screen.get_layout_metadata(default_shell); screen @@ -4081,6 +4107,7 @@ pub(crate) fn screen_thread_main( .send_to_plugin(PluginInstruction::ListClientsMetadata( session_layout_metadata, client_id, + completion_tx, )) .with_context(err_context)?; }, @@ -4113,11 +4140,11 @@ pub(crate) fn screen_thread_main( .with_context(err_context) .non_fatal(); }, - ScreenInstruction::EditScrollback(client_id) => { + ScreenInstruction::EditScrollback(client_id, completion_tx) => { active_tab_and_connected_client_id!( screen, client_id, - |tab: &mut Tab, client_id: ClientId| tab.edit_scrollback(client_id), + |tab: &mut Tab, client_id: ClientId| tab.edit_scrollback(client_id, completion_tx), ? ); screen.render(None)?; @@ -4156,76 +4183,102 @@ pub(crate) fn screen_thread_main( ); } }, - ScreenInstruction::ScrollUp(client_id) => { + ScreenInstruction::ScrollUp( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.scroll_active_terminal_up(client_id) ); - screen.unblock_input()?; screen.render(None)?; }, - ScreenInstruction::MovePane(client_id) => { + ScreenInstruction::MovePane( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.move_active_pane(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MovePaneBackwards(client_id) => { + ScreenInstruction::MovePaneBackwards( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.move_active_pane_backwards(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MovePaneDown(client_id) => { + ScreenInstruction::MovePaneDown( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.move_active_pane_down(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MovePaneUp(client_id) => { + ScreenInstruction::MovePaneUp( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.move_active_pane_up(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MovePaneRight(client_id) => { + ScreenInstruction::MovePaneRight( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.move_active_pane_right(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::MovePaneLeft(client_id) => { + ScreenInstruction::MovePaneLeft( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.move_active_pane_left(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::ScrollUpAt(point, client_id) => { + ScreenInstruction::ScrollUpAt( + point, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4233,18 +4286,25 @@ pub(crate) fn screen_thread_main( .handle_scrollwheel_up(&point, 3, client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ScrollDown(client_id) => { + ScreenInstruction::ScrollDown( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.scroll_active_terminal_down(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ScrollDownAt(point, client_id) => { + ScreenInstruction::ScrollDownAt( + point, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4252,9 +4312,12 @@ pub(crate) fn screen_thread_main( .handle_scrollwheel_down(&point, 3, client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ScrollToBottom(client_id) => { + ScreenInstruction::ScrollToBottom( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4262,9 +4325,12 @@ pub(crate) fn screen_thread_main( .scroll_active_terminal_to_bottom(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ScrollToTop(client_id) => { + ScreenInstruction::ScrollToTop( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4272,9 +4338,12 @@ pub(crate) fn screen_thread_main( .scroll_active_terminal_to_top(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::PageScrollUp(client_id) => { + ScreenInstruction::PageScrollUp( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4282,9 +4351,12 @@ pub(crate) fn screen_thread_main( .scroll_active_terminal_up_page(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::PageScrollDown(client_id) => { + ScreenInstruction::PageScrollDown( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4292,9 +4364,12 @@ pub(crate) fn screen_thread_main( .scroll_active_terminal_down_page(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::HalfPageScrollUp(client_id) => { + ScreenInstruction::HalfPageScrollUp( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4302,9 +4377,12 @@ pub(crate) fn screen_thread_main( .scroll_active_terminal_up_half_page(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::HalfPageScrollDown(client_id) => { + ScreenInstruction::HalfPageScrollDown( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4312,7 +4390,6 @@ pub(crate) fn screen_thread_main( .scroll_active_terminal_down_half_page(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, ScreenInstruction::ClearScroll(client_id) => { active_tab_and_connected_client_id!( @@ -4322,16 +4399,14 @@ pub(crate) fn screen_thread_main( .clear_active_terminal_scroll(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::CloseFocusedPane(client_id) => { + ScreenInstruction::CloseFocusedPane(client_id, completion_tx) => { active_tab_and_connected_client_id!( screen, client_id, - |tab: &mut Tab, client_id: ClientId| tab.close_focused_pane(client_id), ? + |tab: &mut Tab, client_id: ClientId| tab.close_focused_pane(client_id, completion_tx), ? ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, ScreenInstruction::SetSelectable(pid, selectable) => { @@ -4369,23 +4444,31 @@ pub(crate) fn screen_thread_main( screen.render(None)?; screen.log_and_report_session_state()?; }, - ScreenInstruction::ClosePane(id, client_id) => { + ScreenInstruction::ClosePane( + id, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + exit_status, + ) => { match client_id { Some(client_id) => { - active_tab!(screen, client_id, |tab: &mut Tab| tab - .close_pane(id, false,)); + active_tab!(screen, client_id, |tab: &mut Tab| tab.close_pane( + id, + false, + exit_status + )); }, None => { for tab in screen.tabs.values_mut() { if tab.get_all_pane_ids().contains(&id) { - tab.close_pane(id, false); + tab.close_pane(id, false, exit_status); break; } } }, } - screen.unblock_input()?; screen.log_and_report_session_state()?; screen.retain_only_existing_panes_in_pane_groups(); }, @@ -4397,29 +4480,39 @@ pub(crate) fn screen_thread_main( break; } } - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::UpdatePaneName(c, client_id) => { + ScreenInstruction::UpdatePaneName( + c, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.update_active_pane_name(c, client_id), ? ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::UndoRenamePane(client_id) => { + ScreenInstruction::UndoRenamePane( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.undo_active_rename_pane(client_id), ? ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ToggleActiveTerminalFullscreen(client_id) => { + ScreenInstruction::ToggleActiveTerminalFullscreen( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4427,31 +4520,41 @@ pub(crate) fn screen_thread_main( .toggle_active_pane_fullscreen(client_id) ); screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::TogglePaneFrames => { + ScreenInstruction::TogglePaneFrames( + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.draw_pane_frames = !screen.draw_pane_frames; for tab in screen.tabs.values_mut() { tab.set_pane_frames(screen.draw_pane_frames); } screen.render(None)?; - screen.unblock_input()?; screen.log_and_report_session_state()?; }, - ScreenInstruction::SwitchTabNext(client_id) => { + ScreenInstruction::SwitchTabNext( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.switch_tab_next(None, true, client_id)?; - screen.unblock_input()?; screen.render(None)?; }, - ScreenInstruction::SwitchTabPrev(client_id) => { + ScreenInstruction::SwitchTabPrev( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.switch_tab_prev(None, true, client_id)?; - screen.unblock_input()?; screen.render(None)?; }, - ScreenInstruction::CloseTab(client_id) => { + ScreenInstruction::CloseTab( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.close_tab(client_id)?; - screen.unblock_input()?; screen.render(None)?; }, ScreenInstruction::NewTab( @@ -4463,6 +4566,7 @@ pub(crate) fn screen_thread_main( swap_layouts, should_change_focus_to_new_tab, (client_id, is_web_client), + completion_tx, ) => { let tab_index = screen.get_new_tab_index(); pending_tab_ids.insert(tab_index); @@ -4488,6 +4592,7 @@ pub(crate) fn screen_thread_main( tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + completion_tx, ))?; }, ScreenInstruction::ApplyLayout( @@ -4499,6 +4604,8 @@ pub(crate) fn screen_thread_main( tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it ) => { screen.apply_layout( layout, @@ -4550,7 +4657,6 @@ pub(crate) fn screen_thread_main( screen.bus.senders.send_to_screen(event).non_fatal(); } - screen.unblock_input()?; screen.render(None)?; // we do this here in order to recover from a race condition on app start // that sometimes causes Zellij to think the terminal window is a different size @@ -4565,7 +4671,12 @@ pub(crate) fn screen_thread_main( } } }, - ScreenInstruction::GoToTab(tab_index, client_id) => { + ScreenInstruction::GoToTab( + tab_index, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { let client_id_to_switch = if client_id.is_none() { None } else if screen @@ -4584,7 +4695,6 @@ pub(crate) fn screen_thread_main( // after) Some(client_id) if pending_tab_ids.is_empty() => { screen.go_to_tab(tab_index as usize, client_id)?; - screen.unblock_input()?; screen.render(None)?; }, _ => { @@ -4600,6 +4710,7 @@ pub(crate) fn screen_thread_main( default_shell, create, client_id, + completion_tx, ) => { let client_id = if client_id.is_none() { None @@ -4619,7 +4730,6 @@ pub(crate) fn screen_thread_main( .copied() .unwrap_or(false); if let Ok(tab_exists) = screen.go_to_tab_name(tab_name.clone(), client_id) { - screen.unblock_input()?; screen.render(None)?; if create && !tab_exists { let tab_index = screen.get_new_tab_index(); @@ -4641,38 +4751,49 @@ pub(crate) fn screen_thread_main( tab_index, should_change_focus_to_new_tab, (client_id, is_web_client), + completion_tx, ))?; + continue; // so we don't get to the completion signalling below } } } }, - ScreenInstruction::UpdateTabName(c, client_id) => { + ScreenInstruction::UpdateTabName( + c, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.update_active_tab_name(c, client_id)?; - screen.unblock_input()?; screen.render(None)?; }, - ScreenInstruction::UndoRenameTab(client_id) => { + ScreenInstruction::UndoRenameTab( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.undo_active_rename_tab(client_id)?; - screen.unblock_input()?; screen.render(None)?; }, - ScreenInstruction::MoveTabLeft(client_id) => { + ScreenInstruction::MoveTabLeft(client_id, completion_tx) => { if pending_tab_ids.is_empty() { screen.move_active_tab_to_left(client_id)?; screen.render(None)?; } else { - pending_events_waiting_for_tab.push(ScreenInstruction::MoveTabLeft(client_id)); + // Defer execution, forward completion_tx + pending_events_waiting_for_tab + .push(ScreenInstruction::MoveTabLeft(client_id, completion_tx)); } - screen.unblock_input()?; }, - ScreenInstruction::MoveTabRight(client_id) => { + ScreenInstruction::MoveTabRight(client_id, completion_tx) => { if pending_tab_ids.is_empty() { screen.move_active_tab_to_right(client_id)?; screen.render(None)?; } else { - pending_events_waiting_for_tab.push(ScreenInstruction::MoveTabRight(client_id)); + // Defer execution, forward completion_tx + pending_events_waiting_for_tab + .push(ScreenInstruction::MoveTabRight(client_id, completion_tx)); } - screen.unblock_input()?; }, ScreenInstruction::TerminalResize(new_size) => { screen.resize_to_screen(new_size)?; @@ -4691,17 +4812,28 @@ pub(crate) fn screen_thread_main( ScreenInstruction::TerminalColorRegisters(color_registers) => { screen.update_terminal_color_registers(color_registers); }, - ScreenInstruction::ChangeMode(mode_info, client_id) => { + ScreenInstruction::ChangeMode( + mode_info, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.change_mode(mode_info, client_id)?; screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ChangeModeForAllClients(mode_info) => { + ScreenInstruction::ChangeModeForAllClients( + mode_info, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.change_mode_for_all_clients(mode_info)?; screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ToggleActiveSyncTab(client_id) => { + ScreenInstruction::ToggleActiveSyncTab( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4709,12 +4841,20 @@ pub(crate) fn screen_thread_main( ); screen.log_and_report_session_state()?; screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::MouseEvent(event, client_id) => { + ScreenInstruction::MouseEvent( + event, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.handle_mouse_event(event, client_id); }, - ScreenInstruction::Copy(client_id) => { + ScreenInstruction::Copy( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab!(screen, client_id, |tab: &mut Tab| tab .copy_selection(client_id), ?); screen.render(None)?; @@ -4722,9 +4862,12 @@ pub(crate) fn screen_thread_main( ScreenInstruction::Exit => { break; }, - ScreenInstruction::ToggleTab(client_id) => { + ScreenInstruction::ToggleTab( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.toggle_tab(client_id)?; - screen.unblock_input()?; screen.render(None)?; }, ScreenInstruction::AddClient( @@ -4775,14 +4918,16 @@ pub(crate) fn screen_thread_main( ScreenInstruction::AddOverlay(overlay, _client_id) => { screen.get_active_overlays_mut().pop(); screen.get_active_overlays_mut().push(overlay); - screen.unblock_input()?; }, ScreenInstruction::RemoveOverlay(_client_id) => { screen.get_active_overlays_mut().pop(); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::ConfirmPrompt(_client_id) => { + ScreenInstruction::ConfirmPrompt( + _client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { let overlay = screen.get_active_overlays_mut().pop(); let instruction = overlay.and_then(|o| o.prompt_confirm()); if let Some(instruction) = instruction { @@ -4792,14 +4937,21 @@ pub(crate) fn screen_thread_main( .send_to_server(*instruction) .context("failed to confirm prompt")?; } - screen.unblock_input()?; }, - ScreenInstruction::DenyPrompt(_client_id) => { + ScreenInstruction::DenyPrompt( + _client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.get_active_overlays_mut().pop(); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::UpdateSearch(c, client_id) => { + ScreenInstruction::UpdateSearch( + c, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4807,7 +4959,11 @@ pub(crate) fn screen_thread_main( ); screen.render(None)?; }, - ScreenInstruction::SearchDown(client_id) => { + ScreenInstruction::SearchDown( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4815,16 +4971,23 @@ pub(crate) fn screen_thread_main( ); screen.render(None)?; }, - ScreenInstruction::SearchUp(client_id) => { + ScreenInstruction::SearchUp( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.search_up(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::SearchToggleCaseSensitivity(client_id) => { + ScreenInstruction::SearchToggleCaseSensitivity( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4832,25 +4995,30 @@ pub(crate) fn screen_thread_main( .toggle_search_case_sensitivity(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::SearchToggleWrap(client_id) => { + ScreenInstruction::SearchToggleWrap( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.toggle_search_wrap(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, - ScreenInstruction::SearchToggleWholeWord(client_id) => { + ScreenInstruction::SearchToggleWholeWord( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, |tab: &mut Tab, client_id: ClientId| tab.toggle_search_whole_words(client_id) ); screen.render(None)?; - screen.unblock_input()?; }, ScreenInstruction::AddRedPaneFrameColorOverride(pane_ids, error_text) => { let all_tabs = screen.get_tabs_mut(); @@ -4892,7 +5060,11 @@ pub(crate) fn screen_thread_main( } screen.render(None)?; }, - ScreenInstruction::PreviousSwapLayout(client_id) => { + ScreenInstruction::PreviousSwapLayout( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4901,9 +5073,12 @@ pub(crate) fn screen_thread_main( ); screen.render(None)?; screen.log_and_report_session_state()?; - screen.unblock_input()?; }, - ScreenInstruction::NextSwapLayout(client_id) => { + ScreenInstruction::NextSwapLayout( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { active_tab_and_connected_client_id!( screen, client_id, @@ -4912,18 +5087,18 @@ pub(crate) fn screen_thread_main( ); screen.render(None)?; screen.log_and_report_session_state()?; - screen.unblock_input()?; }, - ScreenInstruction::QueryTabNames(client_id) => { + ScreenInstruction::QueryTabNames(client_id, completion_tx) => { let tab_names = screen .get_tabs_mut() .values() .map(|tab| tab.name.clone()) .collect::<Vec<String>>(); - screen - .bus - .senders - .send_to_server(ServerInstruction::Log(tab_names, client_id))?; + screen.bus.senders.send_to_server(ServerInstruction::Log( + tab_names, + client_id, + completion_tx, + ))?; }, ScreenInstruction::NewTiledPluginPane( run_plugin, @@ -4931,6 +5106,7 @@ pub(crate) fn screen_thread_main( skip_cache, cwd, client_id, + completion_tx, ) => { let tab_index = screen.active_tab_indices.values().next().unwrap_or(&1); let size = Size::default(); @@ -4952,6 +5128,7 @@ pub(crate) fn screen_thread_main( cwd, None, None, + completion_tx, ))?; }, ScreenInstruction::NewFloatingPluginPane( @@ -4961,6 +5138,7 @@ pub(crate) fn screen_thread_main( cwd, floating_pane_coordinates, client_id, + completion_tx, ) => match screen.active_tab_indices.values().next() { Some(tab_index) => { let size = Size::default(); @@ -4982,6 +5160,7 @@ pub(crate) fn screen_thread_main( cwd, None, floating_pane_coordinates, + completion_tx, ))?; }, None => { @@ -4996,6 +5175,7 @@ pub(crate) fn screen_thread_main( pane_id_to_replace, skip_cache, client_id, + completion_tx, ) => match screen.active_tab_indices.values().next() { Some(tab_index) => { let size = Size::default(); @@ -5017,6 +5197,7 @@ pub(crate) fn screen_thread_main( None, None, None, + completion_tx, ))?; }, None => { @@ -5025,7 +5206,7 @@ pub(crate) fn screen_thread_main( ); }, }, - ScreenInstruction::StartOrReloadPluginPane(run_plugin, pane_title) => { + ScreenInstruction::StartOrReloadPluginPane(run_plugin, pane_title, completion_tx) => { let tab_index = screen.active_tab_indices.values().next().unwrap_or(&1); let size = Size::default(); let should_float = Some(false); @@ -5039,6 +5220,7 @@ pub(crate) fn screen_thread_main( run_plugin, *tab_index, size, + completion_tx, ))?; }, ScreenInstruction::AddPlugin( @@ -5054,6 +5236,7 @@ pub(crate) fn screen_thread_main( floating_pane_coordinates, should_focus_plugin, client_id, + completion_tx, ) => { let close_replaced_pane = false; // TODO: support this let mut new_pane_placement = NewPanePlacement::default(); @@ -5070,7 +5253,7 @@ pub(crate) fn screen_thread_main( } if should_be_in_place { new_pane_placement = NewPanePlacement::with_pane_id_to_replace( - pane_id_to_replace, + pane_id_to_replace.map(|id| id.into()), close_replaced_pane, ); } @@ -5088,6 +5271,7 @@ pub(crate) fn screen_thread_main( floating_pane_coordinates, should_focus_plugin, client_id, + completion_tx, )); continue; } @@ -5138,6 +5322,7 @@ pub(crate) fn screen_thread_main( should_focus_plugin.unwrap_or(true), new_pane_placement, Some(client_id), + None, ) }, ?); } else if let Some(active_tab) = @@ -5151,6 +5336,7 @@ pub(crate) fn screen_thread_main( should_focus_plugin.unwrap_or(true), new_pane_placement, None, + None, )?; } else { log::error!("Tab index not found: {:?}", tab_index); @@ -5160,7 +5346,6 @@ pub(crate) fn screen_thread_main( screen.render(None)?; } screen.log_and_report_session_state()?; - screen.unblock_input()?; }, ScreenInstruction::UpdatePluginLoadingStage(pid, loading_indication) => { let found_plugin = @@ -5206,6 +5391,7 @@ pub(crate) fn screen_thread_main( pane_id_to_replace, skip_cache, client_id, + completion_tx, ) => match pane_id_to_replace { Some(pane_id_to_replace) if should_open_in_place => { match screen.active_tab_indices.values().next() { @@ -5227,6 +5413,7 @@ pub(crate) fn screen_thread_main( None, None, None, + completion_tx, ))?; }, None => { @@ -5275,6 +5462,7 @@ pub(crate) fn screen_thread_main( None, None, None, + completion_tx, ))?; } }, @@ -5292,6 +5480,7 @@ pub(crate) fn screen_thread_main( skip_cache, cwd, client_id, + completion_tx, ) => match pane_id_to_replace { Some(pane_id_to_replace) => match screen.active_tab_indices.values().next() { Some(tab_index) => { @@ -5312,6 +5501,7 @@ pub(crate) fn screen_thread_main( cwd, None, None, + completion_tx, ))?; }, None => { @@ -5350,6 +5540,7 @@ pub(crate) fn screen_thread_main( cwd, None, None, + completion_tx, ))?; }, None => { @@ -5369,11 +5560,22 @@ pub(crate) fn screen_thread_main( } screen.log_and_report_session_state()?; }, - ScreenInstruction::FocusPaneWithId(pane_id, should_float_if_hidden, client_id) => { + ScreenInstruction::FocusPaneWithId( + pane_id, + should_float_if_hidden, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.focus_pane_with_id(pane_id, should_float_if_hidden, client_id)?; screen.log_and_report_session_state()?; }, - ScreenInstruction::RenamePane(pane_id, new_name) => { + ScreenInstruction::RenamePane( + pane_id, + new_name, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { let all_tabs = screen.get_tabs_mut(); for tab in all_tabs.values_mut() { if tab.has_pane_with_pid(&pane_id) { @@ -5386,7 +5588,12 @@ pub(crate) fn screen_thread_main( } screen.log_and_report_session_state()?; }, - ScreenInstruction::RenameTab(tab_index, new_name) => { + ScreenInstruction::RenameTab( + tab_index, + new_name, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { match screen.tabs.get_mut(&tab_index.saturating_sub(1)) { Some(tab) => { tab.name = String::from_utf8_lossy(&new_name).to_string(); @@ -5415,13 +5622,27 @@ pub(crate) fn screen_thread_main( ); } }, - ScreenInstruction::BreakPane(default_layout, default_shell, client_id) => { + ScreenInstruction::BreakPane( + default_layout, + default_shell, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.break_pane(default_shell, default_layout, client_id)?; }, - ScreenInstruction::BreakPaneRight(client_id) => { + ScreenInstruction::BreakPaneRight( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.break_pane_to_new_tab(Direction::Right, client_id)?; }, - ScreenInstruction::BreakPaneLeft(client_id) => { + ScreenInstruction::BreakPaneLeft( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.break_pane_to_new_tab(Direction::Left, client_id)?; }, ScreenInstruction::UpdateSessionInfos(new_session_infos, resurrectable_sessions) => { @@ -5434,6 +5655,8 @@ pub(crate) fn screen_thread_main( invoked_with, close_replaced_pane, client_id_tab_index_or_pane_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it ) => { screen.replace_pane( new_pane_id, @@ -5444,17 +5667,19 @@ pub(crate) fn screen_thread_main( client_id_tab_index_or_pane_id, )?; - screen.unblock_input()?; screen.log_and_report_session_state()?; - - screen.render(None)?; }, ScreenInstruction::SerializeLayoutForResurrection => { if screen.session_serialization { screen.dump_layout_to_hd()?; } }, - ScreenInstruction::RenameSession(name, client_id) => { + ScreenInstruction::RenameSession( + name, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { if screen.session_infos_on_machine.contains_key(&name) { let error_text = "A session by this name already exists."; log::error!("{}", error_text); @@ -5518,7 +5743,6 @@ pub(crate) fn screen_thread_main( // set the env variable set_session_name(name.clone()); - screen.unblock_input()?; let connected_client_ids: Vec<ClientId> = screen.active_tab_indices.keys().copied().collect(); for client_id in connected_client_ids { @@ -5570,17 +5794,18 @@ pub(crate) fn screen_thread_main( ) .non_fatal(); }, - ScreenInstruction::RerunCommandPane(terminal_pane_id) => { - screen.rerun_command_pane_with_id(terminal_pane_id) + ScreenInstruction::RerunCommandPane(terminal_pane_id, completion_tx) => { + screen.rerun_command_pane_with_id(terminal_pane_id, completion_tx) }, ScreenInstruction::ResizePaneWithId(resize, pane_id) => { screen.resize_pane_with_id(resize, pane_id) }, - ScreenInstruction::EditScrollbackForPaneWithId(pane_id) => { + ScreenInstruction::EditScrollbackForPaneWithId(pane_id, completion_tx) => { let all_tabs = screen.get_tabs_mut(); for tab in all_tabs.values_mut() { if tab.has_pane_with_pid(&pane_id) { - tab.edit_scrollback_for_pane_with_id(pane_id).non_fatal(); + tab.edit_scrollback_for_pane_with_id(pane_id, completion_tx) + .non_fatal(); break; } } @@ -5590,7 +5815,7 @@ pub(crate) fn screen_thread_main( let all_tabs = screen.get_tabs_mut(); for tab in all_tabs.values_mut() { if tab.has_pane_with_pid(&pane_id) { - tab.write_to_pane_id(&None, bytes, false, pane_id, None) + tab.write_to_pane_id(&None, bytes, false, pane_id, None, None) .non_fatal(); break; } @@ -5811,16 +6036,24 @@ pub(crate) fn screen_thread_main( } screen.clear_pane_group(&client_id); }, - ScreenInstruction::TogglePanePinned(client_id) => { + ScreenInstruction::TogglePanePinned( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.toggle_pane_pinned(client_id); }, ScreenInstruction::SetFloatingPanePinned(pane_id, should_be_pinned) => { screen.set_floating_pane_pinned(pane_id, should_be_pinned); }, - ScreenInstruction::StackPanes(pane_ids_to_stack, client_id) => { + ScreenInstruction::StackPanes( + pane_ids_to_stack, + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { if let Some(last_pane_id) = screen.stack_panes(pane_ids_to_stack) { let _ = screen.focus_pane_with_id(last_pane_id, false, client_id); - let _ = screen.unblock_input(); let _ = screen.render(None); let pane_group = screen.get_client_pane_group(&client_id); if !pane_group.is_empty() { @@ -5834,9 +6067,12 @@ pub(crate) fn screen_thread_main( screen.clear_pane_group(&client_id); } }, - ScreenInstruction::ChangeFloatingPanesCoordinates(pane_ids_and_coordinates) => { + ScreenInstruction::ChangeFloatingPanesCoordinates( + pane_ids_and_coordinates, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.change_floating_panes_coordinates(pane_ids_and_coordinates); - let _ = screen.unblock_input(); let _ = screen.render(None); }, ScreenInstruction::GroupAndUngroupPanes( @@ -5853,10 +6089,18 @@ pub(crate) fn screen_thread_main( ); let _ = screen.log_and_report_session_state(); }, - ScreenInstruction::TogglePaneInGroup(client_id) => { + ScreenInstruction::TogglePaneInGroup( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.toggle_pane_in_group(client_id).non_fatal(); }, - ScreenInstruction::ToggleGroupMarking(client_id) => { + ScreenInstruction::ToggleGroupMarking( + client_id, + _completion_tx, // the action ends here, dropping this will release anything + // waiting for it + ) => { screen.toggle_group_marking(client_id).non_fatal(); }, ScreenInstruction::SessionSharingStatusChange(web_sharing) => { diff --git a/zellij-server/src/tab/layout_applier.rs b/zellij-server/src/tab/layout_applier.rs index 6c047504..5e52888a 100644 --- a/zellij-server/src/tab/layout_applier.rs +++ b/zellij-server/src/tab/layout_applier.rs @@ -319,9 +319,10 @@ impl<'a> LayoutApplier<'a> { .assign_geom_for_pane_with_run(run_instruction); } for (unused_pid, _) in new_terminal_ids { - let _ = self - .senders - .send_to_pty(PtyInstruction::ClosePane(PaneId::Terminal(*unused_pid))); + let _ = self.senders.send_to_pty(PtyInstruction::ClosePane( + PaneId::Terminal(*unused_pid), + None, + )); } } fn new_tiled_plugin_pane( @@ -458,6 +459,7 @@ impl<'a> LayoutApplier<'a> { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + None, ); if let Some(pane_initial_contents) = &floating_pane_layout.pane_initial_contents { new_pane.handle_pty_bytes(pane_initial_contents.as_bytes().into()); @@ -511,6 +513,7 @@ impl<'a> LayoutApplier<'a> { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + None, ); if let Some(pane_initial_contents) = &layout.pane_initial_contents { new_pane.handle_pty_bytes(pane_initial_contents.as_bytes().into()); diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 2b76ead1..cd87b817 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -14,8 +14,8 @@ use std::path::PathBuf; use uuid::Uuid; use zellij_utils::data::PaneContents; use zellij_utils::data::{ - Direction, KeyWithModifier, PaneInfo, PermissionStatus, PermissionType, PluginPermission, - ResizeStrategy, WebSharing, + Direction, KeyWithModifier, NewPanePlacement, PaneInfo, PermissionStatus, PermissionType, + PluginPermission, ResizeStrategy, WebSharing, }; use zellij_utils::errors::prelude::*; use zellij_utils::input::command::RunCommand; @@ -33,6 +33,7 @@ use layout_applier::LayoutApplier; use swap_layouts::SwapLayouts; use self::clipboard::ClipboardProvider; +use crate::route::NotificationEnd; use crate::{ os_input_output::ServerOsApi, output::{CharacterChunk, Output, SixelImageChunk}, @@ -41,7 +42,7 @@ use crate::{ panes::{FloatingPanes, TiledPanes}, panes::{LinkHandler, PaneId, PluginPane, TerminalPane}, plugins::PluginInstruction, - pty::{ClientTabIndexOrPaneId, NewPanePlacement, PtyInstruction, VteBytes}, + pty::{ClientTabIndexOrPaneId, PtyInstruction, VteBytes}, thread_bus::ThreadSenders, ClientId, ServerInstruction, }; @@ -632,6 +633,7 @@ pub trait Pane { client_id: Option<ClientId>, _get_full_scrollback: bool, ) -> PaneContents; + fn update_exit_status(&mut self, _exit_status: i32) {} } #[derive(Clone, Debug)] @@ -850,10 +852,10 @@ impl Tab { ) { Ok(should_show_floating_panes) => { if should_show_floating_panes && !self.floating_panes.panes_are_visible() { - self.toggle_floating_panes(Some(client_id), None) + self.toggle_floating_panes(Some(client_id), None, None) .non_fatal(); } else if !should_show_floating_panes && self.floating_panes.panes_are_visible() { - self.toggle_floating_panes(Some(client_id), None) + self.toggle_floating_panes(Some(client_id), None, None) .non_fatal(); } self.tiled_panes.reapply_pane_frames(); @@ -1228,6 +1230,7 @@ impl Tab { &mut self, client_id: Option<ClientId>, default_shell: Option<TerminalAction>, + completion_tx: Option<NotificationEnd>, ) -> Result<()> { if self.floating_panes.panes_are_visible() { self.hide_floating_panes(); @@ -1260,6 +1263,8 @@ impl Tab { NewPanePlacement::Floating(None), should_start_suppressed, client_id_or_tab_index, + completion_tx, + false, // set_blocking ); self.senders .send_to_pty(instruction) @@ -1280,6 +1285,7 @@ impl Tab { should_focus_pane: bool, new_pane_placement: NewPanePlacement, client_id: Option<ClientId>, + blocking_notification: Option<NotificationEnd>, ) -> Result<()> { match new_pane_placement { NewPanePlacement::NoPreference => self.new_no_preference_pane( @@ -1289,6 +1295,7 @@ impl Tab { start_suppressed, should_focus_pane, client_id, + blocking_notification, ), NewPanePlacement::Tiled(None) => self.new_tiled_pane( pid, @@ -1297,13 +1304,24 @@ impl Tab { start_suppressed, should_focus_pane, client_id, + blocking_notification, ), NewPanePlacement::Tiled(Some(direction)) => { if let Some(client_id) = client_id { if direction == Direction::Left || direction == Direction::Right { - self.vertical_split(pid, initial_pane_title, client_id)?; + self.vertical_split( + pid, + initial_pane_title, + client_id, + blocking_notification, + )?; } else { - self.horizontal_split(pid, initial_pane_title, client_id)?; + self.horizontal_split( + pid, + initial_pane_title, + client_id, + blocking_notification, + )?; } } Ok(()) @@ -1315,6 +1333,7 @@ impl Tab { start_suppressed, should_focus_pane, floating_pane_coordinates, + blocking_notification, ), NewPanePlacement::InPlace { pane_id_to_replace, @@ -1323,9 +1342,10 @@ impl Tab { pid, initial_pane_title, invoked_with, - pane_id_to_replace, + pane_id_to_replace.map(|id| id.into()), close_replaced_pane, client_id, + blocking_notification, ), NewPanePlacement::Stacked(pane_id_to_stack_under) => self.new_stacked_pane( pid, @@ -1333,8 +1353,9 @@ impl Tab { invoked_with, start_suppressed, should_focus_pane, - pane_id_to_stack_under, + pane_id_to_stack_under.map(|id| id.into()), client_id, + blocking_notification, ), } } @@ -1346,6 +1367,7 @@ impl Tab { start_suppressed: bool, should_focus_pane: bool, client_id: Option<ClientId>, + blocking_notification: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to create new pane with id {pid:?}"); self.close_down_to_max_terminals() @@ -1370,6 +1392,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + blocking_notification, )) as Box<dyn Pane> }, PaneId::Plugin(plugin_pid) => { @@ -1448,6 +1471,7 @@ impl Tab { start_suppressed: bool, should_focus_pane: bool, client_id: Option<ClientId>, + blocking_notification: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to create new pane with id {pid:?}"); if should_focus_pane { @@ -1475,6 +1499,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + blocking_notification, )) as Box<dyn Pane> }, PaneId::Plugin(plugin_pid) => { @@ -1543,6 +1568,7 @@ impl Tab { start_suppressed: bool, should_focus_pane: bool, floating_pane_coordinates: Option<FloatingPaneCoordinates>, + blocking_notification: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to create new pane with id {pid:?}"); if should_focus_pane { @@ -1570,6 +1596,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + blocking_notification, )) as Box<dyn Pane> }, PaneId::Plugin(plugin_pid) => { @@ -1638,6 +1665,7 @@ impl Tab { pane_id_to_replace: Option<PaneId>, close_replaced_pane: bool, client_id: Option<ClientId>, + blocking_notification: Option<NotificationEnd>, ) -> Result<()> { match (pane_id_to_replace, client_id) { (Some(pane_id_to_replace), _) => { @@ -1646,6 +1674,7 @@ impl Tab { pid, close_replaced_pane, invoked_with, + blocking_notification, )?; }, (None, Some(client_id)) => match self.get_active_pane_id(client_id) { @@ -1655,6 +1684,7 @@ impl Tab { pid, close_replaced_pane, invoked_with, + blocking_notification, )?; }, None => { @@ -1679,6 +1709,7 @@ impl Tab { should_focus_pane: bool, pane_id_to_stack_under: Option<PaneId>, client_id: Option<ClientId>, + blocking_notification: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to create new pane with id {pid:?}"); if should_focus_pane { @@ -1706,6 +1737,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + blocking_notification, )) as Box<dyn Pane> }, PaneId::Plugin(plugin_pid) => { @@ -1887,6 +1919,7 @@ impl Tab { new_pane_id: PaneId, close_replaced_pane: bool, run: Option<Run>, + completion_tx: Option<NotificationEnd>, ) -> Result<()> { // this method creates a new pane from pid and replaces it with the active pane // the active pane is then suppressed (hidden and not rendered) until the current @@ -1913,6 +1946,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + completion_tx, ); let replaced_pane = if self.floating_panes.panes_contain(&old_pane_id) { self.floating_panes @@ -1925,7 +1959,7 @@ impl Tab { if close_replaced_pane { if let Some(pid) = replaced_pane.as_ref().map(|p| p.pid()) { self.senders - .send_to_pty(PtyInstruction::ClosePane(pid)) + .send_to_pty(PtyInstruction::ClosePane(pid, None)) .with_context(err_context)?; } drop(replaced_pane); @@ -2023,6 +2057,7 @@ impl Tab { &mut self, pane_id_to_replace: PaneId, pane_to_replace_with: Box<dyn Pane>, + completion_tx: Option<NotificationEnd>, ) { let mut replaced_pane = if self.floating_panes.panes_contain(&pane_id_to_replace) { self.floating_panes @@ -2034,7 +2069,9 @@ impl Tab { }; if let Some(replaced_pane) = replaced_pane.take() { let pane_id = replaced_pane.pid(); - let _ = self.senders.send_to_pty(PtyInstruction::ClosePane(pane_id)); + let _ = self + .senders + .send_to_pty(PtyInstruction::ClosePane(pane_id, completion_tx)); let _ = self.senders.send_to_plugin(PluginInstruction::Update(vec![( None, None, @@ -2048,6 +2085,7 @@ impl Tab { pid: PaneId, initial_pane_title: Option<String>, client_id: ClientId, + completion_tx: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to split pane {pid:?} horizontally for client {client_id}"); @@ -2079,6 +2117,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + completion_tx, ); self.tiled_panes .split_pane_horizontally(pid, Box::new(new_terminal), client_id); @@ -2097,7 +2136,7 @@ impl Tab { .with_context(err_context)?; } self.senders - .send_to_pty(PtyInstruction::ClosePane(pid)) + .send_to_pty(PtyInstruction::ClosePane(pid, completion_tx)) .with_context(err_context)?; return Ok(()); } @@ -2108,6 +2147,7 @@ impl Tab { pid: PaneId, initial_pane_title: Option<String>, client_id: ClientId, + completion_tx: Option<NotificationEnd>, ) -> Result<()> { let err_context = || format!("failed to split pane {pid:?} vertically for client {client_id}"); @@ -2139,6 +2179,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + completion_tx, ); self.tiled_panes .split_pane_vertically(pid, Box::new(new_terminal), client_id); @@ -2157,7 +2198,7 @@ impl Tab { .with_context(err_context)?; } self.senders - .send_to_pty(PtyInstruction::ClosePane(pid)) + .send_to_pty(PtyInstruction::ClosePane(pid, completion_tx)) .with_context(err_context)?; return Ok(()); } @@ -2374,6 +2415,7 @@ impl Tab { raw_input_bytes_are_kitty, pane_id, Some(client_id), + None, ) .context("failed to write to terminals on current tab")?; if ui_change_triggered { @@ -2421,6 +2463,7 @@ impl Tab { raw_input_bytes_are_kitty, pane_id, Some(client_id), + None, ) .with_context(|| format!("failed to write to active terminal for client {client_id}")) } @@ -2439,7 +2482,7 @@ impl Tab { .get_pane_id_at(position, false) .with_context(err_context)?; if let Some(pane_id) = pane_id { - self.write_to_pane_id(&None, input_bytes, false, pane_id, Some(client_id)) + self.write_to_pane_id(&None, input_bytes, false, pane_id, Some(client_id), None) .with_context(err_context)?; return Ok(()); } @@ -2449,7 +2492,7 @@ impl Tab { .get_pane_id_at(position, false) .with_context(err_context)?; if let Some(pane_id) = pane_id { - self.write_to_pane_id(&None, input_bytes, false, pane_id, Some(client_id)) + self.write_to_pane_id(&None, input_bytes, false, pane_id, Some(client_id), None) .with_context(err_context)?; return Ok(()); } @@ -2463,6 +2506,7 @@ impl Tab { raw_input_bytes_are_kitty: bool, pane_id: PaneId, client_id: Option<ClientId>, + completion_tx: Option<NotificationEnd>, ) -> Result<bool> { // returns true if we need to update the UI (eg. when a command pane is closed with ctrl-c) let err_context = || format!("failed to write to pane with id {pane_id:?}"); @@ -2510,12 +2554,13 @@ impl Tab { .send_to_pty(PtyInstruction::ReRunCommandInPane( PaneId::Terminal(active_terminal_id), command, + completion_tx, )) .with_context(err_context)?; should_update_ui = true; }, Some(AdjustedInput::CloseThisPane) => { - self.close_pane(PaneId::Terminal(active_terminal_id), false); + self.close_pane(PaneId::Terminal(active_terminal_id), false, None); should_update_ui = true; }, Some(AdjustedInput::DropToShellInThisPane { working_dir }) => { @@ -2525,6 +2570,7 @@ impl Tab { pane_id: PaneId::Terminal(active_terminal_id), shell: Some(self.default_shell.clone()), working_dir, + completion_tx, }) .with_context(err_context)?; should_update_ui = true; @@ -3299,9 +3345,9 @@ impl Tab { let terminals = self.get_tiled_pane_ids(); for &pid in terminals.iter().skip(max_panes - 1) { self.senders - .send_to_pty(PtyInstruction::ClosePane(pid)) + .send_to_pty(PtyInstruction::ClosePane(pid, None)) .context("failed to close down to max terminals")?; - self.close_pane(pid, false); + self.close_pane(pid, false, None); } } Ok(()) @@ -3364,7 +3410,12 @@ impl Tab { pane.set_mouse_selection_support(selection_support); } } - pub fn close_pane(&mut self, id: PaneId, ignore_suppressed_panes: bool) { + pub fn close_pane( + &mut self, + id: PaneId, + ignore_suppressed_panes: bool, + exit_status: Option<i32>, + ) { // we need to ignore suppressed panes when we toggle a pane to be floating/embedded(tiled) // this is because in that case, while we do use this logic, we're not actually closing the // pane, we're moving it @@ -3378,8 +3429,8 @@ impl Tab { }, }; } - if self.floating_panes.panes_contain(&id) { - let _closed_pane = self.floating_panes.remove_pane(id); + let closed_pane = if self.floating_panes.panes_contain(&id) { + let closed_pane = self.floating_panes.remove_pane(id); self.floating_panes.move_clients_out_of_pane(id); if !self.floating_panes.has_selectable_panes() { self.swap_layouts.reset_floating_damage(); @@ -3396,11 +3447,12 @@ impl Tab { // confusing let _ = self.relayout_floating_panes(false); } + closed_pane } else { if self.tiled_panes.fullscreen_is_active() { self.tiled_panes.unset_fullscreen(); } - let _closed_pane = self.tiled_panes.remove_pane(id); + let closed_pane = self.tiled_panes.remove_pane(id); self.set_force_render(); self.tiled_panes.set_force_render(); if self.auto_layout && !self.swap_layouts.is_tiled_damaged() { @@ -3409,7 +3461,14 @@ impl Tab { // confusing let _ = self.relayout_tiled_panes(false); } + closed_pane }; + if let Some(exit_status) = exit_status { + if let Some(mut closed_pane) = closed_pane { + // in case we need to update on Drop + closed_pane.update_exit_status(exit_status); + } + } let _ = self.senders.send_to_plugin(PluginInstruction::Update(vec![( None, None, @@ -3561,24 +3620,31 @@ impl Tab { ) }) } - pub fn close_focused_pane(&mut self, client_id: ClientId) -> Result<()> { + pub fn close_focused_pane( + &mut self, + client_id: ClientId, + completion_tx: Option<NotificationEnd>, + ) -> Result<()> { let err_context = |pane_id| { format!("failed to close focused pane (ID {pane_id:?}) for client {client_id}") }; if self.floating_panes.panes_are_visible() { if let Some(active_floating_pane_id) = self.floating_panes.active_pane_id(client_id) { - self.close_pane(active_floating_pane_id, false); + self.close_pane(active_floating_pane_id, false, None); self.senders - .send_to_pty(PtyInstruction::ClosePane(active_floating_pane_id)) + .send_to_pty(PtyInstruction::ClosePane( + active_floating_pane_id, + completion_tx, + )) .with_context(|| err_context(active_floating_pane_id))?; return Ok(()); } } if let Some(active_pane_id) = self.tiled_panes.get_active_pane_id(client_id) { - self.close_pane(active_pane_id, false); + self.close_pane(active_pane_id, false, None); self.senders - .send_to_pty(PtyInstruction::ClosePane(active_pane_id)) + .send_to_pty(PtyInstruction::ClosePane(active_pane_id, completion_tx)) .with_context(|| err_context(active_pane_id))?; } Ok(()) @@ -3623,7 +3689,11 @@ impl Tab { } Ok(()) } - pub fn edit_scrollback(&mut self, client_id: ClientId) -> Result<()> { + pub fn edit_scrollback( + &mut self, + client_id: ClientId, + completion_tx: Option<NotificationEnd>, + ) -> Result<()> { let err_context = || format!("failed to edit scrollback for client {client_id}"); let mut file = temp_dir(); @@ -3642,10 +3712,15 @@ impl Tab { file, line_number, ClientTabIndexOrPaneId::ClientId(client_id), + completion_tx, )) .with_context(err_context) } - pub fn edit_scrollback_for_pane_with_id(&mut self, pane_id: PaneId) -> Result<()> { + pub fn edit_scrollback_for_pane_with_id( + &mut self, + pane_id: PaneId, + completion_tx: Option<NotificationEnd>, + ) -> Result<()> { if let PaneId::Terminal(_terminal_pane_id) = pane_id { let mut file = temp_dir(); file.push(format!("{}.dump", Uuid::new_v4())); @@ -3658,6 +3733,7 @@ impl Tab { file, line_number, ClientTabIndexOrPaneId::PaneId(pane_id), + completion_tx, )) } else { log::error!("Editing plugin pane scrollback is currently unsupported."); @@ -5146,7 +5222,11 @@ impl Tab { self.focus_suppressed_pane_for_all_clients(PaneId::Plugin(pid)); } } - pub fn rerun_terminal_pane_with_id(&mut self, terminal_pane_id: u32) { + pub fn rerun_terminal_pane_with_id( + &mut self, + terminal_pane_id: u32, + completion_tx: Option<NotificationEnd>, + ) { let pane_id = PaneId::Terminal(terminal_pane_id); match self .floating_panes @@ -5160,6 +5240,7 @@ impl Tab { let _ = self.senders.send_to_pty(PtyInstruction::ReRunCommandInPane( pane_id, command_to_rerun, + completion_tx, )); } else { log::error!("Pane is still running!") @@ -5411,6 +5492,7 @@ impl Tab { self.arrow_fonts, self.styled_underlines, self.explicitly_disable_kitty_keyboard_protocol, + None, ); new_pane.update_name("EDITING SCROLLBACK"); // we do this here and not in the // constructor so it won't be overrided diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs index 9962611d..029df49d 100644 --- a/zellij-server/src/tab/unit/tab_integration_tests.rs +++ b/zellij-server/src/tab/unit/tab_integration_tests.rs @@ -32,7 +32,6 @@ use zellij_utils::ipc::IpcReceiverWithContext; use zellij_utils::pane_size::{Size, SizeInPixels}; use zellij_utils::position::Position; -use crate::pty::NewPanePlacement; use crate::pty_writer::PtyWriteInstruction; use zellij_utils::channels::{self, ChannelWithContext, SenderWithContext}; @@ -43,7 +42,7 @@ use std::rc::Rc; use interprocess::local_socket::LocalSocketStream; use zellij_utils::{ - data::{InputMode, ModeInfo, Palette, Style}, + data::{InputMode, ModeInfo, NewPanePlacement, Palette, Style}, input::command::{RunCommand, TerminalAction}, ipc::{ClientToServerMsg, ServerToClientMsg}, }; @@ -966,6 +965,7 @@ fn increase_tiled_pane_sizes_with_stacked_resizes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1019,14 +1019,15 @@ fn increase_tiled_pane_sizes_with_stacked_resizes_into_uneven_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } tab.move_focus_up(client_id).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, client_id) + tab.vertical_split(PaneId::Terminal(4), None, client_id, None) .unwrap(); tab.move_focus_right(client_id).unwrap(); - tab.horizontal_split(PaneId::Terminal(5), None, client_id) + tab.horizontal_split(PaneId::Terminal(5), None, client_id, None) .unwrap(); tab.move_focus_down(client_id).unwrap(); @@ -1081,6 +1082,7 @@ fn split_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1089,7 +1091,7 @@ fn split_stack_vertically() { .unwrap(); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) .unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, client_id) + tab.vertical_split(PaneId::Terminal(4), None, client_id, None) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -1121,6 +1123,7 @@ fn split_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1129,7 +1132,7 @@ fn split_stack_horizontally() { .unwrap(); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) .unwrap(); - tab.horizontal_split(PaneId::Terminal(4), None, client_id) + tab.horizontal_split(PaneId::Terminal(4), None, client_id, None) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -1163,6 +1166,7 @@ fn render_stacks_without_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1171,7 +1175,7 @@ fn render_stacks_without_pane_frames() { .unwrap(); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) .unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, client_id) + tab.vertical_split(PaneId::Terminal(4), None, client_id, None) .unwrap(); for i in 5..7 { let new_pane_id_1 = PaneId::Terminal(i); @@ -1183,6 +1187,7 @@ fn render_stacks_without_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1197,6 +1202,7 @@ fn render_stacks_without_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1211,6 +1217,7 @@ fn render_stacks_without_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -1254,6 +1261,7 @@ fn dump_screen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes())) @@ -1290,6 +1298,7 @@ fn clear_screen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes())) @@ -1315,7 +1324,8 @@ fn new_floating_pane() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -1324,6 +1334,7 @@ fn new_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1359,6 +1370,7 @@ fn new_stacked_pane() { true, NewPanePlacement::Stacked(None), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -1381,7 +1393,8 @@ fn floating_panes_persist_across_toggles() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -1390,9 +1403,11 @@ fn floating_panes_persist_across_toggles() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); // here we send bytes to the pane when it's not visible to make sure they're still handled and // we see them once we toggle the panes back tab.handle_pty_bytes( @@ -1400,7 +1415,8 @@ fn floating_panes_persist_across_toggles() { Vec::from("\n\n\n I am scratch terminal".as_bytes()), ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -1421,7 +1437,8 @@ fn toggle_floating_panes_off() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -1430,6 +1447,7 @@ fn toggle_floating_panes_off() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1437,7 +1455,8 @@ fn toggle_floating_panes_off() { Vec::from("\n\n\n I am scratch terminal".as_bytes()), ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -1458,7 +1477,8 @@ fn toggle_floating_panes_on() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -1467,6 +1487,7 @@ fn toggle_floating_panes_on() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1474,8 +1495,10 @@ fn toggle_floating_panes_on() { Vec::from("\n\n\n I am scratch terminal".as_bytes()), ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -1500,7 +1523,8 @@ fn five_new_floating_panes() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1509,6 +1533,7 @@ fn five_new_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1519,6 +1544,7 @@ fn five_new_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1529,6 +1555,7 @@ fn five_new_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1539,6 +1566,7 @@ fn five_new_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1549,6 +1577,7 @@ fn five_new_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1584,7 +1613,8 @@ fn increase_floating_pane_size() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1593,6 +1623,7 @@ fn increase_floating_pane_size() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1622,7 +1653,8 @@ fn decrease_floating_pane_size() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1631,6 +1663,7 @@ fn decrease_floating_pane_size() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1660,7 +1693,8 @@ fn resize_floating_pane_left() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1669,6 +1703,7 @@ fn resize_floating_pane_left() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1701,7 +1736,8 @@ fn resize_floating_pane_right() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1710,6 +1746,7 @@ fn resize_floating_pane_right() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1742,7 +1779,8 @@ fn resize_floating_pane_up() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1751,6 +1789,7 @@ fn resize_floating_pane_up() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1783,7 +1822,8 @@ fn resize_floating_pane_down() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1792,6 +1832,7 @@ fn resize_floating_pane_down() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1828,7 +1869,8 @@ fn move_floating_pane_focus_left() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1837,6 +1879,7 @@ fn move_floating_pane_focus_left() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1847,6 +1890,7 @@ fn move_floating_pane_focus_left() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1857,6 +1901,7 @@ fn move_floating_pane_focus_left() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1867,6 +1912,7 @@ fn move_floating_pane_focus_left() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1877,6 +1923,7 @@ fn move_floating_pane_focus_left() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -1923,7 +1970,8 @@ fn move_floating_pane_focus_right() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -1932,6 +1980,7 @@ fn move_floating_pane_focus_right() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1942,6 +1991,7 @@ fn move_floating_pane_focus_right() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1952,6 +2002,7 @@ fn move_floating_pane_focus_right() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1962,6 +2013,7 @@ fn move_floating_pane_focus_right() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -1972,6 +2024,7 @@ fn move_floating_pane_focus_right() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2019,7 +2072,8 @@ fn move_floating_pane_focus_up() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2028,6 +2082,7 @@ fn move_floating_pane_focus_up() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2038,6 +2093,7 @@ fn move_floating_pane_focus_up() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2048,6 +2104,7 @@ fn move_floating_pane_focus_up() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2058,6 +2115,7 @@ fn move_floating_pane_focus_up() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2068,6 +2126,7 @@ fn move_floating_pane_focus_up() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2114,7 +2173,8 @@ fn move_floating_pane_focus_down() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2123,6 +2183,7 @@ fn move_floating_pane_focus_down() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2133,6 +2194,7 @@ fn move_floating_pane_focus_down() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2143,6 +2205,7 @@ fn move_floating_pane_focus_down() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2153,6 +2216,7 @@ fn move_floating_pane_focus_down() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2163,6 +2227,7 @@ fn move_floating_pane_focus_down() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2210,7 +2275,8 @@ fn move_floating_pane_focus_with_mouse() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2219,6 +2285,7 @@ fn move_floating_pane_focus_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2229,6 +2296,7 @@ fn move_floating_pane_focus_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2239,6 +2307,7 @@ fn move_floating_pane_focus_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2249,6 +2318,7 @@ fn move_floating_pane_focus_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2259,6 +2329,7 @@ fn move_floating_pane_focus_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2314,7 +2385,8 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2323,6 +2395,7 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2333,6 +2406,7 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2343,6 +2417,7 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2353,6 +2428,7 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2363,6 +2439,7 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2418,7 +2495,8 @@ fn drag_pane_with_mouse() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2427,6 +2505,7 @@ fn drag_pane_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2437,6 +2516,7 @@ fn drag_pane_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2447,6 +2527,7 @@ fn drag_pane_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2457,6 +2538,7 @@ fn drag_pane_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2467,6 +2549,7 @@ fn drag_pane_with_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2522,7 +2605,8 @@ fn mark_text_inside_floating_pane() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2531,6 +2615,7 @@ fn mark_text_inside_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2541,6 +2626,7 @@ fn mark_text_inside_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2551,6 +2637,7 @@ fn mark_text_inside_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2561,6 +2648,7 @@ fn mark_text_inside_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2571,6 +2659,7 @@ fn mark_text_inside_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2634,7 +2723,8 @@ fn resize_tab_with_floating_panes() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2643,6 +2733,7 @@ fn resize_tab_with_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2653,6 +2744,7 @@ fn resize_tab_with_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2663,6 +2755,7 @@ fn resize_tab_with_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2673,6 +2766,7 @@ fn resize_tab_with_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2683,6 +2777,7 @@ fn resize_tab_with_floating_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2728,7 +2823,8 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2737,6 +2833,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2747,6 +2844,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2757,6 +2855,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2767,6 +2866,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2777,6 +2877,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2818,7 +2919,8 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -2827,6 +2929,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2837,6 +2940,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2847,6 +2951,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2857,6 +2962,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -2867,6 +2973,7 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2909,7 +3016,8 @@ fn embed_floating_pane() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -2918,6 +3026,7 @@ fn embed_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2954,6 +3063,7 @@ fn float_embedded_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -2983,7 +3093,8 @@ fn embed_floating_pane_without_pane_frames() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.set_pane_frames(false); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -2992,6 +3103,7 @@ fn embed_floating_pane_without_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -3029,6 +3141,7 @@ fn float_embedded_pane_without_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -3140,6 +3253,7 @@ fn rename_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -3235,7 +3349,8 @@ fn move_floating_pane_with_sixel_image() { }))); let mut output = Output::new(sixel_image_store.clone(), character_cell_size, true); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3244,6 +3359,7 @@ fn move_floating_pane_with_sixel_image() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); let fixture = read_fixture("sixel-image-500px.six"); @@ -3287,7 +3403,8 @@ fn floating_pane_above_sixel_image() { }))); let mut output = Output::new(sixel_image_store.clone(), character_cell_size, true); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3296,6 +3413,7 @@ fn floating_pane_above_sixel_image() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); let fixture = read_fixture("sixel-image-500px.six"); @@ -3359,7 +3477,8 @@ fn suppress_floating_pane() { let editor_pane_id = PaneId::Terminal(3); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3368,6 +3487,7 @@ fn suppress_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) @@ -3400,7 +3520,7 @@ fn close_suppressing_tiled_pane() { .unwrap(); tab.handle_pty_bytes(1, Vec::from("\n\n\nI am the original pane".as_bytes())) .unwrap(); - tab.close_pane(new_pane_id, false); + tab.close_pane(new_pane_id, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3423,7 +3543,8 @@ fn close_suppressing_floating_pane() { let editor_pane_id = PaneId::Terminal(3); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3432,6 +3553,7 @@ fn close_suppressing_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) @@ -3440,7 +3562,7 @@ fn close_suppressing_floating_pane() { .unwrap(); tab.handle_pty_bytes(2, Vec::from("\n\n\nI am the original pane".as_bytes())) .unwrap(); - tab.close_pane(editor_pane_id, false); + tab.close_pane(editor_pane_id, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3468,7 +3590,7 @@ fn suppress_tiled_pane_float_it_and_close() { tab.handle_pty_bytes(1, Vec::from("\n\n\nI am the original pane".as_bytes())) .unwrap(); tab.toggle_pane_embed_or_floating(client_id).unwrap(); - tab.close_pane(new_pane_id, false); + tab.close_pane(new_pane_id, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3491,7 +3613,8 @@ fn suppress_floating_pane_embed_it_and_close_it() { let editor_pane_id = PaneId::Terminal(3); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3500,6 +3623,7 @@ fn suppress_floating_pane_embed_it_and_close_it() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) @@ -3509,7 +3633,7 @@ fn suppress_floating_pane_embed_it_and_close_it() { tab.handle_pty_bytes(2, Vec::from("\n\n\nI am the original pane".as_bytes())) .unwrap(); tab.toggle_pane_embed_or_floating(client_id).unwrap(); - tab.close_pane(editor_pane_id, false); + tab.close_pane(editor_pane_id, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3561,7 +3685,8 @@ fn resize_whole_tab_while_floting_pane_is_suppressed() { let editor_pane_id = PaneId::Terminal(3); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3570,6 +3695,7 @@ fn resize_whole_tab_while_floting_pane_is_suppressed() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) @@ -3671,7 +3797,8 @@ fn enter_search_floating_pane() { let mut tab = create_new_tab(size, mode_info); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id, None, @@ -3680,6 +3807,7 @@ fn enter_search_floating_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); @@ -4455,6 +4583,7 @@ fn move_pane_focus_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -4489,7 +4618,8 @@ fn move_floating_pane_focus_sends_tty_csi_event() { let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -4498,6 +4628,7 @@ fn move_floating_pane_focus_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4508,6 +4639,7 @@ fn move_floating_pane_focus_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -4548,7 +4680,8 @@ fn toggle_floating_panes_on_sends_tty_csi_event() { let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -4557,6 +4690,7 @@ fn toggle_floating_panes_on_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4567,9 +4701,11 @@ fn toggle_floating_panes_on_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.handle_pty_bytes( 1, // subscribe to focus events @@ -4588,7 +4724,8 @@ fn toggle_floating_panes_on_sends_tty_csi_event() { Vec::from("\u{1b}[?1004h".as_bytes()), ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); assert_snapshot!(format!("{:?}", *tty_stdin_bytes.lock().unwrap())); } @@ -4608,7 +4745,8 @@ fn toggle_floating_panes_off_sends_tty_csi_event() { let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -4617,6 +4755,7 @@ fn toggle_floating_panes_off_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4627,6 +4766,7 @@ fn toggle_floating_panes_off_sends_tty_csi_event() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_pty_bytes( @@ -4647,7 +4787,8 @@ fn toggle_floating_panes_off_sends_tty_csi_event() { Vec::from("\u{1b}[?1004h".as_bytes()), ) .unwrap(); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); assert_snapshot!(format!("{:?}", *tty_stdin_bytes.lock().unwrap())); } @@ -4697,6 +4838,7 @@ fn can_swap_tiled_layout_at_runtime() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.next_swap_layout().unwrap(); @@ -4753,7 +4895,8 @@ fn can_swap_floating_layout_at_runtime() { let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.toggle_floating_panes(Some(client_id), None).unwrap(); + tab.toggle_floating_panes(Some(client_id), None, None) + .unwrap(); tab.new_pane( new_pane_id_1, None, @@ -4762,6 +4905,7 @@ fn can_swap_floating_layout_at_runtime() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4772,6 +4916,7 @@ fn can_swap_floating_layout_at_runtime() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.next_swap_layout().unwrap(); @@ -4833,6 +4978,7 @@ fn swapping_layouts_after_resize_snaps_to_current_layout() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.next_swap_layout().unwrap(); @@ -4893,6 +5039,7 @@ fn swap_tiled_layout_with_stacked_children() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4903,6 +5050,7 @@ fn swap_tiled_layout_with_stacked_children() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4913,6 +5061,7 @@ fn swap_tiled_layout_with_stacked_children() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -4966,6 +5115,7 @@ fn swap_tiled_layout_with_only_stacked_children() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4976,6 +5126,7 @@ fn swap_tiled_layout_with_only_stacked_children() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -4986,6 +5137,7 @@ fn swap_tiled_layout_with_only_stacked_children() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -5042,6 +5194,7 @@ fn swap_tiled_layout_with_stacked_children_and_no_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5052,6 +5205,7 @@ fn swap_tiled_layout_with_stacked_children_and_no_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5062,6 +5216,7 @@ fn swap_tiled_layout_with_stacked_children_and_no_pane_frames() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -5118,6 +5273,7 @@ fn move_focus_up_with_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5128,6 +5284,7 @@ fn move_focus_up_with_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5138,6 +5295,7 @@ fn move_focus_up_with_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); @@ -5196,6 +5354,7 @@ fn move_focus_down_with_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5206,6 +5365,7 @@ fn move_focus_down_with_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5216,6 +5376,7 @@ fn move_focus_down_with_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); @@ -5276,11 +5437,12 @@ fn move_focus_right_into_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } tab.move_focus_left(client_id); - tab.horizontal_split(PaneId::Terminal(16), None, client_id) + tab.horizontal_split(PaneId::Terminal(16), None, client_id, None) .unwrap(); tab.move_focus_up(client_id); @@ -5347,11 +5509,12 @@ fn move_focus_left_into_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } tab.move_focus_right(client_id); - tab.horizontal_split(PaneId::Terminal(1), None, client_id) + tab.horizontal_split(PaneId::Terminal(1), None, client_id, None) .unwrap(); tab.move_focus_up(client_id); @@ -5420,6 +5583,7 @@ fn move_focus_up_into_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } @@ -5427,7 +5591,7 @@ fn move_focus_up_into_stacked_panes() { tab.move_focus_up(client_id); tab.move_focus_left(client_id); tab.move_focus_down(client_id); - tab.vertical_split(PaneId::Terminal(7), None, client_id) + tab.vertical_split(PaneId::Terminal(7), None, client_id, None) .unwrap(); tab.move_focus_up(client_id); @@ -5494,12 +5658,13 @@ fn move_focus_down_into_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); } tab.move_focus_left(client_id); tab.move_focus_up(client_id); - tab.vertical_split(PaneId::Terminal(7), None, client_id) + tab.vertical_split(PaneId::Terminal(7), None, client_id, None) .unwrap(); tab.move_focus_down(client_id); @@ -5564,6 +5729,7 @@ fn close_main_stacked_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5574,6 +5740,7 @@ fn close_main_stacked_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5584,9 +5751,10 @@ fn close_main_stacked_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); - tab.close_pane(new_pane_id_2, false); + tab.close_pane(new_pane_id_2, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -5643,6 +5811,7 @@ fn close_main_stacked_pane_in_mid_stack() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5653,6 +5822,7 @@ fn close_main_stacked_pane_in_mid_stack() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5663,6 +5833,7 @@ fn close_main_stacked_pane_in_mid_stack() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5673,6 +5844,7 @@ fn close_main_stacked_pane_in_mid_stack() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5683,12 +5855,13 @@ fn close_main_stacked_pane_in_mid_stack() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.move_focus_up(client_id); - tab.close_pane(new_pane_id_3, false); + tab.close_pane(new_pane_id_3, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -5745,6 +5918,7 @@ fn close_one_liner_stacked_pane_below_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5755,6 +5929,7 @@ fn close_one_liner_stacked_pane_below_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5765,6 +5940,7 @@ fn close_one_liner_stacked_pane_below_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5775,6 +5951,7 @@ fn close_one_liner_stacked_pane_below_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5785,13 +5962,14 @@ fn close_one_liner_stacked_pane_below_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_left(client_id); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.move_focus_up(client_id); - tab.close_pane(new_pane_id_2, false); + tab.close_pane(new_pane_id_2, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -5848,6 +6026,7 @@ fn close_one_liner_stacked_pane_above_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5858,6 +6037,7 @@ fn close_one_liner_stacked_pane_above_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5868,6 +6048,7 @@ fn close_one_liner_stacked_pane_above_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5878,6 +6059,7 @@ fn close_one_liner_stacked_pane_above_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5888,12 +6070,13 @@ fn close_one_liner_stacked_pane_above_main_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.move_focus_up(client_id); - tab.close_pane(new_pane_id_2, false); + tab.close_pane(new_pane_id_2, false, None); tab.render(&mut output, None).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -5950,6 +6133,7 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5960,6 +6144,7 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5970,6 +6155,7 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5980,6 +6166,7 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -5990,6 +6177,7 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); @@ -6056,6 +6244,7 @@ fn can_increase_size_of_main_pane_in_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6066,6 +6255,7 @@ fn can_increase_size_of_main_pane_in_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6076,6 +6266,7 @@ fn can_increase_size_of_main_pane_in_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6086,6 +6277,7 @@ fn can_increase_size_of_main_pane_in_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6096,6 +6288,7 @@ fn can_increase_size_of_main_pane_in_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); @@ -6162,6 +6355,7 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6172,6 +6366,7 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6182,6 +6377,7 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6192,6 +6388,7 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6202,6 +6399,7 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); let _ = tab.move_focus_right(client_id); @@ -6263,6 +6461,7 @@ fn can_increase_size_into_pane_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6273,6 +6472,7 @@ fn can_increase_size_into_pane_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6283,6 +6483,7 @@ fn can_increase_size_into_pane_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6293,6 +6494,7 @@ fn can_increase_size_into_pane_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6303,6 +6505,7 @@ fn can_increase_size_into_pane_stack_horizontally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.resize( @@ -6368,6 +6571,7 @@ fn can_increase_size_into_pane_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6378,6 +6582,7 @@ fn can_increase_size_into_pane_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6388,6 +6593,7 @@ fn can_increase_size_into_pane_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6398,6 +6604,7 @@ fn can_increase_size_into_pane_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6408,6 +6615,7 @@ fn can_increase_size_into_pane_stack_vertically() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_right(client_id); @@ -6476,6 +6684,7 @@ fn can_increase_size_into_pane_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6486,6 +6695,7 @@ fn can_increase_size_into_pane_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6496,6 +6706,7 @@ fn can_increase_size_into_pane_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6506,6 +6717,7 @@ fn can_increase_size_into_pane_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6516,6 +6728,7 @@ fn can_increase_size_into_pane_stack_non_directionally() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) @@ -6576,6 +6789,7 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6586,6 +6800,7 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6596,6 +6811,7 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6606,6 +6822,7 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6616,6 +6833,7 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.resize_whole_tab(Size { @@ -6678,6 +6896,7 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6688,6 +6907,7 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6698,6 +6918,7 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6708,6 +6929,7 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6718,6 +6940,7 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.resize_whole_tab(Size { @@ -6785,6 +7008,7 @@ fn cannot_decrease_stack_size_beyond_minimum_height() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6795,6 +7019,7 @@ fn cannot_decrease_stack_size_beyond_minimum_height() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6805,6 +7030,7 @@ fn cannot_decrease_stack_size_beyond_minimum_height() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6815,6 +7041,7 @@ fn cannot_decrease_stack_size_beyond_minimum_height() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6825,6 +7052,7 @@ fn cannot_decrease_stack_size_beyond_minimum_height() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_down(client_id); @@ -6892,6 +7120,7 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6902,6 +7131,7 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6912,6 +7142,7 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6922,6 +7153,7 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -6932,6 +7164,7 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_mouse_event( @@ -6996,6 +7229,7 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7006,6 +7240,7 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7016,6 +7251,7 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7026,6 +7262,7 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7036,6 +7273,7 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_mouse_event( @@ -7105,6 +7343,7 @@ fn close_stacked_pane_with_previously_focused_other_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7115,6 +7354,7 @@ fn close_stacked_pane_with_previously_focused_other_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7125,6 +7365,7 @@ fn close_stacked_pane_with_previously_focused_other_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7135,6 +7376,7 @@ fn close_stacked_pane_with_previously_focused_other_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7145,6 +7387,7 @@ fn close_stacked_pane_with_previously_focused_other_pane() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.handle_mouse_event( @@ -7157,7 +7400,7 @@ fn close_stacked_pane_with_previously_focused_other_pane() { client_id, ) .unwrap(); - tab.close_pane(PaneId::Terminal(4), false); + tab.close_pane(PaneId::Terminal(4), false, None); tab.render(&mut output, None).unwrap(); let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position( output.serialize().unwrap().get(&client_id).unwrap(), @@ -7220,6 +7463,7 @@ fn close_pane_near_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7230,6 +7474,7 @@ fn close_pane_near_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7240,6 +7485,7 @@ fn close_pane_near_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7250,6 +7496,7 @@ fn close_pane_near_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7260,9 +7507,10 @@ fn close_pane_near_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); - tab.close_pane(PaneId::Terminal(6), false); + tab.close_pane(PaneId::Terminal(6), false, None); tab.render(&mut output, None).unwrap(); let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position( output.serialize().unwrap().get(&client_id).unwrap(), @@ -7326,6 +7574,7 @@ fn focus_next_pane_expands_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7336,6 +7585,7 @@ fn focus_next_pane_expands_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7346,6 +7596,7 @@ fn focus_next_pane_expands_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7356,6 +7607,7 @@ fn focus_next_pane_expands_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7366,6 +7618,7 @@ fn focus_next_pane_expands_stacked_panes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_left(client_id); @@ -7428,6 +7681,7 @@ fn stacked_panes_can_become_fullscreen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7438,6 +7692,7 @@ fn stacked_panes_can_become_fullscreen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7448,6 +7703,7 @@ fn stacked_panes_can_become_fullscreen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7458,6 +7714,7 @@ fn stacked_panes_can_become_fullscreen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.new_pane( @@ -7468,6 +7725,7 @@ fn stacked_panes_can_become_fullscreen() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.move_focus_up(client_id); @@ -8126,6 +8384,7 @@ fn new_pane_in_auto_layout() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -8196,6 +8455,7 @@ fn new_pane_in_stacked_resizes() { true, NewPanePlacement::default(), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -8511,7 +8771,7 @@ fn when_closing_a_pane_in_auto_layout_the_focus_goes_to_last_focused_pane() { ); let _ = tab.move_focus_down(client_id); let _ = tab.move_focus_down(client_id); - tab.close_pane(PaneId::Terminal(3), false); + tab.close_pane(PaneId::Terminal(3), false, None); tab.render(&mut output, None).unwrap(); let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position( @@ -9146,6 +9406,7 @@ fn new_floating_pane_in_auto_layout() { true, NewPanePlacement::Floating(None), Some(client_id), + None, ) .unwrap(); tab.render(&mut output, None).unwrap(); @@ -9456,7 +9717,7 @@ fn when_closing_a_floating_pane_in_auto_layout_the_focus_goes_to_last_focused_pa ); tab.move_focus_up(client_id); tab.move_focus_up(client_id); - tab.close_pane(PaneId::Terminal(1), false); + tab.close_pane(PaneId::Terminal(1), false, None); tab.render(&mut output, None).unwrap(); let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position( diff --git a/zellij-server/src/tab/unit/tab_tests.rs b/zellij-server/src/tab/unit/tab_tests.rs index bca69529..f5284b88 100644 --- a/zellij-server/src/tab/unit/tab_tests.rs +++ b/zellij-server/src/tab/unit/tab_tests.rs @@ -1,7 +1,6 @@ use super::Tab; use crate::pane_groups::PaneGroups; use crate::panes::sixel::SixelImageStore; -use crate::pty::NewPanePlacement; use crate::screen::CopyOptions; use crate::{ os_input_output::{AsyncReader, Pid, ServerOsApi}, @@ -11,7 +10,7 @@ use crate::{ }; use std::net::{IpAddr, Ipv4Addr}; use std::path::PathBuf; -use zellij_utils::data::{Direction, Resize, ResizeStrategy, WebSharing}; +use zellij_utils::data::{Direction, NewPanePlacement, Resize, ResizeStrategy, WebSharing}; use zellij_utils::errors::prelude::*; use zellij_utils::input::layout::{SplitDirection, SplitSize, TiledPaneLayout}; use zellij_utils::ipc::IpcReceiverWithContext; @@ -400,7 +399,8 @@ fn write_to_suppressed_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); // Suppress pane 2 and remove it from active panes tab.replace_active_pane_with_editor_pane(PaneId::Terminal(2), 1) @@ -416,6 +416,7 @@ fn write_to_suppressed_pane() { false, PaneId::Terminal(2), None, + None, ) .unwrap(); } @@ -429,7 +430,7 @@ fn split_panes_vertically() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "The tab has two panes"); assert_eq!( tab.tiled_panes @@ -526,7 +527,7 @@ fn split_panes_horizontally() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "The tab has two panes"); assert_eq!( @@ -634,6 +635,7 @@ fn split_largest_pane() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); } @@ -817,7 +819,8 @@ pub fn cannot_split_panes_vertically_when_active_pane_is_too_small() { let size = Size { cols: 8, rows: 20 }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); assert_eq!( tab.tiled_panes.panes.len(), 1, @@ -830,7 +833,8 @@ pub fn cannot_split_panes_horizontally_when_active_pane_is_too_small() { let size = Size { cols: 121, rows: 4 }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); assert_eq!( tab.tiled_panes.panes.len(), 1, @@ -851,6 +855,7 @@ pub fn cannot_split_largest_pane_when_there_is_no_room() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); assert_eq!( @@ -869,7 +874,8 @@ pub fn cannot_split_panes_vertically_when_active_pane_has_fixed_columns() { fixed_child.split_size = Some(SplitSize::Fixed(30)); initial_layout.children = vec![fixed_child, TiledPaneLayout::default()]; let mut tab = create_new_tab_with_layout(size, initial_layout); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "Tab still has two panes"); } @@ -882,7 +888,8 @@ pub fn cannot_split_panes_horizontally_when_active_pane_has_fixed_rows() { fixed_child.split_size = Some(SplitSize::Fixed(12)); initial_layout.children = vec![fixed_child, TiledPaneLayout::default()]; let mut tab = create_new_tab_with_layout(size, initial_layout); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "Tab still has two panes"); } @@ -904,6 +911,7 @@ pub fn toggle_focused_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); } @@ -988,6 +996,7 @@ pub fn toggle_focused_pane_fullscreen_with_stacked_resizes() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); } @@ -1072,6 +1081,7 @@ fn switch_to_next_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab @@ -1083,6 +1093,7 @@ fn switch_to_next_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab @@ -1094,6 +1105,7 @@ fn switch_to_next_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab @@ -1105,6 +1117,7 @@ fn switch_to_next_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); @@ -1145,6 +1158,7 @@ fn switch_to_prev_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab @@ -1156,6 +1170,7 @@ fn switch_to_prev_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab @@ -1167,6 +1182,7 @@ fn switch_to_prev_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab @@ -1178,6 +1194,7 @@ fn switch_to_prev_pane_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); @@ -1215,8 +1232,8 @@ pub fn close_pane_with_another_pane_above_it() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 1, "One pane left in tab"); assert_eq!( @@ -1281,9 +1298,9 @@ pub fn close_pane_with_another_pane_below_it() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 1, "One pane left in tab"); assert_eq!( @@ -1345,8 +1362,8 @@ pub fn close_pane_with_another_pane_to_the_left() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 1, "One pane left in tab"); assert_eq!( @@ -1408,9 +1425,9 @@ pub fn close_pane_with_another_pane_to_the_right() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 1, "One pane left in tab"); assert_eq!( @@ -1475,11 +1492,11 @@ pub fn close_pane_with_multiple_panes_above_it() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab"); assert_eq!( @@ -1587,10 +1604,10 @@ pub fn close_pane_with_multiple_panes_below_it() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab"); assert_eq!( @@ -1698,11 +1715,11 @@ pub fn close_pane_with_multiple_panes_to_the_left() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab"); assert_eq!( @@ -1810,10 +1827,10 @@ pub fn close_pane_with_multiple_panes_to_the_right() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 2, "Two panes left in tab"); assert_eq!( @@ -1926,21 +1943,21 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() { let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_6 = PaneId::Terminal(7); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(new_pane_id_3, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(new_pane_id_4, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_4, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(new_pane_id_5, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_5, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_down(&mut tab, 1); - tab.vertical_split(new_pane_id_6, None, 1).unwrap(); + tab.vertical_split(new_pane_id_6, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab"); @@ -2227,20 +2244,20 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() { let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_6 = PaneId::Terminal(7); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(new_pane_id_3, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(new_pane_id_4, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_4, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(new_pane_id_5, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_5, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_up(&mut tab, 1); - tab.vertical_split(new_pane_id_6, None, 1).unwrap(); + tab.vertical_split(new_pane_id_6, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab"); @@ -2529,23 +2546,23 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() { let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_6 = PaneId::Terminal(7); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(new_pane_id_3, None, 1).unwrap(); + tab.vertical_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(new_pane_id_4, None, 1).unwrap(); + tab.vertical_split(new_pane_id_4, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(new_pane_id_5, None, 1).unwrap(); + tab.vertical_split(new_pane_id_5, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_right(&mut tab, 1); tab_resize_up(&mut tab, 1); tab_resize_up(&mut tab, 1); - tab.horizontal_split(new_pane_id_6, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_6, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab"); @@ -2834,22 +2851,22 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() { let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_6 = PaneId::Terminal(7); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(new_pane_id_3, None, 1).unwrap(); + tab.vertical_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(new_pane_id_4, None, 1).unwrap(); + tab.vertical_split(new_pane_id_4, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(new_pane_id_5, None, 1).unwrap(); + tab.vertical_split(new_pane_id_5, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_left(&mut tab, 1); tab_resize_up(&mut tab, 1); tab_resize_up(&mut tab, 1); - tab.horizontal_split(new_pane_id_6, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_6, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); - tab.close_focused_pane(1).unwrap(); + tab.close_focused_pane(1, None).unwrap(); assert_eq!(tab.tiled_panes.panes.len(), 6, "Six panes left in tab"); @@ -3122,7 +3139,7 @@ pub fn move_focus_down() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_down(1).unwrap(); @@ -3145,9 +3162,9 @@ pub fn move_focus_down_to_the_most_recently_used_pane() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); - tab.vertical_split(new_pane_id_3, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_down(1).unwrap(); @@ -3173,7 +3190,7 @@ pub fn move_focus_up() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); assert_eq!( @@ -3195,10 +3212,10 @@ pub fn move_focus_up_to_the_most_recently_used_pane() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); - tab.vertical_split(new_pane_id_3, None, 1).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); tab.move_focus_up(1).unwrap(); @@ -3224,7 +3241,7 @@ pub fn move_focus_left() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); assert_eq!( @@ -3246,10 +3263,10 @@ pub fn move_focus_left_to_the_most_recently_used_pane() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_3, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); tab.move_focus_left(1).unwrap(); @@ -3275,7 +3292,7 @@ pub fn move_focus_right() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_right(1).unwrap(); @@ -3298,9 +3315,9 @@ pub fn move_focus_right_to_the_most_recently_used_pane() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_3, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_right(1).unwrap(); @@ -3326,7 +3343,7 @@ pub fn move_active_pane_down() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_active_pane_down(1); @@ -3354,9 +3371,9 @@ pub fn move_active_pane_down_to_the_most_recently_used_position() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); - tab.vertical_split(new_pane_id_3, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_active_pane_down(1); @@ -3387,7 +3404,7 @@ pub fn move_active_pane_up() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab.move_active_pane_up(1); assert_eq!( @@ -3414,10 +3431,10 @@ pub fn move_active_pane_up_to_the_most_recently_used_position() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); - tab.vertical_split(new_pane_id_3, None, 1).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); + tab.vertical_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); tab.move_active_pane_up(1); @@ -3449,7 +3466,7 @@ pub fn move_active_pane_left() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); tab.move_active_pane_left(1); assert_eq!( @@ -3476,10 +3493,10 @@ pub fn move_active_pane_left_to_the_most_recently_used_position() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_3, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_right(1).unwrap(); tab.move_active_pane_left(1); @@ -3511,7 +3528,7 @@ pub fn move_active_pane_right() { let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.vertical_split(new_pane_id, None, 1).unwrap(); + tab.vertical_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_active_pane_right(1); @@ -3539,9 +3556,9 @@ pub fn move_active_pane_right_to_the_most_recently_used_position() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_3, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_3, None, 1, None).unwrap(); tab.move_focus_left(1).unwrap(); tab.move_active_pane_right(1); @@ -3580,7 +3597,7 @@ pub fn resize_down_with_pane_above() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab_resize_down(&mut tab, 1); assert_eq!( @@ -3687,7 +3704,7 @@ pub fn resize_down_with_pane_below() { let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); let new_pane_id = PaneId::Terminal(2); - tab.horizontal_split(new_pane_id, None, 1).unwrap(); + tab.horizontal_split(new_pane_id, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -3801,8 +3818,8 @@ pub fn resize_down_with_panes_above_and_below() { let first_pane_id = PaneId::Terminal(1); let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); - tab.horizontal_split(new_pane_id_2, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); + tab.horizontal_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -3955,9 +3972,9 @@ pub fn resize_down_with_multiple_panes_above() { let first_pane_id = PaneId::Terminal(1); let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_2 = PaneId::Terminal(3); - tab.horizontal_split(new_pane_id_1, None, 1).unwrap(); + tab.horizontal_split(new_pane_id_1, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(new_pane_id_2, None, 1).unwrap(); + tab.vertical_split(new_pane_id_2, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -4111,10 +4128,11 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() { let pane_to_the_left = PaneId::Terminal(2); let focused_pane = PaneId::Terminal(3); let pane_above = PaneId::Terminal(4); - tab.horizontal_split(pane_to_the_left, None, 1).unwrap(); - tab.vertical_split(focused_pane, None, 1).unwrap(); + tab.horizontal_split(pane_to_the_left, None, 1, None) + .unwrap(); + tab.vertical_split(focused_pane, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(pane_above, None, 1).unwrap(); + tab.vertical_split(pane_above, None, 1, None).unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -4312,10 +4330,11 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() { let pane_below_and_left = PaneId::Terminal(2); let pane_below = PaneId::Terminal(3); let focused_pane = PaneId::Terminal(4); - tab.horizontal_split(pane_below_and_left, None, 1).unwrap(); - tab.vertical_split(pane_below, None, 1).unwrap(); + tab.horizontal_split(pane_below_and_left, None, 1, None) + .unwrap(); + tab.vertical_split(pane_below, None, 1, None).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(focused_pane, None, 1).unwrap(); + tab.vertical_split(focused_pane, None, 1, None).unwrap(); tab_resize_down(&mut tab, 1); assert_eq!( @@ -4512,10 +4531,12 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() { let focused_pane = PaneId::Terminal(2); let pane_to_the_right = PaneId::Terminal(3); let pane_above_and_right = PaneId::Terminal(4); - tab.horizontal_split(focused_pane, None, 1).unwrap(); - tab.vertical_split(pane_to_the_right, None, 1).unwrap(); + tab.horizontal_split(focused_pane, None, 1, None).unwrap(); + tab.vertical_split(pane_to_the_right, None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(pane_above_and_right, None, 1).unwrap(); + tab.vertical_split(pane_above_and_right, None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -4714,10 +4735,12 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() { let pane_below = PaneId::Terminal(2); let pane_below_and_right = PaneId::Terminal(3); let pane_to_the_right = PaneId::Terminal(4); - tab.horizontal_split(pane_below, None, 1).unwrap(); - tab.vertical_split(pane_below_and_right, None, 1).unwrap(); + tab.horizontal_split(pane_below, None, 1, None).unwrap(); + tab.vertical_split(pane_below_and_right, None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(pane_to_the_right, None, 1).unwrap(); + tab.vertical_split(pane_to_the_right, None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -4911,12 +4934,17 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -5197,12 +5225,17 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -5482,16 +5515,23 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -5857,16 +5897,23 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_ }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_left(1).unwrap(); @@ -6232,7 +6279,8 @@ pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_down(&mut tab, 1); @@ -6413,7 +6461,8 @@ pub fn resize_left_with_pane_to_the_left() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab_resize_left(&mut tab, 1); assert_eq!( @@ -6517,7 +6566,8 @@ pub fn resize_left_with_pane_to_the_right() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -6623,8 +6673,10 @@ pub fn resize_left_with_panes_to_the_left_and_right() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -6772,9 +6824,11 @@ pub fn resize_left_with_multiple_panes_to_the_left() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -6923,10 +6977,13 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -7118,10 +7175,13 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -7314,10 +7374,13 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab_resize_left(&mut tab, 1); assert_eq!( @@ -7508,10 +7571,13 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -7705,13 +7771,18 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -7991,13 +8062,18 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -8278,17 +8354,24 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_down(&mut tab, 1); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -8654,18 +8737,25 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_down(&mut tab, 1); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_left(&mut tab, 1); @@ -9026,7 +9116,8 @@ pub fn cannot_resize_left_when_pane_to_the_left_is_at_minimum_width() { let size = Size { cols: 10, rows: 20 }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab_resize_left(&mut tab, 1); assert_eq!( @@ -9068,7 +9159,8 @@ pub fn resize_right_with_pane_to_the_left() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab_resize_right(&mut tab, 1); assert_eq!( @@ -9173,7 +9265,8 @@ pub fn resize_right_with_pane_to_the_right() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -9279,8 +9372,10 @@ pub fn resize_right_with_panes_to_the_left_and_right() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -9429,9 +9524,11 @@ pub fn resize_right_with_multiple_panes_to_the_left() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -9580,11 +9677,14 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab_resize_right(&mut tab, 1); assert_eq!( @@ -9774,11 +9874,14 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -9970,11 +10073,14 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -10166,11 +10272,14 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -10365,13 +10474,18 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -10650,13 +10764,18 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_ }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -10936,17 +11055,24 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_up(&mut tab, 1); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -11311,18 +11437,25 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_up(&mut tab, 1); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_right(&mut tab, 1); @@ -11682,7 +11815,8 @@ pub fn cannot_resize_right_when_pane_to_the_left_is_at_minimum_width() { let size = Size { cols: 10, rows: 20 }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab_resize_right(&mut tab, 1); assert_eq!( @@ -11771,7 +11905,8 @@ pub fn resize_up_with_pane_above() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab_resize_up(&mut tab, 1); assert_eq!( @@ -11877,7 +12012,8 @@ pub fn resize_up_with_pane_below() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -11987,8 +12123,10 @@ pub fn resize_up_with_panes_above_and_below() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -12137,9 +12275,11 @@ pub fn resize_up_with_multiple_panes_above() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -12287,11 +12427,14 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab_resize_up(&mut tab, 1); assert_eq!( @@ -12483,11 +12626,14 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -12680,11 +12826,14 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -12877,11 +13026,14 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -13075,12 +13227,17 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -13359,12 +13516,17 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab.move_focus_up(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -13644,16 +13806,23 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_ }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -14018,17 +14187,24 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(4), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(4), None, 1, None) + .unwrap(); tab.move_focus_down(1).unwrap(); - tab.vertical_split(PaneId::Terminal(5), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(6), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(5), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(6), None, 1, None) + .unwrap(); tab.move_focus_up(1).unwrap(); tab.move_focus_left(1).unwrap(); - tab.vertical_split(PaneId::Terminal(7), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(8), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(7), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(8), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_up(&mut tab, 1); @@ -14392,7 +14568,8 @@ pub fn cannot_resize_up_when_pane_above_is_at_minimum_height() { }; let stacked_resize = true; let mut tab = create_new_tab(size, stacked_resize); - tab.horizontal_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab_resize_down(&mut tab, 1); assert_eq!( @@ -14474,7 +14651,7 @@ pub fn nondirectional_resize_increase_with_1_pane_to_left() { let stacked_resize = false; // note - this is not the default let mut tab = create_new_tab(size, stacked_resize); let new_pane_id_1 = PaneId::Terminal(2); - tab.vertical_split(new_pane_id_1, None, 1).unwrap(); + tab.vertical_split(new_pane_id_1, None, 1, None).unwrap(); tab_resize_increase(&mut tab, 1); // should behave like `resize_left_with_pane_to_the_left` @@ -14508,9 +14685,11 @@ pub fn nondirectional_resize_increase_with_2_panes_to_left() { }; let stacked_resize = false; // note - this is not the default let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_right(1).unwrap(); tab_resize_increase(&mut tab, 1); @@ -14567,9 +14746,11 @@ pub fn nondirectional_resize_increase_with_1_pane_to_right_1_pane_above() { }; let stacked_resize = false; // note - this is not the default let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); - tab.horizontal_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.horizontal_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab_resize_increase(&mut tab, 1); assert_eq!( @@ -14624,8 +14805,10 @@ pub fn nondirectional_resize_increase_with_1_pane_to_right_1_pane_to_left() { }; let stacked_resize = false; // note - this is not the default let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_increase(&mut tab, 1); @@ -14681,8 +14864,10 @@ pub fn nondirectional_resize_increase_with_pane_above_aligned_right_with_current }; let stacked_resize = false; // note - this is not the default let mut tab = create_new_tab(size, stacked_resize); - tab.vertical_split(PaneId::Terminal(2), None, 1).unwrap(); - tab.vertical_split(PaneId::Terminal(3), None, 1).unwrap(); + tab.vertical_split(PaneId::Terminal(2), None, 1, None) + .unwrap(); + tab.vertical_split(PaneId::Terminal(3), None, 1, None) + .unwrap(); tab.move_focus_left(1).unwrap(); tab_resize_increase(&mut tab, 1); @@ -14778,9 +14963,10 @@ fn correctly_resize_frameless_panes_on_pane_close() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); - tab.close_pane(PaneId::Terminal(2), true); + tab.close_pane(PaneId::Terminal(2), true, None); // the size should be the same after adding and then removing a pane let pane = tab.tiled_panes.panes.get(&PaneId::Terminal(1)).unwrap(); diff --git a/zellij-server/src/ui/overlay/prompt.rs b/zellij-server/src/ui/overlay/prompt.rs index b6b46f40..0cbfe351 100644 --- a/zellij-server/src/ui/overlay/prompt.rs +++ b/zellij-server/src/ui/overlay/prompt.rs @@ -56,7 +56,7 @@ impl Overlayable for Prompt { pub fn _generate_quit_prompt(client_id: ClientId) -> Overlay { let prompt = Prompt::new( (" Do you want to quit zellij? [Y]es / [N]o").to_string(), - Some(Box::new(ServerInstruction::ClientExit(client_id))), + Some(Box::new(ServerInstruction::ClientExit(client_id, None))), None, ); Overlay { diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs index 845cf0e2..171096f7 100644 --- a/zellij-server/src/unit/screen_tests.rs +++ b/zellij-server/src/unit/screen_tests.rs @@ -34,14 +34,17 @@ use std::sync::{Arc, Mutex}; use crate::{ plugins::PluginInstruction, - pty::{ClientTabIndexOrPaneId, NewPanePlacement, PtyInstruction}, + pty::{ClientTabIndexOrPaneId, PtyInstruction}, }; use zellij_utils::ipc::PixelDimensions; use interprocess::local_socket::LocalSocketStream; use zellij_utils::{ channels::{self, ChannelWithContext, Receiver}, - data::{Direction, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PluginCapabilities}, + data::{ + Direction, FloatingPaneCoordinates, InputMode, ModeInfo, NewPanePlacement, Palette, + PluginCapabilities, + }, ipc::{ClientAttributes, ClientToServerMsg, ServerToClientMsg}, }; @@ -139,6 +142,7 @@ fn send_cli_action_to_server( action, client_id, None, + None, senders.clone(), capabilities, client_attributes.clone(), @@ -147,6 +151,7 @@ fn send_cli_action_to_server( None, client_keybinds.clone(), default_mode, + None, ) .unwrap(); } @@ -399,6 +404,7 @@ impl MockScreen { (vec![], vec![]), // swap layouts should_change_focus_to_new_tab, (self.main_client_id, false), + None, )); let _ = self.to_screen.send(ScreenInstruction::ApplyLayout( pane_layout, @@ -409,6 +415,7 @@ impl MockScreen { tab_index, true, (self.main_client_id, false), + None, )); self.last_opened_tab_index = Some(tab_index); std::thread::sleep(std::time::Duration::from_millis(100)); // give time for the async render @@ -487,6 +494,7 @@ impl MockScreen { (vec![], vec![]), // swap layouts should_change_focus_to_new_tab, (self.main_client_id, false), + None, )); let _ = self.to_screen.send(ScreenInstruction::ApplyLayout( pane_layout, @@ -497,6 +505,7 @@ impl MockScreen { tab_index, true, (self.main_client_id, false), + None, )); self.last_opened_tab_index = Some(tab_index); screen_thread @@ -521,6 +530,7 @@ impl MockScreen { (vec![], vec![]), // swap layouts should_change_focus_to_new_tab, (self.main_client_id, false), + None, )); let _ = self.to_screen.send(ScreenInstruction::ApplyLayout( tab_layout, @@ -531,6 +541,7 @@ impl MockScreen { 0, true, (self.main_client_id, false), + None, )); self.last_opened_tab_index = Some(tab_index); } @@ -649,7 +660,6 @@ impl MockScreen { } }) .unwrap(); - MockScreen { main_client_id, pty_receiver: Some(pty_receiver), @@ -676,6 +686,32 @@ impl MockScreen { pub fn set_advanced_hover_effects(&mut self, advanced_mouse_actions: bool) { self.advanced_mouse_actions = advanced_mouse_actions; } + pub fn drop_all_pty_messages(&mut self) { + let pty_receiver = self.pty_receiver.take(); + std::thread::Builder::new() + .name("pty_thread".to_string()) + .spawn({ + move || { + if let Some(pty_receiver) = pty_receiver { + loop { + let (event, _err_ctx) = pty_receiver + .recv() + .expect("failed to receive event on channel"); + match event { + PtyInstruction::Exit => { + break; + }, + _ => { + // here the event will be dropped - we do this so that the completion_tx will drop and release the + // test actions + }, + } + } + } + } + }) + .unwrap(); + } } macro_rules! log_actions_in_thread { @@ -690,11 +726,11 @@ macro_rules! log_actions_in_thread { .expect("failed to receive event on channel"); match event { $exit_event => { - log.lock().unwrap().push(event); + log.lock().unwrap().push(event.clone()); break; }, _ => { - log.lock().unwrap().push(event); + log.lock().unwrap().push(event.clone()); }, } } @@ -1241,6 +1277,7 @@ fn switch_to_tab_with_fullscreen() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); @@ -1364,6 +1401,7 @@ fn attach_after_first_tab_closed() { true, NewPanePlacement::default(), Some(1), + None, ) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); @@ -1400,6 +1438,7 @@ fn open_new_floating_pane_with_custom_coordinates() { pinned: None, })), Some(1), + None, ) .unwrap(); let active_pane = active_tab.get_active_pane(1).unwrap(); @@ -1434,6 +1473,7 @@ fn open_new_floating_pane_with_custom_coordinates_exceeding_viewport() { pinned: None, })), Some(1), + None, ) .unwrap(); let active_pane = active_tab.get_active_pane(1).unwrap(); @@ -1468,6 +1508,7 @@ pub fn mouse_hover_effect() { let _ = mock_screen.to_screen.send(ScreenInstruction::MouseEvent( hover_mouse_event_1, client_id, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -1504,6 +1545,7 @@ pub fn disabled_mouse_hover_effect() { let _ = mock_screen.to_screen.send(ScreenInstruction::MouseEvent( hover_mouse_event_1, client_id, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -1617,6 +1659,7 @@ fn group_panes_following_focus() { true, NewPanePlacement::Tiled(None), Some(client_id), + None, ) .unwrap(); } @@ -1674,6 +1717,7 @@ fn break_group_with_mouse() { true, NewPanePlacement::Tiled(None), Some(client_id), + None, ) .unwrap(); } @@ -2057,8 +2101,12 @@ pub fn send_cli_edit_scrollback_action() { .clone(); let mut found_instruction = false; for instruction in received_pty_instructions.lock().unwrap().iter() { - if let PtyInstruction::OpenInPlaceEditor(scrollback_contents_file, terminal_id, client_id) = - instruction + if let PtyInstruction::OpenInPlaceEditor( + scrollback_contents_file, + terminal_id, + client_id, + _, + ) = instruction { assert_eq!(scrollback_contents_file, &PathBuf::from(&dumped_file_name)); assert_eq!(terminal_id, &Some(1)); @@ -2589,6 +2637,7 @@ pub fn send_cli_new_pane_action_with_default_parameters() { height: None, pinned: None, stacked: false, + blocking: false, }; send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be @@ -2634,6 +2683,7 @@ pub fn send_cli_new_pane_action_with_split_direction() { height: None, pinned: None, stacked: false, + blocking: false, }; send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be @@ -2679,6 +2729,7 @@ pub fn send_cli_new_pane_action_with_command_and_cwd() { height: None, pinned: None, stacked: false, + blocking: false, }; send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be @@ -2735,6 +2786,7 @@ pub fn send_cli_new_pane_action_with_floating_pane_and_coordinates() { height: None, pinned: None, stacked: false, + blocking: false, }; send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be @@ -2890,7 +2942,7 @@ pub fn send_cli_switch_mode_action() { .unwrap() .iter() .find(|instruction| match instruction { - ServerInstruction::ChangeModeForAllClients(..) => true, + ServerInstruction::ChangeMode(..) => true, _ => false, }) .cloned(); @@ -2990,6 +3042,7 @@ pub fn send_cli_close_pane_action() { initial_layout.children_split_direction = SplitDirection::Vertical; initial_layout.children = vec![TiledPaneLayout::default(), TiledPaneLayout::default()]; let mut mock_screen = MockScreen::new(size); + mock_screen.drop_all_pty_messages(); let session_metadata = mock_screen.clone_session_metadata(); let screen_thread = mock_screen.run(Some(initial_layout), vec![]); let received_server_instructions = Arc::new(Mutex::new(vec![])); @@ -3630,6 +3683,7 @@ pub fn screen_can_break_pane_to_a_new_tab() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // we send ApplyLayout, because in prod this is eventually received after the message traverses @@ -3644,17 +3698,18 @@ pub fn screen_can_break_pane_to_a_new_tab() { 1, true, (1, false), + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // move back to make sure the other pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1)); + .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); // move forward to make sure the broken pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusRightOrNextTab(1)); + .send(ScreenInstruction::MoveFocusRightOrNextTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -3688,6 +3743,7 @@ pub fn screen_cannot_break_last_selectable_pane_to_a_new_tab() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); @@ -3731,6 +3787,7 @@ pub fn screen_can_break_floating_pane_to_a_new_tab() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // we send ApplyLayout, because in prod this is eventually received after the message traverses @@ -3748,17 +3805,18 @@ pub fn screen_can_break_floating_pane_to_a_new_tab() { 1, true, (1, false), + None, )); std::thread::sleep(std::time::Duration::from_millis(200)); // move back to make sure the other pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1)); + .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(200)); // move forward to make sure the broken pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusRightOrNextTab(1)); + .send(ScreenInstruction::MoveFocusRightOrNextTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(200)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -3806,6 +3864,7 @@ pub fn screen_can_break_plugin_pane_to_a_new_tab() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // we send ApplyLayout, because in prod this is eventually received after the message traverses @@ -3820,17 +3879,18 @@ pub fn screen_can_break_plugin_pane_to_a_new_tab() { 1, true, (1, false), + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // move back to make sure the other pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1)); + .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); // move forward to make sure the broken pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusRightOrNextTab(1)); + .send(ScreenInstruction::MoveFocusRightOrNextTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -3879,6 +3939,7 @@ pub fn screen_can_break_floating_plugin_pane_to_a_new_tab() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // we send ApplyLayout, because in prod this is eventually received after the message traverses @@ -3896,17 +3957,18 @@ pub fn screen_can_break_floating_plugin_pane_to_a_new_tab() { 1, true, (1, false), + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); // move back to make sure the other pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1)); + .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); // move forward to make sure the broken pane is in the previous tab let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusRightOrNextTab(1)); + .send(ScreenInstruction::MoveFocusRightOrNextTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -3946,15 +4008,16 @@ pub fn screen_can_move_pane_to_a_new_tab_right() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1)); + .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); let _ = mock_screen .to_screen - .send(ScreenInstruction::BreakPaneRight(1)); + .send(ScreenInstruction::BreakPaneRight(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); @@ -3994,15 +4057,16 @@ pub fn screen_can_move_pane_to_a_new_tab_left() { Box::new(Layout::default()), Default::default(), 1, + None, )); std::thread::sleep(std::time::Duration::from_millis(100)); let _ = mock_screen .to_screen - .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1)); + .send(ScreenInstruction::MoveFocusLeftOrPreviousTab(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); let _ = mock_screen .to_screen - .send(ScreenInstruction::BreakPaneLeft(1)); + .send(ScreenInstruction::BreakPaneLeft(1, None)); std::thread::sleep(std::time::Duration::from_millis(100)); mock_screen.teardown(vec![server_thread, screen_thread]); diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap index aaa64760..e36f78b8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled(None), false, ClientId(10)), Exit] +[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled(None), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap index bbe39929..73fec393 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: Some(100), cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled(None), false, ClientId(10)), Exit] +[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: Some(100), cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled(None), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap index c621db39..c09ce65b 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled(Some(Down)), false, ClientId(10)), Exit] +[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled(Some(Down)), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_launch_or_focus_plugin_action.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_launch_or_focus_plugin_action.snap index e4b7c405..ca824efe 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_launch_or_focus_plugin_action.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_launch_or_focus_plugin_action.snap @@ -32,5 +32,11 @@ Some( None, None, None, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap index dc786585..de7e1ed5 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", new_pane_instruction)" --- -Some(SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Tiled(Some(Right)), false, ClientId(10))) +Some(SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Tiled(Some(Right)), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false)) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_default_parameters.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_default_parameters.snap index 70d863de..75f460d5 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_default_parameters.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_default_parameters.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled(None), false, ClientId(10)), Exit] +[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled(None), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap index 6595f4fa..4d5b11c8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Floating(Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None, pinned: None })), false, ClientId(10)), Exit] +[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Floating(Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None, pinned: None })), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_split_direction.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_split_direction.snap index a46b0152..7ac623b8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_split_direction.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_split_direction.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled(Some(Right)), false, ClientId(10)), Exit] +[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled(Some(Right)), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None }), false), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap index 3f80e04f..30640244 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap @@ -64,5 +64,6 @@ Some( 1, false, ), + None, ), ) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap index fdb53446..1a0677e6 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap @@ -91,4 +91,10 @@ NewTab( 10, false, ), + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_query_tab_names_action.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_query_tab_names_action.snap index bdaf546f..ed703453 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_query_tab_names_action.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_query_tab_names_action.snap @@ -1,7 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2713 -expression: "format!(\"{:#?}\", log_tab_names_action)" +expression: "format!(\"{:#?}\", log_tab_names_instruction)" --- Some( Log( @@ -10,5 +9,11 @@ Some( "Tab #2", ], 10, + Some( + NotificationEnd { + channel: None, + exit_status: None, + }, + ), ), ) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-3.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-3.snap index a0d450ef..1cff5ec6 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-3.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-3.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1407 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 11 ││ │ -02 (C): │fill pane up with something 12 ││ │ -03 (C): │fill pane up with something 13 ││ │ -04 (C): │fill pane up with something 14 ││ │ -05 (C): │fill pane up with something 15 ││ │ -06 (C): │fill pane up with something 16 ││ │ -07 (C): │fill pane up with something 17 ││ │ -08 (C): │fill pane up with something 18 ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 1/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 12 ││ │ +02 (C): │fill pane up with something 13 ││ │ +03 (C): │fill pane up with something 14 ││ │ +04 (C): │fill pane up with something 15 ││ │ +05 (C): │fill pane up with something 16 ││ │ +06 (C): │fill pane up with something 17 ││ │ +07 (C): │fill pane up with something 18 ││ │ +08 (C): │fill pane up with something 19 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-4.snap index 6f985b85..d297bad8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-4.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-4.snap @@ -1,5 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -expression: "format!(\"{}\", snapshot_count)" +expression: "format!(\"{}\", snapshot)" --- -3 +00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 11 ││ │ +02 (C): │fill pane up with something 12 ││ │ +03 (C): │fill pane up with something 13 ││ │ +04 (C): │fill pane up with something 14 ││ │ +05 (C): │fill pane up with something 15 ││ │ +06 (C): │fill pane up with something 16 ││ │ +07 (C): │fill pane up with something 17 ││ │ +08 (C): │fill pane up with something 18 ││ │ +09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-5.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-5.snap index e305c70e..5f006c14 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-5.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-5.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1407 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 4/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 9 ││ │ -02 (C): │fill pane up with something 10 ││ │ -03 (C): │fill pane up with something 11 ││ │ -04 (C): │fill pane up with something 12 ││ │ -05 (C): │fill pane up with something 13 ││ │ -06 (C): │fill pane up with something 14 ││ │ -07 (C): │fill pane up with something 15 ││ │ -08 (C): │fill pane up with something 16 ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 3/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 10 ││ │ +02 (C): │fill pane up with something 11 ││ │ +03 (C): │fill pane up with something 12 ││ │ +04 (C): │fill pane up with something 13 ││ │ +05 (C): │fill pane up with something 14 ││ │ +06 (C): │fill pane up with something 15 ││ │ +07 (C): │fill pane up with something 16 ││ │ +08 (C): │fill pane up with something 17 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-6.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-6.snap index e2f43ec0..92fc1f4a 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-6.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-6.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1407 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 3/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 10 ││ │ -02 (C): │fill pane up with something 11 ││ │ -03 (C): │fill pane up with something 12 ││ │ -04 (C): │fill pane up with something 13 ││ │ -05 (C): │fill pane up with something 14 ││ │ -06 (C): │fill pane up with something 15 ││ │ -07 (C): │fill pane up with something 16 ││ │ -08 (C): │fill pane up with something 17 ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 4/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 9 ││ │ +02 (C): │fill pane up with something 10 ││ │ +03 (C): │fill pane up with something 11 ││ │ +04 (C): │fill pane up with something 12 ││ │ +05 (C): │fill pane up with something 13 ││ │ +06 (C): │fill pane up with something 14 ││ │ +07 (C): │fill pane up with something 15 ││ │ +08 (C): │fill pane up with something 16 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-7.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-7.snap index a0d450ef..5f006c14 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-7.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-7.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1407 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 11 ││ │ -02 (C): │fill pane up with something 12 ││ │ -03 (C): │fill pane up with something 13 ││ │ -04 (C): │fill pane up with something 14 ││ │ -05 (C): │fill pane up with something 15 ││ │ -06 (C): │fill pane up with something 16 ││ │ -07 (C): │fill pane up with something 17 ││ │ -08 (C): │fill pane up with something 18 ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 3/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 10 ││ │ +02 (C): │fill pane up with something 11 ││ │ +03 (C): │fill pane up with something 12 ││ │ +04 (C): │fill pane up with something 13 ││ │ +05 (C): │fill pane up with something 14 ││ │ +06 (C): │fill pane up with something 15 ││ │ +07 (C): │fill pane up with something 16 ││ │ +08 (C): │fill pane up with something 17 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-8.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-8.snap index 5455f620..d297bad8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-8.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_down_action-8.snap @@ -1,6 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1409 -expression: "format!(\"{}\", snapshot_count)" +expression: "format!(\"{}\", snapshot)" --- -7 +00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 11 ││ │ +02 (C): │fill pane up with something 12 ││ │ +03 (C): │fill pane up with something 13 ││ │ +04 (C): │fill pane up with something 14 ││ │ +05 (C): │fill pane up with something 15 ││ │ +06 (C): │fill pane up with something 16 ││ │ +07 (C): │fill pane up with something 17 ││ │ +08 (C): │fill pane up with something 18 ││ │ +09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-3.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-3.snap index 96aaf171..1cff5ec6 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-3.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-3.snap @@ -2,13 +2,13 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 0/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 13 ││ │ -02 (C): │fill pane up with something 14 ││ │ -03 (C): │fill pane up with something 15 ││ │ -04 (C): │fill pane up with something 16 ││ │ -05 (C): │fill pane up with something 17 ││ │ -06 (C): │fill pane up with something 18 ││ │ -07 (C): │fill pane up with something 19 ││ │ -08 (C): │ ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 1/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 12 ││ │ +02 (C): │fill pane up with something 13 ││ │ +03 (C): │fill pane up with something 14 ││ │ +04 (C): │fill pane up with something 15 ││ │ +05 (C): │fill pane up with something 16 ││ │ +06 (C): │fill pane up with something 17 ││ │ +07 (C): │fill pane up with something 18 ││ │ +08 (C): │fill pane up with something 19 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-4.snap index 6f985b85..d297bad8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-4.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-4.snap @@ -1,5 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -expression: "format!(\"{}\", snapshot_count)" +expression: "format!(\"{}\", snapshot)" --- -3 +00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 11 ││ │ +02 (C): │fill pane up with something 12 ││ │ +03 (C): │fill pane up with something 13 ││ │ +04 (C): │fill pane up with something 14 ││ │ +05 (C): │fill pane up with something 15 ││ │ +06 (C): │fill pane up with something 16 ││ │ +07 (C): │fill pane up with something 17 ││ │ +08 (C): │fill pane up with something 18 ││ │ +09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-5.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-5.snap index e473c1ad..5f006c14 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-5.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-5.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1484 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 4/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 9 ││ │ -02 (C): │fill pane up with something 10 ││ │ -03 (C): │fill pane up with something 11 ││ │ -04 (C): │fill pane up with something 12 ││ │ -05 (C): │fill pane up with something 13 ││ │ -06 (C): │fill pane up with something 14 ││ │ -07 (C): │fill pane up with something 15 ││ │ -08 (C): │fill pane up with something 16 ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 3/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 10 ││ │ +02 (C): │fill pane up with something 11 ││ │ +03 (C): │fill pane up with something 12 ││ │ +04 (C): │fill pane up with something 13 ││ │ +05 (C): │fill pane up with something 14 ││ │ +06 (C): │fill pane up with something 15 ││ │ +07 (C): │fill pane up with something 16 ││ │ +08 (C): │fill pane up with something 17 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-6.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-6.snap index 2a584fa3..92fc1f4a 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-6.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-6.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1484 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 0/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 13 ││ │ -02 (C): │fill pane up with something 14 ││ │ -03 (C): │fill pane up with something 15 ││ │ -04 (C): │fill pane up with something 16 ││ │ -05 (C): │fill pane up with something 17 ││ │ -06 (C): │fill pane up with something 18 ││ │ -07 (C): │fill pane up with something 19 ││ │ -08 (C): │ ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 4/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 9 ││ │ +02 (C): │fill pane up with something 10 ││ │ +03 (C): │fill pane up with something 11 ││ │ +04 (C): │fill pane up with something 12 ││ │ +05 (C): │fill pane up with something 13 ││ │ +06 (C): │fill pane up with something 14 ││ │ +07 (C): │fill pane up with something 15 ││ │ +08 (C): │fill pane up with something 16 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-7.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-7.snap index a24fe8bb..96aaf171 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-7.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_to_bottom_action-7.snap @@ -1,6 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1486 -expression: "format!(\"{}\", snapshot_count)" +expression: "format!(\"{}\", snapshot)" --- -6 +00 (C): ┌ Pane #1 ────────────── SCROLL: 0/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 13 ││ │ +02 (C): │fill pane up with something 14 ││ │ +03 (C): │fill pane up with something 15 ││ │ +04 (C): │fill pane up with something 16 ││ │ +05 (C): │fill pane up with something 17 ││ │ +06 (C): │fill pane up with something 18 ││ │ +07 (C): │fill pane up with something 19 ││ │ +08 (C): │ ││ │ +09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-3.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-3.snap index 7ccbbdea..1cff5ec6 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-3.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-3.snap @@ -1,16 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1327 expression: "format!(\"{}\", snapshot)" --- -00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ -01 (C): │fill pane up with something 11 ││ │ -02 (C): │fill pane up with something 12 ││ │ -03 (C): │fill pane up with something 13 ││ │ -04 (C): │fill pane up with something 14 ││ │ -05 (C): │fill pane up with something 15 ││ │ -06 (C): │fill pane up with something 16 ││ │ -07 (C): │fill pane up with something 17 ││ │ -08 (C): │fill pane up with something 18 ││ │ +00 (C): ┌ Pane #1 ────────────── SCROLL: 1/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 12 ││ │ +02 (C): │fill pane up with something 13 ││ │ +03 (C): │fill pane up with something 14 ││ │ +04 (C): │fill pane up with something 15 ││ │ +05 (C): │fill pane up with something 16 ││ │ +06 (C): │fill pane up with something 17 ││ │ +07 (C): │fill pane up with something 18 ││ │ +08 (C): │fill pane up with something 19 ││ │ 09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ - diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-4.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-4.snap index 18a949ac..d297bad8 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-4.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_scroll_up_action-4.snap @@ -1,6 +1,14 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1329 -expression: "format!(\"{}\", snapshot_count)" +expression: "format!(\"{}\", snapshot)" --- -3 +00 (C): ┌ Pane #1 ────────────── SCROLL: 2/13 ┐┌ Pane #2 ─────────────────────────────┐ +01 (C): │fill pane up with something 11 ││ │ +02 (C): │fill pane up with something 12 ││ │ +03 (C): │fill pane up with something 13 ││ │ +04 (C): │fill pane up with something 14 ││ │ +05 (C): │fill pane up with something 15 ││ │ +06 (C): │fill pane up with something 16 ││ │ +07 (C): │fill pane up with something 17 ││ │ +08 (C): │fill pane up with something 18 ││ │ +09 (C): └──────────────────────────────────────┘└──────────────────────────────────────┘ diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_switch_mode_action.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_switch_mode_action.snap index 283fafef..2ef0d483 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_switch_mode_action.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_switch_mode_action.snap @@ -1,6 +1,5 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2521 expression: "format!(\"{:?}\", switch_mode_action)" --- -Some(ChangeModeForAllClients(Locked)) +Some(ChangeMode(10, Locked)) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_active_tab_sync_action.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_active_tab_sync_action.snap index 97a33ab7..14f77c44 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_active_tab_sync_action.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_toggle_active_tab_sync_action.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ApplyCachedResizes, ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), Write([102, 111, 111], 1), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, Exit] +[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ApplyCachedResizes, ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), Write([102, 111, 111], 1), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_action_to_screen.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_action_to_screen.snap index 23ecdce1..06163127 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_action_to_screen.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_action_to_screen.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, Exit] +[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_chars_action_to_screen.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_chars_action_to_screen.snap index 938d5ce2..dded3206 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_chars_action_to_screen.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_write_chars_action_to_screen.snap @@ -2,4 +2,4 @@ source: zellij-server/src/./unit/screen_tests.rs expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())" --- -[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([105, 110, 112, 117, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 99, 108, 105], 0), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, Exit] +[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([105, 110, 112, 117, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 99, 108, 105], 0), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, Exit] diff --git a/zellij-utils/assets/prost/api.action.rs b/zellij-utils/assets/prost/api.action.rs index b835236b..8f381ee0 100644 --- a/zellij-utils/assets/prost/api.action.rs +++ b/zellij-utils/assets/prost/api.action.rs @@ -476,6 +476,7 @@ pub enum ActionName { TogglePaneInGroup = 87, ToggleGroupMarking = 88, NewStackedPane = 89, + SwitchSession = 90, } impl ActionName { /// String value of the enum field names used in the ProtoBuf definition. @@ -571,6 +572,7 @@ impl ActionName { ActionName::TogglePaneInGroup => "TogglePaneInGroup", ActionName::ToggleGroupMarking => "ToggleGroupMarking", ActionName::NewStackedPane => "NewStackedPane", + ActionName::SwitchSession => "SwitchSession", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -663,6 +665,7 @@ impl ActionName { "TogglePaneInGroup" => Some(Self::TogglePaneInGroup), "ToggleGroupMarking" => Some(Self::ToggleGroupMarking), "NewStackedPane" => Some(Self::NewStackedPane), + "SwitchSession" => Some(Self::SwitchSession), _ => None, } } diff --git a/zellij-utils/assets/prost_ipc/client_server_contract.rs b/zellij-utils/assets/prost_ipc/client_server_contract.rs index 26b5a155..c977170c 100644 --- a/zellij-utils/assets/prost_ipc/client_server_contract.rs +++ b/zellij-utils/assets/prost_ipc/client_server_contract.rs @@ -119,7 +119,7 @@ pub struct RgbColor { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Action { - #[prost(oneof="action::ActionType", tags="1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91")] + #[prost(oneof="action::ActionType", tags="1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93")] pub action_type: ::core::option::Option<action::ActionType>, } /// Nested message and enum types in `Action`. @@ -309,9 +309,13 @@ pub mod action { TogglePaneInGroup(super::TogglePaneInGroupAction), #[prost(message, tag="91")] ToggleGroupMarking(super::ToggleGroupMarkingAction), + #[prost(message, tag="92")] + SwitchSession(super::SwitchSessionAction), + #[prost(message, tag="93")] + NewBlockingPane(super::NewBlockingPaneAction), } } -// Action message definitions (all 91 variants) +// Action message definitions (all 92 variants) /// Simple action types (no data) #[allow(clippy::derive_partial_eq_without_eq)] @@ -629,6 +633,16 @@ pub struct NewStackedPaneAction { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct NewBlockingPaneAction { + #[prost(message, optional, tag="1")] + pub placement: ::core::option::Option<NewPanePlacement>, + #[prost(string, optional, tag="2")] + pub pane_name: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub command: ::core::option::Option<RunCommandAction>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PaneNameInputAction { #[prost(uint32, repeated, tag="1")] pub input: ::prost::alloc::vec::Vec<u32>, @@ -984,6 +998,51 @@ pub struct ConnectToSession { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct SwitchSessionAction { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(uint32, optional, tag="2")] + pub tab_position: ::core::option::Option<u32>, + #[prost(message, optional, tag="3")] + pub pane_id: ::core::option::Option<PaneIdWithPlugin>, + #[prost(message, optional, tag="4")] + pub layout: ::core::option::Option<LayoutInfo>, + #[prost(string, optional, tag="5")] + pub cwd: ::core::option::Option<::prost::alloc::string::String>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NewPanePlacement { + #[prost(oneof="new_pane_placement::PlacementType", tags="1, 2, 3, 4, 5")] + pub placement_type: ::core::option::Option<new_pane_placement::PlacementType>, +} +/// Nested message and enum types in `NewPanePlacement`. +pub mod new_pane_placement { + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum PlacementType { + #[prost(bool, tag="1")] + NoPreference(bool), + #[prost(enumeration="super::Direction", tag="2")] + Tiled(i32), + #[prost(message, tag="3")] + Floating(super::FloatingPaneCoordinates), + #[prost(message, tag="4")] + InPlace(super::NewPanePlacementInPlace), + #[prost(message, tag="5")] + Stacked(super::PaneId), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NewPanePlacementInPlace { + #[prost(message, optional, tag="1")] + pub pane_id_to_replace: ::core::option::Option<PaneId>, + #[prost(bool, tag="2")] + pub close_replaced_pane: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PaneIdWithPlugin { #[prost(uint32, tag="1")] pub pane_id: u32, @@ -1813,6 +1872,7 @@ pub enum ExitReason { Disconnect = 5, WebClientsForbidden = 6, Error = 7, + CustomExitStatus = 8, } impl ExitReason { /// String value of the enum field names used in the ProtoBuf definition. @@ -1829,6 +1889,7 @@ impl ExitReason { ExitReason::Disconnect => "EXIT_REASON_DISCONNECT", ExitReason::WebClientsForbidden => "EXIT_REASON_WEB_CLIENTS_FORBIDDEN", ExitReason::Error => "EXIT_REASON_ERROR", + ExitReason::CustomExitStatus => "EXIT_REASON_CUSTOM_EXIT_STATUS", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1842,6 +1903,7 @@ impl ExitReason { "EXIT_REASON_DISCONNECT" => Some(Self::Disconnect), "EXIT_REASON_WEB_CLIENTS_FORBIDDEN" => Some(Self::WebClientsForbidden), "EXIT_REASON_ERROR" => Some(Self::Error), + "EXIT_REASON_CUSTOM_EXIT_STATUS" => Some(Self::CustomExitStatus), _ => None, } } @@ -2396,6 +2458,8 @@ pub struct ActionMsg { pub terminal_id: ::core::option::Option<u32>, #[prost(uint32, optional, tag="3")] pub client_id: ::core::option::Option<u32>, + #[prost(bool, tag="4")] + pub is_cli_client: bool, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs index da1f777a..0fd52473 100644 --- a/zellij-utils/src/cli.rs +++ b/zellij-utils/src/cli.rs @@ -388,6 +388,9 @@ pub enum Sessions { takes_value(false) )] stacked: bool, + /// Whether to block until this command has finished + #[clap(long, value_parser, default_value("false"), takes_value(false))] + blocking: bool, }, /// Load a plugin #[clap(visible_alias = "p")] @@ -686,6 +689,8 @@ pub enum CliAction { takes_value(false) )] stacked: bool, + #[clap(short, long)] + blocking: bool, }, /// Open the specified file in a new zellij pane with your default EDITOR Edit { @@ -940,4 +945,26 @@ tail -f /tmp/my-live-logfile | zellij action pipe --name logs --plugin https://e #[clap(long)] pinned: Option<bool>, }, + /// Detach from the current session + Detach, + /// Switch to a different session + SwitchSession { + /// Name of the session to switch to + name: String, + /// Optional tab position to focus + #[clap(long)] + tab_position: Option<usize>, + /// Optional pane ID to focus (eg. "terminal_1" for terminal pane with id 1, or "plugin_2" for plugin pane with id 2) + #[clap(long)] + pane_id: Option<String>, + /// Layout to apply when switching to the session (relative paths start at layout-dir) + #[clap(short, long, value_parser)] + layout: Option<PathBuf>, + /// Default folder to look for layouts + #[clap(long, value_parser, requires("layout"))] + layout_dir: Option<PathBuf>, + /// Change the working directory when switching + #[clap(short, long, value_parser)] + cwd: Option<PathBuf>, + }, } diff --git a/zellij-utils/src/client_server_contract/client_to_server.proto b/zellij-utils/src/client_server_contract/client_to_server.proto index 9ec0a49f..cae8b6d3 100644 --- a/zellij-utils/src/client_server_contract/client_to_server.proto +++ b/zellij-utils/src/client_server_contract/client_to_server.proto @@ -68,6 +68,7 @@ message ActionMsg { Action action = 1; optional uint32 terminal_id = 2; optional uint32 client_id = 3; + bool is_cli_client = 4; } message KeyMsg { diff --git a/zellij-utils/src/client_server_contract/common_types.proto b/zellij-utils/src/client_server_contract/common_types.proto index be86e0d1..254a2a75 100644 --- a/zellij-utils/src/client_server_contract/common_types.proto +++ b/zellij-utils/src/client_server_contract/common_types.proto @@ -227,10 +227,12 @@ message Action { ChangeFloatingPaneCoordinatesAction change_floating_pane_coordinates = 89; TogglePaneInGroupAction toggle_pane_in_group = 90; ToggleGroupMarkingAction toggle_group_marking = 91; + SwitchSessionAction switch_session = 92; + NewBlockingPaneAction new_blocking_pane = 93; } } -// Action message definitions (all 91 variants) +// Action message definitions (all 92 variants) // Simple action types (no data) message QuitAction {} @@ -364,6 +366,12 @@ message NewStackedPaneAction { optional string pane_name = 2; } +message NewBlockingPaneAction { + NewPanePlacement placement = 1; + optional string pane_name = 2; + optional RunCommandAction command = 3; +} + message PaneNameInputAction { repeated uint32 input = 1; } @@ -605,6 +613,29 @@ message ConnectToSession { optional string cwd = 5; } +message SwitchSessionAction { + string name = 1; + optional uint32 tab_position = 2; + optional PaneIdWithPlugin pane_id = 3; + optional LayoutInfo layout = 4; + optional string cwd = 5; +} + +message NewPanePlacement { + oneof placement_type { + bool no_preference = 1; + Direction tiled = 2; + FloatingPaneCoordinates floating = 3; + NewPanePlacementInPlace in_place = 4; + PaneId stacked = 5; + } +} + +message NewPanePlacementInPlace { + optional PaneId pane_id_to_replace = 1; + bool close_replaced_pane = 2; +} + message PaneIdWithPlugin { uint32 pane_id = 1; bool is_plugin = 2; @@ -619,6 +650,7 @@ enum ExitReason { EXIT_REASON_DISCONNECT = 5; EXIT_REASON_WEB_CLIENTS_FORBIDDEN = 6; EXIT_REASON_ERROR = 7; + EXIT_REASON_CUSTOM_EXIT_STATUS = 8; } // Additional supporting types for Action messages diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs index 53425e0b..7f700d4d 100644 --- a/zellij-utils/src/data.rs +++ b/zellij-utils/src/data.rs @@ -2582,6 +2582,82 @@ impl FromStr for WebSharing { } } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum NewPanePlacement { + NoPreference, + Tiled(Option<Direction>), + Floating(Option<FloatingPaneCoordinates>), + InPlace { + pane_id_to_replace: Option<PaneId>, + close_replaced_pane: bool, + }, + Stacked(Option<PaneId>), +} + +impl Default for NewPanePlacement { + fn default() -> Self { + NewPanePlacement::NoPreference + } +} + +impl NewPanePlacement { + pub fn with_floating_pane_coordinates( + floating_pane_coordinates: Option<FloatingPaneCoordinates>, + ) -> Self { + NewPanePlacement::Floating(floating_pane_coordinates) + } + pub fn with_should_be_in_place( + self, + should_be_in_place: bool, + close_replaced_pane: bool, + ) -> Self { + if should_be_in_place { + NewPanePlacement::InPlace { + pane_id_to_replace: None, + close_replaced_pane, + } + } else { + self + } + } + pub fn with_pane_id_to_replace( + pane_id_to_replace: Option<PaneId>, + close_replaced_pane: bool, + ) -> Self { + NewPanePlacement::InPlace { + pane_id_to_replace, + close_replaced_pane, + } + } + pub fn should_float(&self) -> Option<bool> { + match self { + NewPanePlacement::Floating(_) => Some(true), + NewPanePlacement::Tiled(_) => Some(false), + _ => None, + } + } + pub fn floating_pane_coordinates(&self) -> Option<FloatingPaneCoordinates> { + match self { + NewPanePlacement::Floating(floating_pane_coordinates) => { + floating_pane_coordinates.clone() + }, + _ => None, + } + } + pub fn should_stack(&self) -> bool { + match self { + NewPanePlacement::Stacked(_) => true, + _ => false, + } + } + pub fn id_of_stack_root(&self) -> Option<PaneId> { + match self { + NewPanePlacement::Stacked(id) => *id, + _ => None, + } + } +} + type Context = BTreeMap<String, String>; #[derive(Debug, Clone, EnumDiscriminants, ToString)] diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index fa5374f0..d623197b 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -6,7 +6,7 @@ use super::layout::{ SwapFloatingLayout, SwapTiledLayout, TiledPaneLayout, }; use crate::cli::CliAction; -use crate::data::{Direction, KeyWithModifier, PaneId, Resize}; +use crate::data::{Direction, KeyWithModifier, LayoutInfo, NewPanePlacement, PaneId, Resize}; use crate::data::{FloatingPaneCoordinates, InputMode}; use crate::home::{find_default_config_dir, get_layout_dir}; use crate::input::config::{Config, ConfigError, KdlError}; @@ -99,7 +99,7 @@ impl FromStr for SearchOption { // They might need to be adjusted in the default config // as well `../../assets/config/default.yaml` /// Actions that can be bound to keys. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, strum_macros::Display)] pub enum Action { /// Quit Zellij. Quit, @@ -190,6 +190,11 @@ pub enum Action { pane_name: Option<String>, start_suppressed: bool, }, + NewBlockingPane { + placement: NewPanePlacement, + pane_name: Option<String>, + command: Option<RunCommandAction>, + }, /// Open the file in a new pane using the default editor EditFile { payload: OpenFilePayload, @@ -269,6 +274,14 @@ pub enum Action { }, /// Detach session and exit Detach, + /// Switch to a different session + SwitchSession { + name: String, + tab_position: Option<usize>, + pane_id: Option<(u32, bool)>, // (id, is_plugin) + layout: Option<LayoutInfo>, + cwd: Option<PathBuf>, + }, LaunchOrFocusPlugin { plugin: RunPluginOrAlias, should_float: bool, @@ -478,6 +491,7 @@ impl Action { height, pinned, stacked, + blocking, } => { let current_dir = get_current_dir(); // cwd should only be specified in a plugin alias if it was explicitly given to us, @@ -486,7 +500,51 @@ impl Action { let cwd = cwd .map(|cwd| current_dir.join(cwd)) .or_else(|| Some(current_dir.clone())); - if let Some(plugin) = plugin { + if blocking { + // For blocking panes, we don't support plugins + if plugin.is_some() { + return Err("Blocking panes do not support plugin variants".to_string()); + } + + let command = if !command.is_empty() { + let mut command = command.clone(); + let (command, args) = (PathBuf::from(command.remove(0)), command); + let hold_on_start = start_suspended; + let hold_on_close = !close_on_exit; + Some(RunCommandAction { + command, + args, + cwd, + direction, + hold_on_close, + hold_on_start, + ..Default::default() + }) + } else { + None + }; + + let placement = if floating { + NewPanePlacement::Floating(FloatingPaneCoordinates::new( + x, y, width, height, pinned, + )) + } else if in_place { + NewPanePlacement::InPlace { + pane_id_to_replace: None, + close_replaced_pane: false, + } + } else if stacked { + NewPanePlacement::Stacked(None) + } else { + NewPanePlacement::Tiled(direction) + }; + + Ok(vec![Action::NewBlockingPane { + placement, + pane_name: name, + command, + }]) + } else if let Some(plugin) = plugin { let plugin = match RunPluginLocation::parse(&plugin, cwd.clone()) { Ok(location) => { let user_configuration = configuration.unwrap_or_default(); @@ -633,9 +691,7 @@ impl Action { coordinates: FloatingPaneCoordinates::new(x, y, width, height, pinned), }]) }, - CliAction::SwitchMode { input_mode } => { - Ok(vec![Action::SwitchModeForAllClients { input_mode }]) - }, + CliAction::SwitchMode { input_mode } => Ok(vec![Action::SwitchToMode { input_mode }]), CliAction::TogglePaneEmbedOrFloating => Ok(vec![Action::TogglePaneEmbedOrFloating]), CliAction::ToggleFloatingPanes => Ok(vec![Action::ToggleFloatingPanes]), CliAction::ClosePane => Ok(vec![Action::CloseFocus]), @@ -939,6 +995,56 @@ impl Action { } } }, + CliAction::Detach => Ok(vec![Action::Detach]), + CliAction::SwitchSession { + name, + tab_position, + pane_id, + layout, + layout_dir, + cwd, + } => { + let pane_id = match pane_id { + Some(stringified_pane_id) => match PaneId::from_str(&stringified_pane_id) { + Ok(PaneId::Terminal(id)) => Some((id, false)), + Ok(PaneId::Plugin(id)) => Some((id, true)), + Err(_e) => { + return Err(format!( + "Malformed pane id: {}, expecting either a bare integer (eg. 1), a terminal pane id (eg. terminal_1) or a plugin pane id (eg. plugin_1)", + stringified_pane_id + )); + }, + }, + None => None, + }; + + let cwd = cwd.map(|cwd| { + let current_dir = get_current_dir(); + current_dir.join(cwd) + }); + + let layout_dir = layout_dir.map(|layout_dir| { + let current_dir = get_current_dir(); + current_dir.join(layout_dir) + }); + + let layout_info = if let Some(layout_path) = layout { + let layout_dir = layout_dir + .or_else(|| config.and_then(|c| c.options.layout_dir.clone())) + .or_else(|| get_layout_dir(find_default_config_dir())); + LayoutInfo::from_config(&layout_dir, &Some(layout_path)) + } else { + None + }; + + Ok(vec![Action::SwitchSession { + name: name.clone(), + tab_position: tab_position.clone(), + pane_id, + layout: layout_info, + cwd, + }]) + }, } } pub fn launches_plugin(&self, plugin_url: &str) -> bool { diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs index 1f37b2e7..53dd4d9f 100644 --- a/zellij-utils/src/ipc.rs +++ b/zellij-utils/src/ipc.rs @@ -121,6 +121,7 @@ pub enum ClientToServerMsg { action: Action, terminal_id: Option<u32>, client_id: Option<ClientId>, + is_cli_client: bool, }, Key { key: KeyWithModifier, @@ -181,6 +182,7 @@ pub enum ExitReason { CannotAttach, Disconnect, WebClientsForbidden, + CustomExitStatus(i32), Error(String), } @@ -225,6 +227,7 @@ There are a few things you can try now: " ) }, + Self::CustomExitStatus(exit_status) => write!(f, "Exit {}", exit_status), Self::Error(e) => write!(f, "Error occurred in server:\n{}", e), } } diff --git a/zellij-utils/src/ipc/protobuf_conversion.rs b/zellij-utils/src/ipc/protobuf_conversion.rs index 658c10f3..ab06faae 100644 --- a/zellij-utils/src/ipc/protobuf_conversion.rs +++ b/zellij-utils/src/ipc/protobuf_conversion.rs @@ -78,10 +78,12 @@ impl From<ClientToServerMsg> for ProtoClientToServerMsg { action, terminal_id, client_id, + is_cli_client, } => client_to_server_msg::Message::Action(ActionMsg { action: Some(action.into()), terminal_id, client_id: client_id.map(|id| id as u32), + is_cli_client, }), ClientToServerMsg::Key { key, @@ -198,6 +200,7 @@ impl TryFrom<ProtoClientToServerMsg> for ClientToServerMsg { .try_into()?, terminal_id: action.terminal_id, client_id: action.client_id.map(|id| id as u16), + is_cli_client: action.is_cli_client, }), Some(client_to_server_msg::Message::Key(key)) => Ok(ClientToServerMsg::Key { key: key.key.ok_or_else(|| anyhow!("Missing key"))?.try_into()?, @@ -239,6 +242,9 @@ impl From<ServerToClientMsg> for ProtoServerToClientMsg { ServerToClientMsg::Exit { exit_reason } => { let (proto_exit_reason, payload) = match exit_reason { ExitReason::Error(ref msg) => (ProtoExitReason::Error, Some(msg.clone())), + ExitReason::CustomExitStatus(status) => { + (ProtoExitReason::CustomExitStatus, Some(status.to_string())) + }, other => (ProtoExitReason::from(other), None), }; server_to_client_msg::Message::Exit(ExitMsg { @@ -310,6 +316,13 @@ impl TryFrom<ProtoServerToClientMsg> for ServerToClientMsg { exit.payload.unwrap_or_else(|| "Protobuf error".to_string()); ExitReason::Error(error_msg) }, + ProtoExitReason::CustomExitStatus => { + let status_str = exit.payload.unwrap_or_else(|| "0".to_string()); + let status = status_str + .parse::<i32>() + .map_err(|_| anyhow!("Invalid custom exit status: {}", status_str))?; + ExitReason::CustomExitStatus(status) + }, other => other.try_into()?, }; @@ -704,21 +717,22 @@ impl From<crate::input::actions::Action> HalfPageScrollDownAction, HalfPageScrollUpAction, KeybindPipeAction, LaunchOrFocusPluginAction, LaunchPluginAction, ListClientsAction, MouseEventAction, MoveFocusAction, MoveFocusOrTabAction, MovePaneAction, MovePaneBackwardsAction, - MoveTabAction, NewFloatingPaneAction, NewFloatingPluginPaneAction, - NewInPlacePaneAction, NewInPlacePluginPaneAction, NewPaneAction, NewStackedPaneAction, - NewTabAction, NewTiledPaneAction, NewTiledPluginPaneAction, NextSwapLayoutAction, - NoOpAction, PageScrollDownAction, PageScrollUpAction, PaneNameInputAction, - PreviousSwapLayoutAction, QueryTabNamesAction, QuitAction, RenamePluginPaneAction, - RenameSessionAction, RenameTabAction, RenameTerminalPaneAction, ResizeAction, - RunAction, ScrollDownAction, ScrollDownAtAction, ScrollToBottomAction, - ScrollToTopAction, ScrollUpAction, ScrollUpAtAction, SearchAction, SearchInputAction, - SearchToggleOptionAction, SkipConfirmAction, StackPanesAction, - StartOrReloadPluginAction, SwitchFocusAction, SwitchModeForAllClientsAction, - SwitchToModeAction, TabNameInputAction, ToggleActiveSyncTabAction, - ToggleFloatingPanesAction, ToggleFocusFullscreenAction, ToggleGroupMarkingAction, - ToggleMouseModeAction, TogglePaneEmbedOrFloatingAction, TogglePaneFramesAction, - TogglePaneInGroupAction, TogglePanePinnedAction, ToggleTabAction, UndoRenamePaneAction, - UndoRenameTabAction, WriteAction, WriteCharsAction, + MoveTabAction, NewBlockingPaneAction, NewFloatingPaneAction, + NewFloatingPluginPaneAction, NewInPlacePaneAction, NewInPlacePluginPaneAction, + NewPaneAction, NewStackedPaneAction, NewTabAction, NewTiledPaneAction, + NewTiledPluginPaneAction, NextSwapLayoutAction, NoOpAction, PageScrollDownAction, + PageScrollUpAction, PaneIdWithPlugin, PaneNameInputAction, PreviousSwapLayoutAction, + QueryTabNamesAction, QuitAction, RenamePluginPaneAction, RenameSessionAction, + RenameTabAction, RenameTerminalPaneAction, ResizeAction, RunAction, ScrollDownAction, + ScrollDownAtAction, ScrollToBottomAction, ScrollToTopAction, ScrollUpAction, + ScrollUpAtAction, SearchAction, SearchInputAction, SearchToggleOptionAction, + SkipConfirmAction, StackPanesAction, StartOrReloadPluginAction, SwitchFocusAction, + SwitchModeForAllClientsAction, SwitchSessionAction, SwitchToModeAction, + TabNameInputAction, ToggleActiveSyncTabAction, ToggleFloatingPanesAction, + ToggleFocusFullscreenAction, ToggleGroupMarkingAction, ToggleMouseModeAction, + TogglePaneEmbedOrFloatingAction, TogglePaneFramesAction, TogglePaneInGroupAction, + TogglePanePinnedAction, ToggleTabAction, UndoRenamePaneAction, UndoRenameTabAction, + WriteAction, WriteCharsAction, }; use std::collections::HashMap; @@ -890,6 +904,15 @@ impl From<crate::input::actions::Action> pane_name, }) }, + crate::input::actions::Action::NewBlockingPane { + placement, + pane_name, + command, + } => ActionType::NewBlockingPane(NewBlockingPaneAction { + placement: Some(placement.into()), + pane_name, + command: command.map(|c| c.into()), + }), crate::input::actions::Action::TogglePaneEmbedOrFloating => { ActionType::TogglePaneEmbedOrFloating(TogglePaneEmbedOrFloatingAction {}) }, @@ -960,6 +983,22 @@ impl From<crate::input::actions::Action> command: Some(command.into()), }), crate::input::actions::Action::Detach => ActionType::Detach(DetachAction {}), + crate::input::actions::Action::SwitchSession { + name, + tab_position, + pane_id, + layout, + cwd, + } => ActionType::SwitchSession(SwitchSessionAction { + name: name.clone(), + tab_position: tab_position.map(|p| p as u32), + pane_id: pane_id.map(|(id, is_plugin)| PaneIdWithPlugin { + pane_id: id, + is_plugin: is_plugin, + }), + layout: layout.as_ref().map(|l| l.clone().into()), + cwd: cwd.as_ref().map(|p| p.to_string_lossy().to_string()), + }), crate::input::actions::Action::LaunchOrFocusPlugin { plugin, should_float, @@ -1383,6 +1422,19 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action> pane_name: new_stacked_action.pane_name, }) }, + ActionType::NewBlockingPane(new_blocking_action) => { + Ok(crate::input::actions::Action::NewBlockingPane { + placement: new_blocking_action + .placement + .ok_or_else(|| anyhow!("NewBlockingPane missing placement"))? + .try_into()?, + pane_name: new_blocking_action.pane_name, + command: new_blocking_action + .command + .map(|c| c.try_into()) + .transpose()?, + }) + }, ActionType::TogglePaneEmbedOrFloating(_) => { Ok(crate::input::actions::Action::TogglePaneEmbedOrFloating) }, @@ -1466,6 +1518,21 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action> .try_into()?, }), ActionType::Detach(_) => Ok(crate::input::actions::Action::Detach), + ActionType::SwitchSession(switch_session_action) => { + Ok(crate::input::actions::Action::SwitchSession { + name: switch_session_action.name.clone(), + tab_position: switch_session_action.tab_position.map(|p| p as usize), + pane_id: switch_session_action + .pane_id + .as_ref() + .map(|p| (p.pane_id, p.is_plugin)), + layout: switch_session_action + .layout + .map(|l| l.try_into()) + .transpose()?, + cwd: switch_session_action.cwd.map(PathBuf::from), + }) + }, ActionType::LaunchOrFocusPlugin(launch_plugin_action) => { Ok(crate::input::actions::Action::LaunchOrFocusPlugin { plugin: launch_plugin_action @@ -1870,6 +1937,7 @@ impl From<ExitReason> for ProtoExitReason { ExitReason::Disconnect => ProtoExitReason::Disconnect, ExitReason::WebClientsForbidden => ProtoExitReason::WebClientsForbidden, ExitReason::Error(_msg) => ProtoExitReason::Error, + ExitReason::CustomExitStatus(_status) => ProtoExitReason::CustomExitStatus, } } } @@ -1885,6 +1953,7 @@ impl TryFrom<ProtoExitReason> for ExitReason { ProtoExitReason::Disconnect => Ok(ExitReason::Disconnect), ProtoExitReason::WebClientsForbidden => Ok(ExitReason::WebClientsForbidden), ProtoExitReason::Error => Ok(ExitReason::Error("Protobuf error".to_string())), + ProtoExitReason::CustomExitStatus => Ok(ExitReason::CustomExitStatus(0)), ProtoExitReason::Unspecified => Err(anyhow!("Unspecified exit reason")), } } @@ -2197,6 +2266,88 @@ impl TryFrom<crate::client_server_contract::client_server_contract::FloatingPane } } +// NewPanePlacement conversion +impl From<crate::data::NewPanePlacement> + for crate::client_server_contract::client_server_contract::NewPanePlacement +{ + fn from(placement: crate::data::NewPanePlacement) -> Self { + use crate::client_server_contract::client_server_contract::new_pane_placement::PlacementType; + let placement_type = match placement { + crate::data::NewPanePlacement::NoPreference => PlacementType::NoPreference(true), + crate::data::NewPanePlacement::Tiled(direction) => { + PlacementType::Tiled(direction.map(direction_to_proto_i32).unwrap_or(0)) + }, + crate::data::NewPanePlacement::Floating(coords) => { + PlacementType::Floating(coords.map(|c| c.into()).unwrap_or_default()) + }, + crate::data::NewPanePlacement::InPlace { + pane_id_to_replace, + close_replaced_pane, + } => PlacementType::InPlace( + crate::client_server_contract::client_server_contract::NewPanePlacementInPlace { + pane_id_to_replace: pane_id_to_replace.map(|id| id.into()), + close_replaced_pane, + }, + ), + crate::data::NewPanePlacement::Stacked(pane_id) => { + PlacementType::Stacked(pane_id.map(|id| id.into()).unwrap_or_default()) + }, + }; + Self { + placement_type: Some(placement_type), + } + } +} + +// Reverse NewPanePlacement conversion +impl TryFrom<crate::client_server_contract::client_server_contract::NewPanePlacement> + for crate::data::NewPanePlacement +{ + type Error = anyhow::Error; + fn try_from( + placement: crate::client_server_contract::client_server_contract::NewPanePlacement, + ) -> Result<Self> { + use crate::client_server_contract::client_server_contract::new_pane_placement::PlacementType; + match placement + .placement_type + .ok_or_else(|| anyhow!("NewPanePlacement missing placement_type"))? + { + PlacementType::NoPreference(_) => Ok(crate::data::NewPanePlacement::NoPreference), + PlacementType::Tiled(direction) => { + let direction = if direction == 0 { + None + } else { + Some(proto_i32_to_direction(direction)?) + }; + Ok(crate::data::NewPanePlacement::Tiled(direction)) + }, + PlacementType::Floating(coords) => { + let coords = if coords == Default::default() { + None + } else { + Some(coords.try_into()?) + }; + Ok(crate::data::NewPanePlacement::Floating(coords)) + }, + PlacementType::InPlace(in_place) => Ok(crate::data::NewPanePlacement::InPlace { + pane_id_to_replace: in_place + .pane_id_to_replace + .map(|id| id.try_into()) + .transpose()?, + close_replaced_pane: in_place.close_replaced_pane, + }), + PlacementType::Stacked(pane_id) => { + let pane_id = if pane_id == Default::default() { + None + } else { + Some(pane_id.try_into()?) + }; + Ok(crate::data::NewPanePlacement::Stacked(pane_id)) + }, + } + } +} + // MouseEvent conversion impl From<crate::input::mouse::MouseEvent> for crate::client_server_contract::client_server_contract::MouseEvent diff --git a/zellij-utils/src/ipc/tests/roundtrip_tests.rs b/zellij-utils/src/ipc/tests/roundtrip_tests.rs index a2585181..2ec513da 100644 --- a/zellij-utils/src/ipc/tests/roundtrip_tests.rs +++ b/zellij-utils/src/ipc/tests/roundtrip_tests.rs @@ -696,11 +696,13 @@ fn test_client_messages() { action: Action::Quit, terminal_id: None, client_id: None, + is_cli_client: false, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Quit, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Write { @@ -710,6 +712,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Write { @@ -720,6 +723,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::WriteChars { @@ -727,6 +731,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SwitchToMode { @@ -735,6 +740,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SwitchModeForAllClients { @@ -743,6 +749,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -751,6 +758,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -759,6 +767,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -767,6 +776,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -775,6 +785,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -783,6 +794,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -791,21 +803,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusNextPane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusPreviousPane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SwitchFocus, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MoveFocus { @@ -814,6 +830,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MoveFocusOrTab { @@ -821,11 +838,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MovePane { direction: None }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MovePane { @@ -833,16 +852,19 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MovePaneBackwards, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ClearScreen, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::DumpScreen { @@ -851,6 +873,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::DumpScreen { @@ -859,21 +882,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::DumpLayout, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditScrollback, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollUp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollUpAt { @@ -881,6 +908,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollUpAt { @@ -888,11 +916,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollDown, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollDownAt { @@ -900,51 +930,61 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollToBottom, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollToTop, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PageScrollUp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PageScrollDown, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::HalfPageScrollUp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::HalfPageScrollDown, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleFocusFullscreen, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePaneFrames, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleActiveSyncTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewPane { @@ -954,6 +994,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewPane { @@ -963,6 +1004,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -980,6 +1022,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1001,6 +1044,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1022,6 +1066,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1043,6 +1088,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1070,6 +1116,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1097,6 +1144,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1124,6 +1172,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1145,6 +1194,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPane { @@ -1154,6 +1204,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPane { @@ -1178,6 +1229,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPane { @@ -1206,6 +1258,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTiledPane { @@ -1215,6 +1268,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTiledPane { @@ -1237,6 +1291,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewInPlacePane { @@ -1258,6 +1313,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewInPlacePane { @@ -1266,6 +1322,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewStackedPane { @@ -1287,6 +1344,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewStackedPane { @@ -1295,21 +1353,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePaneEmbedOrFloating, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleFloatingPanes, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CloseFocus, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PaneNameInput { @@ -1317,11 +1379,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::UndoRenamePane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1335,6 +1399,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1348,6 +1413,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1364,6 +1430,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1380,6 +1447,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1397,6 +1465,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1426,6 +1495,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1442,6 +1512,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1458,6 +1529,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1476,6 +1548,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1495,6 +1568,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1514,6 +1588,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1533,6 +1608,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1552,6 +1628,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1571,6 +1648,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1590,6 +1668,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1609,6 +1688,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1628,6 +1708,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1644,6 +1725,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1666,6 +1748,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1690,6 +1773,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1718,6 +1802,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1734,6 +1819,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1754,6 +1840,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1770,6 +1857,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1806,6 +1894,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1827,6 +1916,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1840,6 +1930,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1853,31 +1944,37 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NoOp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToNextTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToPreviousTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CloseTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToTab { index: 0 }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToTabName { @@ -1886,6 +1983,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToTabName { @@ -1894,11 +1992,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TabNameInput { @@ -1906,11 +2006,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::UndoRenameTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MoveTab { @@ -1918,6 +2020,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Run { @@ -1935,11 +2038,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Detach, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchOrFocusPlugin { @@ -1952,6 +2057,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchOrFocusPlugin { @@ -1964,6 +2070,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchPlugin { @@ -1976,6 +2083,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchPlugin { @@ -1988,6 +2096,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MouseEvent { @@ -2006,6 +2115,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MouseEvent { @@ -2024,6 +2134,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MouseEvent { @@ -2042,21 +2153,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Copy, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Confirm, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Deny, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SkipConfirm { @@ -2064,6 +2179,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchInput { @@ -2071,6 +2187,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Search { @@ -2078,6 +2195,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Search { @@ -2085,6 +2203,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchToggleOption { @@ -2092,6 +2211,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchToggleOption { @@ -2099,6 +2219,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchToggleOption { @@ -2106,26 +2227,31 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleMouseMode, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PreviousSwapLayout, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NextSwapLayout, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::QueryTabNames, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTiledPluginPane { @@ -2136,6 +2262,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPluginPane { @@ -2147,6 +2274,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPluginPane { @@ -2164,6 +2292,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewInPlacePluginPane { @@ -2173,6 +2302,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::StartOrReloadPlugin { @@ -2180,16 +2310,19 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CloseTerminalPane { pane_id: 11 }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ClosePluginPane { pane_id: 12 }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusTerminalPaneWithId { @@ -2198,6 +2331,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusTerminalPaneWithId { @@ -2206,6 +2340,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusPluginPaneWithId { @@ -2214,6 +2349,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusPluginPaneWithId { @@ -2222,6 +2358,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenameTerminalPane { @@ -2230,6 +2367,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenamePluginPane { @@ -2238,6 +2376,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenameTab { @@ -2246,21 +2385,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::BreakPane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::BreakPaneRight, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::BreakPaneLeft, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenameSession { @@ -2268,6 +2411,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CliPipe { @@ -2286,6 +2430,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CliPipe { @@ -2304,6 +2449,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::KeybindPipe { @@ -2322,6 +2468,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::KeybindPipe { @@ -2340,21 +2487,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ListClients, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePanePinned, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::StackPanes { pane_ids: vec![] }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::StackPanes { @@ -2367,6 +2518,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ChangeFloatingPaneCoordinates { @@ -2382,16 +2534,19 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePaneInGroup, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleGroupMarking, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Key { key: KeyWithModifier { diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index ad541a48..789c3d96 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -1022,6 +1022,35 @@ impl Action { }, }, Action::Detach => Some(KdlNode::new("Detach")), + Action::SwitchSession { + name, + tab_position, + pane_id, + layout, + cwd, + } => { + let mut node = KdlNode::new("SwitchSession"); + node.push(KdlEntry::new_prop("name", name.clone())); + if let Some(pos) = tab_position { + node.push(KdlEntry::new_prop("tab_position", *pos as i64)); + } + if let Some((id, is_plugin)) = pane_id { + node.push(KdlEntry::new_prop("pane_id", *id as i64)); + if *is_plugin { + node.push(KdlEntry::new_prop("is_plugin", true)); + } + } + if let Some(layout_info) = layout { + node.push(KdlEntry::new_prop("layout", layout_info.name())); + } + if let Some(cwd_path) = cwd { + node.push(KdlEntry::new_prop( + "cwd", + cwd_path.to_string_lossy().to_string(), + )); + } + Some(node) + }, Action::LaunchOrFocusPlugin { plugin: run_plugin_or_alias, should_float, @@ -1466,6 +1495,50 @@ impl TryFrom<(&KdlNode, &Options)> for Action { parse_kdl_action_arguments!(action_name, action_arguments, kdl_action) }, "Detach" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), + "SwitchSession" => { + let name = kdl_get_string_property_or_child_value!(kdl_action, "name") + .map(|s| s.to_string()) + .ok_or(ConfigError::new_kdl_error( + "SwitchSession action requires a 'name' property".into(), + kdl_action.span().offset(), + kdl_action.span().len(), + ))?; + let tab_position = + crate::kdl_get_int_property_or_child_value!(kdl_action, "tab_position") + .map(|i| i as usize); + let pane_id = crate::kdl_get_int_property_or_child_value!(kdl_action, "pane_id") + .map(|i| i as u32); + let is_plugin = + crate::kdl_get_bool_property_or_child_value!(kdl_action, "is_plugin") + .unwrap_or(false); + let pane_id_tuple = pane_id.map(|id| (id, is_plugin)); + + // Parse layout + let layout = if let Some(layout_str) = + kdl_get_string_property_or_child_value!(kdl_action, "layout") + { + let layout_path = PathBuf::from(layout_str); + let layout_dir = config_options + .layout_dir + .clone() + .or_else(|| get_layout_dir(find_default_config_dir())); + LayoutInfo::from_config(&layout_dir, &Some(layout_path)) + } else { + None + }; + + // Parse cwd + let cwd = + kdl_get_string_property_or_child_value!(kdl_action, "cwd").map(PathBuf::from); + + Ok(Action::SwitchSession { + name, + tab_position, + pane_id: pane_id_tuple, + layout, + cwd, + }) + }, "Copy" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), "Clear" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), "Confirm" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), diff --git a/zellij-utils/src/plugin_api/action.proto b/zellij-utils/src/plugin_api/action.proto index 5bdd34e9..2772e725 100644 --- a/zellij-utils/src/plugin_api/action.proto +++ b/zellij-utils/src/plugin_api/action.proto @@ -244,6 +244,7 @@ enum ActionName { TogglePaneInGroup = 87; ToggleGroupMarking = 88; NewStackedPane = 89; + SwitchSession = 90; } message Position { diff --git a/zellij-utils/src/plugin_api/action.rs b/zellij-utils/src/plugin_api/action.rs index 2b48ffe1..c442144a 100644 --- a/zellij-utils/src/plugin_api/action.rs +++ b/zellij-utils/src/plugin_api/action.rs @@ -1388,7 +1388,9 @@ impl TryFrom<Action> for ProtobufAction { pane_id: _, coordinates: _, } - | Action::SkipConfirm { action: _ } => Err("Unsupported action"), + | Action::SkipConfirm { action: _ } + | Action::NewBlockingPane { .. } + | Action::SwitchSession { .. } => Err("Unsupported action"), } } } |
