Layout string flag (#4956)

* allow sending a stringified layout with --layout-string

* add --tab-id to all the things

* fix windows tests

* add pr
This commit is contained in:
Aram Drevekenin
2026-03-30 16:02:09 +02:00
committed by GitHub
parent 16beceaa0a
commit 8ce05f0bbd
26 changed files with 2108 additions and 248 deletions
+1
View File
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* feat: support and forward OSC-99 desktop notifications (https://github.com/zellij-org/zellij/pull/4931)
* fix: normalize temp socket paths in windows (https://github.com/zellij-org/zellij/pull/4923)
* fix: compilation warnings in windows (https://github.com/zellij-org/zellij/pull/4890)
* feat: add --layout-string to allow for in-line layouts, add --tab-id to all new-pane CLI commands (https://github.com/zellij-org/zellij/pull/4956)
## [0.44.0] - 2026-03-23
* fix: meta key handling in web client (https://github.com/zellij-org/zellij/pull/4376)
@@ -442,6 +442,7 @@ impl KeybindProcessor {
command: None,
pane_name: None,
near_current_pane: false,
..
}
)
},
@@ -1386,7 +1386,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
(s("Toggle Embed"), s("Embed"), single_action_key(&km, &[A::TogglePaneEmbedOrFloating, TO_NORMAL])),
(s("Split Right"), s("Right"), single_action_key(&km, &[A::NewPane{direction: Some(Direction::Right), pane_name: None, start_suppressed: false}, TO_NORMAL])),
(s("Split Down"), s("Down"), single_action_key(&km, &[A::NewPane{direction: Some(Direction::Down), pane_name: None, start_suppressed: false}, TO_NORMAL])),
(s("Stack"), s("Stack"), single_action_key(&km, &[A::NewStackedPane{command: None, pane_name: None, near_current_pane: false}, TO_NORMAL])),
(s("Stack"), s("Stack"), single_action_key(&km, &[A::NewStackedPane{command: None, pane_name: None, near_current_pane: false, tab_id: None}, TO_NORMAL])),
(s("Select pane"), s("Select"), to_basemode_key),
]} else if mi.mode == IM::Tab {
// With the default bindings, "Move focus" for tabs is tricky: It binds all the arrow keys
@@ -254,7 +254,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
action_key(&km, &[A::SearchToggleOption{option: SOpt::WholeWord}])),
]} else if mi.mode == IM::Session { vec![
(s("Detach"), s("Detach"), action_key(&km, &[Action::Detach])),
(s("Session Manager"), s("Manager"), action_key(&km, &[A::LaunchOrFocusPlugin{plugin: Default::default(), should_float: true, move_to_focused_tab: true, should_open_in_place: false, close_replaced_pane: false, skip_cache: false}, TO_NORMAL])), // not entirely accurate
(s("Session Manager"), s("Manager"), action_key(&km, &[A::LaunchOrFocusPlugin{plugin: Default::default(), should_float: true, move_to_focused_tab: true, should_open_in_place: false, close_replaced_pane: false, skip_cache: false, tab_id: None}, TO_NORMAL])), // not entirely accurate
(s("Select pane"), s("Select"), to_normal_key),
]} else if mi.mode == IM::Tmux { vec![
(s("Move focus"), s("Move"), action_key_group(&km, &[
+9 -2
View File
@@ -51,6 +51,7 @@ fn main() {
block_until_exit,
near_current_pane,
borderless,
tab_id,
})) = opts.command
{
let cwd = cwd.or_else(|| std::env::current_dir().ok());
@@ -93,6 +94,7 @@ fn main() {
unblock_condition,
near_current_pane,
borderless,
tab_id,
};
commands::send_action_to_session(command_cli_action, opts.session, config);
std::process::exit(0);
@@ -110,6 +112,7 @@ fn main() {
height,
pinned,
borderless,
tab_id,
})) = opts.command
{
let cwd = None;
@@ -142,6 +145,7 @@ fn main() {
unblock_condition,
near_current_pane: false,
borderless,
tab_id,
};
commands::send_action_to_session(command_cli_action, opts.session, config);
std::process::exit(0);
@@ -161,6 +165,7 @@ fn main() {
pinned,
near_current_pane,
borderless,
tab_id,
})) = opts.command
{
let mut file = file;
@@ -185,6 +190,7 @@ fn main() {
pinned,
near_current_pane,
borderless,
tab_id,
};
commands::send_action_to_session(command_cli_action, opts.session, config);
std::process::exit(0);
@@ -256,7 +262,7 @@ fn main() {
commands::delete_session(target_session, force);
} else if let Some(path) = opts.server {
commands::start_server(path, opts.debug);
} else if let Some(layout) = &opts.layout {
} else if opts.layout.is_some() || opts.layout_string.is_some() {
if let Some(session_name) = opts
.session
.as_ref()
@@ -266,7 +272,8 @@ fn main() {
let config = Config::try_from(&opts).ok();
let options = Setup::from_cli_args(&opts).ok().map(|r| r.2);
let new_layout_cli_action = CliAction::NewTab {
layout: Some(layout.clone()),
layout: opts.layout.clone(),
layout_string: opts.layout_string.clone(),
layout_dir: options.as_ref().and_then(|o| o.layout_dir.clone()),
name: None,
cwd: options.as_ref().and_then(|o| o.default_cwd.clone()),
+20 -16
View File
@@ -772,22 +772,26 @@ pub fn start_client(
config_dir: cli_args.config_dir.clone(),
should_ignore_config: cli_args.is_setup_clean(),
configuration_options: Some(config_options.clone()),
layout: cli_args
.layout
.as_ref()
.and_then(|l| {
LayoutInfo::from_cli(
&config_options.layout_dir,
&Some(l.clone()),
std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
)
})
.or_else(|| {
LayoutInfo::from_config(
&config_options.layout_dir,
&config_options.default_layout,
)
}),
layout: if let Some(layout_string) = &cli_args.layout_string {
Some(LayoutInfo::Stringified(layout_string.clone()))
} else {
cli_args
.layout
.as_ref()
.and_then(|l| {
LayoutInfo::from_cli(
&config_options.layout_dir,
&Some(l.clone()),
std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
)
})
.or_else(|| {
LayoutInfo::from_config(
&config_options.layout_dir,
&config_options.default_layout,
)
})
},
terminal_window_size: full_screen_ws,
data_dir: cli_args.data_dir.clone(),
is_debug: cli_args.debug,
+17 -4
View File
@@ -287,7 +287,7 @@ impl WasmBridge {
skip_cache: bool,
client_id: Option<ClientId>,
) -> Result<(PluginId, ClientId)> {
let err_context = move || format!("failed to load plugin");
let _err_context = move || format!("failed to load plugin");
let client_id = client_id
.and_then(|client_id| {
@@ -321,9 +321,22 @@ impl WasmBridge {
match run {
Some(run) => {
let plugin = PluginConfig::from_run_plugin(run)
.with_context(|| format!("failed to resolve plugin {run:?}"))
.with_context(err_context)?;
let plugin = match PluginConfig::from_run_plugin(run) {
Some(plugin) => plugin,
None => {
self.next_plugin_id += 1;
let mut loading_indication =
LoadingIndication::new(run.location.to_string());
handle_plugin_loading_failure(
&self.senders,
plugin_id,
&mut loading_indication,
format!("Failed to resolve plugin: {}", run.location),
Some(client_id),
);
return Ok((plugin_id, client_id));
},
};
let plugin_name = run.location.to_string();
self.cached_events_for_pending_plugins
@@ -1164,6 +1164,7 @@ fn open_plugin_pane_floating(
skip_cache: false,
cwd: Some(env.plugin_cwd.clone()),
coordinates: floating_pane_coordinates,
tab_id: None,
};
let error_msg = || format!("Failed to open floating plugin pane");
let result = apply_action!(action, error_msg, env);
@@ -1403,6 +1404,7 @@ fn open_file(env: &PluginEnv, file_to_open: FileToOpen, context: BTreeMap<String
start_suppressed,
coordinates: None,
near_current_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -1505,6 +1507,7 @@ fn open_file_floating(
start_suppressed,
coordinates: floating_pane_coordinates,
near_current_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -1545,6 +1548,7 @@ fn open_file_in_place(
start_suppressed,
coordinates: None,
near_current_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -1705,6 +1709,7 @@ fn open_terminal(env: &PluginEnv, cwd: PathBuf) {
pane_name: None,
near_current_pane: false,
borderless: None,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -1780,6 +1785,7 @@ fn open_terminal_floating(
pane_name: None,
coordinates: floating_pane_coordinates,
near_current_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -1855,6 +1861,7 @@ fn open_terminal_in_place(env: &PluginEnv, cwd: PathBuf) {
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -2139,6 +2146,7 @@ fn open_command_pane(
pane_name: name,
near_current_pane: false,
borderless: None,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -2246,6 +2254,7 @@ fn open_command_pane_floating(
pane_name: name,
coordinates: floating_pane_coordinates,
near_current_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -2356,6 +2365,7 @@ fn open_command_pane_in_place(
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane: false,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -4423,6 +4433,7 @@ fn try_edit_layout(
start_suppressed: false,
coordinates: None,
near_current_pane: true,
tab_id: None,
};
// Route the action - this is fallible
+98 -78
View File
@@ -637,6 +637,7 @@ pub(crate) fn route_action(
command,
unblock_condition,
near_current_pane,
tab_id,
} => {
let command = command
.map(|cmd| TerminalAction::RunCommand(cmd.into()))
@@ -668,7 +669,9 @@ pub(crate) fn route_action(
_ => pane_id,
};
let client_tab_index_or_paneid = if near_current_pane && pane_id.is_some() {
let client_tab_index_or_paneid = if let Some(tab_id) = tab_id {
ClientTabIndexOrPaneId::TabIndex(tab_id)
} else if near_current_pane && pane_id.is_some() {
ClientTabIndexOrPaneId::PaneId(pane_id.unwrap())
} else {
ClientTabIndexOrPaneId::ClientId(client_id)
@@ -695,27 +698,31 @@ pub(crate) fn route_action(
start_suppressed,
coordinates: floating_pane_coordinates,
near_current_pane,
tab_id,
} => {
let title = format!("Editing: {}", open_file_payload.path.display());
let open_file = TerminalAction::OpenFile(open_file_payload);
let pty_instr = if should_open_in_place {
match pane_id {
Some(pane_id) if near_current_pane => PtyInstruction::SpawnInPlaceTerminal(
Some(open_file),
Some(title),
close_replaced_pane,
ClientTabIndexOrPaneId::PaneId(pane_id),
Some(NotificationEnd::new(completion_tx)),
),
_ => PtyInstruction::SpawnInPlaceTerminal(
Some(open_file),
Some(title),
close_replaced_pane,
ClientTabIndexOrPaneId::ClientId(client_id),
Some(NotificationEnd::new(completion_tx)),
),
}
let client_tab_index_or_paneid = if let Some(tab_id) = tab_id {
ClientTabIndexOrPaneId::TabIndex(tab_id)
} else if near_current_pane && pane_id.is_some() {
ClientTabIndexOrPaneId::PaneId(pane_id.unwrap())
} else {
ClientTabIndexOrPaneId::ClientId(client_id)
};
PtyInstruction::SpawnInPlaceTerminal(
Some(open_file),
Some(title),
close_replaced_pane,
client_tab_index_or_paneid,
Some(NotificationEnd::new(completion_tx)),
)
} else {
let client_tab_index_or_paneid = if let Some(tab_id) = tab_id {
ClientTabIndexOrPaneId::TabIndex(tab_id)
} else {
ClientTabIndexOrPaneId::ClientId(client_id)
};
PtyInstruction::SpawnTerminal(
Some(open_file),
Some(title),
@@ -728,7 +735,7 @@ pub(crate) fn route_action(
}
},
start_suppressed,
ClientTabIndexOrPaneId::ClientId(client_id),
client_tab_index_or_paneid,
Some(NotificationEnd::new(completion_tx)),
false, // set_blocking
)
@@ -761,11 +768,14 @@ pub(crate) fn route_action(
pane_name: name,
coordinates: floating_pane_coordinates,
near_current_pane,
tab_id,
} => {
let run_cmd = run_command
.map(|cmd| TerminalAction::RunCommand(cmd.into()))
.or_else(|| default_shell.clone());
let client_tab_index_or_paneid = if near_current_pane && pane_id.is_some() {
let client_tab_index_or_paneid = if let Some(tab_id) = tab_id {
ClientTabIndexOrPaneId::TabIndex(tab_id)
} else if near_current_pane && pane_id.is_some() {
ClientTabIndexOrPaneId::PaneId(pane_id.unwrap())
} else {
ClientTabIndexOrPaneId::ClientId(client_id)
@@ -788,6 +798,7 @@ pub(crate) fn route_action(
near_current_pane,
pane_id_to_replace,
close_replaced_pane,
tab_id,
} => {
let run_cmd = run_command
.map(|cmd| TerminalAction::RunCommand(cmd.into()))
@@ -796,74 +807,70 @@ pub(crate) fn route_action(
Some(pane_id_to_replace) => pane_id_to_replace.try_into().ok(),
None => pane_id,
};
match pane_id {
Some(pane_id) if near_current_pane => {
senders
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
run_cmd,
name,
close_replaced_pane,
ClientTabIndexOrPaneId::PaneId(pane_id),
Some(NotificationEnd::new(completion_tx)),
))
.with_context(err_context)?;
},
_ => {
senders
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
run_cmd,
name,
close_replaced_pane,
ClientTabIndexOrPaneId::ClientId(client_id),
Some(NotificationEnd::new(completion_tx)),
))
.with_context(err_context)?;
},
}
let client_tab_index_or_paneid = if let Some(tab_id) = tab_id {
ClientTabIndexOrPaneId::TabIndex(tab_id)
} else if near_current_pane && pane_id.is_some() {
ClientTabIndexOrPaneId::PaneId(pane_id.unwrap())
} else {
ClientTabIndexOrPaneId::ClientId(client_id)
};
senders
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
run_cmd,
name,
close_replaced_pane,
client_tab_index_or_paneid,
Some(NotificationEnd::new(completion_tx)),
))
.with_context(err_context)?;
},
Action::NewStackedPane {
command: run_command,
pane_name: name,
near_current_pane,
tab_id,
} => {
let run_cmd = run_command
.map(|cmd| TerminalAction::RunCommand(cmd.into()))
.or_else(|| default_shell.clone());
match pane_id {
Some(pane_id) if near_current_pane => {
senders
.send_to_pty(PtyInstruction::SpawnTerminal(
run_cmd,
name,
NewPanePlacement::Stacked {
pane_id_to_stack_under: Some(pane_id.into()),
borderless: None,
},
false,
ClientTabIndexOrPaneId::PaneId(pane_id),
Some(NotificationEnd::new(completion_tx)),
false, // set_blocking
))
.with_context(err_context)?;
},
_ => {
senders
.send_to_pty(PtyInstruction::SpawnTerminal(
run_cmd,
name,
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
},
false,
ClientTabIndexOrPaneId::ClientId(client_id),
Some(NotificationEnd::new(completion_tx)),
false, // set_blocking
))
.with_context(err_context)?;
},
}
let (pane_placement, client_tab_index_or_paneid) = if let Some(tab_id) = tab_id {
(
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
},
ClientTabIndexOrPaneId::TabIndex(tab_id),
)
} else if near_current_pane && pane_id.is_some() {
let pane_id = pane_id.unwrap();
(
NewPanePlacement::Stacked {
pane_id_to_stack_under: Some(pane_id.into()),
borderless: None,
},
ClientTabIndexOrPaneId::PaneId(pane_id),
)
} else {
(
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
},
ClientTabIndexOrPaneId::ClientId(client_id),
)
};
senders
.send_to_pty(PtyInstruction::SpawnTerminal(
run_cmd,
name,
pane_placement,
false,
client_tab_index_or_paneid,
Some(NotificationEnd::new(completion_tx)),
false, // set_blocking
))
.with_context(err_context)?;
},
Action::NewTiledPane {
direction,
@@ -871,11 +878,14 @@ pub(crate) fn route_action(
pane_name: name,
near_current_pane,
borderless,
tab_id,
} => {
let run_cmd = run_command
.map(|cmd| TerminalAction::RunCommand(cmd.into()))
.or_else(|| default_shell.clone());
let client_tab_index_or_paneid = if near_current_pane && pane_id.is_some() {
let client_tab_index_or_paneid = if let Some(tab_id) = tab_id {
ClientTabIndexOrPaneId::TabIndex(tab_id)
} else if near_current_pane && pane_id.is_some() {
ClientTabIndexOrPaneId::PaneId(pane_id.unwrap())
} else {
ClientTabIndexOrPaneId::ClientId(client_id)
@@ -1296,6 +1306,7 @@ pub(crate) fn route_action(
pane_name: name,
skip_cache,
cwd,
tab_id,
} => {
senders
.send_to_screen(ScreenInstruction::NewTiledPluginPane(
@@ -1305,6 +1316,7 @@ pub(crate) fn route_action(
cwd,
client_id,
Some(NotificationEnd::new(completion_tx)),
tab_id,
))
.with_context(err_context)?;
},
@@ -1314,6 +1326,7 @@ pub(crate) fn route_action(
skip_cache,
cwd,
coordinates: floating_pane_coordinates,
tab_id,
} => {
senders
.send_to_screen(ScreenInstruction::NewFloatingPluginPane(
@@ -1324,6 +1337,7 @@ pub(crate) fn route_action(
floating_pane_coordinates,
client_id,
Some(NotificationEnd::new(completion_tx)),
tab_id,
))
.with_context(err_context)?;
},
@@ -1332,6 +1346,7 @@ pub(crate) fn route_action(
pane_name: name,
skip_cache,
close_replaced_pane,
tab_id,
} => {
if let Some(pane_id) = pane_id {
senders
@@ -1343,6 +1358,7 @@ pub(crate) fn route_action(
close_replaced_pane,
client_id,
Some(NotificationEnd::new(completion_tx)),
tab_id,
))
.with_context(err_context)?;
} else {
@@ -1365,6 +1381,7 @@ pub(crate) fn route_action(
should_open_in_place,
close_replaced_pane,
skip_cache,
tab_id,
} => {
senders
.send_to_screen(ScreenInstruction::LaunchOrFocusPlugin(
@@ -1377,6 +1394,7 @@ pub(crate) fn route_action(
skip_cache,
client_id,
Some(NotificationEnd::new(completion_tx)),
tab_id,
))
.with_context(err_context)?;
},
@@ -1387,6 +1405,7 @@ pub(crate) fn route_action(
close_replaced_pane,
skip_cache,
cwd,
tab_id,
} => {
senders
.send_to_screen(ScreenInstruction::LaunchPlugin(
@@ -1399,6 +1418,7 @@ pub(crate) fn route_action(
cwd,
client_id,
Some(NotificationEnd::new(completion_tx)),
tab_id,
))
.with_context(err_context)?;
},
+149 -95
View File
@@ -547,6 +547,7 @@ pub enum ScreenInstruction {
Option<PathBuf>,
ClientId,
Option<NotificationEnd>,
Option<usize>, // tab_id
), // Option<String> is
// optional pane title, bool is skip cache, Option<PathBuf> is an optional cwd
NewFloatingPluginPane(
@@ -557,6 +558,7 @@ pub enum ScreenInstruction {
Option<FloatingPaneCoordinates>,
ClientId,
Option<NotificationEnd>,
Option<usize>, // tab_id
), // Option<String> is an
// optional pane title, bool
// is skip cache, Option<PathBuf> is an optional cwd
@@ -568,6 +570,7 @@ pub enum ScreenInstruction {
bool,
ClientId,
Option<NotificationEnd>,
Option<usize>, // tab_id
), // Option<String> is an
// optional pane title, first bool is skip cache, second bool is close_replaced_pane
StartOrReloadPluginPane(RunPluginOrAlias, Option<String>, Option<NotificationEnd>),
@@ -601,6 +604,7 @@ pub enum ScreenInstruction {
bool,
ClientId,
Option<NotificationEnd>,
Option<usize>, // tab_id
), // bools are: should_float, move_to_focused_tab, should_open_in_place, close_replaced_pane, Option<PaneId> is the pane id to replace, bool following it is skip_cache
LaunchPlugin(
RunPluginOrAlias,
@@ -612,6 +616,7 @@ pub enum ScreenInstruction {
Option<PathBuf>,
ClientId,
Option<NotificationEnd>,
Option<usize>, // tab_id
), // bools are: should_float, should_open_in_place, close_replaced_pane, Option<PaneId> is the pane id to replace, Option<PathBuf> is an optional cwd, bool after is skip_cache
SuppressPane(PaneId, ClientId),
UnsuppressPane(PaneId, bool), // bool -> should float if hidden
@@ -5136,6 +5141,29 @@ pub(crate) fn screen_thread_main(
}
},
ClientTabIndexOrPaneId::TabIndex(tab_index) => {
// Some placements (directional split, stacked without a
// target pane) need a client_id to know which pane to
// split relative to. Only resolve one when required.
let needs_client_id = matches!(
new_pane_placement,
NewPanePlacement::Tiled {
direction: Some(_),
..
} | NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
..
}
);
let client_id = if needs_client_id {
screen
.active_tab_ids
.iter()
.find(|(_, tid)| **tid == tab_index)
.map(|(cid, _)| *cid)
.or_else(|| screen.active_tab_ids.keys().next().copied())
} else {
None
};
if let Some(active_tab) = screen.tabs.get_mut(&tab_index) {
active_tab.new_pane(
pid,
@@ -5144,7 +5172,7 @@ pub(crate) fn screen_thread_main(
start_suppressed,
true,
new_pane_placement,
None,
client_id,
blocking_notification,
)?;
if let Some(hold_for_command) = hold_for_command {
@@ -7028,8 +7056,10 @@ pub(crate) fn screen_thread_main(
cwd,
client_id,
completion_tx,
explicit_tab_id,
) => {
let tab_index = screen.active_tab_ids.values().next().unwrap_or(&1);
let tab_index = explicit_tab_id
.unwrap_or_else(|| *screen.active_tab_ids.values().next().unwrap_or(&1));
let size = Size::default();
let should_float = Some(false);
let should_be_opened_in_place = false;
@@ -7042,7 +7072,7 @@ pub(crate) fn screen_thread_main(
false, // close_replaced_pane
pane_title,
run_plugin,
*tab_index,
tab_index,
None,
client_id,
size,
@@ -7061,36 +7091,41 @@ pub(crate) fn screen_thread_main(
floating_pane_coordinates,
client_id,
completion_tx,
) => match screen.active_tab_ids.values().next() {
Some(tab_index) => {
let size = Size::default();
let should_float = Some(true);
let should_be_opened_in_place = false;
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
should_float,
should_be_opened_in_place,
false, // close_replaced_pane
pane_title,
run_plugin,
*tab_index,
None,
client_id,
size,
skip_cache,
cwd,
None,
floating_pane_coordinates,
completion_tx,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
explicit_tab_id,
) => {
let resolved_tab_index =
explicit_tab_id.or_else(|| screen.active_tab_ids.values().next().copied());
match resolved_tab_index {
Some(tab_index) => {
let size = Size::default();
let should_float = Some(true);
let should_be_opened_in_place = false;
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
should_float,
should_be_opened_in_place,
false, // close_replaced_pane
pane_title,
run_plugin,
tab_index,
None,
client_id,
size,
skip_cache,
cwd,
None,
floating_pane_coordinates,
completion_tx,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
}
},
ScreenInstruction::NewInPlacePluginPane(
run_plugin,
@@ -7100,36 +7135,41 @@ pub(crate) fn screen_thread_main(
close_replaced_pane,
client_id,
completion_tx,
) => match screen.active_tab_ids.values().next() {
Some(tab_index) => {
let size = Size::default();
let should_float = None;
let should_be_in_place = true;
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
should_float,
should_be_in_place,
close_replaced_pane,
pane_title,
run_plugin,
*tab_index,
Some(pane_id_to_replace),
client_id,
size,
skip_cache,
None,
None,
None,
completion_tx,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
explicit_tab_id,
) => {
let resolved_tab_index =
explicit_tab_id.or_else(|| screen.active_tab_ids.values().next().copied());
match resolved_tab_index {
Some(tab_index) => {
let size = Size::default();
let should_float = None;
let should_be_in_place = true;
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
should_float,
should_be_in_place,
close_replaced_pane,
pane_title,
run_plugin,
tab_index,
Some(pane_id_to_replace),
client_id,
size,
skip_cache,
None,
None,
None,
completion_tx,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
}
},
ScreenInstruction::StartOrReloadPluginPane(run_plugin, pane_title, completion_tx) => {
let tab_index = screen.active_tab_ids.values().next().unwrap_or(&1);
@@ -7326,9 +7366,12 @@ pub(crate) fn screen_thread_main(
skip_cache,
client_id,
mut completion_tx,
explicit_tab_id,
) => match pane_id_to_replace {
Some(pane_id_to_replace) if should_open_in_place => {
match screen.active_tab_ids.values().next() {
let resolved_tab_index =
explicit_tab_id.or_else(|| screen.active_tab_ids.values().next().copied());
match resolved_tab_index {
Some(tab_index) => {
let size = Size::default();
screen
@@ -7340,7 +7383,7 @@ pub(crate) fn screen_thread_main(
close_replaced_pane,
None,
run_plugin,
*tab_index,
tab_index,
Some(pane_id_to_replace),
client_id,
size,
@@ -7370,7 +7413,10 @@ pub(crate) fn screen_thread_main(
.get(&client_id)
.map(|tab_index| (*tab_index, client_id))
});
match client_id_and_focused_tab {
let resolved_tab_and_client = explicit_tab_id
.and_then(|tid| client_id.map(|cid| (tid, cid)))
.or(client_id_and_focused_tab);
match resolved_tab_and_client {
Some((tab_index, client_id)) => {
if screen.focus_plugin_pane(
&run_plugin,
@@ -7420,35 +7466,40 @@ pub(crate) fn screen_thread_main(
cwd,
client_id,
completion_tx,
explicit_tab_id,
) => match pane_id_to_replace {
Some(pane_id_to_replace) => match screen.active_tab_ids.values().next() {
Some(tab_index) => {
let size = Size::default();
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
Some(should_float),
should_open_in_place,
close_replaced_pane,
None,
run_plugin,
*tab_index,
Some(pane_id_to_replace),
client_id,
size,
skip_cache,
cwd,
None,
None,
completion_tx,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
Some(pane_id_to_replace) => {
let resolved_tab_index =
explicit_tab_id.or_else(|| screen.active_tab_ids.values().next().copied());
match resolved_tab_index {
Some(tab_index) => {
let size = Size::default();
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
Some(should_float),
should_open_in_place,
close_replaced_pane,
None,
run_plugin,
tab_index,
Some(pane_id_to_replace),
client_id,
size,
skip_cache,
cwd,
None,
None,
completion_tx,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
}
},
None => {
let client_id = if screen.active_tab_ids.contains_key(&client_id) {
@@ -7462,7 +7513,10 @@ pub(crate) fn screen_thread_main(
.get(&client_id)
.map(|tab_index| (*tab_index, client_id))
});
match client_id_and_focused_tab {
let resolved_tab_and_client = explicit_tab_id
.and_then(|tid| client_id.map(|cid| (tid, cid)))
.or(client_id_and_focused_tab);
match resolved_tab_and_client {
Some((tab_index, client_id)) => {
screen
.bus
+414
View File
@@ -3094,6 +3094,7 @@ pub fn send_cli_new_pane_action_with_default_parameters() {
unblock_condition: None,
near_current_pane: false,
borderless: Some(false),
tab_id: 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
@@ -3147,6 +3148,7 @@ pub fn send_cli_new_pane_action_with_split_direction() {
unblock_condition: None,
near_current_pane: false,
borderless: Some(false),
tab_id: 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
@@ -3200,6 +3202,7 @@ pub fn send_cli_new_pane_action_with_command_and_cwd() {
unblock_condition: None,
near_current_pane: false,
borderless: Some(false),
tab_id: 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
@@ -3264,6 +3267,7 @@ pub fn send_cli_new_pane_action_with_floating_pane_and_coordinates() {
unblock_condition: None,
near_current_pane: false,
borderless: Some(false),
tab_id: 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
@@ -3306,6 +3310,7 @@ pub fn send_cli_edit_action_with_default_parameters() {
pinned: None,
borderless: Some(false),
near_current_pane: false,
tab_id: None,
};
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
@@ -3348,6 +3353,7 @@ pub fn send_cli_edit_action_with_line_number() {
pinned: None,
borderless: Some(false),
near_current_pane: false,
tab_id: None,
};
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
@@ -3390,6 +3396,7 @@ pub fn send_cli_edit_action_with_split_direction() {
pinned: None,
borderless: Some(false),
near_current_pane: false,
tab_id: None,
};
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
@@ -3580,6 +3587,7 @@ pub fn send_cli_new_tab_action_default_params() {
let new_tab_action = CliAction::NewTab {
name: None,
layout: None,
layout_string: None,
layout_dir: None,
cwd: None,
initial_command: vec![],
@@ -3627,6 +3635,7 @@ pub fn send_cli_new_tab_action_with_name_and_layout() {
"{}/src/unit/fixtures/layout-with-three-panes.kdl",
env!("CARGO_MANIFEST_DIR")
))),
layout_string: None,
layout_dir: None,
cwd: None,
initial_command: vec![],
@@ -3959,6 +3968,7 @@ pub fn send_cli_launch_or_focus_plugin_action() {
url: "file:/path/to/fake/plugin".to_owned(),
configuration: Default::default(),
skip_plugin_cache: false,
tab_id: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -4021,6 +4031,7 @@ pub fn send_cli_launch_or_focus_plugin_action_when_plugin_is_already_loaded() {
url: "file:/path/to/fake/plugin".to_owned(),
configuration: Default::default(),
skip_plugin_cache: false,
tab_id: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -4105,6 +4116,7 @@ pub fn send_cli_launch_or_focus_plugin_action_when_plugin_is_already_loaded_for_
url: "fixture_plugin_for_tests".to_owned(),
configuration: Default::default(),
skip_plugin_cache: false,
tab_id: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -5097,6 +5109,7 @@ pub fn send_cli_new_pane_in_place_with_close_replaced_pane() {
unblock_condition: None,
near_current_pane: false,
borderless: None,
tab_id: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -5147,6 +5160,7 @@ pub fn send_cli_edit_in_place_with_close_replaced_pane() {
pinned: None,
near_current_pane: false,
borderless: None,
tab_id: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -5192,6 +5206,7 @@ pub fn send_cli_launch_or_focus_plugin_in_place_with_close_replaced_pane() {
url: "file:/path/to/fake/plugin".to_owned(),
configuration: Default::default(),
skip_plugin_cache: false,
tab_id: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -7663,3 +7678,402 @@ pub fn inactive_tab_plugins_get_fresh_state_on_activation() {
active_tab.position
);
}
#[test]
pub fn send_cli_new_tab_action_with_layout_string() {
let size = Size { cols: 80, rows: 10 };
let client_id = 10;
let mut initial_layout = TiledPaneLayout::default();
initial_layout.children_split_direction = SplitDirection::Vertical;
initial_layout.children = vec![TiledPaneLayout::default(), TiledPaneLayout::default()];
let mut mock_screen = MockScreen::new(size);
let session_metadata = mock_screen.clone_session_metadata();
let screen_thread = mock_screen.run(Some(initial_layout), vec![]);
let received_plugin_instructions = Arc::new(Mutex::new(vec![]));
let plugin_receiver = mock_screen.plugin_receiver.take().unwrap();
let plugin_thread = log_actions_in_thread!(
received_plugin_instructions,
PluginInstruction::Exit,
plugin_receiver
);
// Same layout as layout-with-three-panes.kdl but passed as a string
let new_tab_action = CliAction::NewTab {
name: None,
layout: None,
layout_string: Some("layout {\n pane\n pane\n pane\n}\n".into()),
layout_dir: None,
cwd: None,
initial_command: vec![],
initial_plugin: None,
close_on_exit: Default::default(),
start_suspended: Default::default(),
block_until_exit: false,
block_until_exit_success: false,
block_until_exit_failure: false,
};
send_cli_action_to_server(&session_metadata, new_tab_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![plugin_thread, screen_thread]);
let new_tab_instruction = received_plugin_instructions
.lock()
.unwrap()
.iter()
.rev()
.find(|i| {
if let PluginInstruction::NewTab(..) = i {
return true;
} else {
return false;
}
})
.unwrap()
.clone();
let output = format!("{:#?}", new_tab_instruction);
// Normalize Windows path separators for cross-platform snapshot consistency
let output = output.replace("\\\\", "/");
assert_snapshot!(output);
}
#[test]
pub fn send_cli_new_tab_action_with_layout_string_and_name() {
let size = Size { cols: 80, rows: 10 };
let client_id = 10;
let mut initial_layout = TiledPaneLayout::default();
initial_layout.children_split_direction = SplitDirection::Vertical;
initial_layout.children = vec![TiledPaneLayout::default(), TiledPaneLayout::default()];
let mut mock_screen = MockScreen::new(size);
let session_metadata = mock_screen.clone_session_metadata();
let screen_thread = mock_screen.run(Some(initial_layout), vec![]);
let received_plugin_instructions = Arc::new(Mutex::new(vec![]));
let plugin_receiver = mock_screen.plugin_receiver.take().unwrap();
let plugin_thread = log_actions_in_thread!(
received_plugin_instructions,
PluginInstruction::Exit,
plugin_receiver
);
let new_tab_action = CliAction::NewTab {
name: Some("my-string-layout-tab".into()),
layout: None,
layout_string: Some("layout {\n pane\n pane\n pane\n}\n".into()),
layout_dir: None,
cwd: None,
initial_command: vec![],
initial_plugin: None,
close_on_exit: Default::default(),
start_suspended: Default::default(),
block_until_exit: false,
block_until_exit_success: false,
block_until_exit_failure: false,
};
send_cli_action_to_server(&session_metadata, new_tab_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![plugin_thread, screen_thread]);
let new_tab_instruction = received_plugin_instructions
.lock()
.unwrap()
.iter()
.rev()
.find(|i| {
if let PluginInstruction::NewTab(..) = i {
return true;
} else {
return false;
}
})
.unwrap()
.clone();
let output = format!("{:#?}", new_tab_instruction);
// Normalize Windows path separators for cross-platform snapshot consistency
let output = output.replace("\\\\", "/");
assert_snapshot!(output);
}
#[test]
pub fn send_cli_new_pane_action_with_tab_id() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 10;
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![],
plugin: None,
cwd: None,
floating: false,
in_place: false,
close_replaced_pane: false,
name: None,
close_on_exit: false,
start_suspended: false,
configuration: None,
skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
pinned: None,
stacked: false,
blocking: false,
block_until_exit_success: false,
block_until_exit_failure: false,
block_until_exit: false,
unblock_condition: None,
near_current_pane: false,
borderless: Some(false),
tab_id: Some(0),
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![pty_thread, screen_thread]);
let pty_instructions = received_pty_instructions.lock().unwrap();
// Verify that the PTY instruction uses TabIndex(0) instead of ClientId
let pty_debug = format!("{:?}", *pty_instructions);
assert!(
pty_debug.contains("TabIndex(0)"),
"Expected TabIndex(0) in PTY instructions, got: {}",
pty_debug
);
}
#[test]
pub fn send_cli_new_floating_pane_action_with_tab_id() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 10;
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: None,
command: vec![],
plugin: None,
cwd: None,
floating: true,
in_place: false,
close_replaced_pane: false,
name: None,
close_on_exit: false,
start_suspended: false,
configuration: None,
skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
pinned: None,
stacked: false,
blocking: false,
block_until_exit_success: false,
block_until_exit_failure: false,
block_until_exit: false,
unblock_condition: None,
near_current_pane: false,
borderless: None,
tab_id: Some(0),
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![pty_thread, screen_thread]);
let pty_instructions = received_pty_instructions.lock().unwrap();
let pty_debug = format!("{:?}", *pty_instructions);
assert!(
pty_debug.contains("TabIndex(0)"),
"Expected TabIndex(0) in PTY instructions for floating pane, got: {}",
pty_debug
);
}
#[test]
pub fn send_cli_edit_action_with_tab_id() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 10;
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_edit_action = CliAction::Edit {
file: PathBuf::from("/tmp/test.rs"),
direction: None,
line_number: None,
floating: false,
in_place: false,
close_replaced_pane: false,
cwd: None,
x: None,
y: None,
width: None,
height: None,
pinned: None,
near_current_pane: false,
borderless: None,
tab_id: Some(0),
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![pty_thread, screen_thread]);
let pty_instructions = received_pty_instructions.lock().unwrap();
let pty_debug = format!("{:?}", *pty_instructions);
assert!(
pty_debug.contains("TabIndex(0)"),
"Expected TabIndex(0) in PTY instructions for edit, got: {}",
pty_debug
);
}
#[test]
pub fn send_cli_new_pane_action_with_tab_id_and_direction() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 10;
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![],
plugin: None,
cwd: None,
floating: false,
in_place: false,
close_replaced_pane: false,
name: None,
close_on_exit: false,
start_suspended: false,
configuration: None,
skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
pinned: None,
stacked: false,
blocking: false,
block_until_exit_success: false,
block_until_exit_failure: false,
block_until_exit: false,
unblock_condition: None,
near_current_pane: false,
borderless: Some(false),
tab_id: Some(0),
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![pty_thread, screen_thread]);
let pty_instructions = received_pty_instructions.lock().unwrap();
let pty_debug = format!("{:?}", *pty_instructions);
assert!(
pty_debug.contains("TabIndex(0)"),
"Expected TabIndex(0) in PTY instructions with direction, got: {}",
pty_debug
);
}
#[test]
pub fn send_cli_new_pane_action_with_tab_id_and_stacked() {
let size = Size {
cols: 121,
rows: 20,
};
let client_id = 10;
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: None,
command: vec!["ls".into()],
plugin: None,
cwd: None,
floating: false,
in_place: false,
close_replaced_pane: false,
name: None,
close_on_exit: false,
start_suspended: false,
configuration: None,
skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
pinned: None,
stacked: true,
blocking: false,
block_until_exit_success: false,
block_until_exit_failure: false,
block_until_exit: false,
unblock_condition: None,
near_current_pane: false,
borderless: None,
tab_id: Some(0),
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![pty_thread, screen_thread]);
let pty_instructions = received_pty_instructions.lock().unwrap();
let pty_debug = format!("{:?}", *pty_instructions);
assert!(
pty_debug.contains("TabIndex(0)"),
"Expected TabIndex(0) in PTY instructions with stacked, got: {}",
pty_debug
);
}
@@ -0,0 +1,119 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:#?}\", new_tab_instruction)"
---
NewTab(
None,
None,
Some(
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [],
split_size: None,
run: Some(
Cwd(
"./.",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [],
split_size: None,
run: Some(
Cwd(
"./.",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [],
split_size: None,
run: Some(
Cwd(
"./.",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
],
split_size: None,
run: Some(
Cwd(
".",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
),
[],
1,
None,
false,
true,
(
10,
false,
),
Some(
NotificationEnd {
channel: None,
exit_status: None,
unblock_condition: None,
affected_pane_id: None,
affected_tab_id: None,
error_message: None,
stdout_message: None,
},
),
)
@@ -0,0 +1,119 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:#?}\", new_tab_instruction)"
---
NewTab(
None,
None,
Some(
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [],
split_size: None,
run: Some(
Cwd(
"./.",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [],
split_size: None,
run: Some(
Cwd(
"./.",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
TiledPaneLayout {
children_split_direction: Horizontal,
name: None,
children: [],
split_size: None,
run: Some(
Cwd(
"./.",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
],
split_size: None,
run: Some(
Cwd(
".",
),
),
borderless: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
is_expanded_in_stack: false,
exclude_from_sync: None,
run_instructions_to_ignore: [],
hide_floating_panes: false,
pane_initial_contents: None,
default_fg: None,
default_bg: None,
},
),
[],
1,
None,
false,
true,
(
10,
false,
),
Some(
NotificationEnd {
channel: None,
exit_status: None,
unblock_condition: None,
affected_pane_id: None,
affected_tab_id: None,
error_message: None,
stdout_message: None,
},
),
)
@@ -808,6 +808,8 @@ pub struct EditFileAction {
pub near_current_pane: bool,
#[prost(bool, tag="8")]
pub close_replaced_pane: bool,
#[prost(uint32, optional, tag="9")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -820,6 +822,8 @@ pub struct NewFloatingPaneAction {
pub coordinates: ::core::option::Option<FloatingPaneCoordinates>,
#[prost(bool, tag="7")]
pub near_current_pane: bool,
#[prost(uint32, optional, tag="8")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -834,6 +838,8 @@ pub struct NewTiledPaneAction {
pub near_current_pane: bool,
#[prost(bool, optional, tag="8")]
pub borderless: ::core::option::Option<bool>,
#[prost(uint32, optional, tag="9")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -848,6 +854,8 @@ pub struct NewInPlacePaneAction {
pub pane_id_to_replace: ::core::option::Option<PaneId>,
#[prost(bool, tag="5")]
pub close_replaced_pane: bool,
#[prost(uint32, optional, tag="6")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -858,6 +866,8 @@ pub struct NewStackedPaneAction {
pub pane_name: ::core::option::Option<::prost::alloc::string::String>,
#[prost(bool, tag="3")]
pub near_current_pane: bool,
#[prost(uint32, optional, tag="4")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -872,6 +882,8 @@ pub struct NewBlockingPaneAction {
pub unblock_condition: ::core::option::Option<i32>,
#[prost(bool, tag="5")]
pub near_current_pane: bool,
#[prost(uint32, optional, tag="6")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -950,6 +962,8 @@ pub struct LaunchOrFocusPluginAction {
pub skip_cache: bool,
#[prost(bool, tag="6")]
pub close_replaced_pane: bool,
#[prost(uint32, optional, tag="7")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -966,6 +980,8 @@ pub struct LaunchPluginAction {
pub cwd: ::core::option::Option<::prost::alloc::string::String>,
#[prost(bool, tag="6")]
pub close_replaced_pane: bool,
#[prost(uint32, optional, tag="7")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1008,6 +1024,8 @@ pub struct NewTiledPluginPaneAction {
pub skip_cache: bool,
#[prost(string, optional, tag="4")]
pub cwd: ::core::option::Option<::prost::alloc::string::String>,
#[prost(uint32, optional, tag="5")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1022,6 +1040,8 @@ pub struct NewFloatingPluginPaneAction {
pub cwd: ::core::option::Option<::prost::alloc::string::String>,
#[prost(message, optional, tag="5")]
pub coordinates: ::core::option::Option<FloatingPaneCoordinates>,
#[prost(uint32, optional, tag="6")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1034,6 +1054,8 @@ pub struct NewInPlacePluginPaneAction {
pub skip_cache: bool,
#[prost(bool, tag="4")]
pub close_replaced_pane: bool,
#[prost(uint32, optional, tag="5")]
pub tab_id: ::core::option::Option<u32>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
+66 -4
View File
@@ -59,6 +59,12 @@ pub struct CliArgs {
#[clap(short, long, value_parser, overrides_with = "layout")]
pub layout: Option<PathBuf>,
/// Raw KDL layout string to use directly (instead of a file path)
/// if inside a session (or using the --session flag) will be added to the session as a new tab
/// or tabs, otherwise will start a new session
#[clap(long, value_parser, conflicts_with_all = &["layout", "new-session-with-layout"])]
pub layout_string: Option<String>,
/// Name of a predefined layout inside the layout directory or the path to a layout file
/// Will always start a new session, even if inside an existing session
#[clap(short, long, value_parser, overrides_with = "new_session_with_layout")]
@@ -515,6 +521,14 @@ pub enum Sessions {
/// mouse)
#[clap(short, long, value_parser)]
borderless: Option<bool>,
/// Target a specific tab by ID
#[clap(
long,
value_parser,
conflicts_with("near-current-pane"),
conflicts_with("in-place")
)]
tab_id: Option<usize>,
},
/// Load a plugin
/// Returns: Created pane ID (format: plugin_<id>)
@@ -575,6 +589,9 @@ pub enum Sessions {
/// mouse)
#[clap(short, long, value_parser)]
borderless: Option<bool>,
/// Target a specific tab by ID
#[clap(long, value_parser, conflicts_with("in-place"))]
tab_id: Option<usize>,
},
/// Edit file with default $EDITOR / $VISUAL
/// Returns: Created pane ID (format: terminal_<id>)
@@ -641,6 +658,14 @@ pub enum Sessions {
/// mouse)
#[clap(short, long, value_parser)]
borderless: Option<bool>,
/// Target a specific tab by ID
#[clap(
long,
value_parser,
conflicts_with("near-current-pane"),
conflicts_with("in-place")
)]
tab_id: Option<usize>,
},
ConvertConfig {
old_config_file: PathBuf,
@@ -1010,6 +1035,14 @@ pub enum CliAction {
/// mouse)
#[clap(long, value_parser)]
borderless: Option<bool>,
/// Target a specific tab by ID
#[clap(
long,
value_parser,
conflicts_with("near-current-pane"),
conflicts_with("in-place")
)]
tab_id: Option<usize>,
},
/// Open the specified file in a new zellij pane with your default EDITOR
/// Returns: Created pane ID (format: terminal_<id>)
@@ -1075,6 +1108,14 @@ pub enum CliAction {
/// mouse)
#[clap(short, long, value_parser)]
borderless: Option<bool>,
/// Target a specific tab by ID
#[clap(
long,
value_parser,
conflicts_with("near-current-pane"),
conflicts_with("in-place")
)]
tab_id: Option<usize>,
},
/// Switch input mode of all connected clients [locked|pane|tab|resize|move|search|session]
SwitchMode {
@@ -1187,9 +1228,13 @@ pub enum CliAction {
/// Returns: The created tab's ID as a single number on stdout
NewTab {
/// Layout to use for the new tab
#[clap(short, long, value_parser)]
#[clap(short, long, value_parser, conflicts_with = "layout-string")]
layout: Option<PathBuf>,
/// Raw KDL layout string to use directly (instead of a layout file path)
#[clap(long, value_parser, conflicts_with = "layout")]
layout_string: Option<String>,
/// Default folder to look for layouts
#[clap(long, value_parser, requires("layout"))]
layout_dir: Option<PathBuf>,
@@ -1292,8 +1337,16 @@ pub enum CliAction {
/// Override the layout of the active tab
OverrideLayout {
/// Path to the layout file
#[clap(value_parser)]
layout: PathBuf,
#[clap(
value_parser,
required_unless_present = "layout-string",
conflicts_with = "layout-string"
)]
layout: Option<PathBuf>,
/// Raw KDL layout string to use directly (instead of a layout file path)
#[clap(long, value_parser, conflicts_with = "layout")]
layout_string: Option<String>,
/// Default folder to look for layouts
#[clap(long, value_parser)]
@@ -1341,6 +1394,9 @@ pub enum CliAction {
configuration: Option<PluginUserConfiguration>,
#[clap(short, long, value_parser)]
skip_plugin_cache: bool,
/// Target a specific tab by ID
#[clap(long, value_parser, conflicts_with("in-place"))]
tab_id: Option<usize>,
},
/// Returns: Plugin pane ID (format: plugin_<id>)
LaunchPlugin {
@@ -1362,6 +1418,9 @@ pub enum CliAction {
configuration: Option<PluginUserConfiguration>,
#[clap(short, long, value_parser)]
skip_plugin_cache: bool,
/// Target a specific tab by ID
#[clap(long, value_parser, conflicts_with("in-place"))]
tab_id: Option<usize>,
},
RenameSession {
name: String,
@@ -1573,8 +1632,11 @@ tail -f /tmp/my-live-logfile | zellij action pipe --name logs --plugin https://e
#[clap(long)]
pane_id: Option<String>,
/// Layout to apply when switching to the session (relative paths start at layout-dir)
#[clap(short, long, value_parser)]
#[clap(short, long, value_parser, conflicts_with = "layout-string")]
layout: Option<PathBuf>,
/// Raw KDL layout string to use directly
#[clap(long, value_parser, conflicts_with = "layout")]
layout_string: Option<String>,
/// Default folder to look for layouts
#[clap(long, value_parser, requires("layout"))]
layout_dir: Option<PathBuf>,
@@ -454,6 +454,7 @@ message EditFileAction {
optional FloatingPaneCoordinates coordinates = 6;
bool near_current_pane = 7;
bool close_replaced_pane = 8;
optional uint32 tab_id = 9;
}
message NewFloatingPaneAction {
@@ -461,6 +462,7 @@ message NewFloatingPaneAction {
optional string pane_name = 2;
optional FloatingPaneCoordinates coordinates = 3;
bool near_current_pane = 7;
optional uint32 tab_id = 8;
}
message NewTiledPaneAction {
@@ -469,6 +471,7 @@ message NewTiledPaneAction {
optional string pane_name = 3;
bool near_current_pane = 7;
optional bool borderless = 8;
optional uint32 tab_id = 9;
}
message NewInPlacePaneAction {
@@ -477,12 +480,14 @@ message NewInPlacePaneAction {
bool near_current_pane = 3;
optional PaneId pane_id_to_replace = 4;
bool close_replaced_pane = 5;
optional uint32 tab_id = 6;
}
message NewStackedPaneAction {
optional RunCommandAction command = 1;
optional string pane_name = 2;
bool near_current_pane = 3;
optional uint32 tab_id = 4;
}
message NewBlockingPaneAction {
@@ -491,6 +496,7 @@ message NewBlockingPaneAction {
optional RunCommandAction command = 3;
optional UnblockCondition unblock_condition = 4;
bool near_current_pane = 5;
optional uint32 tab_id = 6;
}
message PaneNameInputAction {
@@ -538,6 +544,7 @@ message LaunchOrFocusPluginAction {
bool should_open_in_place = 4;
bool skip_cache = 5;
bool close_replaced_pane = 6;
optional uint32 tab_id = 7;
}
message LaunchPluginAction {
@@ -547,6 +554,7 @@ message LaunchPluginAction {
bool skip_cache = 4;
optional string cwd = 5;
bool close_replaced_pane = 6;
optional uint32 tab_id = 7;
}
message MouseEventAction {
@@ -574,6 +582,7 @@ message NewTiledPluginPaneAction {
optional string pane_name = 2;
bool skip_cache = 3;
optional string cwd = 4;
optional uint32 tab_id = 5;
}
message NewFloatingPluginPaneAction {
@@ -582,6 +591,7 @@ message NewFloatingPluginPaneAction {
bool skip_cache = 3;
optional string cwd = 4;
optional FloatingPaneCoordinates coordinates = 5;
optional uint32 tab_id = 6;
}
message NewInPlacePluginPaneAction {
@@ -589,6 +599,7 @@ message NewInPlacePluginPaneAction {
optional string pane_name = 2;
bool skip_cache = 3;
bool close_replaced_pane = 4;
optional uint32 tab_id = 5;
}
message StartOrReloadPluginAction {
File diff suppressed because it is too large Load Diff
@@ -1095,6 +1095,8 @@ impl From<crate::input::actions::Action>
start_suppressed,
coordinates,
near_current_pane,
tab_id,
..
} => ActionType::EditFile(EditFileAction {
payload: Some(payload.into()),
direction: direction.map(|d| direction_to_proto_i32(d)),
@@ -1104,17 +1106,21 @@ impl From<crate::input::actions::Action>
start_suppressed,
coordinates: coordinates.map(|c| c.into()),
near_current_pane,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewFloatingPane {
command,
pane_name,
coordinates,
near_current_pane,
tab_id,
..
} => ActionType::NewFloatingPane(NewFloatingPaneAction {
command: command.map(|c| c.into()),
pane_name,
coordinates: coordinates.map(|c| c.into()),
near_current_pane,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewTiledPane {
direction,
@@ -1122,12 +1128,15 @@ impl From<crate::input::actions::Action>
pane_name,
near_current_pane,
borderless,
tab_id,
..
} => ActionType::NewTiledPane(NewTiledPaneAction {
direction: direction.map(|d| direction_to_proto_i32(d)),
command: command.map(|c| c.into()),
pane_name,
near_current_pane,
borderless,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewInPlacePane {
command,
@@ -1135,21 +1144,27 @@ impl From<crate::input::actions::Action>
near_current_pane,
pane_id_to_replace,
close_replaced_pane,
tab_id,
..
} => ActionType::NewInPlacePane(NewInPlacePaneAction {
command: command.map(|c| c.into()),
pane_name,
near_current_pane,
pane_id_to_replace: pane_id_to_replace.and_then(|p| p.try_into().ok()),
close_replaced_pane,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewStackedPane {
command,
pane_name,
near_current_pane,
tab_id,
..
} => ActionType::NewStackedPane(NewStackedPaneAction {
command: command.map(|c| c.into()),
pane_name,
near_current_pane,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewBlockingPane {
placement,
@@ -1157,12 +1172,15 @@ impl From<crate::input::actions::Action>
command,
unblock_condition,
near_current_pane,
tab_id,
..
} => ActionType::NewBlockingPane(NewBlockingPaneAction {
placement: Some(placement.into()),
pane_name,
command: command.map(|c| c.into()),
unblock_condition: unblock_condition.map(|c| unblock_condition_to_proto_i32(c)),
near_current_pane,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::TogglePaneEmbedOrFloating => {
ActionType::TogglePaneEmbedOrFloating(TogglePaneEmbedOrFloatingAction {})
@@ -1283,6 +1301,8 @@ impl From<crate::input::actions::Action>
should_open_in_place,
close_replaced_pane,
skip_cache,
tab_id,
..
} => ActionType::LaunchOrFocusPlugin(LaunchOrFocusPluginAction {
plugin: Some(plugin.into()),
should_float,
@@ -1290,6 +1310,7 @@ impl From<crate::input::actions::Action>
should_open_in_place,
close_replaced_pane,
skip_cache,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::LaunchPlugin {
plugin,
@@ -1298,6 +1319,8 @@ impl From<crate::input::actions::Action>
close_replaced_pane,
skip_cache,
cwd,
tab_id,
..
} => ActionType::LaunchPlugin(LaunchPluginAction {
plugin: Some(plugin.into()),
should_float,
@@ -1305,6 +1328,7 @@ impl From<crate::input::actions::Action>
close_replaced_pane,
skip_cache,
cwd: cwd.map(|p| p.to_string_lossy().to_string()),
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::MouseEvent { event } => {
ActionType::MouseEvent(MouseEventAction {
@@ -1362,11 +1386,14 @@ impl From<crate::input::actions::Action>
pane_name,
skip_cache,
cwd,
tab_id,
..
} => ActionType::NewTiledPluginPane(NewTiledPluginPaneAction {
plugin: Some(plugin.into()),
pane_name,
skip_cache,
cwd: cwd.map(|p| p.to_string_lossy().to_string()),
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewFloatingPluginPane {
plugin,
@@ -1374,23 +1401,29 @@ impl From<crate::input::actions::Action>
skip_cache,
cwd,
coordinates,
tab_id,
..
} => ActionType::NewFloatingPluginPane(NewFloatingPluginPaneAction {
plugin: Some(plugin.into()),
pane_name,
skip_cache,
cwd: cwd.map(|p| p.to_string_lossy().to_string()),
coordinates: coordinates.map(|c| c.into()),
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::NewInPlacePluginPane {
plugin,
pane_name,
skip_cache,
close_replaced_pane,
tab_id,
..
} => ActionType::NewInPlacePluginPane(NewInPlacePluginPaneAction {
plugin: Some(plugin.into()),
pane_name,
skip_cache,
close_replaced_pane,
tab_id: tab_id.map(|t| t as u32),
}),
crate::input::actions::Action::StartOrReloadPlugin { plugin } => {
ActionType::StartOrReloadPlugin(StartOrReloadPluginAction {
@@ -1916,6 +1949,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
.map(|c| c.try_into())
.transpose()?,
near_current_pane: edit_file_action.near_current_pane,
tab_id: edit_file_action.tab_id.map(|t| t as usize),
}),
ActionType::NewFloatingPane(new_floating_action) => {
Ok(crate::input::actions::Action::NewFloatingPane {
@@ -1929,6 +1963,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
.map(|c| c.try_into())
.transpose()?,
near_current_pane: new_floating_action.near_current_pane,
tab_id: new_floating_action.tab_id.map(|t| t as usize),
})
},
ActionType::NewTiledPane(new_tiled_action) => {
@@ -1941,6 +1976,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
pane_name: new_tiled_action.pane_name,
near_current_pane: new_tiled_action.near_current_pane,
borderless: new_tiled_action.borderless,
tab_id: new_tiled_action.tab_id.map(|t| t as usize),
})
},
ActionType::NewInPlacePane(new_in_place_action) => {
@@ -1955,6 +1991,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
.pane_id_to_replace
.and_then(|p| p.try_into().ok()),
close_replaced_pane: new_in_place_action.close_replaced_pane,
tab_id: new_in_place_action.tab_id.map(|t| t as usize),
})
},
ActionType::NewStackedPane(new_stacked_action) => {
@@ -1965,6 +2002,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
.transpose()?,
pane_name: new_stacked_action.pane_name,
near_current_pane: new_stacked_action.near_current_pane,
tab_id: new_stacked_action.tab_id.map(|t| t as usize),
})
},
ActionType::NewBlockingPane(new_blocking_action) => {
@@ -1983,6 +2021,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
.map(|c| proto_i32_to_unblock_condition(c))
.transpose()?,
near_current_pane: new_blocking_action.near_current_pane,
tab_id: new_blocking_action.tab_id.map(|t| t as usize),
})
},
ActionType::TogglePaneEmbedOrFloating(_) => {
@@ -2126,6 +2165,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
should_open_in_place: launch_plugin_action.should_open_in_place,
close_replaced_pane: launch_plugin_action.close_replaced_pane,
skip_cache: launch_plugin_action.skip_cache,
tab_id: launch_plugin_action.tab_id.map(|t| t as usize),
})
},
ActionType::LaunchPlugin(launch_plugin_action) => {
@@ -2139,6 +2179,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
close_replaced_pane: launch_plugin_action.close_replaced_pane,
skip_cache: launch_plugin_action.skip_cache,
cwd: launch_plugin_action.cwd.map(PathBuf::from),
tab_id: launch_plugin_action.tab_id.map(|t| t as usize),
})
},
ActionType::MouseEvent(mouse_event_action) => {
@@ -2210,6 +2251,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
pane_name: new_tiled_plugin_action.pane_name,
skip_cache: new_tiled_plugin_action.skip_cache,
cwd: new_tiled_plugin_action.cwd.map(PathBuf::from),
tab_id: new_tiled_plugin_action.tab_id.map(|t| t as usize),
})
},
ActionType::NewFloatingPluginPane(new_floating_plugin_action) => {
@@ -2225,6 +2267,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
.coordinates
.map(|c| c.try_into())
.transpose()?,
tab_id: new_floating_plugin_action.tab_id.map(|t| t as usize),
})
},
ActionType::NewInPlacePluginPane(new_in_place_plugin_action) => {
@@ -2236,6 +2279,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action>
pane_name: new_in_place_plugin_action.pane_name,
skip_cache: new_in_place_plugin_action.skip_cache,
close_replaced_pane: new_in_place_plugin_action.close_replaced_pane,
tab_id: new_in_place_plugin_action.tab_id.map(|t| t as usize),
})
},
ActionType::StartOrReloadPlugin(start_plugin_action) => {
+179 -2
View File
@@ -1,8 +1,8 @@
use super::test_framework::*;
use crate::data::{
BareKey, CommandOrPlugin, ConnectToSession, Direction, FloatingPaneCoordinates, InputMode,
KeyModifier, KeyWithModifier, LayoutInfo, LayoutMetadata, OriginatingPlugin, PaneId, PluginTag,
Resize, WebSharing,
KeyModifier, KeyWithModifier, LayoutInfo, LayoutMetadata, NewPanePlacement, OriginatingPlugin,
PaneId, PluginTag, Resize, WebSharing,
};
use crate::input::actions::{Action, SearchDirection, SearchOption};
use crate::input::cli_assets::CliAssets;
@@ -1054,6 +1054,7 @@ fn test_client_messages() {
start_suppressed: false,
coordinates: None,
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1078,6 +1079,7 @@ fn test_client_messages() {
start_suppressed: false,
coordinates: None,
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1102,6 +1104,7 @@ fn test_client_messages() {
start_suppressed: false,
coordinates: None,
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1126,6 +1129,7 @@ fn test_client_messages() {
start_suppressed: true,
coordinates: FloatingPaneCoordinates::new(None, None, None, None, None, Some(false)),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1157,6 +1161,7 @@ fn test_client_messages() {
Some(false),
),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1188,6 +1193,7 @@ fn test_client_messages() {
Some(false),
),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1219,6 +1225,7 @@ fn test_client_messages() {
Some(false),
),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1250,6 +1257,7 @@ fn test_client_messages() {
Some(false)
),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1261,6 +1269,7 @@ fn test_client_messages() {
pane_name: None,
coordinates: None,
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1288,6 +1297,7 @@ fn test_client_messages() {
Some(false),
),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1319,6 +1329,7 @@ fn test_client_messages() {
Some(false),
),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1331,6 +1342,7 @@ fn test_client_messages() {
pane_name: None,
near_current_pane: false,
borderless: None,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1356,6 +1368,7 @@ fn test_client_messages() {
pane_name: Some("my_pane_name".to_owned()),
near_current_pane: false,
borderless: Some(true),
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1381,6 +1394,7 @@ fn test_client_messages() {
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1393,6 +1407,7 @@ fn test_client_messages() {
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1416,6 +1431,7 @@ fn test_client_messages() {
}),
pane_name: Some("my_pane_name".to_owned()),
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -1426,6 +1442,7 @@ fn test_client_messages() {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2230,6 +2247,7 @@ fn test_client_messages() {
should_open_in_place: true,
close_replaced_pane: false,
skip_cache: true,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2244,6 +2262,7 @@ fn test_client_messages() {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2258,6 +2277,7 @@ fn test_client_messages() {
close_replaced_pane: false,
skip_cache: true,
cwd: None,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2272,6 +2292,7 @@ fn test_client_messages() {
close_replaced_pane: false,
skip_cache: false,
cwd: Some(PathBuf::from("/path/to/cwd")),
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2438,6 +2459,7 @@ fn test_client_messages() {
pane_name: Some("my_pane_name".to_owned()),
skip_cache: false,
cwd: Some(PathBuf::from("relative/path/to/cwd")),
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2450,6 +2472,7 @@ fn test_client_messages() {
skip_cache: true,
cwd: Some(PathBuf::from("relative/path/to/cwd")),
coordinates: None,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2469,6 +2492,7 @@ fn test_client_messages() {
Some(true),
Some(false),
),
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
@@ -2480,6 +2504,159 @@ fn test_client_messages() {
pane_name: Some("my_pane_name".to_owned()),
skip_cache: true,
close_replaced_pane: false,
tab_id: None,
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
// tab_id roundtrip tests - verify tab_id survives serialization
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewTiledPane {
direction: Some(Direction::Right),
command: None,
pane_name: None,
near_current_pane: false,
borderless: None,
tab_id: Some(3),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewFloatingPane {
command: None,
pane_name: None,
coordinates: None,
near_current_pane: false,
tab_id: Some(5),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewStackedPane {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: Some(2),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewBlockingPane {
placement: NewPanePlacement::Tiled {
direction: None,
borderless: None
},
pane_name: None,
command: None,
unblock_condition: None,
near_current_pane: false,
tab_id: Some(1),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::EditFile {
payload: OpenFilePayload {
path: PathBuf::from("/file/path"),
line_number: None,
cwd: None,
originating_plugin: None,
},
direction: None,
floating: false,
in_place: false,
close_replaced_pane: false,
start_suppressed: false,
coordinates: None,
near_current_pane: false,
tab_id: Some(4),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewInPlacePane {
command: None,
pane_name: None,
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane: false,
tab_id: Some(7),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::LaunchOrFocusPlugin {
plugin: RunPluginOrAlias::RunPlugin(RunPlugin::default()),
should_float: true,
move_to_focused_tab: false,
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: Some(2),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::LaunchPlugin {
plugin: RunPluginOrAlias::RunPlugin(RunPlugin::default()),
should_float: false,
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
cwd: None,
tab_id: Some(6),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewTiledPluginPane {
plugin: RunPluginOrAlias::RunPlugin(RunPlugin::default()),
pane_name: None,
skip_cache: false,
cwd: None,
tab_id: Some(1),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewFloatingPluginPane {
plugin: RunPluginOrAlias::RunPlugin(RunPlugin::default()),
pane_name: None,
skip_cache: false,
cwd: None,
coordinates: None,
tab_id: Some(3),
},
terminal_id: Some(1),
client_id: Some(100),
is_cli_client: true,
});
test_client_roundtrip!(ClientToServerMsg::Action {
action: Action::NewInPlacePluginPane {
plugin: RunPluginOrAlias::RunPlugin(RunPlugin::default()),
pane_name: None,
skip_cache: false,
close_replaced_pane: false,
tab_id: Some(2),
},
terminal_id: Some(1),
client_id: Some(100),
+14 -1
View File
@@ -558,6 +558,7 @@ impl Action {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
});
} else {
let direction = Direction::from_str(string.as_str()).map_err(|_| {
@@ -840,6 +841,7 @@ impl Action {
pane_name: name,
near_current_pane: false,
borderless: _,
..
} => {
let mut node = KdlNode::new("Run");
let mut node_children = KdlDocument::new();
@@ -890,6 +892,7 @@ impl Action {
pane_name: name,
coordinates: floating_pane_coordinates,
near_current_pane: false,
..
} => {
let mut node = KdlNode::new("Run");
let mut node_children = KdlDocument::new();
@@ -983,6 +986,7 @@ impl Action {
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane,
..
} => {
let mut node = KdlNode::new("Run");
let mut node_children = KdlDocument::new();
@@ -1029,6 +1033,7 @@ impl Action {
command: run_command_action,
pane_name: name,
near_current_pane: _,
..
} => match run_command_action {
Some(run_command_action) => {
let mut node = KdlNode::new("Run");
@@ -1108,6 +1113,7 @@ impl Action {
should_open_in_place,
close_replaced_pane,
skip_cache: skip_plugin_cache,
..
} => {
let mut node = KdlNode::new("LaunchOrFocusPlugin");
let mut node_children = KdlDocument::new();
@@ -1157,6 +1163,7 @@ impl Action {
close_replaced_pane,
skip_cache: skip_plugin_cache,
cwd,
..
} => {
let mut node = KdlNode::new("LaunchPlugin");
let mut node_children = KdlDocument::new();
@@ -1993,6 +2000,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
x, y, width, height, pinned, borderless,
),
near_current_pane: false,
tab_id: None,
})
} else if in_place {
Ok(Action::NewInPlacePane {
@@ -2001,12 +2009,14 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
near_current_pane: false,
pane_id_to_replace: None,
close_replaced_pane,
tab_id: None,
})
} else if stacked {
Ok(Action::NewStackedPane {
command: Some(run_command_action),
pane_name: name,
near_current_pane: false,
tab_id: None,
})
} else {
Ok(Action::NewTiledPane {
@@ -2015,6 +2025,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
pane_name: name,
near_current_pane: false,
borderless: None,
tab_id: None,
})
}
},
@@ -2071,6 +2082,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
should_open_in_place,
close_replaced_pane,
skip_cache: skip_plugin_cache,
tab_id: None,
})
},
"LaunchPlugin" => {
@@ -2120,7 +2132,8 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
close_replaced_pane,
skip_cache: skip_plugin_cache,
cwd: None, // we explicitly do not send the current dir here so that it will be
// filled from the active pane == better UX
// filled from the active pane == better UX
tab_id: None,
})
},
"PreviousSwapLayout" => Ok(Action::PreviousSwapLayout),
+24
View File
@@ -338,6 +338,7 @@ impl TryFrom<ProtobufAction> for Action {
start_suppressed: false,
coordinates: None,
near_current_pane,
tab_id: None,
})
},
_ => Err("Wrong payload for Action::NewPane"),
@@ -353,6 +354,7 @@ impl TryFrom<ProtobufAction> for Action {
pane_name,
coordinates: None,
near_current_pane,
tab_id: None,
})
} else {
Ok(Action::NewFloatingPane {
@@ -360,6 +362,7 @@ impl TryFrom<ProtobufAction> for Action {
pane_name: None,
coordinates: None,
near_current_pane,
tab_id: None,
})
}
},
@@ -382,6 +385,7 @@ impl TryFrom<ProtobufAction> for Action {
pane_name,
near_current_pane,
borderless,
tab_id: None,
})
} else {
Ok(Action::NewTiledPane {
@@ -390,6 +394,7 @@ impl TryFrom<ProtobufAction> for Action {
pane_name: None,
near_current_pane,
borderless,
tab_id: None,
})
}
},
@@ -658,6 +663,7 @@ impl TryFrom<ProtobufAction> for Action {
should_open_in_place,
close_replaced_pane: false,
skip_cache: skip_plugin_cache,
tab_id: None,
})
},
_ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
@@ -688,6 +694,7 @@ impl TryFrom<ProtobufAction> for Action {
close_replaced_pane: false,
skip_cache: skip_plugin_cache,
cwd: None,
tab_id: None,
})
},
_ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
@@ -807,6 +814,7 @@ impl TryFrom<ProtobufAction> for Action {
pane_name,
skip_cache: skip_plugin_cache,
cwd: None,
tab_id: None,
})
},
_ => Err("Wrong payload for Action::NewTiledPluginPane"),
@@ -832,6 +840,7 @@ impl TryFrom<ProtobufAction> for Action {
skip_cache: skip_plugin_cache,
cwd: None,
coordinates: None,
tab_id: None,
})
},
_ => Err("Wrong payload for Action::MiddleClick"),
@@ -984,6 +993,7 @@ impl TryFrom<ProtobufAction> for Action {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
}),
},
Some(ProtobufActionName::NewBlockingPane) => match protobuf_action.optional_payload {
@@ -1005,6 +1015,7 @@ impl TryFrom<ProtobufAction> for Action {
command,
unblock_condition,
near_current_pane,
tab_id: None,
})
},
_ => Err("Wrong payload for Action::NewBlockingPane"),
@@ -1024,6 +1035,7 @@ impl TryFrom<ProtobufAction> for Action {
near_current_pane,
pane_id_to_replace,
close_replaced_pane,
tab_id: None,
})
} else {
Ok(Action::NewInPlacePane {
@@ -1032,6 +1044,7 @@ impl TryFrom<ProtobufAction> for Action {
near_current_pane,
pane_id_to_replace,
close_replaced_pane,
tab_id: None,
})
}
},
@@ -1298,6 +1311,7 @@ impl TryFrom<Action> for ProtobufAction {
start_suppressed: _start_suppressed,
coordinates: _floating_pane_coordinates,
near_current_pane,
..
} => {
let file_to_edit = open_file_payload.path.display().to_string();
let cwd = open_file_payload.cwd.map(|cwd| cwd.display().to_string());
@@ -1322,6 +1336,7 @@ impl TryFrom<Action> for ProtobufAction {
pane_name,
coordinates: _coordinates,
near_current_pane,
..
} => {
let command = run_command_action.and_then(|r| {
let mut protobuf_run_command_action: ProtobufRunCommandAction =
@@ -1345,6 +1360,7 @@ impl TryFrom<Action> for ProtobufAction {
pane_name,
near_current_pane,
borderless,
..
} => {
let direction = direction.and_then(|direction| {
let protobuf_direction: ProtobufResizeDirection = direction.try_into().ok()?;
@@ -1558,6 +1574,7 @@ impl TryFrom<Action> for ProtobufAction {
should_open_in_place,
close_replaced_pane: _close_replaced_pane,
skip_cache: skip_plugin_cache,
..
} => {
let configuration = run_plugin_or_alias.get_configuration().unwrap_or_default();
Ok(ProtobufAction {
@@ -1581,6 +1598,7 @@ impl TryFrom<Action> for ProtobufAction {
close_replaced_pane: _close_replaced_pane,
skip_cache: skip_plugin_cache,
cwd: _cwd,
..
} => {
let configuration = run_plugin_or_alias.get_configuration().unwrap_or_default();
Ok(ProtobufAction {
@@ -1668,6 +1686,7 @@ impl TryFrom<Action> for ProtobufAction {
pane_name,
skip_cache: skip_plugin_cache,
cwd: _cwd,
..
} => Ok(ProtobufAction {
name: ProtobufActionName::NewTiledPluginPane as i32,
optional_payload: Some(OptionalPayload::NewTiledPluginPanePayload(
@@ -1684,6 +1703,7 @@ impl TryFrom<Action> for ProtobufAction {
skip_cache: skip_plugin_cache,
cwd: _cwd,
coordinates: _coordinates,
..
} => Ok(ProtobufAction {
name: ProtobufActionName::NewFloatingPluginPane as i32,
optional_payload: Some(OptionalPayload::NewFloatingPluginPanePayload(
@@ -1806,6 +1826,7 @@ impl TryFrom<Action> for ProtobufAction {
command: _,
pane_name: _,
near_current_pane: _,
..
} => Ok(ProtobufAction {
name: ProtobufActionName::NewStackedPane as i32,
optional_payload: None,
@@ -1816,6 +1837,7 @@ impl TryFrom<Action> for ProtobufAction {
command,
unblock_condition,
near_current_pane,
..
} => {
let placement: ProtobufNewPanePlacement = placement.try_into()?;
let command = command.and_then(|c| {
@@ -1847,6 +1869,7 @@ impl TryFrom<Action> for ProtobufAction {
near_current_pane,
pane_id_to_replace,
close_replaced_pane,
..
} => {
let command = run_command_action.and_then(|r| {
let mut protobuf_run_command_action: ProtobufRunCommandAction =
@@ -1876,6 +1899,7 @@ impl TryFrom<Action> for ProtobufAction {
pane_name: _,
skip_cache: _,
close_replaced_pane: _,
..
}
| Action::Deny
| Action::Copy
+24 -1
View File
@@ -612,7 +612,9 @@ impl Setup {
// the chosen layout can either be a path relative to the layout_dir or a name of one
// of our assets, this distinction is made when parsing the layout - TODO: ideally, this
// logic should not be split up and all the decisions should happen here
let (layout_info, chosen_layout) = if let Some(chosen_layout) = cli_args.layout.clone() {
let (layout_info, chosen_layout) = if let Some(ref layout_string) = cli_args.layout_string {
(Some(LayoutInfo::Stringified(layout_string.clone())), None)
} else if let Some(chosen_layout) = cli_args.layout.clone() {
let layout_info = LayoutInfo::from_cli(
&layout_dir,
&Some(chosen_layout.clone()),
@@ -631,6 +633,10 @@ impl Setup {
Some(LayoutInfo::Url(ref layout_url)) => {
Layout::from_url(layout_url, config).map(|(_layout, config)| (layout_info, config))
},
Some(LayoutInfo::Stringified(ref raw_layout)) => {
Layout::from_stringified_layout(raw_layout, config)
.map(|(_layout, config)| (layout_info, config))
},
_ => Layout::from_path_or_default(chosen_layout.as_ref(), layout_dir.clone(), config)
.map(|(_layout, config)| (layout_info, config)),
}
@@ -879,4 +885,21 @@ mod setup_test {
let expected = cwd.join("assets/layouts/compact");
assert_eq!(layout_path, expected.display().to_string());
}
#[test]
fn layout_string_cli_argument() {
let layout_kdl = "layout {\n pane\n pane\n}\n".to_string();
let cli_args = CliArgs {
layout_string: Some(layout_kdl.clone()),
..Default::default()
};
let (_, layout_info, _, _, _) = Setup::from_cli_args(&cli_args).unwrap();
let Some(LayoutInfo::Stringified(content)) = layout_info else {
panic!(
"layout info should be Stringified variant, got: {:#?}",
layout_info
);
};
assert_eq!(content, layout_kdl);
}
}
@@ -1349,6 +1349,7 @@ Config {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4190,6 +4191,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4231,6 +4233,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4352,6 +4355,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4443,6 +4447,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4517,6 +4522,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4570,6 +4576,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -1349,6 +1349,7 @@ Config {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4190,6 +4191,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4231,6 +4233,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4352,6 +4355,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4443,6 +4447,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4517,6 +4522,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4570,6 +4576,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -1349,6 +1349,7 @@ Config {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4190,6 +4191,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4231,6 +4233,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4352,6 +4355,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4443,6 +4447,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4517,6 +4522,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4570,6 +4576,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -1349,6 +1349,7 @@ Config {
command: None,
pane_name: None,
near_current_pane: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4190,6 +4191,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4231,6 +4233,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4352,6 +4355,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4443,6 +4447,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4517,6 +4522,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,
@@ -4570,6 +4576,7 @@ Config {
should_open_in_place: false,
close_replaced_pane: false,
skip_cache: false,
tab_id: None,
},
SwitchToMode {
input_mode: Normal,