diff options
| author | Aram Drevekenin <aram@poor.dev> | 2024-07-29 11:40:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-29 11:40:01 +0200 |
| commit | 355463383a18fb9e54afd62d718bed4c085a766f (patch) | |
| tree | 7cf187d4e122133711b45aa249a7e19dc59e1f4f /zellij-server/src | |
| parent | docs(changelog): more plugin apis (diff) | |
| download | sl0ppij-355463383a18fb9e54afd62d718bed4c085a766f.tar.gz sl0ppij-355463383a18fb9e54afd62d718bed4c085a766f.tar.xz sl0ppij-355463383a18fb9e54afd62d718bed4c085a766f.zip | |
feat(plugins): allow opening command panes in the background (hidden) (#3530)
* start background pane
* open command and edit panes in the background
* some cleanups
* style(fmt): rustfmt
* more cleanups
Diffstat (limited to 'zellij-server/src')
32 files changed, 2574 insertions, 551 deletions
diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs index 099a3434..e4263857 100644 --- a/zellij-server/src/os_input_output.rs +++ b/zellij-server/src/os_input_output.rs @@ -288,10 +288,10 @@ fn spawn_terminal( // secondary fd let mut failover_cmd_args = None; let cmd = match terminal_action { - TerminalAction::OpenFile(mut file_to_open, line_number, cwd) => { - if file_to_open.is_relative() { - if let Some(cwd) = cwd.as_ref() { - file_to_open = cwd.join(file_to_open); + TerminalAction::OpenFile(mut payload) => { + if payload.path.is_relative() { + if let Some(cwd) = payload.cwd.as_ref() { + payload.path = cwd.join(payload.path); } } let mut command = default_editor.unwrap_or_else(|| { @@ -306,11 +306,12 @@ fn spawn_terminal( if !command.is_dir() { separate_command_arguments(&mut command, &mut args); } - let file_to_open = file_to_open + let file_to_open = payload + .path .into_os_string() .into_string() .expect("Not valid Utf8 Encoding"); - if let Some(line_number) = line_number { + if let Some(line_number) = payload.line_number { if command.ends_with("vim") || command.ends_with("nvim") || command.ends_with("emacs") @@ -334,7 +335,7 @@ fn spawn_terminal( RunCommand { command, args, - cwd, + cwd: payload.cwd, hold_on_close: false, hold_on_start: false, ..Default::default() diff --git a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs index b8472dfc..75da894e 100644 --- a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs +++ b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs @@ -854,7 +854,7 @@ impl<'a> FloatingPaneGrid<'a> { } } -fn half_size_middle_geom(space: &Viewport, offset: usize) -> PaneGeom { +pub fn half_size_middle_geom(space: &Viewport, offset: usize) -> PaneGeom { let mut geom = PaneGeom { x: space.x + (space.cols as f64 / 4.0).round() as usize + offset, y: space.y + (space.rows as f64 / 4.0).round() as usize + offset, diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs index c9166ce1..2aa74d9c 100644 --- a/zellij-server/src/panes/floating_panes/mod.rs +++ b/zellij-server/src/panes/floating_panes/mod.rs @@ -1,4 +1,4 @@ -mod floating_pane_grid; +pub mod floating_pane_grid; use zellij_utils::{ data::{Direction, PaneInfo, ResizeStrategy}, position::Position, diff --git a/zellij-server/src/panes/mod.rs b/zellij-server/src/panes/mod.rs index 5055d0d3..4cd0fb4b 100644 --- a/zellij-server/src/panes/mod.rs +++ b/zellij-server/src/panes/mod.rs @@ -6,7 +6,7 @@ pub mod sixel; pub mod terminal_character; mod active_panes; -mod floating_panes; +pub mod floating_panes; mod plugin_pane; mod search; mod terminal_pane; diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index 4df05521..6232a3bf 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -98,6 +98,15 @@ impl From<ZellijUtilsPaneId> for PaneId { } } +impl Into<ZellijUtilsPaneId> for PaneId { + fn into(self) -> ZellijUtilsPaneId { + match self { + PaneId::Terminal(id) => ZellijUtilsPaneId::Terminal(id), + PaneId::Plugin(id) => ZellijUtilsPaneId::Plugin(id), + } + } +} + type IsFirstRun = bool; // FIXME: This should hold an os_api handle so that terminal panes can set their own size via FD in diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index 223ecb55..7e97f1d7 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -249,6 +249,7 @@ pub(crate) fn plugin_thread_main( run_plugin_or_alias.populate_run_plugin_if_needed(&plugin_aliases); let cwd = run_plugin_or_alias.get_initial_cwd().or(cwd); let run_plugin = run_plugin_or_alias.get_run_plugin(); + let start_suppressed = false; match wasm_bridge.load_plugin( &run_plugin, Some(tab_index), @@ -268,6 +269,7 @@ pub(crate) fn plugin_thread_main( plugin_id, pane_id_to_replace, cwd, + start_suppressed, Some(client_id), ))); }, @@ -307,6 +309,7 @@ pub(crate) fn plugin_thread_main( // we intentionally do not provide the client_id here because it belongs to // the cli who spawned the command and is not an existing client_id let skip_cache = true; // when reloading we always skip cache + let start_suppressed = false; match wasm_bridge.load_plugin( &Some(run_plugin), Some(tab_index), @@ -328,6 +331,7 @@ pub(crate) fn plugin_thread_main( plugin_id, None, None, + start_suppressed, None, ), )); @@ -365,6 +369,16 @@ pub(crate) fn plugin_thread_main( tab_index, client_id, ) => { + // prefer connected clients so as to avoid opening plugins in the background for + // CLI clients unless no-one else is connected + let client_id = if wasm_bridge.client_is_connected(&client_id) { + client_id + } else if let Some(first_client_id) = wasm_bridge.get_first_client_id() { + first_client_id + } else { + client_id + }; + let mut plugin_ids: HashMap<RunPluginOrAlias, Vec<PluginId>> = HashMap::new(); tab_layout = tab_layout.or_else(|| Some(layout.new_tab().0)); tab_layout diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs index 5ef220db..031f0100 100644 --- a/zellij-server/src/plugins/unit/plugin_tests.rs +++ b/zellij-server/src/plugins/unit/plugin_tests.rs @@ -6655,3 +6655,223 @@ pub fn run_plugin_in_specific_cwd() { "File written into plugin initial cwd" ); } + +#[test] +#[ignore] +pub fn hide_pane_with_id_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let cache_path = plugin_host_folder.join("permissions_test.kdl"); + let (plugin_thread_sender, screen_receiver, teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), + ..Default::default() + }); + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = grant_permissions_and_log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::SuppressPane, + screen_receiver, + 1, + &PermissionType::ChangeApplicationState, + cache_path, + plugin_thread_sender, + client_id + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + false, + plugin_title, + run_plugin, + tab_index, + None, + client_id, + size, + None, + false, + )); + std::thread::sleep(std::time::Duration::from_millis(500)); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(KeyWithModifier::new(BareKey::Char('a')).with_alt_modifier()), // this triggers the enent in the fixture plugin + )])); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let suppress_pane_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::SuppressPane(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", suppress_pane_event)); +} + +#[test] +#[ignore] +pub fn show_pane_with_id_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let cache_path = plugin_host_folder.join("permissions_test.kdl"); + let (plugin_thread_sender, screen_receiver, teardown) = + create_plugin_thread(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), + ..Default::default() + }); + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let screen_thread = grant_permissions_and_log_actions_in_thread!( + received_screen_instructions, + ScreenInstruction::FocusPaneWithId, + screen_receiver, + 1, + &PermissionType::ChangeApplicationState, + cache_path, + plugin_thread_sender, + client_id + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + false, + plugin_title, + run_plugin, + tab_index, + None, + client_id, + size, + None, + false, + )); + std::thread::sleep(std::time::Duration::from_millis(500)); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(KeyWithModifier::new(BareKey::Char('b')).with_alt_modifier()), // this triggers the enent in the fixture plugin + )])); + screen_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let focus_pane_event = received_screen_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let ScreenInstruction::FocusPaneWithId(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", focus_pane_event)); +} + +#[test] +#[ignore] +pub fn open_command_pane_background_plugin_command() { + let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its + // destructor removes the directory + let plugin_host_folder = PathBuf::from(temp_folder.path()); + let cache_path = plugin_host_folder.join("permissions_test.kdl"); + let (plugin_thread_sender, pty_receiver, screen_receiver, teardown) = + create_plugin_thread_with_pty_receiver(Some(plugin_host_folder)); + let plugin_should_float = Some(false); + let plugin_title = Some("test_plugin".to_owned()); + let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin { + _allow_exec_host_cmd: false, + location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), + ..Default::default() + }); + let tab_index = 1; + let client_id = 1; + let size = Size { + cols: 121, + rows: 20, + }; + let received_pty_instructions = Arc::new(Mutex::new(vec![])); + let pty_thread = log_actions_in_thread!( + received_pty_instructions, + PtyInstruction::SpawnTerminal, + pty_receiver, + 1 + ); + let received_screen_instructions = Arc::new(Mutex::new(vec![])); + let _screen_thread = grant_permissions_and_log_actions_in_thread_naked_variant!( + received_screen_instructions, + ScreenInstruction::Exit, + screen_receiver, + 1, + &PermissionType::ChangeApplicationState, + cache_path, + plugin_thread_sender, + client_id + ); + + let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id)); + let _ = plugin_thread_sender.send(PluginInstruction::Load( + plugin_should_float, + false, + plugin_title, + run_plugin, + tab_index, + None, + client_id, + size, + None, + false, + )); + std::thread::sleep(std::time::Duration::from_millis(500)); + let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![( + None, + Some(client_id), + Event::Key(KeyWithModifier::new(BareKey::Char('c')).with_alt_modifier()), // this triggers the enent in the fixture plugin + )])); + pty_thread.join().unwrap(); // this might take a while if the cache is cold + teardown(); + let new_tab_event = received_pty_instructions + .lock() + .unwrap() + .iter() + .find_map(|i| { + if let PtyInstruction::SpawnTerminal(..) = i { + Some(i.clone()) + } else { + None + } + }) + .clone(); + assert_snapshot!(format!("{:#?}", new_tab_event)); +} diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__hide_pane_with_id_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__hide_pane_with_id_plugin_command.snap new file mode 100644 index 00000000..43cae6bf --- /dev/null +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__hide_pane_with_id_plugin_command.snap @@ -0,0 +1,13 @@ +--- +source: zellij-server/src/plugins/./unit/plugin_tests.rs +assertion_line: 6727 +expression: "format!(\"{:#?}\", suppress_pane_event)" +--- +Some( + SuppressPane( + Terminal( + 1, + ), + 1, + ), +) 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 new file mode 100644 index 00000000..8c86f8f3 --- /dev/null +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_background_plugin_command.snap @@ -0,0 +1,37 @@ +--- +source: zellij-server/src/plugins/./unit/plugin_tests.rs +assertion_line: 6876 +expression: "format!(\"{:#?}\", new_tab_event)" +--- +Some( + SpawnTerminal( + Some( + RunCommand( + RunCommand { + command: "/path/to/my/file.rs", + args: [ + "arg1", + "arg2", + ], + cwd: None, + hold_on_close: true, + hold_on_start: false, + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), + }, + ), + ), + None, + None, + None, + true, + ClientId( + 1, + ), + ), +) 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 f8262b52..a89e1b2f 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 @@ -31,6 +31,7 @@ Some( ), None, None, + false, ClientId( 1, ), 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 a1247d5e..048dc905 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 @@ -31,6 +31,7 @@ Some( ), None, None, + false, ClientId( 1, ), 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 9a1ffe58..e4a14a40 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 @@ -1,17 +1,26 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3846 +assertion_line: 3996 expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" --- Some( SpawnTerminal( Some( OpenFile( - "/path/to/my/file.rs", - None, - Some( - "CWD", - ), + OpenFilePayload { + path: "/path/to/my/file.rs", + line_number: None, + cwd: Some( + "CWD", + ), + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), + }, ), ), Some( @@ -21,6 +30,7 @@ Some( "Editing: /path/to/my/file.rs", ), None, + false, ClientId( 1, ), 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 b24094af..ab031be5 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 @@ -1,17 +1,26 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 3927 +assertion_line: 4078 expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" --- Some( SpawnTerminal( Some( OpenFile( - "/path/to/my/file.rs", - None, - Some( - "CWD", - ), + OpenFilePayload { + path: "/path/to/my/file.rs", + line_number: None, + cwd: Some( + "CWD", + ), + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), + }, ), ), Some( @@ -21,6 +30,7 @@ Some( "Editing: /path/to/my/file.rs", ), None, + false, ClientId( 1, ), 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 dca771df..9d9747d8 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 @@ -1,19 +1,28 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4090 +assertion_line: 4243 expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" --- Some( SpawnTerminal( Some( OpenFile( - "/path/to/my/file.rs", - Some( - 42, - ), - Some( - "CWD", - ), + OpenFilePayload { + path: "/path/to/my/file.rs", + line_number: Some( + 42, + ), + cwd: Some( + "CWD", + ), + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), + }, ), ), Some( @@ -23,6 +32,7 @@ Some( "Editing: /path/to/my/file.rs", ), None, + false, ClientId( 1, ), 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 fd9d8e82..aa3aa515 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 @@ -1,19 +1,28 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4009 +assertion_line: 4161 expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" --- Some( SpawnTerminal( Some( OpenFile( - "/path/to/my/file.rs", - Some( - 42, - ), - Some( - "CWD", - ), + OpenFilePayload { + path: "/path/to/my/file.rs", + line_number: Some( + 42, + ), + cwd: Some( + "CWD", + ), + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), + }, ), ), Some( @@ -23,6 +32,7 @@ Some( "Editing: /path/to/my/file.rs", ), None, + false, ClientId( 1, ), 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 0ade1098..e61ebbdb 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 @@ -24,6 +24,7 @@ Some( ), None, None, + false, ClientId( 1, ), 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 3491f831..1df64a8f 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 @@ -24,6 +24,7 @@ Some( ), None, None, + false, ClientId( 1, ), 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 new file mode 100644 index 00000000..f13aded1 --- /dev/null +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__show_pane_with_id_plugin_command.snap @@ -0,0 +1,14 @@ +--- +source: zellij-server/src/plugins/./unit/plugin_tests.rs +assertion_line: 6798 +expression: "format!(\"{:#?}\", focus_pane_event)" +--- +Some( + FocusPaneWithId( + Terminal( + 1, + ), + true, + 1, + ), +) diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index ce68c109..76835183 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -1193,6 +1193,7 @@ impl WasmBridge { cli_client_id, ) { Ok((plugin_id, client_id)) => { + let start_suppressed = false; drop(self.senders.send_to_screen(ScreenInstruction::AddPlugin( Some(should_float), should_be_open_in_place, @@ -1202,6 +1203,7 @@ impl WasmBridge { plugin_id, pane_id_to_replace, cwd, + start_suppressed, Some(client_id), ))); vec![(plugin_id, Some(client_id))] @@ -1268,6 +1270,17 @@ impl WasmBridge { || (message_cid.is_none() && message_pid == Some(*plugin_id)) || (message_cid == Some(*client_id) && message_pid == Some(*plugin_id)) } + pub fn client_is_connected(&self, client_id: &ClientId) -> bool { + self.connected_clients.lock().unwrap().contains(client_id) + } + pub fn get_first_client_id(&self) -> Option<ClientId> { + self.connected_clients + .lock() + .unwrap() + .iter() + .next() + .copied() + } } fn handle_plugin_successful_loading(senders: &ThreadSenders, plugin_id: PluginId) { @@ -1316,6 +1329,9 @@ fn check_event_permission( | Event::SystemClipboardFailure | Event::CommandPaneOpened(..) | Event::CommandPaneExited(..) + | Event::PaneClosed(..) + | Event::EditPaneOpened(..) + | Event::EditPaneExited(..) | Event::InputReceived => PermissionType::ReadApplicationState, _ => return (PermissionStatus::Granted, None), }; diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs index 8722d64a..4f7f04b6 100644 --- a/zellij-server/src/plugins/zellij_exports.rs +++ b/zellij-server/src/plugins/zellij_exports.rs @@ -2,6 +2,7 @@ use super::PluginInstruction; use crate::background_jobs::BackgroundJob; use crate::plugins::plugin_map::PluginEnv; use crate::plugins::wasm_bridge::handle_plugin_crash; +use crate::pty::{ClientTabIndexOrPaneId, PtyInstruction}; use crate::route::route_action; use crate::ServerInstruction; use log::{debug, warn}; @@ -22,6 +23,7 @@ use zellij_utils::data::{ }; use zellij_utils::input::permission::PermissionCache; use zellij_utils::{ + async_std::task, interprocess::local_socket::LocalSocketStream, ipc::{ClientToServerMsg, IpcSenderWithContext}, }; @@ -37,7 +39,7 @@ use zellij_utils::{ errors::prelude::*, input::{ actions::Action, - command::{RunCommand, RunCommandAction, TerminalAction}, + command::{OpenFilePayload, RunCommand, RunCommandAction, TerminalAction}, layout::{Layout, RunPluginOrAlias}, plugins::PluginType, }, @@ -91,10 +93,14 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) { PluginCommand::SetSelectable(selectable) => set_selectable(env, selectable), PluginCommand::GetPluginIds => get_plugin_ids(env), PluginCommand::GetZellijVersion => get_zellij_version(env), - PluginCommand::OpenFile(file_to_open) => open_file(env, file_to_open), - PluginCommand::OpenFileFloating(file_to_open, floating_pane_coordinates) => { - open_file_floating(env, file_to_open, floating_pane_coordinates) + PluginCommand::OpenFile(file_to_open, context) => { + open_file(env, file_to_open, context) }, + PluginCommand::OpenFileFloating( + file_to_open, + floating_pane_coordinates, + context, + ) => open_file_floating(env, file_to_open, floating_pane_coordinates, context), PluginCommand::OpenTerminal(cwd) => open_terminal(env, cwd.path.try_into()?), PluginCommand::OpenTerminalFloating(cwd, floating_pane_coordinates) => { open_terminal_floating(env, cwd.path.try_into()?, floating_pane_coordinates) @@ -221,8 +227,8 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) { delete_dead_session(session_name)? }, PluginCommand::DeleteAllDeadSessions => delete_all_dead_sessions()?, - PluginCommand::OpenFileInPlace(file_to_open) => { - open_file_in_place(env, file_to_open) + PluginCommand::OpenFileInPlace(file_to_open, context) => { + open_file_in_place(env, file_to_open, context) }, PluginCommand::OpenTerminalInPlace(cwd) => { open_terminal_in_place(env, cwd.path.try_into()?) @@ -258,6 +264,9 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) { PluginCommand::ShowPaneWithId(pane_id, should_float_if_hidden) => { show_pane_with_id(env, pane_id.into(), should_float_if_hidden) }, + PluginCommand::OpenCommandPaneBackground(command_to_run, context) => { + open_command_pane_background(env, command_to_run, context) + }, }, (PermissionStatus::Denied, permission) => { log::error!( @@ -355,6 +364,7 @@ fn request_permission(env: &PluginEnv, permissions: Vec<PermissionType>) -> Resu if PermissionCache::from_path_or_default(None) .check_permissions(env.plugin.location.to_string(), &permissions) { + log::info!("PermissionRequestResult 1"); return env .senders .send_to_plugin(PluginInstruction::PermissionRequestResult( @@ -416,22 +426,24 @@ fn get_zellij_version(env: &PluginEnv) { .non_fatal(); } -fn open_file(env: &PluginEnv, file_to_open: FileToOpen) { +fn open_file(env: &PluginEnv, file_to_open: FileToOpen, context: BTreeMap<String, String>) { let error_msg = || format!("failed to open file in plugin {}", env.name()); let floating = false; let in_place = false; + let start_suppressed = false; let path = env.plugin_cwd.join(file_to_open.path); let cwd = file_to_open .cwd .map(|cwd| env.plugin_cwd.join(cwd)) .or_else(|| Some(env.plugin_cwd.clone())); let action = Action::EditFile( - path, - file_to_open.line_number, - cwd, + OpenFilePayload::new(path, file_to_open.line_number, cwd).with_originating_plugin( + OriginatingPlugin::new(env.plugin_id, env.client_id, context), + ), None, floating, in_place, + start_suppressed, None, ); apply_action!(action, error_msg, env); @@ -441,31 +453,39 @@ fn open_file_floating( env: &PluginEnv, file_to_open: FileToOpen, floating_pane_coordinates: Option<FloatingPaneCoordinates>, + context: BTreeMap<String, String>, ) { let error_msg = || format!("failed to open file in plugin {}", env.name()); let floating = true; let in_place = false; + let start_suppressed = false; let path = env.plugin_cwd.join(file_to_open.path); let cwd = file_to_open .cwd .map(|cwd| env.plugin_cwd.join(cwd)) .or_else(|| Some(env.plugin_cwd.clone())); let action = Action::EditFile( - path, - file_to_open.line_number, - cwd, + OpenFilePayload::new(path, file_to_open.line_number, cwd).with_originating_plugin( + OriginatingPlugin::new(env.plugin_id, env.client_id, context), + ), None, floating, in_place, + start_suppressed, floating_pane_coordinates, ); apply_action!(action, error_msg, env); } -fn open_file_in_place(env: &PluginEnv, file_to_open: FileToOpen) { +fn open_file_in_place( + env: &PluginEnv, + file_to_open: FileToOpen, + context: BTreeMap<String, String>, +) { let error_msg = || format!("failed to open file in plugin {}", env.name()); let floating = false; let in_place = true; + let start_suppressed = false; let path = env.plugin_cwd.join(file_to_open.path); let cwd = file_to_open .cwd @@ -473,12 +493,13 @@ fn open_file_in_place(env: &PluginEnv, file_to_open: FileToOpen) { .or_else(|| Some(env.plugin_cwd.clone())); let action = Action::EditFile( - path, - file_to_open.line_number, - cwd, + OpenFilePayload::new(path, file_to_open.line_number, cwd).with_originating_plugin( + OriginatingPlugin::new(env.plugin_id, env.client_id, context), + ), None, floating, in_place, + start_suppressed, None, ); apply_action!(action, error_msg, env); @@ -633,6 +654,43 @@ fn open_command_pane_in_place( apply_action!(action, error_msg, env); } +fn open_command_pane_background( + env: &PluginEnv, + command_to_run: CommandToRun, + context: BTreeMap<String, String>, +) { + let command = command_to_run.path; + let cwd = command_to_run.cwd.map(|cwd| env.plugin_cwd.join(cwd)); + let args = command_to_run.args; + let direction = None; + let hold_on_close = true; + let hold_on_start = false; + let start_suppressed = true; + let name = None; + let run_command_action = RunCommandAction { + command, + args, + cwd, + direction, + hold_on_close, + hold_on_start, + originating_plugin: Some(OriginatingPlugin::new( + env.plugin_id, + env.client_id, + context, + )), + }; + let run_cmd = TerminalAction::RunCommand(run_command_action.into()); + let _ = env.senders.send_to_pty(PtyInstruction::SpawnTerminal( + Some(run_cmd), + None, + name, + None, + start_suppressed, + ClientTabIndexOrPaneId::ClientId(env.client_id), + )); +} + fn switch_tab_to(env: &PluginEnv, tab_idx: u32) { env.senders .send_to_screen(ScreenInstruction::GoToTab(tab_idx, Some(env.client_id))) @@ -646,23 +704,13 @@ fn switch_tab_to(env: &PluginEnv, tab_idx: u32) { } fn set_timeout(env: &PluginEnv, secs: f64) { - // There is a fancy, high-performance way to do this with zero additional threads: - // If the plugin thread keeps a BinaryHeap of timer structs, it can manage multiple and easily `.peek()` at the - // next time to trigger in O(1) time. Once the wake-up time is known, the `wasm` thread can use `recv_timeout()` - // to wait for an event with the timeout set to be the time of the next wake up. If events come in in the meantime, - // they are handled, but if the timeout triggers, we replace the event from `recv()` with an - // `Update(pid, TimerEvent)` and pop the timer from the Heap (or reschedule it). No additional threads for as many - // timers as we'd like. - // - // But that's a lot of code, and this is a few lines: let send_plugin_instructions = env.senders.to_plugin.clone(); let update_target = Some(env.plugin_id); let client_id = env.client_id; let plugin_name = env.name(); - // TODO: we should really use an async task for this - thread::spawn(move || { + task::spawn(async move { let start_time = Instant::now(); - thread::sleep(Duration::from_secs_f64(secs)); + task::sleep(Duration::from_secs_f64(secs)).await; // FIXME: The way that elapsed time is being calculated here is not exact; it doesn't take into account the // time it takes an event to actually reach the plugin after it's sent to the `wasm` thread. let elapsed_time = Instant::now().duration_since(start_time).as_secs_f64(); @@ -1446,6 +1494,7 @@ fn check_command_permission( PluginCommand::OpenCommandPane(..) | PluginCommand::OpenCommandPaneFloating(..) | PluginCommand::OpenCommandPaneInPlace(..) + | PluginCommand::OpenCommandPaneBackground(..) | PluginCommand::RunCommand(..) | PluginCommand::ExecCmd(..) => PermissionType::RunCommands, PluginCommand::WebRequest(..) => PermissionType::WebAccess, diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index 74d66a57..68ee8e2c 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -18,7 +18,7 @@ use zellij_utils::{ errors::prelude::*, errors::{ContextType, PtyContext}, input::{ - command::{RunCommand, TerminalAction}, + command::{OpenFilePayload, RunCommand, TerminalAction}, layout::{FloatingPaneLayout, Layout, Run, RunPluginOrAlias, TiledPaneLayout}, }, pane_size::Size, @@ -43,6 +43,7 @@ pub enum PtyInstruction { Option<bool>, Option<String>, Option<FloatingPaneCoordinates>, + bool, // start suppressed ClientTabIndexOrPaneId, ), // bool (if Some) is // should_float, String is an optional pane name @@ -50,6 +51,7 @@ pub enum PtyInstruction { SpawnTerminalVertically(Option<TerminalAction>, Option<String>, ClientId), // String is an // optional pane // name + // bool is start_suppressed SpawnTerminalHorizontally(Option<TerminalAction>, Option<String>, ClientId), // String is an // optional pane // name @@ -141,29 +143,36 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { should_float, name, floating_pane_coordinates, + start_suppressed, client_or_tab_index, ) => { let err_context = || format!("failed to spawn terminal for {:?}", client_or_tab_index); - let (hold_on_close, run_command, pane_title) = match &terminal_action { - Some(TerminalAction::RunCommand(run_command)) => ( - run_command.hold_on_close, - Some(run_command.clone()), - Some(name.unwrap_or_else(|| run_command.to_string())), - ), - _ => (false, None, name), - }; - let invoked_with = + let (hold_on_close, run_command, pane_title, open_file_payload) = match &terminal_action { - Some(TerminalAction::RunCommand(run_command)) => { - Some(Run::Command(run_command.clone())) - }, - Some(TerminalAction::OpenFile(file, line_number, cwd)) => Some( - Run::EditFile(file.clone(), line_number.clone(), cwd.clone()), + Some(TerminalAction::RunCommand(run_command)) => ( + run_command.hold_on_close, + Some(run_command.clone()), + Some(name.unwrap_or_else(|| run_command.to_string())), + None, ), - _ => None, + Some(TerminalAction::OpenFile(open_file_payload)) => { + (false, None, name, Some(open_file_payload.clone())) + }, + _ => (false, None, name, None), }; + let invoked_with = match &terminal_action { + Some(TerminalAction::RunCommand(run_command)) => { + Some(Run::Command(run_command.clone())) + }, + Some(TerminalAction::OpenFile(payload)) => Some(Run::EditFile( + payload.path.clone(), + payload.line_number.clone(), + payload.cwd.clone(), + )), + _ => None, + }; match pty .spawn_terminal(terminal_action, client_or_tab_index) .with_context(err_context) @@ -191,6 +200,20 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { )])) .with_context(err_context)?; } + if let Some(originating_plugin) = + open_file_payload.and_then(|o| o.originating_plugin) + { + let update_event = + Event::EditPaneOpened(pid, originating_plugin.context.clone()); + pty.bus + .senders + .send_to_plugin(PluginInstruction::Update(vec![( + Some(originating_plugin.plugin_id), + Some(originating_plugin.client_id), + update_event, + )])) + .with_context(err_context)?; + } pty.bus .senders @@ -201,6 +224,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { hold_for_command, invoked_with, floating_pane_coordinates, + start_suppressed, client_or_tab_index, )) .with_context(err_context)?; @@ -218,6 +242,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { hold_for_command, invoked_with, floating_pane_coordinates, + start_suppressed, client_or_tab_index, )) .with_context(err_context)?; @@ -259,16 +284,17 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { ), _ => (false, None, name), }; - let invoked_with = - match &terminal_action { - Some(TerminalAction::RunCommand(run_command)) => { - Some(Run::Command(run_command.clone())) - }, - Some(TerminalAction::OpenFile(file, line_number, cwd)) => Some( - Run::EditFile(file.clone(), line_number.clone(), cwd.clone()), - ), - _ => None, - }; + let invoked_with = match &terminal_action { + Some(TerminalAction::RunCommand(run_command)) => { + Some(Run::Command(run_command.clone())) + }, + Some(TerminalAction::OpenFile(payload)) => Some(Run::EditFile( + payload.path.clone(), + payload.line_number.clone(), + payload.cwd.clone(), + )), + _ => None, + }; match pty .spawn_terminal(terminal_action, client_id_tab_index_or_pane_id) .with_context(err_context) @@ -324,7 +350,11 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> { || format!("failed to open in-place editor for client {}", client_id); match pty.spawn_terminal( - Some(TerminalAction::OpenFile(temp_file, line_number, None)), + Some(TerminalAction::OpenFile(OpenFilePayload::new( + temp_file, + line_number, + None, + ))), ClientTabIndexOrPaneId::ClientId(client_id), ) { Ok((pid, _starts_held)) => { @@ -761,13 +791,13 @@ impl Pty { TerminalAction::RunCommand(ref mut command) => { command.cwd = Some(cwd); }, - TerminalAction::OpenFile(ref _file, _line_number, ref mut edit_cwd) => { - match edit_cwd.as_mut() { + TerminalAction::OpenFile(ref mut payload) => { + match payload.cwd.as_mut() { Some(edit_cwd) => { *edit_cwd = cwd.join(&edit_cwd); }, None => { - let _ = edit_cwd.insert(cwd.clone()); + let _ = payload.cwd.insert(cwd.clone()); }, }; }, @@ -847,14 +877,24 @@ impl Pty { terminal_action }, }; - let (hold_on_start, hold_on_close, originating_plugin) = match &terminal_action { - TerminalAction::RunCommand(run_command) => ( - run_command.hold_on_start, - run_command.hold_on_close, - run_command.originating_plugin.clone(), - ), - _ => (false, false, None), - }; + let (hold_on_start, hold_on_close, originating_command_plugin, originating_edit_plugin) = + match &terminal_action { + TerminalAction::RunCommand(run_command) => ( + run_command.hold_on_start, + run_command.hold_on_close, + run_command.originating_plugin.clone(), + None, + ), + TerminalAction::OpenFile(open_file_payload) => ( + false, + false, + None, + open_file_payload.originating_plugin.clone(), + ), + _ => (false, false, None, None), + }; + // TODO: CONTINUE HERE - get originating_plugin also from TerminalAction::OpenFile and do + // the right thing in the quit_cb below if hold_on_start { // we don't actually open a terminal in this case, just wait for the user to run it @@ -869,22 +909,35 @@ impl Pty { return Ok((terminal_id, starts_held)); } - let originating_plugin = Arc::new(originating_plugin.clone()); + let originating_command_plugin = Arc::new(originating_command_plugin.clone()); + let originating_edit_plugin = Arc::new(originating_edit_plugin.clone()); let quit_cb = Box::new({ let senders = self.bus.senders.clone(); move |pane_id, exit_status, command| { // if this command originated in a plugin, we send the plugin an event letting it // know the command exited and some other useful information if let PaneId::Terminal(pane_id) = pane_id { - if let Some(originating_plugin) = originating_plugin.as_ref() { + if let Some(originating_command_plugin) = originating_command_plugin.as_ref() { let update_event = Event::CommandPaneExited( pane_id, exit_status, - originating_plugin.context.clone(), + originating_command_plugin.context.clone(), + ); + let _ = senders.send_to_plugin(PluginInstruction::Update(vec![( + Some(originating_command_plugin.plugin_id), + Some(originating_command_plugin.client_id), + update_event, + )])); + } + if let Some(originating_edit_plugin) = originating_edit_plugin.as_ref() { + let update_event = Event::EditPaneExited( + pane_id, + exit_status, + originating_edit_plugin.context.clone(), ); let _ = senders.send_to_plugin(PluginInstruction::Update(vec![( - Some(originating_plugin.plugin_id), - Some(originating_plugin.client_id), + Some(originating_edit_plugin.plugin_id), + Some(originating_edit_plugin.client_id), update_event, )])); } @@ -1200,7 +1253,11 @@ impl Pty { .context("no OS I/O interface found") .with_context(err_context)? .spawn_terminal( - TerminalAction::OpenFile(path_to_file, line_number, cwd), + TerminalAction::OpenFile(OpenFilePayload::new( + path_to_file, + line_number, + cwd, + )), quit_cb, self.default_editor.clone(), ) diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index ab5db049..a08ae99e 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -274,7 +274,7 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::TogglePaneFrames) .with_context(err_context)?; }, - Action::NewPane(direction, name) => { + Action::NewPane(direction, name, start_suppressed) => { let shell = default_shell.clone(); let pty_instr = match direction { Some(Direction::Left) => { @@ -295,22 +295,22 @@ pub(crate) fn route_action( None, name, None, + start_suppressed, ClientTabIndexOrPaneId::ClientId(client_id), ), }; senders.send_to_pty(pty_instr).with_context(err_context)?; }, Action::EditFile( - path_to_file, - line_number, - cwd, + open_file_payload, split_direction, should_float, should_open_in_place, + start_suppressed, floating_pane_coordinates, ) => { - let title = format!("Editing: {}", path_to_file.display()); - let open_file = TerminalAction::OpenFile(path_to_file, line_number, cwd); + let title = format!("Editing: {}", open_file_payload.path.display()); + let open_file = TerminalAction::OpenFile(open_file_payload); let pty_instr = match (split_direction, should_float, should_open_in_place) { (Some(Direction::Left), false, false) => { PtyInstruction::SpawnTerminalVertically(Some(open_file), Some(title), client_id) @@ -348,6 +348,7 @@ pub(crate) fn route_action( Some(should_float), Some(title), floating_pane_coordinates, + start_suppressed, ClientTabIndexOrPaneId::ClientId(client_id), ), }; @@ -394,6 +395,7 @@ pub(crate) fn route_action( Some(should_float), name, floating_pane_coordinates, + false, ClientTabIndexOrPaneId::ClientId(client_id), )) .with_context(err_context)?; @@ -447,6 +449,7 @@ pub(crate) fn route_action( Some(should_float), name, None, + false, ClientTabIndexOrPaneId::ClientId(client_id), ), }; @@ -496,6 +499,7 @@ pub(crate) fn route_action( None, None, None, + false, ClientTabIndexOrPaneId::ClientId(client_id), ), }; diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 189c2571..2484b3eb 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -152,6 +152,7 @@ pub enum ScreenInstruction { HoldForCommand, Option<Run>, // invoked with Option<FloatingPaneCoordinates>, + bool, // start suppressed ClientTabIndexOrPaneId, ), OpenInPlaceEditor(PaneId, ClientId), @@ -312,6 +313,7 @@ pub enum ScreenInstruction { u32, // plugin id Option<PaneId>, Option<PathBuf>, // cwd + bool, // start suppressed Option<ClientId>, ), UpdatePluginLoadingStage(u32, LoadingIndication), // u32 - plugin_id @@ -1905,7 +1907,7 @@ impl Screen { tab_index_and_plugin_pane_id = Some((*tab_index, plugin_pane_id)); if move_to_focused_tab && focused_tab_index != *tab_index { plugin_pane_to_move_to_active_tab = - tab.extract_pane(plugin_pane_id, Some(client_id)); + tab.extract_pane(plugin_pane_id, false, Some(client_id)); } break; @@ -1992,7 +1994,7 @@ impl Screen { .with_context(err_context)?; let pane_to_break_is_floating = active_tab.are_floating_panes_visible(); let active_pane = active_tab - .close_pane(active_pane_id, false, Some(client_id)) + .extract_pane(active_pane_id, false, Some(client_id)) .with_context(err_context)?; let active_pane_run_instruction = active_pane.invoked_with().clone(); let tab_index = self.get_new_tab_index(); @@ -2053,7 +2055,7 @@ impl Screen { .with_context(err_context)?; let pane_to_break_is_floating = active_tab.are_floating_panes_visible(); let active_pane = active_tab - .close_pane(active_pane_id, false, Some(client_id)) + .extract_pane(active_pane_id, false, Some(client_id)) .with_context(err_context)?; (active_pane_id, active_pane, pane_to_break_is_floating) }; @@ -2456,6 +2458,7 @@ pub(crate) fn screen_thread_main( hold_for_command, invoked_with, floating_pane_coordinates, + start_suppressed, client_or_tab_index, ) => { match client_or_tab_index { @@ -2466,6 +2469,7 @@ pub(crate) fn screen_thread_main( should_float, invoked_with, floating_pane_coordinates, + start_suppressed, Some(client_id) ) }, ?); @@ -2491,6 +2495,7 @@ pub(crate) fn screen_thread_main( should_float, invoked_with, floating_pane_coordinates, + start_suppressed, None, )?; if let Some(hold_for_command) = hold_for_command { @@ -2999,6 +3004,7 @@ pub(crate) fn screen_thread_main( } }, } + screen.unblock_input()?; screen.log_and_report_session_state()?; }, @@ -3632,6 +3638,7 @@ pub(crate) fn screen_thread_main( plugin_id, pane_id_to_replace, cwd, + start_suppressed, client_id, ) => { let pane_title = pane_title.unwrap_or_else(|| { @@ -3676,6 +3683,7 @@ pub(crate) fn screen_thread_main( should_float, Some(run_plugin), None, + start_suppressed, Some(client_id), ) }, ?); @@ -3688,6 +3696,7 @@ pub(crate) fn screen_thread_main( should_float, Some(run_plugin), None, + start_suppressed, None, )?; } else { diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 92e9eeb9..6b7a2192 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -30,6 +30,7 @@ use self::clipboard::ClipboardProvider; use crate::{ os_input_output::ServerOsApi, output::{CharacterChunk, Output, SixelImageChunk}, + panes::floating_panes::floating_pane_grid::half_size_middle_geom, panes::sixel::SixelImageStore, panes::{FloatingPanes, TiledPanes}, panes::{LinkHandler, PaneId, PluginPane, TerminalPane}, @@ -985,7 +986,7 @@ impl Tab { if let Some(focused_floating_pane_id) = self.floating_panes.active_pane_id(client_id) { if self.tiled_panes.has_room_for_new_pane() { let floating_pane_to_embed = self - .close_pane(focused_floating_pane_id, true, Some(client_id)) + .extract_pane(focused_floating_pane_id, true, Some(client_id)) .with_context(|| format!( "failed to find floating pane (ID: {focused_floating_pane_id:?}) to embed for client {client_id}", )) @@ -1004,7 +1005,7 @@ impl Tab { return Ok(()); } if let Some(embedded_pane_to_float) = - self.close_pane(focused_pane_id, true, Some(client_id)) + self.extract_pane(focused_pane_id, true, Some(client_id)) { self.show_floating_panes(); self.add_floating_pane( @@ -1047,11 +1048,13 @@ impl Tab { Some(client_id) => ClientTabIndexOrPaneId::ClientId(client_id), None => ClientTabIndexOrPaneId::TabIndex(self.index), }; + let should_start_suppressed = false; let instruction = PtyInstruction::SpawnTerminal( default_shell, Some(should_float), name, None, + should_start_suppressed, client_id_or_tab_index, ); self.senders @@ -1071,6 +1074,7 @@ impl Tab { should_float: Option<bool>, invoked_with: Option<Run>, floating_pane_coordinates: Option<FloatingPaneCoordinates>, + start_suppressed: bool, client_id: Option<ClientId>, ) -> Result<()> { let err_context = || format!("failed to create new pane with id {pid:?}"); @@ -1081,7 +1085,7 @@ impl Tab { }; self.close_down_to_max_terminals() .with_context(err_context)?; - let new_pane = match pid { + let mut new_pane = match pid { PaneId::Terminal(term_pid) => { let next_terminal_position = self.get_next_terminal_position(); Box::new(TerminalPane::new( @@ -1128,7 +1132,32 @@ impl Tab { )) as Box<dyn Pane> }, }; - if self.floating_panes.panes_are_visible() { + + if start_suppressed { + // this pane needs to start in the background (suppressed), only accessible if a plugin takes it out + // of there in one way or another + // we need to do some bookkeeping for this pane, namely setting its geom and + // content_offset so that things will appear properly in the terminal - we set it to + // the default geom of the first floating pane - this is just in order to give it some + // reasonable size, when it is shown - if needed - it will be given the proper geom as if it were + // resized + let viewport = { self.viewport.borrow().clone() }; + let new_pane_geom = half_size_middle_geom(&viewport, 0); + new_pane.set_active_at(Instant::now()); + new_pane.set_geom(new_pane_geom); + new_pane.set_content_offset(Offset::frame(1)); + resize_pty!( + new_pane, + self.os_api, + self.senders, + self.character_cell_size + ) + .with_context(err_context)?; + let is_scrollback_editor = false; + self.suppressed_panes + .insert(pid, (is_scrollback_editor, new_pane)); + Ok(()) + } else if self.floating_panes.panes_are_visible() { self.add_floating_pane(new_pane, pid, floating_pane_coordinates, client_id) } else { self.add_tiled_pane(new_pane, pid, client_id) @@ -2448,8 +2477,14 @@ impl Tab { self.get_tiled_panes().map(|(&pid, _)| pid).collect() } pub fn get_all_pane_ids(&self) -> Vec<PaneId> { - // this is here just as a naming thing to make things more explicit - self.get_static_and_floating_pane_ids() + let mut static_and_floating_pane_ids = self.get_static_and_floating_pane_ids(); + let mut suppressed_pane_ids = self + .suppressed_panes + .values() + .map(|(_key, pane)| pane.pid()) + .collect(); + static_and_floating_pane_ids.append(&mut suppressed_pane_ids); + static_and_floating_pane_ids } pub fn get_static_and_floating_pane_ids(&self) -> Vec<PaneId> { self.tiled_panes @@ -2494,26 +2529,22 @@ impl Tab { id: PaneId, ignore_suppressed_panes: bool, client_id: Option<ClientId>, - ) -> Option<Box<dyn Pane>> { + ) { // 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 - // - // TODO: separate the "close_pane" logic and the "move_pane_somewhere_else" logic, they're - // overloaded here and that's not great if !ignore_suppressed_panes && self.suppressed_panes.contains_key(&id) { return match self.replace_pane_with_suppressed_pane(id) { - Ok(pane) => pane, + Ok(_pane) => {}, Err(e) => { Err::<(), _>(e) .with_context(|| format!("failed to close pane {:?}", id)) .non_fatal(); - None }, }; } if self.floating_panes.panes_contain(&id) { - let closed_pane = self.floating_panes.remove_pane(id); + let _closed_pane = self.floating_panes.remove_pane(id); self.floating_panes.move_clients_out_of_pane(id); if !self.floating_panes.has_panes() { self.hide_floating_panes(); @@ -2529,12 +2560,11 @@ impl Tab { // confusing let _ = self.next_swap_layout(client_id, 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() { @@ -2543,14 +2573,30 @@ impl Tab { // confusing let _ = self.next_swap_layout(client_id, false); } - closed_pane - } + }; + let _ = self.senders.send_to_plugin(PluginInstruction::Update(vec![( + None, + None, + Event::PaneClosed(id.into()), + )])); } pub fn extract_pane( &mut self, id: PaneId, + ignore_suppressed_panes: bool, client_id: Option<ClientId>, ) -> Option<Box<dyn Pane>> { + if !ignore_suppressed_panes && self.suppressed_panes.contains_key(&id) { + return match self.replace_pane_with_suppressed_pane(id) { + Ok(pane) => pane, + Err(e) => { + Err::<(), _>(e) + .with_context(|| format!("failed to close pane {:?}", id)) + .non_fatal(); + None + }, + }; + } 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); @@ -2609,9 +2655,11 @@ impl Tab { if self.floating_panes.panes_contain(&id) { self.floating_panes .hold_pane(id, exit_status, is_first_run, run_command); - } else { + } else if self.tiled_panes.panes_contain(&id) { self.tiled_panes .hold_pane(id, exit_status, is_first_run, run_command); + } else if let Some(pane) = self.suppressed_panes.values_mut().find(|p| p.1.pid() == id) { + pane.1.hold(exit_status, is_first_run, run_command); } } pub fn replace_pane_with_suppressed_pane( @@ -3772,7 +3820,7 @@ impl Tab { // not take it out of there when another pane is closed (eg. like happens with the // scrollback editor), but it has to take itself out on its own (eg. a plugin using the // show_self() method) - if let Some(pane) = self.close_pane(pane_id, true, Some(client_id)) { + if let Some(pane) = self.extract_pane(pane_id, true, Some(client_id)) { let is_scrollback_editor = false; self.suppressed_panes .insert(pane_id, (is_scrollback_editor, pane)); diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs index dae50f28..4d94a777 100644 --- a/zellij-server/src/tab/unit/tab_integration_tests.rs +++ b/zellij-server/src/tab/unit/tab_integration_tests.rs @@ -778,7 +778,7 @@ fn dump_screen() { ..Default::default() }); let new_pane_id = PaneId::Terminal(2); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes())) .unwrap(); @@ -806,7 +806,7 @@ fn clear_screen() { ..Default::default() }); let new_pane_id = PaneId::Terminal(2); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes())) .unwrap(); @@ -832,7 +832,7 @@ fn new_floating_pane() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -860,7 +860,7 @@ fn floating_panes_persist_across_toggles() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); // here we send bytes to the pane when it's not visible to make sure they're still handled and @@ -892,7 +892,7 @@ fn toggle_floating_panes_off() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -921,7 +921,7 @@ fn toggle_floating_panes_on() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -955,16 +955,56 @@ fn five_new_floating_panes() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -999,8 +1039,16 @@ fn increase_floating_pane_size() { let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1029,8 +1077,16 @@ fn decrease_floating_pane_size() { let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1059,8 +1115,16 @@ fn resize_floating_pane_left() { let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1092,8 +1156,16 @@ fn resize_floating_pane_right() { let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1125,8 +1197,16 @@ fn resize_floating_pane_up() { let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1158,8 +1238,16 @@ fn resize_floating_pane_down() { let new_pane_id_1 = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1195,16 +1283,56 @@ fn move_floating_pane_focus_left() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1250,16 +1378,56 @@ fn move_floating_pane_focus_right() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1306,16 +1474,56 @@ fn move_floating_pane_focus_up() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1361,16 +1569,56 @@ fn move_floating_pane_focus_down() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1417,16 +1665,56 @@ fn move_floating_pane_focus_with_mouse() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1475,16 +1763,56 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1533,16 +1861,56 @@ fn drag_pane_with_mouse() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1591,16 +1959,56 @@ fn mark_text_inside_floating_pane() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1657,16 +2065,56 @@ fn resize_tab_with_floating_panes() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1711,16 +2159,56 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() { let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1761,16 +2249,56 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b let new_pane_id_5 = PaneId::Terminal(6); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 2, Vec::from("\n\n\n I am scratch terminal".as_bytes()), @@ -1812,7 +2340,7 @@ fn embed_floating_pane() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -1840,7 +2368,7 @@ fn float_embedded_pane() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -1870,7 +2398,7 @@ fn embed_floating_pane_without_pane_frames() { let mut output = Output::default(); tab.set_pane_frames(false); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -1899,7 +2427,7 @@ fn float_embedded_pane_without_pane_frames() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.set_pane_frames(false); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -2002,7 +2530,7 @@ fn rename_floating_pane() { let mut tab = create_new_tab(size, ModeInfo::default()); let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.handle_pty_bytes( 2, @@ -2098,7 +2626,7 @@ 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.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); let fixture = read_fixture("sixel-image-500px.six"); tab.handle_pty_bytes(2, fixture).unwrap(); @@ -2136,7 +2664,7 @@ 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.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); let fixture = read_fixture("sixel-image-500px.six"); tab.handle_pty_bytes(1, fixture).unwrap(); @@ -2194,7 +2722,7 @@ fn suppress_floating_pane() { let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) .unwrap(); @@ -2250,7 +2778,7 @@ fn close_suppressing_floating_pane() { let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) .unwrap(); @@ -2310,7 +2838,7 @@ fn suppress_floating_pane_embed_it_and_close_it() { let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) .unwrap(); @@ -2372,7 +2900,7 @@ fn resize_whole_tab_while_floting_pane_is_suppressed() { let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) .unwrap(); @@ -2474,7 +3002,7 @@ fn enter_search_floating_pane() { let new_pane_id = PaneId::Terminal(2); let mut output = Output::default(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id, None, None, None, None, Some(client_id)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(client_id)) .unwrap(); let pane_content = read_fixture("grid_copy"); @@ -2979,8 +3507,16 @@ fn move_pane_focus_sends_tty_csi_event() { }); let mut tab = create_new_tab_with_os_api(size, ModeInfo::default(), &os_api); let new_pane_id_1 = PaneId::Terminal(2); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 1, // subscribe to focus events @@ -3014,10 +3550,26 @@ fn move_floating_pane_focus_sends_tty_csi_event() { let new_pane_id_2 = PaneId::Terminal(3); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 1, // subscribe to focus events @@ -3057,10 +3609,26 @@ fn toggle_floating_panes_on_sends_tty_csi_event() { let new_pane_id_2 = PaneId::Terminal(3); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.handle_pty_bytes( 1, @@ -3101,10 +3669,26 @@ fn toggle_floating_panes_off_sends_tty_csi_event() { let new_pane_id_2 = PaneId::Terminal(3); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_pty_bytes( 1, // subscribe to focus events @@ -3163,8 +3747,16 @@ fn can_swap_tiled_layout_at_runtime() { ); let new_pane_id_1 = PaneId::Terminal(2); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.next_swap_layout(Some(client_id), false).unwrap(); tab.render(&mut output).unwrap(); let snapshot = take_snapshot( @@ -3218,10 +3810,26 @@ fn can_swap_floating_layout_at_runtime() { let new_pane_id_2 = PaneId::Terminal(3); tab.toggle_floating_panes(Some(client_id), None).unwrap(); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.next_swap_layout(Some(client_id), false).unwrap(); tab.render(&mut output).unwrap(); let snapshot = take_snapshot( @@ -3271,8 +3879,16 @@ fn swapping_layouts_after_resize_snaps_to_current_layout() { ); let new_pane_id_1 = PaneId::Terminal(2); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.next_swap_layout(Some(client_id), false).unwrap(); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) .unwrap(); @@ -3321,12 +3937,36 @@ fn swap_tiled_layout_with_stacked_children() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.render(&mut output).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3368,12 +4008,36 @@ fn swap_tiled_layout_with_only_stacked_children() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.render(&mut output).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3418,12 +4082,36 @@ fn swap_tiled_layout_with_stacked_children_and_no_pane_frames() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.render(&mut output).unwrap(); let snapshot = take_snapshot( output.serialize().unwrap().get(&client_id).unwrap(), @@ -3468,12 +4156,36 @@ fn move_focus_up_with_stacked_panes() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.render(&mut output).unwrap(); @@ -3520,12 +4232,36 @@ fn move_focus_down_with_stacked_panes() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.move_focus_down(client_id); @@ -3580,6 +4316,7 @@ fn move_focus_right_into_stacked_panes() { None, None, None, + false, Some(client_id), ) .unwrap(); @@ -3648,6 +4385,7 @@ fn move_focus_left_into_stacked_panes() { None, None, None, + false, Some(client_id), ) .unwrap(); @@ -3718,6 +4456,7 @@ fn move_focus_up_into_stacked_panes() { None, None, None, + false, Some(client_id), ) .unwrap(); @@ -3789,6 +4528,7 @@ fn move_focus_down_into_stacked_panes() { None, None, None, + false, Some(client_id), ) .unwrap(); @@ -3850,12 +4590,36 @@ fn close_main_stacked_pane() { let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_3 = PaneId::Terminal(4); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.close_pane(new_pane_id_2, false, None); tab.render(&mut output).unwrap(); let snapshot = take_snapshot( @@ -3903,16 +4667,56 @@ fn close_main_stacked_pane_in_mid_stack() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.move_focus_up(client_id); @@ -3963,16 +4767,56 @@ fn close_one_liner_stacked_pane_below_main_pane() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_left(client_id); tab.move_focus_right(client_id); tab.move_focus_up(client_id); @@ -4024,16 +4868,56 @@ fn close_one_liner_stacked_pane_above_main_pane() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.move_focus_up(client_id); tab.move_focus_up(client_id); @@ -4084,16 +4968,56 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.resize( client_id, @@ -4148,16 +5072,56 @@ fn can_increase_size_of_main_pane_in_stack_vertically() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.resize( client_id, @@ -4212,16 +5176,56 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); let _ = tab.move_focus_up(client_id); let _ = tab.move_focus_right(client_id); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) @@ -4272,16 +5276,56 @@ fn can_increase_size_into_pane_stack_horizontally() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.resize( client_id, ResizeStrategy::new(Resize::Increase, Some(Direction::Right)), @@ -4335,16 +5379,56 @@ fn can_increase_size_into_pane_stack_vertically() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_right(client_id); tab.move_focus_down(client_id); tab.resize( @@ -4400,16 +5484,56 @@ fn can_increase_size_into_pane_stack_non_directionally() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); let _ = tab.move_focus_up(client_id); tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) .unwrap(); @@ -4459,16 +5583,56 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.resize_whole_tab(Size { cols: 100, rows: 10, @@ -4519,16 +5683,56 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.resize_whole_tab(Size { cols: 100, rows: 10, @@ -4584,16 +5788,56 @@ fn cannot_decrease_stack_size_beyond_minimum_height() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_down(client_id); for _ in 0..6 { tab.resize( @@ -4649,16 +5893,56 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_left_click(&Position::new(1, 71), client_id) .unwrap(); tab.render(&mut output).unwrap(); @@ -4708,16 +5992,56 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_left_click(&Position::new(1, 71), client_id) .unwrap(); tab.handle_left_click(&Position::new(9, 71), client_id) @@ -4769,16 +6093,56 @@ fn close_stacked_pane_with_previously_focused_other_pane() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.handle_left_click(&Position::new(2, 71), client_id) .unwrap(); tab.handle_left_click(&Position::new(1, 71), client_id) @@ -4836,16 +6200,56 @@ fn close_pane_near_stacked_panes() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.close_pane(PaneId::Terminal(6), false, None); tab.render(&mut output).unwrap(); let (snapshot, cursor_coordinates) = take_snapshot_and_cursor_position( @@ -4900,16 +6304,56 @@ fn focus_next_pane_expands_stacked_panes() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_left(client_id); tab.focus_next_pane(client_id); tab.render(&mut output).unwrap(); @@ -4960,16 +6404,56 @@ fn stacked_panes_can_become_fullscreen() { let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_5 = PaneId::Terminal(6); - tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id)) - .unwrap(); - tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id)) - .unwrap(); + tab.new_pane( + new_pane_id_1, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_2, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_3, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_4, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); + tab.new_pane( + new_pane_id_5, + None, + None, + None, + None, + false, + Some(client_id), + ) + .unwrap(); tab.move_focus_up(client_id); tab.toggle_active_pane_fullscreen(client_id); tab.render(&mut output).unwrap(); @@ -5608,6 +7092,7 @@ fn new_pane_in_auto_layout() { None, None, None, + false, Some(client_id), ) .unwrap(); @@ -6534,6 +8019,7 @@ fn new_floating_pane_in_auto_layout() { Some(should_float), None, None, + false, Some(client_id), ) .unwrap(); diff --git a/zellij-server/src/tab/unit/tab_tests.rs b/zellij-server/src/tab/unit/tab_tests.rs index 5ad917ea..a0c04088 100644 --- a/zellij-server/src/tab/unit/tab_tests.rs +++ b/zellij-server/src/tab/unit/tab_tests.rs @@ -571,7 +571,7 @@ fn split_largest_pane() { let mut tab = create_new_tab(size); for i in 2..5 { let new_pane_id = PaneId::Terminal(i); - tab.new_pane(new_pane_id, None, None, None, None, Some(1)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(1)) .unwrap(); } assert_eq!(tab.tiled_panes.panes.len(), 4, "The tab has four panes"); @@ -777,7 +777,7 @@ pub fn cannot_split_panes_horizontally_when_active_pane_is_too_small() { pub fn cannot_split_largest_pane_when_there_is_no_room() { let size = Size { cols: 8, rows: 4 }; let mut tab = create_new_tab(size); - tab.new_pane(PaneId::Terminal(2), None, None, None, None, Some(1)) + tab.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1)) .unwrap(); assert_eq!( tab.tiled_panes.panes.len(), @@ -821,7 +821,7 @@ pub fn toggle_focused_pane_fullscreen() { let mut tab = create_new_tab(size); for i in 2..5 { let new_pane_id = PaneId::Terminal(i); - tab.new_pane(new_pane_id, None, None, None, None, Some(1)) + tab.new_pane(new_pane_id, None, None, None, None, false, Some(1)) .unwrap(); } tab.toggle_active_pane_fullscreen(1); @@ -896,16 +896,16 @@ fn switch_to_next_pane_fullscreen() { let mut active_tab = create_new_tab(size); active_tab - .new_pane(PaneId::Terminal(1), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(1), None, None, None, None, false, Some(1)) .unwrap(); active_tab - .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1)) .unwrap(); active_tab - .new_pane(PaneId::Terminal(3), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(3), None, None, None, None, false, Some(1)) .unwrap(); active_tab - .new_pane(PaneId::Terminal(4), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(4), None, None, None, None, false, Some(1)) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); @@ -936,16 +936,16 @@ fn switch_to_prev_pane_fullscreen() { //testing four consecutive switches in fullscreen mode active_tab - .new_pane(PaneId::Terminal(1), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(1), None, None, None, None, false, Some(1)) .unwrap(); active_tab - .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1)) .unwrap(); active_tab - .new_pane(PaneId::Terminal(3), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(3), None, None, None, None, false, Some(1)) .unwrap(); active_tab - .new_pane(PaneId::Terminal(4), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(4), None, None, None, None, false, Some(1)) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); // order is now 1 2 3 4 @@ -14427,7 +14427,7 @@ fn correctly_resize_frameless_panes_on_pane_close() { let content_size = (pane.get_content_columns(), pane.get_content_rows()); assert_eq!(content_size, (cols, rows)); - tab.new_pane(PaneId::Terminal(2), None, None, None, None, Some(1)) + tab.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1)) .unwrap(); tab.close_pane(PaneId::Terminal(2), true, None); diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs index 09d2d794..1d3c1405 100644 --- a/zellij-server/src/unit/screen_tests.rs +++ b/zellij-server/src/unit/screen_tests.rs @@ -1166,7 +1166,7 @@ fn switch_to_tab_with_fullscreen() { { let active_tab = screen.get_active_tab_mut(1).unwrap(); active_tab - .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1)) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); } @@ -1281,7 +1281,7 @@ fn attach_after_first_tab_closed() { { let active_tab = screen.get_active_tab_mut(1).unwrap(); active_tab - .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1)) + .new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1)) .unwrap(); active_tab.toggle_active_pane_fullscreen(1); } @@ -1315,6 +1315,7 @@ fn open_new_floating_pane_with_custom_coordinates() { width: Some(SplitSize::Percent(1)), height: Some(SplitSize::Fixed(2)), }), + false, Some(1), ) .unwrap(); @@ -1348,6 +1349,7 @@ fn open_new_floating_pane_with_custom_coordinates_exceeding_viewport() { width: Some(SplitSize::Fixed(10)), height: Some(SplitSize::Fixed(10)), }), + false, Some(1), ) .unwrap(); 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 f4e2645a..6ed151b4 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 @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2031 +assertion_line: 2389 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(Some(OpenFile("/file/to/edit", None, Some("."))), Some(false), Some("Editing: /file/to/edit"), None, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some(false), Some("Editing: /file/to/edit"), None, false, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), 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 e5b22c9f..a6ad8ea0 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 @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2065 +assertion_line: 2427 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(Some(OpenFile("/file/to/edit", Some(100), Some("."))), Some(false), Some("Editing: /file/to/edit"), None, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: Some(100), cwd: Some("."), originating_plugin: None })), Some(false), Some("Editing: /file/to/edit"), None, false, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), 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 7b3459d5..fa4e0e3d 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 @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2178 +assertion_line: 2465 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminalHorizontally(Some(OpenFile("/file/to/edit", None, Some("."))), Some("Editing: /file/to/edit"), 10), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminalHorizontally(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), 10), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] 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 39b5ea9d..bf271501 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 @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1911 +assertion_line: 2222 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(None, Some(false), None, None, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(None, Some(false), None, None, false, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), 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 a1fd2b91..be12965c 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 @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2349 +assertion_line: 2351 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None })), Some(true), None, Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None }), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None })), Some(true), None, Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None }), false, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] |
