feat(panes): allow specifying coordinates for a new floating pane through the CLI or plugins (#3122)

* working

* add tests

* add coordinates to all the places

* refactor: move things around:

* style(fmt): rustfmt

* style(code): cleanups
This commit is contained in:
Aram Drevekenin 2024-02-08 17:35:55 +01:00 committed by GitHub
parent 662c37b508
commit 326c8cd3c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 1078 additions and 337 deletions

View file

@ -167,10 +167,13 @@ impl ZellijPlugin for State {
}); });
}, },
Key::Ctrl('h') => { Key::Ctrl('h') => {
open_file_floating(FileToOpen { open_file_floating(
path: std::path::PathBuf::from("/path/to/my/file.rs"), FileToOpen {
..Default::default() path: std::path::PathBuf::from("/path/to/my/file.rs"),
}); ..Default::default()
},
None,
);
}, },
Key::Ctrl('i') => { Key::Ctrl('i') => {
open_file(FileToOpen { open_file(FileToOpen {
@ -180,11 +183,14 @@ impl ZellijPlugin for State {
}); });
}, },
Key::Ctrl('j') => { Key::Ctrl('j') => {
open_file_floating(FileToOpen { open_file_floating(
path: std::path::PathBuf::from("/path/to/my/file.rs"), FileToOpen {
line_number: Some(42), path: std::path::PathBuf::from("/path/to/my/file.rs"),
..Default::default() line_number: Some(42),
}); ..Default::default()
},
None,
);
}, },
Key::Ctrl('k') => { Key::Ctrl('k') => {
open_terminal(std::path::PathBuf::from("/path/to/my/file.rs").as_path()); open_terminal(std::path::PathBuf::from("/path/to/my/file.rs").as_path());
@ -192,6 +198,7 @@ impl ZellijPlugin for State {
Key::Ctrl('l') => { Key::Ctrl('l') => {
open_terminal_floating( open_terminal_floating(
std::path::PathBuf::from("/path/to/my/file.rs").as_path(), std::path::PathBuf::from("/path/to/my/file.rs").as_path(),
None,
); );
}, },
Key::Ctrl('m') => { Key::Ctrl('m') => {
@ -202,11 +209,14 @@ impl ZellijPlugin for State {
}); });
}, },
Key::Ctrl('n') => { Key::Ctrl('n') => {
open_command_pane_floating(CommandToRun { open_command_pane_floating(
path: std::path::PathBuf::from("/path/to/my/file.rs"), CommandToRun {
args: vec!["arg1".to_owned(), "arg2".to_owned()], path: std::path::PathBuf::from("/path/to/my/file.rs"),
..Default::default() args: vec!["arg1".to_owned(), "arg2".to_owned()],
}); ..Default::default()
},
None,
);
}, },
Key::Ctrl('o') => { Key::Ctrl('o') => {
switch_tab_to(1); switch_tab_to(1);

View file

@ -88,10 +88,13 @@ impl SearchState {
match self.selected_search_result_entry() { match self.selected_search_result_entry() {
Some(SearchResult::File { path, .. }) => { Some(SearchResult::File { path, .. }) => {
if self.should_open_floating { if self.should_open_floating {
open_file_floating(FileToOpen { open_file_floating(
path: PathBuf::from(path), FileToOpen {
..Default::default() path: PathBuf::from(path),
}); ..Default::default()
},
None,
);
} else { } else {
open_file(FileToOpen { open_file(FileToOpen {
path: PathBuf::from(path), path: PathBuf::from(path),
@ -103,11 +106,14 @@ impl SearchState {
path, line_number, .. path, line_number, ..
}) => { }) => {
if self.should_open_floating { if self.should_open_floating {
open_file_floating(FileToOpen { open_file_floating(
path: PathBuf::from(path), FileToOpen {
line_number: Some(line_number), path: PathBuf::from(path),
..Default::default() line_number: Some(line_number),
}); ..Default::default()
},
None,
);
} else { } else {
open_file(FileToOpen { open_file(FileToOpen {
path: PathBuf::from(path), path: PathBuf::from(path),
@ -132,7 +138,7 @@ impl SearchState {
{ {
let dir_path = dir_path_of_result(&path); let dir_path = dir_path_of_result(&path);
if self.should_open_floating { if self.should_open_floating {
open_terminal_floating(&dir_path); open_terminal_floating(&dir_path, None);
} else { } else {
open_terminal(&dir_path); open_terminal(&dir_path);
} }

View file

@ -29,6 +29,10 @@ fn main() {
name, name,
close_on_exit, close_on_exit,
start_suspended, start_suspended,
x,
y,
width,
height,
})) = opts.command })) = opts.command
{ {
let cwd = cwd.or_else(|| std::env::current_dir().ok()); let cwd = cwd.or_else(|| std::env::current_dir().ok());
@ -45,6 +49,10 @@ fn main() {
start_suspended, start_suspended,
configuration: None, configuration: None,
skip_plugin_cache, skip_plugin_cache,
x,
y,
width,
height,
}; };
commands::send_action_to_session(command_cli_action, opts.session, config); commands::send_action_to_session(command_cli_action, opts.session, config);
std::process::exit(0); std::process::exit(0);
@ -55,6 +63,10 @@ fn main() {
in_place, in_place,
configuration, configuration,
skip_plugin_cache, skip_plugin_cache,
x,
y,
width,
height,
})) = opts.command })) = opts.command
{ {
let cwd = std::env::current_dir().ok(); let cwd = std::env::current_dir().ok();
@ -70,6 +82,10 @@ fn main() {
start_suspended: false, start_suspended: false,
configuration, configuration,
skip_plugin_cache, skip_plugin_cache,
x,
y,
width,
height,
}; };
commands::send_action_to_session(command_cli_action, opts.session, config); commands::send_action_to_session(command_cli_action, opts.session, config);
std::process::exit(0); std::process::exit(0);
@ -81,6 +97,10 @@ fn main() {
floating, floating,
in_place, in_place,
cwd, cwd,
x,
y,
width,
height,
})) = opts.command })) = opts.command
{ {
let mut file = file; let mut file = file;
@ -97,6 +117,10 @@ fn main() {
floating, floating,
in_place, in_place,
cwd, cwd,
x,
y,
width,
height,
}; };
commands::send_action_to_session(command_cli_action, opts.session, config); commands::send_action_to_session(command_cli_action, opts.session, config);
std::process::exit(0); std::process::exit(0);

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 3198 assertion_line: 4400
expression: "format!(\"{:#?}\", new_tab_event)" expression: "format!(\"{:#?}\", new_tab_event)"
--- ---
Some( Some(
@ -23,6 +23,7 @@ Some(
true, true,
), ),
None, None,
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 3144 assertion_line: 4323
expression: "format!(\"{:#?}\", new_tab_event)" expression: "format!(\"{:#?}\", new_tab_event)"
--- ---
Some( Some(
@ -23,6 +23,7 @@ Some(
false, false,
), ),
None, None,
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -20,6 +20,7 @@ Some(
Some( Some(
"Editing: /path/to/my/file.rs", "Editing: /path/to/my/file.rs",
), ),
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 3925 assertion_line: 3927
expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")"
--- ---
Some( Some(
@ -20,6 +20,7 @@ Some(
Some( Some(
"Editing: /path/to/my/file.rs", "Editing: /path/to/my/file.rs",
), ),
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 4076 assertion_line: 4090
expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")"
--- ---
Some( Some(
@ -22,6 +22,7 @@ Some(
Some( Some(
"Editing: /path/to/my/file.rs", "Editing: /path/to/my/file.rs",
), ),
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 3999 assertion_line: 4009
expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")" expression: "format!(\"{:#?}\",\n new_tab_event).replace(&format!(\"{:?}\", temp_folder.path()),\n \"\\\"CWD\\\"\")"
--- ---
Some( Some(
@ -22,6 +22,7 @@ Some(
Some( Some(
"Editing: /path/to/my/file.rs", "Editing: /path/to/my/file.rs",
), ),
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 3090 assertion_line: 4246
expression: "format!(\"{:#?}\", new_tab_event)" expression: "format!(\"{:#?}\", new_tab_event)"
--- ---
Some( Some(
@ -22,6 +22,7 @@ Some(
true, true,
), ),
None, None,
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/plugins/./unit/plugin_tests.rs source: zellij-server/src/plugins/./unit/plugin_tests.rs
assertion_line: 3036 assertion_line: 4169
expression: "format!(\"{:#?}\", new_tab_event)" expression: "format!(\"{:#?}\", new_tab_event)"
--- ---
Some( Some(
@ -22,6 +22,7 @@ Some(
false, false,
), ),
None, None,
None,
ClientId( ClientId(
1, 1,
), ),

View file

@ -18,8 +18,8 @@ use std::{
use wasmer::{imports, AsStoreMut, Function, FunctionEnv, FunctionEnvMut, Imports}; use wasmer::{imports, AsStoreMut, Function, FunctionEnv, FunctionEnvMut, Imports};
use wasmer_wasi::WasiEnv; use wasmer_wasi::WasiEnv;
use zellij_utils::data::{ use zellij_utils::data::{
CommandType, ConnectToSession, HttpVerb, LayoutInfo, MessageToPlugin, PermissionStatus, CommandType, ConnectToSession, FloatingPaneCoordinates, HttpVerb, LayoutInfo, MessageToPlugin,
PermissionType, PluginPermission, PermissionStatus, PermissionType, PluginPermission,
}; };
use zellij_utils::input::permission::PermissionCache; use zellij_utils::input::permission::PermissionCache;
use zellij_utils::{ use zellij_utils::{
@ -117,19 +117,20 @@ fn host_run_plugin_command(env: FunctionEnvMut<ForeignFunctionEnv>) {
PluginCommand::GetPluginIds => get_plugin_ids(env), PluginCommand::GetPluginIds => get_plugin_ids(env),
PluginCommand::GetZellijVersion => get_zellij_version(env), PluginCommand::GetZellijVersion => get_zellij_version(env),
PluginCommand::OpenFile(file_to_open) => open_file(env, file_to_open), PluginCommand::OpenFile(file_to_open) => open_file(env, file_to_open),
PluginCommand::OpenFileFloating(file_to_open) => { PluginCommand::OpenFileFloating(file_to_open, floating_pane_coordinates) => {
open_file_floating(env, file_to_open) open_file_floating(env, file_to_open, floating_pane_coordinates)
}, },
PluginCommand::OpenTerminal(cwd) => open_terminal(env, cwd.path.try_into()?), PluginCommand::OpenTerminal(cwd) => open_terminal(env, cwd.path.try_into()?),
PluginCommand::OpenTerminalFloating(cwd) => { PluginCommand::OpenTerminalFloating(cwd, floating_pane_coordinates) => {
open_terminal_floating(env, cwd.path.try_into()?) open_terminal_floating(env, cwd.path.try_into()?, floating_pane_coordinates)
}, },
PluginCommand::OpenCommandPane(command_to_run) => { PluginCommand::OpenCommandPane(command_to_run) => {
open_command_pane(env, command_to_run) open_command_pane(env, command_to_run)
}, },
PluginCommand::OpenCommandPaneFloating(command_to_run) => { PluginCommand::OpenCommandPaneFloating(
open_command_pane_floating(env, command_to_run) command_to_run,
}, floating_pane_coordinates,
) => open_command_pane_floating(env, command_to_run, floating_pane_coordinates),
PluginCommand::SwitchTabTo(tab_index) => switch_tab_to(env, tab_index), PluginCommand::SwitchTabTo(tab_index) => switch_tab_to(env, tab_index),
PluginCommand::SetTimeout(seconds) => set_timeout(env, seconds), PluginCommand::SetTimeout(seconds) => set_timeout(env, seconds),
PluginCommand::ExecCmd(command_line) => exec_cmd(env, command_line), PluginCommand::ExecCmd(command_line) => exec_cmd(env, command_line),
@ -447,11 +448,16 @@ fn open_file(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
None, None,
floating, floating,
in_place, in_place,
None,
); );
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
fn open_file_floating(env: &ForeignFunctionEnv, file_to_open: FileToOpen) { fn open_file_floating(
env: &ForeignFunctionEnv,
file_to_open: FileToOpen,
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let floating = true; let floating = true;
let in_place = false; let in_place = false;
@ -467,6 +473,7 @@ fn open_file_floating(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
None, None,
floating, floating,
in_place, in_place,
floating_pane_coordinates,
); );
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
@ -488,6 +495,7 @@ fn open_file_in_place(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
None, None,
floating, floating,
in_place, in_place,
None,
); );
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
@ -509,7 +517,11 @@ fn open_terminal(env: &ForeignFunctionEnv, cwd: PathBuf) {
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
fn open_terminal_floating(env: &ForeignFunctionEnv, cwd: PathBuf) { fn open_terminal_floating(
env: &ForeignFunctionEnv,
cwd: PathBuf,
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let cwd = env.plugin_env.plugin_cwd.join(cwd); let cwd = env.plugin_env.plugin_cwd.join(cwd);
let mut default_shell = env let mut default_shell = env
@ -522,7 +534,7 @@ fn open_terminal_floating(env: &ForeignFunctionEnv, cwd: PathBuf) {
TerminalAction::RunCommand(run_command) => Some(run_command.into()), TerminalAction::RunCommand(run_command) => Some(run_command.into()),
_ => None, _ => None,
}; };
let action = Action::NewFloatingPane(run_command_action, None); let action = Action::NewFloatingPane(run_command_action, None, floating_pane_coordinates);
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
@ -566,7 +578,11 @@ fn open_command_pane(env: &ForeignFunctionEnv, command_to_run: CommandToRun) {
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
fn open_command_pane_floating(env: &ForeignFunctionEnv, command_to_run: CommandToRun) { fn open_command_pane_floating(
env: &ForeignFunctionEnv,
command_to_run: CommandToRun,
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
) {
let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name());
let command = command_to_run.path; let command = command_to_run.path;
let cwd = command_to_run let cwd = command_to_run
@ -585,7 +601,7 @@ fn open_command_pane_floating(env: &ForeignFunctionEnv, command_to_run: CommandT
hold_on_close, hold_on_close,
hold_on_start, hold_on_start,
}; };
let action = Action::NewFloatingPane(Some(run_command_action), name); let action = Action::NewFloatingPane(Some(run_command_action), name, floating_pane_coordinates);
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }

View file

@ -13,6 +13,7 @@ use std::{collections::HashMap, os::unix::io::RawFd, path::PathBuf};
use zellij_utils::nix::unistd::Pid; use zellij_utils::nix::unistd::Pid;
use zellij_utils::{ use zellij_utils::{
async_std, async_std,
data::FloatingPaneCoordinates,
errors::prelude::*, errors::prelude::*,
errors::{ContextType, PtyContext}, errors::{ContextType, PtyContext},
input::{ input::{
@ -43,6 +44,7 @@ pub enum PtyInstruction {
Option<TerminalAction>, Option<TerminalAction>,
Option<bool>, Option<bool>,
Option<String>, Option<String>,
Option<FloatingPaneCoordinates>,
ClientTabIndexOrPaneId, ClientTabIndexOrPaneId,
), // bool (if Some) is ), // bool (if Some) is
// should_float, String is an optional pane name // should_float, String is an optional pane name
@ -90,6 +92,7 @@ pub enum PtyInstruction {
Size, Size,
bool, // skip cache bool, // skip cache
Option<PathBuf>, // if Some, will not fill cwd but just forward the message Option<PathBuf>, // if Some, will not fill cwd but just forward the message
Option<FloatingPaneCoordinates>,
), ),
Exit, Exit,
} }
@ -135,6 +138,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
terminal_action, terminal_action,
should_float, should_float,
name, name,
floating_pane_coordinates,
client_or_tab_index, client_or_tab_index,
) => { ) => {
let err_context = let err_context =
@ -176,6 +180,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
should_float, should_float,
hold_for_command, hold_for_command,
invoked_with, invoked_with,
floating_pane_coordinates,
client_or_tab_index, client_or_tab_index,
)) ))
.with_context(err_context)?; .with_context(err_context)?;
@ -192,6 +197,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
should_float, should_float,
hold_for_command, hold_for_command,
invoked_with, invoked_with,
floating_pane_coordinates,
client_or_tab_index, client_or_tab_index,
)) ))
.with_context(err_context)?; .with_context(err_context)?;
@ -657,6 +663,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
size, size,
skip_cache, skip_cache,
cwd, cwd,
floating_pane_coordinates,
) => { ) => {
pty.fill_plugin_cwd( pty.fill_plugin_cwd(
should_float, should_float,
@ -669,6 +676,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
size, size,
skip_cache, skip_cache,
cwd, cwd,
floating_pane_coordinates,
)?; )?;
}, },
PtyInstruction::Exit => break, PtyInstruction::Exit => break,
@ -1336,6 +1344,7 @@ impl Pty {
size: Size, size: Size,
skip_cache: bool, skip_cache: bool,
cwd: Option<PathBuf>, cwd: Option<PathBuf>,
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
) -> Result<()> { ) -> Result<()> {
let cwd = cwd.or_else(|| { let cwd = cwd.or_else(|| {
self.active_panes self.active_panes

View file

@ -268,6 +268,7 @@ pub(crate) fn route_action(
shell, shell,
None, None,
name, name,
None,
ClientTabIndexOrPaneId::ClientId(client_id), ClientTabIndexOrPaneId::ClientId(client_id),
), ),
}; };
@ -280,6 +281,7 @@ pub(crate) fn route_action(
split_direction, split_direction,
should_float, should_float,
should_open_in_place, should_open_in_place,
floating_pane_coordinates,
) => { ) => {
let title = format!("Editing: {}", path_to_file.display()); let title = format!("Editing: {}", path_to_file.display());
let open_file = TerminalAction::OpenFile(path_to_file, line_number, cwd); let open_file = TerminalAction::OpenFile(path_to_file, line_number, cwd);
@ -319,6 +321,7 @@ pub(crate) fn route_action(
Some(open_file), Some(open_file),
Some(should_float), Some(should_float),
Some(title), Some(title),
floating_pane_coordinates,
ClientTabIndexOrPaneId::ClientId(client_id), ClientTabIndexOrPaneId::ClientId(client_id),
), ),
}; };
@ -341,7 +344,7 @@ pub(crate) fn route_action(
))) )))
.with_context(err_context)?; .with_context(err_context)?;
}, },
Action::NewFloatingPane(run_command, name) => { Action::NewFloatingPane(run_command, name, floating_pane_coordinates) => {
let should_float = true; let should_float = true;
let run_cmd = run_command let run_cmd = run_command
.map(|cmd| TerminalAction::RunCommand(cmd.into())) .map(|cmd| TerminalAction::RunCommand(cmd.into()))
@ -351,6 +354,7 @@ pub(crate) fn route_action(
run_cmd, run_cmd,
Some(should_float), Some(should_float),
name, name,
floating_pane_coordinates,
ClientTabIndexOrPaneId::ClientId(client_id), ClientTabIndexOrPaneId::ClientId(client_id),
)) ))
.with_context(err_context)?; .with_context(err_context)?;
@ -403,6 +407,7 @@ pub(crate) fn route_action(
run_cmd, run_cmd,
Some(should_float), Some(should_float),
name, name,
None,
ClientTabIndexOrPaneId::ClientId(client_id), ClientTabIndexOrPaneId::ClientId(client_id),
), ),
}; };
@ -451,6 +456,7 @@ pub(crate) fn route_action(
run_cmd, run_cmd,
None, None,
None, None,
None,
ClientTabIndexOrPaneId::ClientId(client_id), ClientTabIndexOrPaneId::ClientId(client_id),
), ),
}; };
@ -666,10 +672,21 @@ pub(crate) fn route_action(
)) ))
.with_context(err_context)?; .with_context(err_context)?;
}, },
Action::NewFloatingPluginPane(run_plugin, name, skip_cache, cwd) => { Action::NewFloatingPluginPane(
run_plugin,
name,
skip_cache,
cwd,
floating_pane_coordinates,
) => {
senders senders
.send_to_screen(ScreenInstruction::NewFloatingPluginPane( .send_to_screen(ScreenInstruction::NewFloatingPluginPane(
run_plugin, name, skip_cache, cwd, client_id, run_plugin,
name,
skip_cache,
cwd,
floating_pane_coordinates,
client_id,
)) ))
.with_context(err_context)?; .with_context(err_context)?;
}, },

View file

@ -46,7 +46,10 @@ use crate::{
ClientId, ServerInstruction, ClientId, ServerInstruction,
}; };
use zellij_utils::{ use zellij_utils::{
data::{Event, InputMode, ModeInfo, Palette, PaletteColor, PluginCapabilities, Style, TabInfo}, data::{
Event, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PaletteColor,
PluginCapabilities, Style, TabInfo,
},
errors::{ContextType, ScreenContext}, errors::{ContextType, ScreenContext},
input::{get_mode_info, options::Options}, input::{get_mode_info, options::Options},
ipc::{ClientAttributes, PixelDimensions, ServerToClientMsg}, ipc::{ClientAttributes, PixelDimensions, ServerToClientMsg},
@ -146,6 +149,7 @@ pub enum ScreenInstruction {
Option<ShouldFloat>, Option<ShouldFloat>,
HoldForCommand, HoldForCommand,
Option<Run>, // invoked with Option<Run>, // invoked with
Option<FloatingPaneCoordinates>,
ClientTabIndexOrPaneId, ClientTabIndexOrPaneId,
), ),
OpenInPlaceEditor(PaneId, ClientId), OpenInPlaceEditor(PaneId, ClientId),
@ -274,7 +278,14 @@ pub enum ScreenInstruction {
QueryTabNames(ClientId), QueryTabNames(ClientId),
NewTiledPluginPane(RunPlugin, Option<String>, bool, Option<PathBuf>, ClientId), // Option<String> is NewTiledPluginPane(RunPlugin, Option<String>, bool, Option<PathBuf>, ClientId), // Option<String> is
// optional pane title, bool is skip cache, Option<PathBuf> is an optional cwd // optional pane title, bool is skip cache, Option<PathBuf> is an optional cwd
NewFloatingPluginPane(RunPlugin, Option<String>, bool, Option<PathBuf>, ClientId), // Option<String> is an NewFloatingPluginPane(
RunPlugin,
Option<String>,
bool,
Option<PathBuf>,
Option<FloatingPaneCoordinates>,
ClientId,
), // Option<String> is an
// optional pane title, bool // optional pane title, bool
// is skip cache, Option<PathBuf> is an optional cwd // is skip cache, Option<PathBuf> is an optional cwd
NewInPlacePluginPane(RunPlugin, Option<String>, PaneId, bool, ClientId), // Option<String> is an NewInPlacePluginPane(RunPlugin, Option<String>, PaneId, bool, ClientId), // Option<String> is an
@ -1760,6 +1771,7 @@ impl Screen {
new_active_tab.add_floating_pane( new_active_tab.add_floating_pane(
plugin_pane_to_move_to_active_tab, plugin_pane_to_move_to_active_tab,
pane_id, pane_id,
None,
Some(client_id), Some(client_id),
)?; )?;
} else { } else {
@ -1844,7 +1856,7 @@ impl Screen {
let (mut tiled_panes_layout, mut floating_panes_layout) = default_layout.new_tab(); let (mut tiled_panes_layout, mut floating_panes_layout) = default_layout.new_tab();
if pane_to_break_is_floating { if pane_to_break_is_floating {
tab.show_floating_panes(); tab.show_floating_panes();
tab.add_floating_pane(active_pane, active_pane_id, Some(client_id))?; tab.add_floating_pane(active_pane, active_pane_id, None, Some(client_id))?;
if let Some(already_running_layout) = floating_panes_layout if let Some(already_running_layout) = floating_panes_layout
.iter_mut() .iter_mut()
.find(|i| i.run == active_pane_run_instruction) .find(|i| i.run == active_pane_run_instruction)
@ -1909,7 +1921,12 @@ impl Screen {
if pane_to_break_is_floating { if pane_to_break_is_floating {
new_active_tab.show_floating_panes(); new_active_tab.show_floating_panes();
new_active_tab.add_floating_pane(active_pane, active_pane_id, Some(client_id))?; new_active_tab.add_floating_pane(
active_pane,
active_pane_id,
None,
Some(client_id),
)?;
} else { } else {
new_active_tab.hide_floating_panes(); new_active_tab.hide_floating_panes();
new_active_tab.add_tiled_pane(active_pane, active_pane_id, Some(client_id))?; new_active_tab.add_tiled_pane(active_pane, active_pane_id, Some(client_id))?;
@ -2217,6 +2234,7 @@ pub(crate) fn screen_thread_main(
should_float, should_float,
hold_for_command, hold_for_command,
invoked_with, invoked_with,
floating_pane_coordinates,
client_or_tab_index, client_or_tab_index,
) => { ) => {
match client_or_tab_index { match client_or_tab_index {
@ -2226,6 +2244,7 @@ pub(crate) fn screen_thread_main(
initial_pane_title, initial_pane_title,
should_float, should_float,
invoked_with, invoked_with,
floating_pane_coordinates,
Some(client_id) Some(client_id)
) )
}, ?); }, ?);
@ -2250,6 +2269,7 @@ pub(crate) fn screen_thread_main(
initial_pane_title, initial_pane_title,
should_float, should_float,
invoked_with, invoked_with,
floating_pane_coordinates,
None, None,
)?; )?;
if let Some(hold_for_command) = hold_for_command { if let Some(hold_for_command) = hold_for_command {
@ -3241,6 +3261,7 @@ pub(crate) fn screen_thread_main(
size, size,
skip_cache, skip_cache,
cwd, cwd,
None,
))?; ))?;
}, },
ScreenInstruction::NewFloatingPluginPane( ScreenInstruction::NewFloatingPluginPane(
@ -3248,6 +3269,7 @@ pub(crate) fn screen_thread_main(
pane_title, pane_title,
skip_cache, skip_cache,
cwd, cwd,
floating_pane_coordinates,
client_id, client_id,
) => match screen.active_tab_indices.values().next() { ) => match screen.active_tab_indices.values().next() {
Some(tab_index) => { Some(tab_index) => {
@ -3268,6 +3290,7 @@ pub(crate) fn screen_thread_main(
size, size,
skip_cache, skip_cache,
cwd, cwd,
floating_pane_coordinates,
))?; ))?;
}, },
None => { None => {
@ -3301,6 +3324,7 @@ pub(crate) fn screen_thread_main(
size, size,
skip_cache, skip_cache,
None, None,
None,
))?; ))?;
}, },
None => { None => {
@ -3378,6 +3402,7 @@ pub(crate) fn screen_thread_main(
should_float, should_float,
Some(run_plugin), Some(run_plugin),
None, None,
None,
) )
}, ?); }, ?);
} else if let Some(active_tab) = } else if let Some(active_tab) =
@ -3389,6 +3414,7 @@ pub(crate) fn screen_thread_main(
should_float, should_float,
Some(run_plugin), Some(run_plugin),
None, None,
None,
)?; )?;
} else { } else {
log::error!("Tab index not found: {:?}", tab_index); log::error!("Tab index not found: {:?}", tab_index);
@ -3462,6 +3488,7 @@ pub(crate) fn screen_thread_main(
size, size,
skip_cache, skip_cache,
None, None,
None,
))?; ))?;
}, },
None => { None => {
@ -3507,6 +3534,7 @@ pub(crate) fn screen_thread_main(
Size::default(), Size::default(),
skip_cache, skip_cache,
None, None,
None,
))?; ))?;
} }
}, },
@ -3542,6 +3570,7 @@ pub(crate) fn screen_thread_main(
size, size,
skip_cache, skip_cache,
cwd, cwd,
None,
))?; ))?;
}, },
None => { None => {
@ -3578,6 +3607,7 @@ pub(crate) fn screen_thread_main(
Size::default(), Size::default(),
skip_cache, skip_cache,
cwd, cwd,
None,
))?; ))?;
}, },
None => { None => {

View file

@ -46,7 +46,7 @@ use std::{
str, str,
}; };
use zellij_utils::{ use zellij_utils::{
data::{Event, InputMode, ModeInfo, Palette, PaletteColor, Style}, data::{Event, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PaletteColor, Style},
input::{ input::{
command::TerminalAction, command::TerminalAction,
layout::{ layout::{
@ -991,7 +991,12 @@ impl Tab {
self.close_pane(focused_pane_id, true, Some(client_id)) self.close_pane(focused_pane_id, true, Some(client_id))
{ {
self.show_floating_panes(); self.show_floating_panes();
self.add_floating_pane(embedded_pane_to_float, focused_pane_id, Some(client_id))?; self.add_floating_pane(
embedded_pane_to_float,
focused_pane_id,
None,
Some(client_id),
)?;
} }
} }
Ok(()) Ok(())
@ -1030,6 +1035,7 @@ impl Tab {
default_shell, default_shell,
Some(should_float), Some(should_float),
name, name,
None,
client_id_or_tab_index, client_id_or_tab_index,
); );
self.senders self.senders
@ -1048,6 +1054,7 @@ impl Tab {
initial_pane_title: Option<String>, initial_pane_title: Option<String>,
should_float: Option<bool>, should_float: Option<bool>,
invoked_with: Option<Run>, invoked_with: Option<Run>,
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
client_id: Option<ClientId>, client_id: Option<ClientId>,
) -> Result<()> { ) -> Result<()> {
let err_context = || format!("failed to create new pane with id {pid:?}"); let err_context = || format!("failed to create new pane with id {pid:?}");
@ -1105,7 +1112,7 @@ impl Tab {
}, },
}; };
if self.floating_panes.panes_are_visible() { if self.floating_panes.panes_are_visible() {
self.add_floating_pane(new_pane, pid, client_id) self.add_floating_pane(new_pane, pid, floating_pane_coordinates, client_id)
} else { } else {
self.add_tiled_pane(new_pane, pid, client_id) self.add_tiled_pane(new_pane, pid, client_id)
} }
@ -3615,7 +3622,7 @@ impl Tab {
Some(pane) => { Some(pane) => {
if should_float { if should_float {
self.show_floating_panes(); self.show_floating_panes();
self.add_floating_pane(pane.1, pane_id, Some(client_id)) self.add_floating_pane(pane.1, pane_id, None, Some(client_id))
} else { } else {
self.hide_floating_panes(); self.hide_floating_panes();
self.add_tiled_pane(pane.1, pane_id, Some(client_id)) self.add_tiled_pane(pane.1, pane_id, Some(client_id))
@ -3655,10 +3662,16 @@ impl Tab {
&mut self, &mut self,
mut pane: Box<dyn Pane>, mut pane: Box<dyn Pane>,
pane_id: PaneId, pane_id: PaneId,
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
client_id: Option<ClientId>, client_id: Option<ClientId>,
) -> Result<()> { ) -> Result<()> {
let err_context = || format!("failed to add floating pane"); let err_context = || format!("failed to add floating pane");
if let Some(new_pane_geom) = self.floating_panes.find_room_for_new_pane() { if let Some(mut new_pane_geom) = self.floating_panes.find_room_for_new_pane() {
if let Some(floating_pane_coordinates) = floating_pane_coordinates {
let viewport = self.viewport.borrow();
new_pane_geom.adjust_coordinates(floating_pane_coordinates, *viewport);
self.swap_layouts.set_is_floating_damaged();
}
pane.set_active_at(Instant::now()); pane.set_active_at(Instant::now());
pane.set_geom(new_pane_geom); pane.set_geom(new_pane_geom);
pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame

View file

@ -760,7 +760,7 @@ fn dump_screen() {
..Default::default() ..Default::default()
}); });
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes())) tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes()))
.unwrap(); .unwrap();
@ -788,7 +788,7 @@ fn clear_screen() {
..Default::default() ..Default::default()
}); });
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes())) tab.handle_pty_bytes(2, Vec::from("scratch".as_bytes()))
.unwrap(); .unwrap();
@ -814,7 +814,7 @@ fn new_floating_pane() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -842,7 +842,7 @@ fn floating_panes_persist_across_toggles() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.toggle_floating_panes(Some(client_id), None).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 // here we send bytes to the pane when it's not visible to make sure they're still handled and
@ -874,7 +874,7 @@ fn toggle_floating_panes_off() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -903,7 +903,7 @@ fn toggle_floating_panes_on() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -937,15 +937,15 @@ fn five_new_floating_panes() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -981,7 +981,7 @@ fn increase_floating_pane_size() {
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1011,7 +1011,7 @@ fn decrease_floating_pane_size() {
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1041,7 +1041,7 @@ fn resize_floating_pane_left() {
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1074,7 +1074,7 @@ fn resize_floating_pane_right() {
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1107,7 +1107,7 @@ fn resize_floating_pane_up() {
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1140,7 +1140,7 @@ fn resize_floating_pane_down() {
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1177,15 +1177,15 @@ fn move_floating_pane_focus_left() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1232,15 +1232,15 @@ fn move_floating_pane_focus_right() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1288,15 +1288,15 @@ fn move_floating_pane_focus_up() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1343,15 +1343,15 @@ fn move_floating_pane_focus_down() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1399,15 +1399,15 @@ fn move_floating_pane_focus_with_mouse() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1457,15 +1457,15 @@ fn move_pane_focus_with_mouse_to_non_floating_pane() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1515,15 +1515,15 @@ fn drag_pane_with_mouse() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1573,15 +1573,15 @@ fn mark_text_inside_floating_pane() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1639,15 +1639,15 @@ fn resize_tab_with_floating_panes() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1693,15 +1693,15 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically() {
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1743,15 +1743,15 @@ fn shrink_whole_tab_with_floating_panes_horizontally_and_vertically_and_expand_b
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1794,7 +1794,7 @@ fn embed_floating_pane() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1822,7 +1822,7 @@ fn float_embedded_pane() {
let mut tab = create_new_tab(size, ModeInfo::default()); let mut tab = create_new_tab(size, ModeInfo::default());
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1852,7 +1852,7 @@ fn embed_floating_pane_without_pane_frames() {
let mut output = Output::default(); let mut output = Output::default();
tab.set_pane_frames(false); tab.set_pane_frames(false);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1881,7 +1881,7 @@ fn float_embedded_pane_without_pane_frames() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.set_pane_frames(false); tab.set_pane_frames(false);
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -1984,7 +1984,7 @@ fn rename_floating_pane() {
let mut tab = create_new_tab(size, ModeInfo::default()); let mut tab = create_new_tab(size, ModeInfo::default());
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
2, 2,
@ -2080,7 +2080,7 @@ fn move_floating_pane_with_sixel_image() {
let mut output = Output::new(sixel_image_store.clone(), character_cell_size, true); let mut output = Output::new(sixel_image_store.clone(), character_cell_size, true);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
let fixture = read_fixture("sixel-image-500px.six"); let fixture = read_fixture("sixel-image-500px.six");
tab.handle_pty_bytes(2, fixture).unwrap(); tab.handle_pty_bytes(2, fixture).unwrap();
@ -2118,7 +2118,7 @@ fn floating_pane_above_sixel_image() {
let mut output = Output::new(sixel_image_store.clone(), character_cell_size, true); let mut output = Output::new(sixel_image_store.clone(), character_cell_size, true);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
let fixture = read_fixture("sixel-image-500px.six"); let fixture = read_fixture("sixel-image-500px.six");
tab.handle_pty_bytes(1, fixture).unwrap(); tab.handle_pty_bytes(1, fixture).unwrap();
@ -2176,7 +2176,7 @@ fn suppress_floating_pane() {
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id)
.unwrap(); .unwrap();
@ -2232,7 +2232,7 @@ fn close_suppressing_floating_pane() {
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id)
.unwrap(); .unwrap();
@ -2292,7 +2292,7 @@ fn suppress_floating_pane_embed_it_and_close_it() {
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id)
.unwrap(); .unwrap();
@ -2354,7 +2354,7 @@ fn resize_whole_tab_while_floting_pane_is_suppressed() {
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id) tab.replace_active_pane_with_editor_pane(editor_pane_id, client_id)
.unwrap(); .unwrap();
@ -2456,7 +2456,7 @@ fn enter_search_floating_pane() {
let new_pane_id = PaneId::Terminal(2); let new_pane_id = PaneId::Terminal(2);
let mut output = Output::default(); let mut output = Output::default();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id, None, None, None, Some(client_id)) tab.new_pane(new_pane_id, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
let pane_content = read_fixture("grid_copy"); let pane_content = read_fixture("grid_copy");
@ -2961,7 +2961,7 @@ fn move_pane_focus_sends_tty_csi_event() {
}); });
let mut tab = create_new_tab_with_os_api(size, ModeInfo::default(), &os_api); let mut tab = create_new_tab_with_os_api(size, ModeInfo::default(), &os_api);
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
1, 1,
@ -2996,9 +2996,9 @@ fn move_floating_pane_focus_sends_tty_csi_event() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
1, 1,
@ -3039,9 +3039,9 @@ fn toggle_floating_panes_on_sends_tty_csi_event() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
@ -3083,9 +3083,9 @@ fn toggle_floating_panes_off_sends_tty_csi_event() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_pty_bytes( tab.handle_pty_bytes(
1, 1,
@ -3145,7 +3145,7 @@ fn can_swap_tiled_layout_at_runtime() {
); );
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.next_swap_layout(Some(client_id), false).unwrap(); tab.next_swap_layout(Some(client_id), false).unwrap();
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
@ -3200,9 +3200,9 @@ fn can_swap_floating_layout_at_runtime() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
tab.toggle_floating_panes(Some(client_id), None).unwrap(); tab.toggle_floating_panes(Some(client_id), None).unwrap();
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.next_swap_layout(Some(client_id), false).unwrap(); tab.next_swap_layout(Some(client_id), false).unwrap();
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
@ -3253,7 +3253,7 @@ fn swapping_layouts_after_resize_snaps_to_current_layout() {
); );
let new_pane_id_1 = PaneId::Terminal(2); let new_pane_id_1 = PaneId::Terminal(2);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.next_swap_layout(Some(client_id), false).unwrap(); tab.next_swap_layout(Some(client_id), false).unwrap();
tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None))
@ -3303,11 +3303,11 @@ fn swap_tiled_layout_with_stacked_children() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
let new_pane_id_3 = PaneId::Terminal(4); let new_pane_id_3 = PaneId::Terminal(4);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
let snapshot = take_snapshot( let snapshot = take_snapshot(
@ -3350,11 +3350,11 @@ fn swap_tiled_layout_with_only_stacked_children() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
let new_pane_id_3 = PaneId::Terminal(4); let new_pane_id_3 = PaneId::Terminal(4);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
let snapshot = take_snapshot( let snapshot = take_snapshot(
@ -3400,11 +3400,11 @@ fn swap_tiled_layout_with_stacked_children_and_no_pane_frames() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
let new_pane_id_3 = PaneId::Terminal(4); let new_pane_id_3 = PaneId::Terminal(4);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
let snapshot = take_snapshot( let snapshot = take_snapshot(
@ -3450,11 +3450,11 @@ fn move_focus_up_with_stacked_panes() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
let new_pane_id_3 = PaneId::Terminal(4); let new_pane_id_3 = PaneId::Terminal(4);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.move_focus_up(client_id); tab.move_focus_up(client_id);
@ -3502,11 +3502,11 @@ fn move_focus_down_with_stacked_panes() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
let new_pane_id_3 = PaneId::Terminal(4); let new_pane_id_3 = PaneId::Terminal(4);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.move_focus_up(client_id); tab.move_focus_up(client_id);
@ -3561,6 +3561,7 @@ fn move_focus_right_into_stacked_panes() {
None, None,
None, None,
None, None,
None,
Some(client_id), Some(client_id),
) )
.unwrap(); .unwrap();
@ -3628,6 +3629,7 @@ fn move_focus_left_into_stacked_panes() {
None, None,
None, None,
None, None,
None,
Some(client_id), Some(client_id),
) )
.unwrap(); .unwrap();
@ -3697,6 +3699,7 @@ fn move_focus_up_into_stacked_panes() {
None, None,
None, None,
None, None,
None,
Some(client_id), Some(client_id),
) )
.unwrap(); .unwrap();
@ -3767,6 +3770,7 @@ fn move_focus_down_into_stacked_panes() {
None, None,
None, None,
None, None,
None,
Some(client_id), Some(client_id),
) )
.unwrap(); .unwrap();
@ -3828,11 +3832,11 @@ fn close_main_stacked_pane() {
let new_pane_id_2 = PaneId::Terminal(3); let new_pane_id_2 = PaneId::Terminal(3);
let new_pane_id_3 = PaneId::Terminal(4); let new_pane_id_3 = PaneId::Terminal(4);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.close_pane(new_pane_id_2, false, None); tab.close_pane(new_pane_id_2, false, None);
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
@ -3881,15 +3885,15 @@ fn close_main_stacked_pane_in_mid_stack() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.move_focus_up(client_id); tab.move_focus_up(client_id);
@ -3941,15 +3945,15 @@ fn close_one_liner_stacked_pane_below_main_pane() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_left(client_id); tab.move_focus_left(client_id);
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
@ -4002,15 +4006,15 @@ fn close_one_liner_stacked_pane_above_main_pane() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.move_focus_up(client_id); tab.move_focus_up(client_id);
@ -4062,15 +4066,15 @@ fn can_increase_size_of_main_pane_in_stack_horizontally() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.resize( tab.resize(
@ -4126,15 +4130,15 @@ fn can_increase_size_of_main_pane_in_stack_vertically() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.resize( tab.resize(
@ -4190,15 +4194,15 @@ fn can_increase_size_of_main_pane_in_stack_non_directionally() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
let _ = tab.move_focus_up(client_id); let _ = tab.move_focus_up(client_id);
let _ = tab.move_focus_right(client_id); let _ = tab.move_focus_right(client_id);
@ -4250,15 +4254,15 @@ fn can_increase_size_into_pane_stack_horizontally() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.resize( tab.resize(
client_id, client_id,
@ -4313,15 +4317,15 @@ fn can_increase_size_into_pane_stack_vertically() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_right(client_id); tab.move_focus_right(client_id);
tab.move_focus_down(client_id); tab.move_focus_down(client_id);
@ -4378,15 +4382,15 @@ fn can_increase_size_into_pane_stack_non_directionally() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
let _ = tab.move_focus_up(client_id); let _ = tab.move_focus_up(client_id);
tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None)) tab.resize(client_id, ResizeStrategy::new(Resize::Increase, None))
@ -4437,15 +4441,15 @@ fn decreasing_size_of_whole_tab_treats_stacked_panes_properly() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.resize_whole_tab(Size { tab.resize_whole_tab(Size {
cols: 100, cols: 100,
@ -4497,15 +4501,15 @@ fn increasing_size_of_whole_tab_treats_stacked_panes_properly() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.resize_whole_tab(Size { tab.resize_whole_tab(Size {
cols: 100, cols: 100,
@ -4562,15 +4566,15 @@ fn cannot_decrease_stack_size_beyond_minimum_height() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_down(client_id); tab.move_focus_down(client_id);
for _ in 0..6 { for _ in 0..6 {
@ -4627,15 +4631,15 @@ fn focus_stacked_pane_over_flexible_pane_with_the_mouse() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_left_click(&Position::new(1, 71), client_id) tab.handle_left_click(&Position::new(1, 71), client_id)
.unwrap(); .unwrap();
@ -4686,15 +4690,15 @@ fn focus_stacked_pane_under_flexible_pane_with_the_mouse() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_left_click(&Position::new(1, 71), client_id) tab.handle_left_click(&Position::new(1, 71), client_id)
.unwrap(); .unwrap();
@ -4747,15 +4751,15 @@ fn close_stacked_pane_with_previously_focused_other_pane() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.handle_left_click(&Position::new(2, 71), client_id) tab.handle_left_click(&Position::new(2, 71), client_id)
.unwrap(); .unwrap();
@ -4814,15 +4818,15 @@ fn close_pane_near_stacked_panes() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.close_pane(PaneId::Terminal(6), false, None); tab.close_pane(PaneId::Terminal(6), false, None);
tab.render(&mut output).unwrap(); tab.render(&mut output).unwrap();
@ -4878,15 +4882,15 @@ fn focus_next_pane_expands_stacked_panes() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_left(client_id); tab.move_focus_left(client_id);
tab.focus_next_pane(client_id); tab.focus_next_pane(client_id);
@ -4938,15 +4942,15 @@ fn stacked_panes_can_become_fullscreen() {
let new_pane_id_4 = PaneId::Terminal(5); let new_pane_id_4 = PaneId::Terminal(5);
let new_pane_id_5 = PaneId::Terminal(6); let new_pane_id_5 = PaneId::Terminal(6);
tab.new_pane(new_pane_id_1, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_1, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_2, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_2, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_3, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_3, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_4, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_4, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.new_pane(new_pane_id_5, None, None, None, Some(client_id)) tab.new_pane(new_pane_id_5, None, None, None, None, Some(client_id))
.unwrap(); .unwrap();
tab.move_focus_up(client_id); tab.move_focus_up(client_id);
tab.toggle_active_pane_fullscreen(client_id); tab.toggle_active_pane_fullscreen(client_id);
@ -5608,6 +5612,7 @@ fn new_pane_in_auto_layout() {
None, None,
None, None,
None, None,
None,
Some(client_id), Some(client_id),
) )
.unwrap(); .unwrap();
@ -6552,6 +6557,7 @@ fn new_floating_pane_in_auto_layout() {
None, None,
Some(should_float), Some(should_float),
None, None,
None,
Some(client_id), Some(client_id),
) )
.unwrap(); .unwrap();

View file

@ -559,7 +559,7 @@ fn split_largest_pane() {
let mut tab = create_new_tab(size); let mut tab = create_new_tab(size);
for i in 2..5 { for i in 2..5 {
let new_pane_id = PaneId::Terminal(i); let new_pane_id = PaneId::Terminal(i);
tab.new_pane(new_pane_id, None, None, None, Some(1)) tab.new_pane(new_pane_id, None, None, None, None, Some(1))
.unwrap(); .unwrap();
} }
assert_eq!(tab.tiled_panes.panes.len(), 4, "The tab has four panes"); assert_eq!(tab.tiled_panes.panes.len(), 4, "The tab has four panes");
@ -765,7 +765,7 @@ pub fn cannot_split_panes_horizontally_when_active_pane_is_too_small() {
pub fn cannot_split_largest_pane_when_there_is_no_room() { pub fn cannot_split_largest_pane_when_there_is_no_room() {
let size = Size { cols: 8, rows: 4 }; let size = Size { cols: 8, rows: 4 };
let mut tab = create_new_tab(size); let mut tab = create_new_tab(size);
tab.new_pane(PaneId::Terminal(2), None, None, None, Some(1)) tab.new_pane(PaneId::Terminal(2), None, None, None, None, Some(1))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
tab.tiled_panes.panes.len(), tab.tiled_panes.panes.len(),
@ -809,7 +809,7 @@ pub fn toggle_focused_pane_fullscreen() {
let mut tab = create_new_tab(size); let mut tab = create_new_tab(size);
for i in 2..5 { for i in 2..5 {
let new_pane_id = PaneId::Terminal(i); let new_pane_id = PaneId::Terminal(i);
tab.new_pane(new_pane_id, None, None, None, Some(1)) tab.new_pane(new_pane_id, None, None, None, None, Some(1))
.unwrap(); .unwrap();
} }
tab.toggle_active_pane_fullscreen(1); tab.toggle_active_pane_fullscreen(1);
@ -884,16 +884,16 @@ fn switch_to_next_pane_fullscreen() {
let mut active_tab = create_new_tab(size); let mut active_tab = create_new_tab(size);
active_tab active_tab
.new_pane(PaneId::Terminal(1), None, None, None, Some(1)) .new_pane(PaneId::Terminal(1), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(2), None, None, None, Some(1)) .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(3), None, None, None, Some(1)) .new_pane(PaneId::Terminal(3), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(4), None, None, None, Some(1)) .new_pane(PaneId::Terminal(4), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab.toggle_active_pane_fullscreen(1); active_tab.toggle_active_pane_fullscreen(1);
@ -924,16 +924,16 @@ fn switch_to_prev_pane_fullscreen() {
//testing four consecutive switches in fullscreen mode //testing four consecutive switches in fullscreen mode
active_tab active_tab
.new_pane(PaneId::Terminal(1), None, None, None, Some(1)) .new_pane(PaneId::Terminal(1), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(2), None, None, None, Some(1)) .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(3), None, None, None, Some(1)) .new_pane(PaneId::Terminal(3), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(4), None, None, None, Some(1)) .new_pane(PaneId::Terminal(4), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab.toggle_active_pane_fullscreen(1); active_tab.toggle_active_pane_fullscreen(1);
// order is now 1 2 3 4 // order is now 1 2 3 4
@ -14415,7 +14415,7 @@ fn correctly_resize_frameless_panes_on_pane_close() {
let content_size = (pane.get_content_columns(), pane.get_content_rows()); let content_size = (pane.get_content_columns(), pane.get_content_rows());
assert_eq!(content_size, (cols, rows)); assert_eq!(content_size, (cols, rows));
tab.new_pane(PaneId::Terminal(2), None, None, None, Some(1)) tab.new_pane(PaneId::Terminal(2), None, None, None, None, Some(1))
.unwrap(); .unwrap();
tab.close_pane(PaneId::Terminal(2), true, None); tab.close_pane(PaneId::Terminal(2), true, None);

View file

@ -15,7 +15,8 @@ use zellij_utils::errors::{prelude::*, ErrorContext};
use zellij_utils::input::actions::Action; use zellij_utils::input::actions::Action;
use zellij_utils::input::command::{RunCommand, TerminalAction}; use zellij_utils::input::command::{RunCommand, TerminalAction};
use zellij_utils::input::layout::{ use zellij_utils::input::layout::{
FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginLocation, SplitDirection, TiledPaneLayout, FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginLocation, SplitDirection, SplitSize,
TiledPaneLayout,
}; };
use zellij_utils::input::options::Options; use zellij_utils::input::options::Options;
use zellij_utils::ipc::IpcReceiverWithContext; use zellij_utils::ipc::IpcReceiverWithContext;
@ -32,7 +33,7 @@ use zellij_utils::ipc::PixelDimensions;
use zellij_utils::{ use zellij_utils::{
channels::{self, ChannelWithContext, Receiver}, channels::{self, ChannelWithContext, Receiver},
data::{Direction, InputMode, ModeInfo, Palette, PluginCapabilities}, data::{Direction, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PluginCapabilities},
interprocess::local_socket::LocalSocketStream, interprocess::local_socket::LocalSocketStream,
ipc::{ClientAttributes, ClientToServerMsg, ServerToClientMsg}, ipc::{ClientAttributes, ClientToServerMsg, ServerToClientMsg},
}; };
@ -923,7 +924,7 @@ fn switch_to_tab_with_fullscreen() {
{ {
let active_tab = screen.get_active_tab_mut(1).unwrap(); let active_tab = screen.get_active_tab_mut(1).unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(2), None, None, None, Some(1)) .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab.toggle_active_pane_fullscreen(1); active_tab.toggle_active_pane_fullscreen(1);
} }
@ -1038,7 +1039,7 @@ fn attach_after_first_tab_closed() {
{ {
let active_tab = screen.get_active_tab_mut(1).unwrap(); let active_tab = screen.get_active_tab_mut(1).unwrap();
active_tab active_tab
.new_pane(PaneId::Terminal(2), None, None, None, Some(1)) .new_pane(PaneId::Terminal(2), None, None, None, None, Some(1))
.unwrap(); .unwrap();
active_tab.toggle_active_pane_fullscreen(1); active_tab.toggle_active_pane_fullscreen(1);
} }
@ -1049,6 +1050,72 @@ fn attach_after_first_tab_closed() {
screen.add_client(1).expect("TEST"); screen.add_client(1).expect("TEST");
} }
#[test]
fn open_new_floating_pane_with_custom_coordinates() {
let size = Size {
cols: 121,
rows: 20,
};
let mut screen = create_new_screen(size);
new_tab(&mut screen, 1, 0);
let active_tab = screen.get_active_tab_mut(1).unwrap();
let should_float = Some(true);
active_tab
.new_pane(
PaneId::Terminal(2),
None,
should_float,
None,
Some(FloatingPaneCoordinates {
x: Some(SplitSize::Percent(10)),
y: Some(SplitSize::Fixed(5)),
width: Some(SplitSize::Percent(1)),
height: Some(SplitSize::Fixed(2)),
}),
Some(1),
)
.unwrap();
let active_pane = active_tab.get_active_pane(1).unwrap();
assert_eq!(active_pane.x(), 12, "x coordinates set properly");
assert_eq!(active_pane.y(), 5, "y coordinates set properly");
assert_eq!(active_pane.rows(), 2, "rows set properly");
assert_eq!(active_pane.cols(), 1, "columns set properly");
}
#[test]
fn open_new_floating_pane_with_custom_coordinates_exceeding_viewport() {
let size = Size {
cols: 121,
rows: 20,
};
let mut screen = create_new_screen(size);
new_tab(&mut screen, 1, 0);
let active_tab = screen.get_active_tab_mut(1).unwrap();
let should_float = Some(true);
active_tab
.new_pane(
PaneId::Terminal(2),
None,
should_float,
None,
Some(FloatingPaneCoordinates {
x: Some(SplitSize::Fixed(122)),
y: Some(SplitSize::Fixed(21)),
width: Some(SplitSize::Fixed(10)),
height: Some(SplitSize::Fixed(10)),
}),
Some(1),
)
.unwrap();
let active_pane = active_tab.get_active_pane(1).unwrap();
assert_eq!(active_pane.x(), 111, "x coordinates set properly");
assert_eq!(active_pane.y(), 10, "y coordinates set properly");
assert_eq!(active_pane.rows(), 10, "rows set properly");
assert_eq!(active_pane.cols(), 10, "columns set properly");
}
// Following are tests for sending CLI actions // Following are tests for sending CLI actions
// these tests are only partially relevant to Screen // these tests are only partially relevant to Screen
// and are included here for two reasons: // and are included here for two reasons:
@ -1900,6 +1967,10 @@ pub fn send_cli_new_pane_action_with_default_parameters() {
start_suspended: false, start_suspended: false,
configuration: None, configuration: None,
skip_plugin_cache: false, skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
}; };
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@ -1939,6 +2010,10 @@ pub fn send_cli_new_pane_action_with_split_direction() {
start_suspended: false, start_suspended: false,
configuration: None, configuration: None,
skip_plugin_cache: false, skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
}; };
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@ -1978,6 +2053,53 @@ pub fn send_cli_new_pane_action_with_command_and_cwd() {
start_suspended: false, start_suspended: false,
configuration: None, configuration: None,
skip_plugin_cache: false, skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
mock_screen.teardown(vec![pty_thread, screen_thread]);
assert_snapshot!(format!("{:?}", *received_pty_instructions.lock().unwrap()));
}
#[test]
pub fn send_cli_new_pane_action_with_floating_pane_and_coordinates() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 10; // fake client id should not appear in the screen's state
let mut mock_screen = MockScreen::new(size);
let pty_receiver = mock_screen.pty_receiver.take().unwrap();
let session_metadata = mock_screen.clone_session_metadata();
let mut initial_layout = TiledPaneLayout::default();
initial_layout.children_split_direction = SplitDirection::Vertical;
initial_layout.children = vec![TiledPaneLayout::default(), TiledPaneLayout::default()];
let screen_thread = mock_screen.run(Some(initial_layout), vec![]);
let received_pty_instructions = Arc::new(Mutex::new(vec![]));
let pty_thread = log_actions_in_thread!(
received_pty_instructions,
PtyInstruction::Exit,
pty_receiver
);
let cli_new_pane_action = CliAction::NewPane {
direction: Some(Direction::Right),
command: vec!["htop".into()],
plugin: None,
cwd: Some("/some/folder".into()),
floating: true,
in_place: false,
name: None,
close_on_exit: false,
start_suspended: false,
configuration: None,
skip_plugin_cache: false,
x: Some("10".to_owned()),
y: None,
width: Some("20%".to_owned()),
height: None,
}; };
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id); send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@ -2012,6 +2134,10 @@ pub fn send_cli_edit_action_with_default_parameters() {
floating: false, floating: false,
in_place: false, in_place: false,
cwd: None, cwd: None,
x: None,
y: None,
width: None,
height: None,
}; };
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id); send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@ -2046,6 +2172,10 @@ pub fn send_cli_edit_action_with_line_number() {
floating: false, floating: false,
in_place: false, in_place: false,
cwd: None, cwd: None,
x: None,
y: None,
width: None,
height: None,
}; };
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id); send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@ -2080,6 +2210,10 @@ pub fn send_cli_edit_action_with_split_direction() {
floating: false, floating: false,
in_place: false, in_place: false,
cwd: None, cwd: None,
x: None,
y: None,
width: None,
height: None,
}; };
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id); send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/./unit/screen_tests.rs source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 2102 assertion_line: 2031
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
--- ---
[SpawnTerminal(Some(OpenFile("/file/to/edit", None, Some("."))), Some(false), Some("Editing: /file/to/edit"), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] [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]

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/./unit/screen_tests.rs source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 2140 assertion_line: 2065
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
--- ---
[SpawnTerminal(Some(OpenFile("/file/to/edit", Some(100), Some("."))), Some(false), Some("Editing: /file/to/edit"), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] [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]

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/./unit/screen_tests.rs source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 2627 assertion_line: 2639
expression: "format!(\"{:#?}\", pty_fill_plugin_cwd_instruction)" expression: "format!(\"{:#?}\", pty_fill_plugin_cwd_instruction)"
--- ---
Some( Some(
@ -28,5 +28,6 @@ Some(
}, },
false, false,
None, None,
None,
), ),
) )

View file

@ -1,6 +1,6 @@
--- ---
source: zellij-server/src/./unit/screen_tests.rs source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 1831 assertion_line: 1911
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
--- ---
[SpawnTerminal(None, Some(false), None, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] [SpawnTerminal(None, Some(false), None, None, ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit]

View file

@ -0,0 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 2040
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 })), 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]

View file

@ -84,8 +84,8 @@ pub fn open_file(file_to_open: FileToOpen) {
} }
/// Open a file in the user's default `$EDITOR` in a new floating pane /// Open a file in the user's default `$EDITOR` in a new floating pane
pub fn open_file_floating(file_to_open: FileToOpen) { pub fn open_file_floating(file_to_open: FileToOpen, coordinates: Option<FloatingPaneCoordinates>) {
let plugin_command = PluginCommand::OpenFileFloating(file_to_open); let plugin_command = PluginCommand::OpenFileFloating(file_to_open, coordinates);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec()); object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() }; unsafe { host_run_plugin_command() };
@ -109,9 +109,12 @@ pub fn open_terminal<P: AsRef<Path>>(path: P) {
} }
/// Open a new floating terminal pane to the specified location on the host filesystem /// Open a new floating terminal pane to the specified location on the host filesystem
pub fn open_terminal_floating<P: AsRef<Path>>(path: P) { pub fn open_terminal_floating<P: AsRef<Path>>(
path: P,
coordinates: Option<FloatingPaneCoordinates>,
) {
let file_to_open = FileToOpen::new(path.as_ref().to_path_buf()); let file_to_open = FileToOpen::new(path.as_ref().to_path_buf());
let plugin_command = PluginCommand::OpenTerminalFloating(file_to_open); let plugin_command = PluginCommand::OpenTerminalFloating(file_to_open, coordinates);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec()); object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() }; unsafe { host_run_plugin_command() };
@ -136,14 +139,17 @@ pub fn open_command_pane(command_to_run: CommandToRun) {
} }
/// Open a new floating command pane with the specified command and args (this sort of pane allows the user to control the command, re-run it and see its exit status through the Zellij UI). /// Open a new floating command pane with the specified command and args (this sort of pane allows the user to control the command, re-run it and see its exit status through the Zellij UI).
pub fn open_command_pane_floating(command_to_run: CommandToRun) { pub fn open_command_pane_floating(
let plugin_command = PluginCommand::OpenCommandPaneFloating(command_to_run); command_to_run: CommandToRun,
coordinates: Option<FloatingPaneCoordinates>,
) {
let plugin_command = PluginCommand::OpenCommandPaneFloating(command_to_run, coordinates);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec()); object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() }; unsafe { host_run_plugin_command() };
} }
/// Open a new floating command pane with the specified command and args (this sort of pane allows the user to control the command, re-run it and see its exit status through the Zellij UI). /// Open a new in place command pane with the specified command and args (this sort of pane allows the user to control the command, re-run it and see its exit status through the Zellij UI).
pub fn open_command_pane_in_place(command_to_run: CommandToRun) { pub fn open_command_pane_in_place(command_to_run: CommandToRun) {
let plugin_command = PluginCommand::OpenCommandPaneInPlace(command_to_run); let plugin_command = PluginCommand::OpenCommandPaneInPlace(command_to_run);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();

View file

@ -209,12 +209,16 @@ pub struct UnsubscribePayload {
pub struct OpenFilePayload { pub struct OpenFilePayload {
#[prost(message, optional, tag = "1")] #[prost(message, optional, tag = "1")]
pub file_to_open: ::core::option::Option<super::file::File>, pub file_to_open: ::core::option::Option<super::file::File>,
#[prost(message, optional, tag = "2")]
pub floating_pane_coordinates: ::core::option::Option<FloatingPaneCoordinates>,
} }
#[allow(clippy::derive_partial_eq_without_eq)] #[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)] #[derive(Clone, PartialEq, ::prost::Message)]
pub struct OpenCommandPanePayload { pub struct OpenCommandPanePayload {
#[prost(message, optional, tag = "1")] #[prost(message, optional, tag = "1")]
pub command_to_run: ::core::option::Option<super::command::Command>, pub command_to_run: ::core::option::Option<super::command::Command>,
#[prost(message, optional, tag = "2")]
pub floating_pane_coordinates: ::core::option::Option<FloatingPaneCoordinates>,
} }
#[allow(clippy::derive_partial_eq_without_eq)] #[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)] #[derive(Clone, PartialEq, ::prost::Message)]
@ -303,6 +307,26 @@ pub struct IdAndNewName {
#[prost(string, tag = "2")] #[prost(string, tag = "2")]
pub new_name: ::prost::alloc::string::String, pub new_name: ::prost::alloc::string::String,
} }
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FloatingPaneCoordinates {
#[prost(message, optional, tag = "1")]
pub x: ::core::option::Option<FixedOrPercentValue>,
#[prost(message, optional, tag = "2")]
pub y: ::core::option::Option<FixedOrPercentValue>,
#[prost(message, optional, tag = "3")]
pub width: ::core::option::Option<FixedOrPercentValue>,
#[prost(message, optional, tag = "4")]
pub height: ::core::option::Option<FixedOrPercentValue>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FixedOrPercentValue {
#[prost(enumeration = "FixedOrPercent", tag = "1")]
pub r#type: i32,
#[prost(uint32, tag = "2")]
pub value: u32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)] #[repr(i32)]
pub enum CommandName { pub enum CommandName {
@ -627,3 +651,29 @@ impl HttpVerb {
} }
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum FixedOrPercent {
Fixed = 0,
Percent = 1,
}
impl FixedOrPercent {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
FixedOrPercent::Fixed => "Fixed",
FixedOrPercent::Percent => "Percent",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"Fixed" => Some(Self::Fixed),
"Percent" => Some(Self::Percent),
_ => None,
}
}
}

View file

@ -216,6 +216,19 @@ pub enum Sessions {
/// Start the command suspended, only running after you first presses ENTER /// Start the command suspended, only running after you first presses ENTER
#[clap(short, long, value_parser, default_value("false"), takes_value(false))] #[clap(short, long, value_parser, default_value("false"), takes_value(false))]
start_suspended: bool, start_suspended: bool,
/// The x coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
x: Option<String>,
/// The y coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
y: Option<String>,
/// The width if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
width: Option<String>,
/// The height if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
height: Option<String>,
}, },
/// Load a plugin /// Load a plugin
#[clap(visible_alias = "r")] #[clap(visible_alias = "r")]
@ -246,6 +259,18 @@ pub enum Sessions {
/// Skip the memory and HD cache and force recompile of the plugin (good for development) /// Skip the memory and HD cache and force recompile of the plugin (good for development)
#[clap(short, long, value_parser, default_value("false"), takes_value(false))] #[clap(short, long, value_parser, default_value("false"), takes_value(false))]
skip_plugin_cache: bool, skip_plugin_cache: bool,
/// The x coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
x: Option<String>,
/// The y coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
y: Option<String>,
/// The width if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
width: Option<String>,
/// The height if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
height: Option<String>,
}, },
/// Edit file with default $EDITOR / $VISUAL /// Edit file with default $EDITOR / $VISUAL
#[clap(visible_alias = "e")] #[clap(visible_alias = "e")]
@ -279,6 +304,18 @@ pub enum Sessions {
/// Change the working directory of the editor /// Change the working directory of the editor
#[clap(long, value_parser)] #[clap(long, value_parser)]
cwd: Option<PathBuf>, cwd: Option<PathBuf>,
/// The x coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
x: Option<String>,
/// The y coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
y: Option<String>,
/// The width if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
width: Option<String>,
/// The height if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
height: Option<String>,
}, },
ConvertConfig { ConvertConfig {
old_config_file: PathBuf, old_config_file: PathBuf,
@ -458,8 +495,20 @@ pub enum CliAction {
start_suspended: bool, start_suspended: bool,
#[clap(long, value_parser)] #[clap(long, value_parser)]
configuration: Option<PluginUserConfiguration>, configuration: Option<PluginUserConfiguration>,
#[clap(short, long, value_parser)] #[clap(long, value_parser)]
skip_plugin_cache: bool, skip_plugin_cache: bool,
/// The x coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
x: Option<String>,
/// The y coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
y: Option<String>,
/// The width if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
width: Option<String>,
/// The height if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
height: Option<String>,
}, },
/// Open the specified file in a new zellij pane with your default EDITOR /// Open the specified file in a new zellij pane with your default EDITOR
Edit { Edit {
@ -492,6 +541,18 @@ pub enum CliAction {
/// Change the working directory of the editor /// Change the working directory of the editor
#[clap(long, value_parser)] #[clap(long, value_parser)]
cwd: Option<PathBuf>, cwd: Option<PathBuf>,
/// The x coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
x: Option<String>,
/// The y coordinates if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(short, long, requires("floating"))]
y: Option<String>,
/// The width if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
width: Option<String>,
/// The height if the pane is floating as a bare integer (eg. 1) or percent (eg. 10%)
#[clap(long, requires("floating"))]
height: Option<String>,
}, },
/// Switch input mode of all connected clients [locked|pane|tab|resize|move|search|session] /// Switch input mode of all connected clients [locked|pane|tab|resize|move|search|session]
SwitchMode { SwitchMode {

View file

@ -1,5 +1,6 @@
use crate::input::actions::Action; use crate::input::actions::Action;
use crate::input::config::ConversionError; use crate::input::config::ConversionError;
use crate::input::layout::SplitSize;
use clap::ArgEnum; use clap::ArgEnum;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
@ -1166,6 +1167,86 @@ impl PipeMessage {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
pub struct FloatingPaneCoordinates {
pub x: Option<SplitSize>,
pub y: Option<SplitSize>,
pub width: Option<SplitSize>,
pub height: Option<SplitSize>,
}
impl FloatingPaneCoordinates {
pub fn new(
x: Option<String>,
y: Option<String>,
width: Option<String>,
height: Option<String>,
) -> Option<Self> {
let x = x.and_then(|x| SplitSize::from_str(&x).ok());
let y = y.and_then(|y| SplitSize::from_str(&y).ok());
let width = width.and_then(|width| SplitSize::from_str(&width).ok());
let height = height.and_then(|height| SplitSize::from_str(&height).ok());
if x.is_none() && y.is_none() && width.is_none() && height.is_none() {
None
} else {
Some(FloatingPaneCoordinates {
x,
y,
width,
height,
})
}
}
pub fn with_x_fixed(mut self, x: usize) -> Self {
self.x = Some(SplitSize::Fixed(x));
self
}
pub fn with_x_percent(mut self, x: usize) -> Self {
if x > 100 {
eprintln!("x must be between 0 and 100");
return self;
}
self.x = Some(SplitSize::Percent(x));
self
}
pub fn with_y_fixed(mut self, y: usize) -> Self {
self.y = Some(SplitSize::Fixed(y));
self
}
pub fn with_y_percent(mut self, y: usize) -> Self {
if y > 100 {
eprintln!("y must be between 0 and 100");
return self;
}
self.y = Some(SplitSize::Percent(y));
self
}
pub fn with_width_fixed(mut self, width: usize) -> Self {
self.width = Some(SplitSize::Fixed(width));
self
}
pub fn with_width_percent(mut self, width: usize) -> Self {
if width > 100 {
eprintln!("width must be between 0 and 100");
return self;
}
self.width = Some(SplitSize::Percent(width));
self
}
pub fn with_height_fixed(mut self, height: usize) -> Self {
self.height = Some(SplitSize::Fixed(height));
self
}
pub fn with_height_percent(mut self, height: usize) -> Self {
if height > 100 {
eprintln!("height must be between 0 and 100");
return self;
}
self.height = Some(SplitSize::Percent(height));
self
}
}
#[derive(Debug, Clone, EnumDiscriminants, ToString)] #[derive(Debug, Clone, EnumDiscriminants, ToString)]
#[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))] #[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))]
#[strum_discriminants(name(CommandType))] #[strum_discriminants(name(CommandType))]
@ -1176,11 +1257,11 @@ pub enum PluginCommand {
GetPluginIds, GetPluginIds,
GetZellijVersion, GetZellijVersion,
OpenFile(FileToOpen), OpenFile(FileToOpen),
OpenFileFloating(FileToOpen), OpenFileFloating(FileToOpen, Option<FloatingPaneCoordinates>),
OpenTerminal(FileToOpen), // only used for the path as cwd OpenTerminal(FileToOpen), // only used for the path as cwd
OpenTerminalFloating(FileToOpen), // only used for the path as cwd OpenTerminalFloating(FileToOpen, Option<FloatingPaneCoordinates>), // only used for the path as cwd
OpenCommandPane(CommandToRun), OpenCommandPane(CommandToRun),
OpenCommandPaneFloating(CommandToRun), OpenCommandPaneFloating(CommandToRun, Option<FloatingPaneCoordinates>),
SwitchTabTo(u32), // tab index SwitchTabTo(u32), // tab index
SetTimeout(f64), // seconds SetTimeout(f64), // seconds
ExecCmd(Vec<String>), ExecCmd(Vec<String>),

View file

@ -6,8 +6,8 @@ use super::layout::{
TiledPaneLayout, TiledPaneLayout,
}; };
use crate::cli::CliAction; use crate::cli::CliAction;
use crate::data::InputMode;
use crate::data::{Direction, Resize}; use crate::data::{Direction, Resize};
use crate::data::{FloatingPaneCoordinates, InputMode};
use crate::home::{find_default_config_dir, get_layout_dir}; use crate::home::{find_default_config_dir, get_layout_dir};
use crate::input::config::{Config, ConfigError, KdlError}; use crate::input::config::{Config, ConfigError, KdlError};
use crate::input::options::OnForceClose; use crate::input::options::OnForceClose;
@ -166,9 +166,14 @@ pub enum Action {
Option<Direction>, Option<Direction>,
bool, bool,
bool, bool,
Option<FloatingPaneCoordinates>,
), // usize is an optional line number, Option<PathBuf> is an optional cwd, bool is floating true/false, second bool is in_place ), // usize is an optional line number, Option<PathBuf> is an optional cwd, bool is floating true/false, second bool is in_place
/// Open a new floating pane /// Open a new floating pane
NewFloatingPane(Option<RunCommandAction>, Option<String>), // String is an optional pane name NewFloatingPane(
Option<RunCommandAction>,
Option<String>,
Option<FloatingPaneCoordinates>,
), // String is an optional pane name
/// Open a new tiled (embedded, non-floating) pane /// Open a new tiled (embedded, non-floating) pane
NewTiledPane(Option<Direction>, Option<RunCommandAction>, Option<String>), // String is an NewTiledPane(Option<Direction>, Option<RunCommandAction>, Option<String>), // String is an
/// Open a new pane in place of the focused one, suppressing it instead /// Open a new pane in place of the focused one, suppressing it instead
@ -242,7 +247,13 @@ pub enum Action {
/// Open a new tiled (embedded, non-floating) plugin pane /// Open a new tiled (embedded, non-floating) plugin pane
NewTiledPluginPane(RunPlugin, Option<String>, bool, Option<PathBuf>), // String is an optional name, bool is NewTiledPluginPane(RunPlugin, Option<String>, bool, Option<PathBuf>), // String is an optional name, bool is
// skip_cache, Option<PathBuf> is cwd // skip_cache, Option<PathBuf> is cwd
NewFloatingPluginPane(RunPlugin, Option<String>, bool, Option<PathBuf>), // String is an optional name, bool is NewFloatingPluginPane(
RunPlugin,
Option<String>,
bool,
Option<PathBuf>,
Option<FloatingPaneCoordinates>,
), // String is an optional name, bool is
// skip_cache, Option<PathBuf> is cwd // skip_cache, Option<PathBuf> is cwd
NewInPlacePluginPane(RunPlugin, Option<String>, bool), // String is an optional name, bool is NewInPlacePluginPane(RunPlugin, Option<String>, bool), // String is an optional name, bool is
// skip_cache // skip_cache
@ -330,6 +341,10 @@ impl Action {
start_suspended, start_suspended,
configuration, configuration,
skip_plugin_cache, skip_plugin_cache,
x,
y,
width,
height,
} => { } => {
let current_dir = get_current_dir(); let current_dir = get_current_dir();
let cwd = cwd let cwd = cwd
@ -350,6 +365,7 @@ impl Action {
name, name,
skip_plugin_cache, skip_plugin_cache,
cwd, cwd,
FloatingPaneCoordinates::new(x, y, width, height),
)]) )])
} else if in_place { } else if in_place {
Ok(vec![Action::NewInPlacePluginPane( Ok(vec![Action::NewInPlacePluginPane(
@ -390,6 +406,7 @@ impl Action {
Ok(vec![Action::NewFloatingPane( Ok(vec![Action::NewFloatingPane(
Some(run_command_action), Some(run_command_action),
name, name,
FloatingPaneCoordinates::new(x, y, width, height),
)]) )])
} else if in_place { } else if in_place {
Ok(vec![Action::NewInPlacePane(Some(run_command_action), name)]) Ok(vec![Action::NewInPlacePane(Some(run_command_action), name)])
@ -402,7 +419,11 @@ impl Action {
} }
} else { } else {
if floating { if floating {
Ok(vec![Action::NewFloatingPane(None, name)]) Ok(vec![Action::NewFloatingPane(
None,
name,
FloatingPaneCoordinates::new(x, y, width, height),
)])
} else if in_place { } else if in_place {
Ok(vec![Action::NewInPlacePane(None, name)]) Ok(vec![Action::NewInPlacePane(None, name)])
} else { } else {
@ -417,6 +438,10 @@ impl Action {
floating, floating,
in_place, in_place,
cwd, cwd,
x,
y,
width,
height,
} => { } => {
let mut file = file; let mut file = file;
let current_dir = get_current_dir(); let current_dir = get_current_dir();
@ -435,6 +460,7 @@ impl Action {
direction, direction,
floating, floating,
in_place, in_place,
FloatingPaneCoordinates::new(x, y, width, height),
)]) )])
}, },
CliAction::SwitchMode { input_mode } => { CliAction::SwitchMode { input_mode } => {

View file

@ -69,6 +69,17 @@ pub enum SplitSize {
Fixed(usize), // An absolute number of columns or rows Fixed(usize), // An absolute number of columns or rows
} }
impl SplitSize {
pub fn to_fixed(&self, full_size: usize) -> usize {
match self {
SplitSize::Percent(percent) => {
((*percent as f64 / 100.0) * full_size as f64).floor() as usize
},
SplitSize::Fixed(fixed) => *fixed,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Run { pub enum Run {
#[serde(rename = "plugin")] #[serde(rename = "plugin")]

View file

@ -1,7 +1,7 @@
mod kdl_layout_parser; mod kdl_layout_parser;
use crate::data::{ use crate::data::{
Direction, InputMode, Key, LayoutInfo, Palette, PaletteColor, PaneInfo, PaneManifest, Direction, FloatingPaneCoordinates, InputMode, Key, LayoutInfo, Palette, PaletteColor,
PermissionType, Resize, SessionInfo, TabInfo, PaneInfo, PaneManifest, PermissionType, Resize, SessionInfo, TabInfo,
}; };
use crate::envs::EnvironmentVariables; use crate::envs::EnvironmentVariables;
use crate::home::{find_default_config_dir, get_layout_dir}; use crate::home::{find_default_config_dir, get_layout_dir};
@ -904,8 +904,24 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
hold_on_close, hold_on_close,
hold_on_start, hold_on_start,
}; };
let x = command_metadata
.and_then(|c_m| kdl_child_string_value_for_entry(c_m, "x"))
.map(|s| s.to_owned());
let y = command_metadata
.and_then(|c_m| kdl_child_string_value_for_entry(c_m, "y"))
.map(|s| s.to_owned());
let width = command_metadata
.and_then(|c_m| kdl_child_string_value_for_entry(c_m, "width"))
.map(|s| s.to_owned());
let height = command_metadata
.and_then(|c_m| kdl_child_string_value_for_entry(c_m, "height"))
.map(|s| s.to_owned());
if floating { if floating {
Ok(Action::NewFloatingPane(Some(run_command_action), name)) Ok(Action::NewFloatingPane(
Some(run_command_action),
name,
FloatingPaneCoordinates::new(x, y, width, height),
))
} else if in_place { } else if in_place {
Ok(Action::NewInPlacePane(Some(run_command_action), name)) Ok(Action::NewInPlacePane(Some(run_command_action), name))
} else { } else {

View file

@ -4,7 +4,8 @@ use std::{
hash::{Hash, Hasher}, hash::{Hash, Hasher},
}; };
use crate::input::layout::SplitDirection; use crate::data::FloatingPaneCoordinates;
use crate::input::layout::{SplitDirection, SplitSize};
use crate::position::Position; use crate::position::Position;
/// Contains the position and size of a [`Pane`], or more generally of any terminal, measured /// Contains the position and size of a [`Pane`], or more generally of any terminal, measured
@ -130,6 +131,18 @@ impl Dimension {
pub fn is_percent(&self) -> bool { pub fn is_percent(&self) -> bool {
matches!(self.constraint, Constraint::Percent(_)) matches!(self.constraint, Constraint::Percent(_))
} }
pub fn from_split_size(split_size: SplitSize, full_size: usize) -> Self {
match split_size {
SplitSize::Fixed(fixed) => Dimension {
constraint: Constraint::Fixed(fixed),
inner: fixed,
},
SplitSize::Percent(percent) => Dimension {
constraint: Constraint::Percent(percent as f64),
inner: ((percent as f64 / 100.0) * full_size as f64).floor() as usize,
},
}
}
} }
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
@ -181,6 +194,42 @@ impl PaneGeom {
SplitDirection::Horizontal => self.rows.is_percent(), SplitDirection::Horizontal => self.rows.is_percent(),
} }
} }
pub fn adjust_coordinates(
&mut self,
floating_pane_coordinates: FloatingPaneCoordinates,
viewport: Viewport,
) {
if let Some(x) = floating_pane_coordinates.x {
self.x = x.to_fixed(viewport.cols);
}
if let Some(y) = floating_pane_coordinates.y {
self.y = y.to_fixed(viewport.rows);
}
if let Some(height) = floating_pane_coordinates.height {
self.rows = Dimension::from_split_size(height, viewport.rows);
}
if let Some(width) = floating_pane_coordinates.width {
self.cols = Dimension::from_split_size(width, viewport.cols);
}
if self.x < viewport.x {
self.x = viewport.x;
} else if self.x > viewport.x + viewport.cols {
self.x = (viewport.x + viewport.cols).saturating_sub(self.cols.as_usize());
}
if self.y < viewport.y {
self.y = viewport.y;
} else if self.y > viewport.y + viewport.rows {
self.y = (viewport.y + viewport.rows).saturating_sub(self.rows.as_usize());
}
if self.x + self.cols.as_usize() > viewport.x + viewport.cols {
let new_cols = (viewport.x + viewport.cols).saturating_sub(self.x);
self.cols.set_inner(new_cols);
}
if self.y + self.rows.as_usize() > viewport.y + viewport.rows {
let new_rows = (viewport.y + viewport.rows).saturating_sub(self.y);
self.rows.set_inner(new_rows);
}
}
} }
impl Display for PaneGeom { impl Display for PaneGeom {

View file

@ -240,6 +240,7 @@ impl TryFrom<ProtobufAction> for Action {
direction, direction,
should_float, should_float,
should_be_in_place, should_be_in_place,
None,
)) ))
}, },
_ => Err("Wrong payload for Action::NewPane"), _ => Err("Wrong payload for Action::NewPane"),
@ -249,9 +250,13 @@ impl TryFrom<ProtobufAction> for Action {
if let Some(payload) = payload.command { if let Some(payload) = payload.command {
let pane_name = payload.pane_name.clone(); let pane_name = payload.pane_name.clone();
let run_command_action: RunCommandAction = payload.try_into()?; let run_command_action: RunCommandAction = payload.try_into()?;
Ok(Action::NewFloatingPane(Some(run_command_action), pane_name)) Ok(Action::NewFloatingPane(
Some(run_command_action),
pane_name,
None,
))
} else { } else {
Ok(Action::NewFloatingPane(None, None)) Ok(Action::NewFloatingPane(None, None, None))
} }
}, },
_ => Err("Wrong payload for Action::NewFloatingPane"), _ => Err("Wrong payload for Action::NewFloatingPane"),
@ -573,6 +578,7 @@ impl TryFrom<ProtobufAction> for Action {
pane_name, pane_name,
skip_plugin_cache, skip_plugin_cache,
None, None,
None,
)) ))
}, },
_ => Err("Wrong payload for Action::MiddleClick"), _ => Err("Wrong payload for Action::MiddleClick"),
@ -874,6 +880,7 @@ impl TryFrom<Action> for ProtobufAction {
direction, direction,
should_float, should_float,
_should_be_in_place, _should_be_in_place,
_floating_pane_coordinates,
) => { ) => {
let file_to_edit = path_to_file.display().to_string(); let file_to_edit = path_to_file.display().to_string();
let cwd = cwd.map(|cwd| cwd.display().to_string()); let cwd = cwd.map(|cwd| cwd.display().to_string());
@ -892,7 +899,7 @@ impl TryFrom<Action> for ProtobufAction {
})), })),
}) })
}, },
Action::NewFloatingPane(run_command_action, pane_name) => { Action::NewFloatingPane(run_command_action, pane_name, _coordinates) => {
let command = run_command_action.and_then(|r| { let command = run_command_action.and_then(|r| {
let mut protobuf_run_command_action: ProtobufRunCommandAction = let mut protobuf_run_command_action: ProtobufRunCommandAction =
r.try_into().ok()?; r.try_into().ok()?;
@ -1046,7 +1053,7 @@ impl TryFrom<Action> for ProtobufAction {
should_float, should_float,
should_open_in_place, should_open_in_place,
skip_plugin_cache, skip_plugin_cache,
cwd, _cwd,
) => { ) => {
let url: Url = Url::from(&run_plugin.location); let url: Url = Url::from(&run_plugin.location);
Ok(ProtobufAction { Ok(ProtobufAction {
@ -1154,7 +1161,13 @@ impl TryFrom<Action> for ProtobufAction {
)), )),
}) })
}, },
Action::NewFloatingPluginPane(run_plugin, pane_name, skip_plugin_cache, _cwd) => { Action::NewFloatingPluginPane(
run_plugin,
pane_name,
skip_plugin_cache,
_cwd,
_coordinates,
) => {
let plugin_url: Url = Url::from(&run_plugin.location); let plugin_url: Url = Url::from(&run_plugin.location);
Ok(ProtobufAction { Ok(ProtobufAction {
name: ProtobufActionName::NewFloatingPluginPane as i32, name: ProtobufActionName::NewFloatingPluginPane as i32,

View file

@ -209,10 +209,12 @@ message UnsubscribePayload {
message OpenFilePayload { message OpenFilePayload {
file.File file_to_open = 1; file.File file_to_open = 1;
optional FloatingPaneCoordinates floating_pane_coordinates = 2;
} }
message OpenCommandPanePayload { message OpenCommandPanePayload {
command.Command command_to_run = 1; command.Command command_to_run = 1;
optional FloatingPaneCoordinates floating_pane_coordinates = 2;
} }
message SwitchTabToPayload { message SwitchTabToPayload {
@ -275,3 +277,20 @@ message IdAndNewName {
uint32 id = 1; // pane id or tab index uint32 id = 1; // pane id or tab index
string new_name = 2; string new_name = 2;
} }
message FloatingPaneCoordinates {
optional FixedOrPercentValue x = 1;
optional FixedOrPercentValue y = 2;
optional FixedOrPercentValue width = 3;
optional FixedOrPercentValue height = 4;
}
message FixedOrPercentValue {
FixedOrPercent type = 1;
uint32 value = 2;
}
enum FixedOrPercent {
Fixed = 0;
Percent = 1;
}

View file

@ -4,10 +4,13 @@ pub use super::generated_api::api::{
input_mode::InputMode as ProtobufInputMode, input_mode::InputMode as ProtobufInputMode,
plugin_command::{ plugin_command::{
plugin_command::Payload, CliPipeOutputPayload, CommandName, ContextItem, EnvVariable, plugin_command::Payload, CliPipeOutputPayload, CommandName, ContextItem, EnvVariable,
ExecCmdPayload, HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, ExecCmdPayload, FixedOrPercent as ProtobufFixedOrPercent,
MessageToPluginPayload, MovePayload, NewPluginArgs as ProtobufNewPluginArgs, FixedOrPercentValue as ProtobufFixedOrPercentValue,
OpenCommandPanePayload, OpenFilePayload, PaneId as ProtobufPaneId, FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HttpVerb as ProtobufHttpVerb,
PaneType as ProtobufPaneType, PluginCommand as ProtobufPluginCommand, PluginMessagePayload, IdAndNewName, KillSessionsPayload, MessageToPluginPayload, MovePayload,
NewPluginArgs as ProtobufNewPluginArgs, OpenCommandPanePayload, OpenFilePayload,
PaneId as ProtobufPaneId, PaneType as ProtobufPaneType,
PluginCommand as ProtobufPluginCommand, PluginMessagePayload,
RequestPluginPermissionPayload, ResizePayload, RunCommandPayload, SetTimeoutPayload, RequestPluginPermissionPayload, ResizePayload, RunCommandPayload, SetTimeoutPayload,
SubscribePayload, SwitchSessionPayload, SwitchTabToPayload, UnsubscribePayload, SubscribePayload, SwitchSessionPayload, SwitchTabToPayload, UnsubscribePayload,
WebRequestPayload, WebRequestPayload,
@ -17,14 +20,113 @@ pub use super::generated_api::api::{
}; };
use crate::data::{ use crate::data::{
ConnectToSession, HttpVerb, MessageToPlugin, NewPluginArgs, PaneId, PermissionType, ConnectToSession, FloatingPaneCoordinates, HttpVerb, MessageToPlugin, NewPluginArgs, PaneId,
PluginCommand, PermissionType, PluginCommand,
}; };
use crate::input::layout::SplitSize;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::path::PathBuf; use std::path::PathBuf;
impl Into<FloatingPaneCoordinates> for ProtobufFloatingPaneCoordinates {
fn into(self) -> FloatingPaneCoordinates {
FloatingPaneCoordinates {
x: self
.x
.and_then(|x| match ProtobufFixedOrPercent::from_i32(x.r#type) {
Some(ProtobufFixedOrPercent::Percent) => {
Some(SplitSize::Percent(x.value as usize))
},
Some(ProtobufFixedOrPercent::Fixed) => Some(SplitSize::Fixed(x.value as usize)),
None => None,
}),
y: self
.y
.and_then(|y| match ProtobufFixedOrPercent::from_i32(y.r#type) {
Some(ProtobufFixedOrPercent::Percent) => {
Some(SplitSize::Percent(y.value as usize))
},
Some(ProtobufFixedOrPercent::Fixed) => Some(SplitSize::Fixed(y.value as usize)),
None => None,
}),
width: self.width.and_then(|width| {
match ProtobufFixedOrPercent::from_i32(width.r#type) {
Some(ProtobufFixedOrPercent::Percent) => {
Some(SplitSize::Percent(width.value as usize))
},
Some(ProtobufFixedOrPercent::Fixed) => {
Some(SplitSize::Fixed(width.value as usize))
},
None => None,
}
}),
height: self.height.and_then(|height| {
match ProtobufFixedOrPercent::from_i32(height.r#type) {
Some(ProtobufFixedOrPercent::Percent) => {
Some(SplitSize::Percent(height.value as usize))
},
Some(ProtobufFixedOrPercent::Fixed) => {
Some(SplitSize::Fixed(height.value as usize))
},
None => None,
}
}),
}
}
}
impl Into<ProtobufFloatingPaneCoordinates> for FloatingPaneCoordinates {
fn into(self) -> ProtobufFloatingPaneCoordinates {
ProtobufFloatingPaneCoordinates {
x: match self.x {
Some(SplitSize::Percent(percent)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Percent as i32,
value: percent as u32,
}),
Some(SplitSize::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Fixed as i32,
value: fixed as u32,
}),
None => None,
},
y: match self.y {
Some(SplitSize::Percent(percent)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Percent as i32,
value: percent as u32,
}),
Some(SplitSize::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Fixed as i32,
value: fixed as u32,
}),
None => None,
},
width: match self.width {
Some(SplitSize::Percent(percent)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Percent as i32,
value: percent as u32,
}),
Some(SplitSize::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Fixed as i32,
value: fixed as u32,
}),
None => None,
},
height: match self.height {
Some(SplitSize::Percent(percent)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Percent as i32,
value: percent as u32,
}),
Some(SplitSize::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue {
r#type: ProtobufFixedOrPercent::Fixed as i32,
value: fixed as u32,
}),
None => None,
},
}
}
}
impl Into<HttpVerb> for ProtobufHttpVerb { impl Into<HttpVerb> for ProtobufHttpVerb {
fn into(self) -> HttpVerb { fn into(self) -> HttpVerb {
match self { match self {
@ -133,10 +235,14 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
}, },
Some(CommandName::OpenFileFloating) => match protobuf_plugin_command.payload { Some(CommandName::OpenFileFloating) => match protobuf_plugin_command.payload {
Some(Payload::OpenFileFloatingPayload(file_to_open_payload)) => { Some(Payload::OpenFileFloatingPayload(file_to_open_payload)) => {
let floating_pane_coordinates = file_to_open_payload
.floating_pane_coordinates
.map(|f| f.into());
match file_to_open_payload.file_to_open { match file_to_open_payload.file_to_open {
Some(file_to_open) => { Some(file_to_open) => Ok(PluginCommand::OpenFileFloating(
Ok(PluginCommand::OpenFileFloating(file_to_open.try_into()?)) file_to_open.try_into()?,
}, floating_pane_coordinates,
)),
None => Err("Malformed open file payload"), None => Err("Malformed open file payload"),
} }
}, },
@ -155,9 +261,13 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
}, },
Some(CommandName::OpenTerminalFloating) => match protobuf_plugin_command.payload { Some(CommandName::OpenTerminalFloating) => match protobuf_plugin_command.payload {
Some(Payload::OpenTerminalFloatingPayload(file_to_open_payload)) => { Some(Payload::OpenTerminalFloatingPayload(file_to_open_payload)) => {
let floating_pane_coordinates = file_to_open_payload
.floating_pane_coordinates
.map(|f| f.into());
match file_to_open_payload.file_to_open { match file_to_open_payload.file_to_open {
Some(file_to_open) => Ok(PluginCommand::OpenTerminalFloating( Some(file_to_open) => Ok(PluginCommand::OpenTerminalFloating(
file_to_open.try_into()?, file_to_open.try_into()?,
floating_pane_coordinates,
)), )),
None => Err("Malformed open terminal floating payload"), None => Err("Malformed open terminal floating payload"),
} }
@ -177,9 +287,13 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
}, },
Some(CommandName::OpenCommandPaneFloating) => match protobuf_plugin_command.payload { Some(CommandName::OpenCommandPaneFloating) => match protobuf_plugin_command.payload {
Some(Payload::OpenCommandPaneFloatingPayload(command_to_run_payload)) => { Some(Payload::OpenCommandPaneFloatingPayload(command_to_run_payload)) => {
let floating_pane_coordinates = command_to_run_payload
.floating_pane_coordinates
.map(|f| f.into());
match command_to_run_payload.command_to_run { match command_to_run_payload.command_to_run {
Some(command_to_run) => Ok(PluginCommand::OpenCommandPaneFloating( Some(command_to_run) => Ok(PluginCommand::OpenCommandPaneFloating(
command_to_run.try_into()?, command_to_run.try_into()?,
floating_pane_coordinates,
)), )),
None => Err("Malformed open command pane floating payload"), None => Err("Malformed open command pane floating payload"),
} }
@ -783,40 +897,52 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
name: CommandName::OpenFile as i32, name: CommandName::OpenFile as i32,
payload: Some(Payload::OpenFilePayload(OpenFilePayload { payload: Some(Payload::OpenFilePayload(OpenFilePayload {
file_to_open: Some(file_to_open.try_into()?), file_to_open: Some(file_to_open.try_into()?),
floating_pane_coordinates: None,
})), })),
}), }),
PluginCommand::OpenFileFloating(file_to_open) => Ok(ProtobufPluginCommand { PluginCommand::OpenFileFloating(file_to_open, floating_pane_coordinates) => {
name: CommandName::OpenFileFloating as i32, Ok(ProtobufPluginCommand {
payload: Some(Payload::OpenFileFloatingPayload(OpenFilePayload { name: CommandName::OpenFileFloating as i32,
file_to_open: Some(file_to_open.try_into()?), payload: Some(Payload::OpenFileFloatingPayload(OpenFilePayload {
})), file_to_open: Some(file_to_open.try_into()?),
}), floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()),
})),
})
},
PluginCommand::OpenTerminal(cwd) => Ok(ProtobufPluginCommand { PluginCommand::OpenTerminal(cwd) => Ok(ProtobufPluginCommand {
name: CommandName::OpenTerminal as i32, name: CommandName::OpenTerminal as i32,
payload: Some(Payload::OpenTerminalPayload(OpenFilePayload { payload: Some(Payload::OpenTerminalPayload(OpenFilePayload {
file_to_open: Some(cwd.try_into()?), file_to_open: Some(cwd.try_into()?),
floating_pane_coordinates: None,
})), })),
}), }),
PluginCommand::OpenTerminalFloating(cwd) => Ok(ProtobufPluginCommand { PluginCommand::OpenTerminalFloating(cwd, floating_pane_coordinates) => {
name: CommandName::OpenTerminalFloating as i32, Ok(ProtobufPluginCommand {
payload: Some(Payload::OpenTerminalFloatingPayload(OpenFilePayload { name: CommandName::OpenTerminalFloating as i32,
file_to_open: Some(cwd.try_into()?), payload: Some(Payload::OpenTerminalFloatingPayload(OpenFilePayload {
})), file_to_open: Some(cwd.try_into()?),
}), floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()),
})),
})
},
PluginCommand::OpenCommandPane(command_to_run) => Ok(ProtobufPluginCommand { PluginCommand::OpenCommandPane(command_to_run) => Ok(ProtobufPluginCommand {
name: CommandName::OpenCommandPane as i32, name: CommandName::OpenCommandPane as i32,
payload: Some(Payload::OpenCommandPanePayload(OpenCommandPanePayload { payload: Some(Payload::OpenCommandPanePayload(OpenCommandPanePayload {
command_to_run: Some(command_to_run.try_into()?), command_to_run: Some(command_to_run.try_into()?),
floating_pane_coordinates: None,
})), })),
}), }),
PluginCommand::OpenCommandPaneFloating(command_to_run) => Ok(ProtobufPluginCommand { PluginCommand::OpenCommandPaneFloating(command_to_run, floating_pane_coordinates) => {
name: CommandName::OpenCommandPaneFloating as i32, Ok(ProtobufPluginCommand {
payload: Some(Payload::OpenCommandPaneFloatingPayload( name: CommandName::OpenCommandPaneFloating as i32,
OpenCommandPanePayload { payload: Some(Payload::OpenCommandPaneFloatingPayload(
command_to_run: Some(command_to_run.try_into()?), OpenCommandPanePayload {
}, command_to_run: Some(command_to_run.try_into()?),
)), floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()),
}), },
)),
})
},
PluginCommand::SwitchTabTo(tab_index) => Ok(ProtobufPluginCommand { PluginCommand::SwitchTabTo(tab_index) => Ok(ProtobufPluginCommand {
name: CommandName::SwitchTabTo as i32, name: CommandName::SwitchTabTo as i32,
payload: Some(Payload::SwitchTabToPayload(SwitchTabToPayload { payload: Some(Payload::SwitchTabToPayload(SwitchTabToPayload {
@ -1100,12 +1226,14 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
name: CommandName::OpenTerminalInPlace as i32, name: CommandName::OpenTerminalInPlace as i32,
payload: Some(Payload::OpenTerminalInPlacePayload(OpenFilePayload { payload: Some(Payload::OpenTerminalInPlacePayload(OpenFilePayload {
file_to_open: Some(cwd.try_into()?), file_to_open: Some(cwd.try_into()?),
floating_pane_coordinates: None,
})), })),
}), }),
PluginCommand::OpenFileInPlace(file_to_open) => Ok(ProtobufPluginCommand { PluginCommand::OpenFileInPlace(file_to_open) => Ok(ProtobufPluginCommand {
name: CommandName::OpenFileInPlace as i32, name: CommandName::OpenFileInPlace as i32,
payload: Some(Payload::OpenFileInPlacePayload(OpenFilePayload { payload: Some(Payload::OpenFileInPlacePayload(OpenFilePayload {
file_to_open: Some(file_to_open.try_into()?), file_to_open: Some(file_to_open.try_into()?),
floating_pane_coordinates: None,
})), })),
}), }),
PluginCommand::OpenCommandPaneInPlace(command_to_run) => Ok(ProtobufPluginCommand { PluginCommand::OpenCommandPaneInPlace(command_to_run) => Ok(ProtobufPluginCommand {
@ -1113,6 +1241,7 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
payload: Some(Payload::OpenCommandPaneInPlacePayload( payload: Some(Payload::OpenCommandPaneInPlacePayload(
OpenCommandPanePayload { OpenCommandPanePayload {
command_to_run: Some(command_to_run.try_into()?), command_to_run: Some(command_to_run.try_into()?),
floating_pane_coordinates: None,
}, },
)), )),
}), }),