feat(plugins): APIs to break multiple panes into a new tab or an existing tab (#3610)
* feat(plugins): break multiple panes to a new tab * fix(layouts): properly ignore run instructions when breaking panes * feat(plugins): break multiple panes to existing tab * feat(apis): allow these methods to also specify whether they want focus changed to the tab * various fixes * allow specifying name for the new tab when breaking out panes * style(fmt): rustfmt
This commit is contained in:
parent
5868aa297c
commit
d78f3586dd
31 changed files with 837 additions and 132 deletions
|
|
@ -415,6 +415,22 @@ impl ZellijPlugin for State {
|
||||||
BareKey::Char('t') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
BareKey::Char('t') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||||
close_tab_with_index(2);
|
close_tab_with_index(2);
|
||||||
},
|
},
|
||||||
|
BareKey::Char('u') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||||
|
let should_change_focus_to_new_tab = true;
|
||||||
|
break_panes_to_new_tab(
|
||||||
|
&[PaneId::Terminal(1), PaneId::Plugin(2)],
|
||||||
|
Some("new_tab_name".to_owned()),
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
BareKey::Char('v') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||||
|
let should_change_focus_to_target_tab = true;
|
||||||
|
break_panes_to_tab_with_index(
|
||||||
|
&[PaneId::Terminal(1), PaneId::Plugin(2)],
|
||||||
|
2,
|
||||||
|
should_change_focus_to_target_tab,
|
||||||
|
);
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
},
|
},
|
||||||
Event::CustomMessage(message, payload) => {
|
Event::CustomMessage(message, payload) => {
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ pub enum PluginInstruction {
|
||||||
Option<TiledPaneLayout>,
|
Option<TiledPaneLayout>,
|
||||||
Vec<FloatingPaneLayout>,
|
Vec<FloatingPaneLayout>,
|
||||||
usize, // tab_index
|
usize, // tab_index
|
||||||
|
bool, // should change focus to new tab
|
||||||
ClientId,
|
ClientId,
|
||||||
),
|
),
|
||||||
ApplyCachedEvents {
|
ApplyCachedEvents {
|
||||||
|
|
@ -377,6 +378,7 @@ pub(crate) fn plugin_thread_main(
|
||||||
mut tab_layout,
|
mut tab_layout,
|
||||||
mut floating_panes_layout,
|
mut floating_panes_layout,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
) => {
|
) => {
|
||||||
// prefer connected clients so as to avoid opening plugins in the background for
|
// prefer connected clients so as to avoid opening plugins in the background for
|
||||||
|
|
@ -444,6 +446,7 @@ pub(crate) fn plugin_thread_main(
|
||||||
floating_panes_layout,
|
floating_panes_layout,
|
||||||
tab_index,
|
tab_index,
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,60 @@ macro_rules! grant_permissions_and_log_actions_in_thread_naked_variant {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! grant_permissions_and_log_actions_in_thread_struct_variant {
|
||||||
|
( $arc_mutex_log:expr, $exit_event:path, $receiver:expr, $exit_after_count:expr, $permission_type:expr, $cache_path:expr, $plugin_thread_sender:expr, $client_id:expr ) => {
|
||||||
|
std::thread::Builder::new()
|
||||||
|
.name("fake_screen_thread".to_string())
|
||||||
|
.spawn({
|
||||||
|
let log = $arc_mutex_log.clone();
|
||||||
|
let mut exit_event_count = 0;
|
||||||
|
let cache_path = $cache_path.clone();
|
||||||
|
let plugin_thread_sender = $plugin_thread_sender.clone();
|
||||||
|
move || loop {
|
||||||
|
let (event, _err_ctx) = $receiver
|
||||||
|
.recv()
|
||||||
|
.expect("failed to receive event on channel");
|
||||||
|
match event {
|
||||||
|
$exit_event { .. } => {
|
||||||
|
exit_event_count += 1;
|
||||||
|
log.lock().unwrap().push(event);
|
||||||
|
if exit_event_count == $exit_after_count {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ScreenInstruction::RequestPluginPermissions(_, plugin_permission) => {
|
||||||
|
if plugin_permission.permissions.contains($permission_type) {
|
||||||
|
let _ = plugin_thread_sender.send(
|
||||||
|
PluginInstruction::PermissionRequestResult(
|
||||||
|
0,
|
||||||
|
Some($client_id),
|
||||||
|
plugin_permission.permissions,
|
||||||
|
PermissionStatus::Granted,
|
||||||
|
Some(cache_path.clone()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let _ = plugin_thread_sender.send(
|
||||||
|
PluginInstruction::PermissionRequestResult(
|
||||||
|
0,
|
||||||
|
Some($client_id),
|
||||||
|
plugin_permission.permissions,
|
||||||
|
PermissionStatus::Denied,
|
||||||
|
Some(cache_path.clone()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
log.lock().unwrap().push(event);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn create_plugin_thread(
|
fn create_plugin_thread(
|
||||||
zellij_cwd: Option<PathBuf>,
|
zellij_cwd: Option<PathBuf>,
|
||||||
) -> (
|
) -> (
|
||||||
|
|
@ -8120,3 +8174,145 @@ pub fn close_tab_with_index_plugin_command() {
|
||||||
.clone();
|
.clone();
|
||||||
assert_snapshot!(format!("{:#?}", screen_instruction));
|
assert_snapshot!(format!("{:#?}", screen_instruction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
pub fn break_panes_to_new_tab_plugin_command() {
|
||||||
|
let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its
|
||||||
|
// destructor removes the directory
|
||||||
|
let plugin_host_folder = PathBuf::from(temp_folder.path());
|
||||||
|
let cache_path = plugin_host_folder.join("permissions_test.kdl");
|
||||||
|
let (plugin_thread_sender, screen_receiver, teardown) =
|
||||||
|
create_plugin_thread(Some(plugin_host_folder));
|
||||||
|
let plugin_should_float = Some(false);
|
||||||
|
let plugin_title = Some("test_plugin".to_owned());
|
||||||
|
let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin {
|
||||||
|
_allow_exec_host_cmd: false,
|
||||||
|
location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)),
|
||||||
|
configuration: Default::default(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
let tab_index = 1;
|
||||||
|
let client_id = 1;
|
||||||
|
let size = Size {
|
||||||
|
cols: 121,
|
||||||
|
rows: 20,
|
||||||
|
};
|
||||||
|
let received_screen_instructions = Arc::new(Mutex::new(vec![]));
|
||||||
|
let screen_thread = grant_permissions_and_log_actions_in_thread_struct_variant!(
|
||||||
|
received_screen_instructions,
|
||||||
|
ScreenInstruction::BreakPanesToNewTab,
|
||||||
|
screen_receiver,
|
||||||
|
1,
|
||||||
|
&PermissionType::ChangeApplicationState,
|
||||||
|
cache_path,
|
||||||
|
plugin_thread_sender,
|
||||||
|
client_id
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id));
|
||||||
|
let _ = plugin_thread_sender.send(PluginInstruction::Load(
|
||||||
|
plugin_should_float,
|
||||||
|
false,
|
||||||
|
plugin_title,
|
||||||
|
run_plugin,
|
||||||
|
tab_index,
|
||||||
|
None,
|
||||||
|
client_id,
|
||||||
|
size,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
None,
|
||||||
|
Some(client_id),
|
||||||
|
Event::Key(KeyWithModifier::new(BareKey::Char('u')).with_alt_modifier()), // this triggers the enent in the fixture plugin
|
||||||
|
)]));
|
||||||
|
screen_thread.join().unwrap(); // this might take a while if the cache is cold
|
||||||
|
teardown();
|
||||||
|
let screen_instruction = received_screen_instructions
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.find_map(|i| {
|
||||||
|
if let ScreenInstruction::BreakPanesToNewTab { .. } = i {
|
||||||
|
Some(i.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.clone();
|
||||||
|
assert_snapshot!(format!("{:#?}", screen_instruction));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
pub fn break_panes_to_tab_with_index_plugin_command() {
|
||||||
|
let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its
|
||||||
|
// destructor removes the directory
|
||||||
|
let plugin_host_folder = PathBuf::from(temp_folder.path());
|
||||||
|
let cache_path = plugin_host_folder.join("permissions_test.kdl");
|
||||||
|
let (plugin_thread_sender, screen_receiver, teardown) =
|
||||||
|
create_plugin_thread(Some(plugin_host_folder));
|
||||||
|
let plugin_should_float = Some(false);
|
||||||
|
let plugin_title = Some("test_plugin".to_owned());
|
||||||
|
let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin {
|
||||||
|
_allow_exec_host_cmd: false,
|
||||||
|
location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)),
|
||||||
|
configuration: Default::default(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
let tab_index = 1;
|
||||||
|
let client_id = 1;
|
||||||
|
let size = Size {
|
||||||
|
cols: 121,
|
||||||
|
rows: 20,
|
||||||
|
};
|
||||||
|
let received_screen_instructions = Arc::new(Mutex::new(vec![]));
|
||||||
|
let screen_thread = grant_permissions_and_log_actions_in_thread_struct_variant!(
|
||||||
|
received_screen_instructions,
|
||||||
|
ScreenInstruction::BreakPanesToTabWithIndex,
|
||||||
|
screen_receiver,
|
||||||
|
1,
|
||||||
|
&PermissionType::ChangeApplicationState,
|
||||||
|
cache_path,
|
||||||
|
plugin_thread_sender,
|
||||||
|
client_id
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id));
|
||||||
|
let _ = plugin_thread_sender.send(PluginInstruction::Load(
|
||||||
|
plugin_should_float,
|
||||||
|
false,
|
||||||
|
plugin_title,
|
||||||
|
run_plugin,
|
||||||
|
tab_index,
|
||||||
|
None,
|
||||||
|
client_id,
|
||||||
|
size,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
None,
|
||||||
|
Some(client_id),
|
||||||
|
Event::Key(KeyWithModifier::new(BareKey::Char('v')).with_alt_modifier()), // this triggers the enent in the fixture plugin
|
||||||
|
)]));
|
||||||
|
screen_thread.join().unwrap(); // this might take a while if the cache is cold
|
||||||
|
teardown();
|
||||||
|
let screen_instruction = received_screen_instructions
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.find_map(|i| {
|
||||||
|
if let ScreenInstruction::BreakPanesToTabWithIndex { .. } = i {
|
||||||
|
Some(i.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.clone();
|
||||||
|
assert_snapshot!(format!("{:#?}", screen_instruction));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||||
|
assertion_line: 8246
|
||||||
|
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||||
|
---
|
||||||
|
Some(
|
||||||
|
BreakPanesToNewTab {
|
||||||
|
pane_ids: [
|
||||||
|
Terminal(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
Plugin(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
default_shell: Some(
|
||||||
|
RunCommand(
|
||||||
|
RunCommand {
|
||||||
|
command: ".",
|
||||||
|
args: [],
|
||||||
|
cwd: None,
|
||||||
|
hold_on_close: false,
|
||||||
|
hold_on_start: false,
|
||||||
|
originating_plugin: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
should_change_focus_to_new_tab: true,
|
||||||
|
new_tab_name: Some(
|
||||||
|
"new_tab_name",
|
||||||
|
),
|
||||||
|
client_id: 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||||
|
assertion_line: 8317
|
||||||
|
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||||
|
---
|
||||||
|
Some(
|
||||||
|
BreakPanesToTabWithIndex {
|
||||||
|
pane_ids: [
|
||||||
|
Terminal(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
Plugin(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
tab_index: 2,
|
||||||
|
should_change_focus_to_new_tab: true,
|
||||||
|
client_id: 1,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
@ -320,6 +320,26 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
|
||||||
PluginCommand::CloseTabWithIndex(tab_index) => {
|
PluginCommand::CloseTabWithIndex(tab_index) => {
|
||||||
close_tab_with_index(env, tab_index)
|
close_tab_with_index(env, tab_index)
|
||||||
},
|
},
|
||||||
|
PluginCommand::BreakPanesToNewTab(
|
||||||
|
pane_ids,
|
||||||
|
new_tab_name,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
) => break_panes_to_new_tab(
|
||||||
|
env,
|
||||||
|
pane_ids.into_iter().map(|p_id| p_id.into()).collect(),
|
||||||
|
new_tab_name,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
),
|
||||||
|
PluginCommand::BreakPanesToTabWithIndex(
|
||||||
|
pane_ids,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
tab_index,
|
||||||
|
) => break_panes_to_tab_with_index(
|
||||||
|
env,
|
||||||
|
pane_ids.into_iter().map(|p_id| p_id.into()).collect(),
|
||||||
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
(PermissionStatus::Denied, permission) => {
|
(PermissionStatus::Denied, permission) => {
|
||||||
log::error!(
|
log::error!(
|
||||||
|
|
@ -1589,6 +1609,45 @@ fn close_tab_with_index(env: &PluginEnv, tab_index: usize) {
|
||||||
.send_to_screen(ScreenInstruction::CloseTabWithIndex(tab_index));
|
.send_to_screen(ScreenInstruction::CloseTabWithIndex(tab_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn break_panes_to_new_tab(
|
||||||
|
env: &PluginEnv,
|
||||||
|
pane_ids: Vec<PaneId>,
|
||||||
|
new_tab_name: Option<String>,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
) {
|
||||||
|
let default_shell = env.default_shell.clone().or_else(|| {
|
||||||
|
Some(TerminalAction::RunCommand(RunCommand {
|
||||||
|
command: env.path_to_default_shell.clone(),
|
||||||
|
..Default::default()
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
let _ = env
|
||||||
|
.senders
|
||||||
|
.send_to_screen(ScreenInstruction::BreakPanesToNewTab {
|
||||||
|
pane_ids,
|
||||||
|
default_shell,
|
||||||
|
new_tab_name,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
client_id: env.client_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn break_panes_to_tab_with_index(
|
||||||
|
env: &PluginEnv,
|
||||||
|
pane_ids: Vec<PaneId>,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
tab_index: usize,
|
||||||
|
) {
|
||||||
|
let _ = env
|
||||||
|
.senders
|
||||||
|
.send_to_screen(ScreenInstruction::BreakPanesToTabWithIndex {
|
||||||
|
pane_ids,
|
||||||
|
tab_index,
|
||||||
|
client_id: env.client_id,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Custom panic handler for plugins.
|
// Custom panic handler for plugins.
|
||||||
//
|
//
|
||||||
// This is called when a panic occurs in a plugin. Since most panics will likely originate in the
|
// This is called when a panic occurs in a plugin. Since most panics will likely originate in the
|
||||||
|
|
@ -1734,6 +1793,8 @@ fn check_command_permission(
|
||||||
| PluginCommand::RerunCommandPane(..)
|
| PluginCommand::RerunCommandPane(..)
|
||||||
| PluginCommand::ResizePaneIdWithDirection(..)
|
| PluginCommand::ResizePaneIdWithDirection(..)
|
||||||
| PluginCommand::CloseTabWithIndex(..)
|
| PluginCommand::CloseTabWithIndex(..)
|
||||||
|
| PluginCommand::BreakPanesToNewTab(..)
|
||||||
|
| PluginCommand::BreakPanesToTabWithIndex(..)
|
||||||
| PluginCommand::KillSessions(..) => PermissionType::ChangeApplicationState,
|
| PluginCommand::KillSessions(..) => PermissionType::ChangeApplicationState,
|
||||||
PluginCommand::UnblockCliPipeInput(..)
|
PluginCommand::UnblockCliPipeInput(..)
|
||||||
| PluginCommand::BlockCliPipeInput(..)
|
| PluginCommand::BlockCliPipeInput(..)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ pub enum PtyInstruction {
|
||||||
Vec<FloatingPaneLayout>,
|
Vec<FloatingPaneLayout>,
|
||||||
usize, // tab_index
|
usize, // tab_index
|
||||||
HashMap<RunPluginOrAlias, Vec<u32>>, // plugin_ids
|
HashMap<RunPluginOrAlias, Vec<u32>>, // plugin_ids
|
||||||
|
bool, // should change focus to new tab
|
||||||
ClientId,
|
ClientId,
|
||||||
), // the String is the tab name
|
), // the String is the tab name
|
||||||
ClosePane(PaneId),
|
ClosePane(PaneId),
|
||||||
|
|
@ -542,6 +543,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
|
||||||
floating_panes_layout,
|
floating_panes_layout,
|
||||||
tab_index,
|
tab_index,
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
) => {
|
) => {
|
||||||
let err_context = || format!("failed to open new tab for client {}", client_id);
|
let err_context = || format!("failed to open new tab for client {}", client_id);
|
||||||
|
|
@ -558,6 +560,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
|
||||||
terminal_action.clone(),
|
terminal_action.clone(),
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
)
|
)
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
|
|
@ -1015,6 +1018,7 @@ impl Pty {
|
||||||
default_shell: Option<TerminalAction>,
|
default_shell: Option<TerminalAction>,
|
||||||
plugin_ids: HashMap<RunPluginOrAlias, Vec<u32>>,
|
plugin_ids: HashMap<RunPluginOrAlias, Vec<u32>>,
|
||||||
tab_index: usize,
|
tab_index: usize,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let err_context = || format!("failed to spawn terminals for layout for client {client_id}");
|
let err_context = || format!("failed to spawn terminals for layout for client {client_id}");
|
||||||
|
|
@ -1079,6 +1083,7 @@ impl Pty {
|
||||||
new_tab_floating_pane_ids,
|
new_tab_floating_pane_ids,
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
))
|
))
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,7 @@ pub enum ScreenInstruction {
|
||||||
Vec<(u32, HoldForCommand)>, // new floating pane pids
|
Vec<(u32, HoldForCommand)>, // new floating pane pids
|
||||||
HashMap<RunPluginOrAlias, Vec<u32>>,
|
HashMap<RunPluginOrAlias, Vec<u32>>,
|
||||||
usize, // tab_index
|
usize, // tab_index
|
||||||
|
bool, // should change focus to new tab
|
||||||
ClientId,
|
ClientId,
|
||||||
),
|
),
|
||||||
SwitchTabNext(ClientId),
|
SwitchTabNext(ClientId),
|
||||||
|
|
@ -395,6 +396,19 @@ pub enum ScreenInstruction {
|
||||||
TogglePaneIdFullscreen(PaneId),
|
TogglePaneIdFullscreen(PaneId),
|
||||||
TogglePaneEmbedOrEjectForPaneId(PaneId),
|
TogglePaneEmbedOrEjectForPaneId(PaneId),
|
||||||
CloseTabWithIndex(usize),
|
CloseTabWithIndex(usize),
|
||||||
|
BreakPanesToNewTab {
|
||||||
|
pane_ids: Vec<PaneId>,
|
||||||
|
default_shell: Option<TerminalAction>,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
new_tab_name: Option<String>,
|
||||||
|
client_id: ClientId,
|
||||||
|
},
|
||||||
|
BreakPanesToTabWithIndex {
|
||||||
|
pane_ids: Vec<PaneId>,
|
||||||
|
tab_index: usize,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
client_id: ClientId,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&ScreenInstruction> for ScreenContext {
|
impl From<&ScreenInstruction> for ScreenContext {
|
||||||
|
|
@ -602,6 +616,10 @@ impl From<&ScreenInstruction> for ScreenContext {
|
||||||
ScreenContext::TogglePaneEmbedOrEjectForPaneId
|
ScreenContext::TogglePaneEmbedOrEjectForPaneId
|
||||||
},
|
},
|
||||||
ScreenInstruction::CloseTabWithIndex(..) => ScreenContext::CloseTabWithIndex,
|
ScreenInstruction::CloseTabWithIndex(..) => ScreenContext::CloseTabWithIndex,
|
||||||
|
ScreenInstruction::BreakPanesToNewTab { .. } => ScreenContext::BreakPanesToNewTab,
|
||||||
|
ScreenInstruction::BreakPanesToTabWithIndex { .. } => {
|
||||||
|
ScreenContext::BreakPanesToTabWithIndex
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1169,7 +1187,10 @@ impl Screen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for tab_index in tabs_to_close {
|
for tab_index in tabs_to_close {
|
||||||
self.close_tab_at_index(tab_index).context(err_context)?;
|
// cleanup as needed
|
||||||
|
self.close_tab_at_index(tab_index)
|
||||||
|
.context(err_context)
|
||||||
|
.non_fatal();
|
||||||
}
|
}
|
||||||
if output.is_dirty() {
|
if output.is_dirty() {
|
||||||
let serialized_output = output.serialize().context(err_context)?;
|
let serialized_output = output.serialize().context(err_context)?;
|
||||||
|
|
@ -1254,17 +1275,19 @@ impl Screen {
|
||||||
tab_index: usize,
|
tab_index: usize,
|
||||||
swap_layouts: (Vec<SwapTiledLayout>, Vec<SwapFloatingLayout>),
|
swap_layouts: (Vec<SwapTiledLayout>, Vec<SwapFloatingLayout>),
|
||||||
tab_name: Option<String>,
|
tab_name: Option<String>,
|
||||||
client_id: ClientId,
|
client_id: Option<ClientId>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let err_context = || format!("failed to create new tab for client {client_id:?}",);
|
let err_context = || format!("failed to create new tab for client {client_id:?}",);
|
||||||
|
|
||||||
let client_id = if self.get_active_tab(client_id).is_ok() {
|
let client_id = client_id.map(|client_id| {
|
||||||
|
if self.get_active_tab(client_id).is_ok() {
|
||||||
client_id
|
client_id
|
||||||
} else if let Some(first_client_id) = self.get_first_client_id() {
|
} else if let Some(first_client_id) = self.get_first_client_id() {
|
||||||
first_client_id
|
first_client_id
|
||||||
} else {
|
} else {
|
||||||
client_id
|
client_id
|
||||||
};
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let tab_name = tab_name.unwrap_or_else(|| String::new());
|
let tab_name = tab_name.unwrap_or_else(|| String::new());
|
||||||
|
|
||||||
|
|
@ -1314,6 +1337,7 @@ impl Screen {
|
||||||
new_floating_terminal_ids: Vec<(u32, HoldForCommand)>,
|
new_floating_terminal_ids: Vec<(u32, HoldForCommand)>,
|
||||||
new_plugin_ids: HashMap<RunPluginOrAlias, Vec<u32>>,
|
new_plugin_ids: HashMap<RunPluginOrAlias, Vec<u32>>,
|
||||||
tab_index: usize,
|
tab_index: usize,
|
||||||
|
should_change_client_focus: bool,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if self.tabs.get(&tab_index).is_none() {
|
if self.tabs.get(&tab_index).is_none() {
|
||||||
|
|
@ -1332,12 +1356,17 @@ impl Screen {
|
||||||
let err_context = || format!("failed to apply layout for tab {tab_index:?}",);
|
let err_context = || format!("failed to apply layout for tab {tab_index:?}",);
|
||||||
|
|
||||||
// move the relevant clients out of the current tab and place them in the new one
|
// move the relevant clients out of the current tab and place them in the new one
|
||||||
let drained_clients = if self.session_is_mirrored {
|
let drained_clients = if should_change_client_focus {
|
||||||
let client_mode_infos_in_source_tab =
|
if self.session_is_mirrored {
|
||||||
if let Ok(active_tab) = self.get_active_tab_mut(client_id) {
|
let client_mode_infos_in_source_tab = if let Ok(active_tab) =
|
||||||
|
self.get_active_tab_mut(client_id)
|
||||||
|
{
|
||||||
let client_mode_infos_in_source_tab = active_tab.drain_connected_clients(None);
|
let client_mode_infos_in_source_tab = active_tab.drain_connected_clients(None);
|
||||||
if active_tab.has_no_connected_clients() {
|
if active_tab.has_no_connected_clients() {
|
||||||
active_tab.visible(false).with_context(err_context)?;
|
active_tab
|
||||||
|
.visible(false)
|
||||||
|
.with_context(err_context)
|
||||||
|
.non_fatal();
|
||||||
}
|
}
|
||||||
Some(client_mode_infos_in_source_tab)
|
Some(client_mode_infos_in_source_tab)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1353,12 +1382,18 @@ impl Screen {
|
||||||
let client_mode_info_in_source_tab =
|
let client_mode_info_in_source_tab =
|
||||||
active_tab.drain_connected_clients(Some(vec![client_id]));
|
active_tab.drain_connected_clients(Some(vec![client_id]));
|
||||||
if active_tab.has_no_connected_clients() {
|
if active_tab.has_no_connected_clients() {
|
||||||
active_tab.visible(false).with_context(err_context)?;
|
active_tab
|
||||||
|
.visible(false)
|
||||||
|
.with_context(err_context)
|
||||||
|
.non_fatal();
|
||||||
}
|
}
|
||||||
self.update_client_tab_focus(client_id, tab_index);
|
self.update_client_tab_focus(client_id, tab_index);
|
||||||
Some(client_mode_info_in_source_tab)
|
Some(client_mode_info_in_source_tab)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// apply the layout to the new tab
|
// apply the layout to the new tab
|
||||||
|
|
@ -1375,10 +1410,13 @@ impl Screen {
|
||||||
client_id,
|
client_id,
|
||||||
)?;
|
)?;
|
||||||
tab.update_input_modes()?;
|
tab.update_input_modes()?;
|
||||||
tab.visible(true)?;
|
|
||||||
if let Some(drained_clients) = drained_clients {
|
if let Some(drained_clients) = drained_clients {
|
||||||
|
tab.visible(true)?;
|
||||||
tab.add_multiple_clients(drained_clients)?;
|
tab.add_multiple_clients(drained_clients)?;
|
||||||
}
|
}
|
||||||
|
tab.resize_whole_tab(self.size).with_context(err_context)?;
|
||||||
|
tab.set_force_render();
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
|
|
@ -2083,7 +2121,7 @@ impl Screen {
|
||||||
default_layout.swap_tiled_layouts.clone(),
|
default_layout.swap_tiled_layouts.clone(),
|
||||||
default_layout.swap_floating_layouts.clone(),
|
default_layout.swap_floating_layouts.clone(),
|
||||||
);
|
);
|
||||||
self.new_tab(tab_index, swap_layouts, None, client_id)?;
|
self.new_tab(tab_index, swap_layouts, None, Some(client_id))?;
|
||||||
let tab = self.tabs.get_mut(&tab_index).with_context(err_context)?;
|
let tab = self.tabs.get_mut(&tab_index).with_context(err_context)?;
|
||||||
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 {
|
||||||
|
|
@ -2099,12 +2137,14 @@ impl Screen {
|
||||||
tab.add_tiled_pane(active_pane, active_pane_id, Some(client_id))?;
|
tab.add_tiled_pane(active_pane, active_pane_id, Some(client_id))?;
|
||||||
tiled_panes_layout.ignore_run_instruction(active_pane_run_instruction.clone());
|
tiled_panes_layout.ignore_run_instruction(active_pane_run_instruction.clone());
|
||||||
}
|
}
|
||||||
|
let should_change_focus_to_new_tab = true;
|
||||||
self.bus.senders.send_to_plugin(PluginInstruction::NewTab(
|
self.bus.senders.send_to_plugin(PluginInstruction::NewTab(
|
||||||
None,
|
None,
|
||||||
default_shell,
|
default_shell,
|
||||||
Some(tiled_panes_layout),
|
Some(tiled_panes_layout),
|
||||||
floating_panes_layout,
|
floating_panes_layout,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
))?;
|
))?;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2122,6 +2162,63 @@ impl Screen {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn break_multiple_panes_to_new_tab(
|
||||||
|
&mut self,
|
||||||
|
pane_ids: Vec<PaneId>,
|
||||||
|
default_shell: Option<TerminalAction>,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
new_tab_name: Option<String>,
|
||||||
|
client_id: ClientId,
|
||||||
|
) -> Result<()> {
|
||||||
|
let err_context = || "failed break multiple panes to a new tab".to_string();
|
||||||
|
|
||||||
|
let all_tabs = self.get_tabs_mut();
|
||||||
|
let mut extracted_panes = vec![];
|
||||||
|
for pane_id in pane_ids {
|
||||||
|
for tab in all_tabs.values_mut() {
|
||||||
|
// here we pass None instead of the client_id we have because we do not need to
|
||||||
|
// necessarily trigger a relayout for this tab
|
||||||
|
if let Some(pane) = tab.extract_pane(pane_id, true, None).take() {
|
||||||
|
extracted_panes.push(pane);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (mut tiled_panes_layout, floating_panes_layout) = self.default_layout.new_tab();
|
||||||
|
let tab_index = self.get_new_tab_index();
|
||||||
|
let swap_layouts = (
|
||||||
|
self.default_layout.swap_tiled_layouts.clone(),
|
||||||
|
self.default_layout.swap_floating_layouts.clone(),
|
||||||
|
);
|
||||||
|
if should_change_focus_to_new_tab {
|
||||||
|
self.new_tab(tab_index, swap_layouts, None, Some(client_id))?;
|
||||||
|
} else {
|
||||||
|
self.new_tab(tab_index, swap_layouts, None, None)?;
|
||||||
|
}
|
||||||
|
let mut tab = self.tabs.get_mut(&tab_index).with_context(err_context)?;
|
||||||
|
if let Some(new_tab_name) = new_tab_name {
|
||||||
|
tab.name = new_tab_name.clone();
|
||||||
|
}
|
||||||
|
for pane in extracted_panes {
|
||||||
|
let run_instruction = pane.invoked_with().clone();
|
||||||
|
let pane_id = pane.pid();
|
||||||
|
// here we pass None instead of the ClientId, because we do not want this pane to be
|
||||||
|
// necessarily focused
|
||||||
|
tab.add_tiled_pane(pane, pane_id, None)?;
|
||||||
|
tiled_panes_layout.ignore_run_instruction(run_instruction.clone());
|
||||||
|
}
|
||||||
|
self.bus.senders.send_to_plugin(PluginInstruction::NewTab(
|
||||||
|
None,
|
||||||
|
default_shell,
|
||||||
|
Some(tiled_panes_layout),
|
||||||
|
floating_panes_layout,
|
||||||
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
client_id,
|
||||||
|
))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
pub fn break_pane_to_new_tab(
|
pub fn break_pane_to_new_tab(
|
||||||
&mut self,
|
&mut self,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
|
|
@ -2184,6 +2281,57 @@ impl Screen {
|
||||||
self.render(None)?;
|
self.render(None)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn break_multiple_panes_to_tab_with_index(
|
||||||
|
&mut self,
|
||||||
|
pane_ids: Vec<PaneId>,
|
||||||
|
tab_index: usize,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
client_id: ClientId,
|
||||||
|
) -> Result<()> {
|
||||||
|
let all_tabs = self.get_tabs_mut();
|
||||||
|
let has_tab_with_index = all_tabs
|
||||||
|
.values()
|
||||||
|
.find(|t| t.position == tab_index)
|
||||||
|
.is_some();
|
||||||
|
if !has_tab_with_index {
|
||||||
|
log::error!("Cannot find tab with index: {tab_index}");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let mut extracted_panes = vec![];
|
||||||
|
for pane_id in pane_ids {
|
||||||
|
for tab in all_tabs.values_mut() {
|
||||||
|
if tab.position == tab_index {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// here we pass None instead of the client_id we have because we do not need to
|
||||||
|
// necessarily trigger a relayout for this tab
|
||||||
|
if let Some(pane) = tab.extract_pane(pane_id, true, None).take() {
|
||||||
|
extracted_panes.push(pane);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_change_focus_to_new_tab {
|
||||||
|
self.go_to_tab(tab_index + 1, client_id)?;
|
||||||
|
}
|
||||||
|
if extracted_panes.is_empty() {
|
||||||
|
// nothing to do here...
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if let Some(new_active_tab) = self.get_indexed_tab_mut(tab_index) {
|
||||||
|
for pane in extracted_panes {
|
||||||
|
let pane_id = pane.pid();
|
||||||
|
// here we pass None instead of the ClientId, because we do not want this pane to be
|
||||||
|
// necessarily focused
|
||||||
|
new_active_tab.add_tiled_pane(pane, pane_id, None)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("Could not find tab with index: {:?}", tab_index);
|
||||||
|
}
|
||||||
|
self.log_and_report_session_state()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
pub fn replace_pane(
|
pub fn replace_pane(
|
||||||
&mut self,
|
&mut self,
|
||||||
new_pane_id: PaneId,
|
new_pane_id: PaneId,
|
||||||
|
|
@ -3246,8 +3394,9 @@ pub(crate) fn screen_thread_main(
|
||||||
client_id,
|
client_id,
|
||||||
) => {
|
) => {
|
||||||
let tab_index = screen.get_new_tab_index();
|
let tab_index = screen.get_new_tab_index();
|
||||||
|
let should_change_focus_to_new_tab = true;
|
||||||
pending_tab_ids.insert(tab_index);
|
pending_tab_ids.insert(tab_index);
|
||||||
screen.new_tab(tab_index, swap_layouts, tab_name.clone(), client_id)?;
|
screen.new_tab(tab_index, swap_layouts, tab_name.clone(), Some(client_id))?;
|
||||||
screen
|
screen
|
||||||
.bus
|
.bus
|
||||||
.senders
|
.senders
|
||||||
|
|
@ -3257,6 +3406,7 @@ pub(crate) fn screen_thread_main(
|
||||||
layout,
|
layout,
|
||||||
floating_panes_layout,
|
floating_panes_layout,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
|
|
@ -3267,6 +3417,7 @@ pub(crate) fn screen_thread_main(
|
||||||
new_floating_pane_pids,
|
new_floating_pane_pids,
|
||||||
new_plugin_ids,
|
new_plugin_ids,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
) => {
|
) => {
|
||||||
screen.apply_layout(
|
screen.apply_layout(
|
||||||
|
|
@ -3276,6 +3427,7 @@ pub(crate) fn screen_thread_main(
|
||||||
new_floating_pane_pids,
|
new_floating_pane_pids,
|
||||||
new_plugin_ids.clone(),
|
new_plugin_ids.clone(),
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
)?;
|
)?;
|
||||||
pending_tab_ids.remove(&tab_index);
|
pending_tab_ids.remove(&tab_index);
|
||||||
|
|
@ -3363,7 +3515,13 @@ pub(crate) fn screen_thread_main(
|
||||||
screen.render(None)?;
|
screen.render(None)?;
|
||||||
if create && !tab_exists {
|
if create && !tab_exists {
|
||||||
let tab_index = screen.get_new_tab_index();
|
let tab_index = screen.get_new_tab_index();
|
||||||
screen.new_tab(tab_index, swap_layouts, Some(tab_name), client_id)?;
|
let should_change_focus_to_new_tab = true;
|
||||||
|
screen.new_tab(
|
||||||
|
tab_index,
|
||||||
|
swap_layouts,
|
||||||
|
Some(tab_name),
|
||||||
|
Some(client_id),
|
||||||
|
)?;
|
||||||
screen
|
screen
|
||||||
.bus
|
.bus
|
||||||
.senders
|
.senders
|
||||||
|
|
@ -3373,6 +3531,7 @@ pub(crate) fn screen_thread_main(
|
||||||
None,
|
None,
|
||||||
vec![],
|
vec![],
|
||||||
tab_index,
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
client_id,
|
client_id,
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
@ -4427,6 +4586,34 @@ pub(crate) fn screen_thread_main(
|
||||||
ScreenInstruction::CloseTabWithIndex(tab_index) => {
|
ScreenInstruction::CloseTabWithIndex(tab_index) => {
|
||||||
screen.close_tab_at_index(tab_index).non_fatal()
|
screen.close_tab_at_index(tab_index).non_fatal()
|
||||||
},
|
},
|
||||||
|
ScreenInstruction::BreakPanesToNewTab {
|
||||||
|
pane_ids,
|
||||||
|
default_shell,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
new_tab_name,
|
||||||
|
client_id,
|
||||||
|
} => {
|
||||||
|
screen.break_multiple_panes_to_new_tab(
|
||||||
|
pane_ids,
|
||||||
|
default_shell,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
new_tab_name,
|
||||||
|
client_id,
|
||||||
|
)?;
|
||||||
|
},
|
||||||
|
ScreenInstruction::BreakPanesToTabWithIndex {
|
||||||
|
pane_ids,
|
||||||
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
client_id,
|
||||||
|
} => {
|
||||||
|
screen.break_multiple_panes_to_tab_with_index(
|
||||||
|
pane_ids,
|
||||||
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
client_id,
|
||||||
|
)?;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,19 @@ impl<'a> LayoutApplier<'a> {
|
||||||
position_and_size,
|
position_and_size,
|
||||||
layout.borderless,
|
layout.borderless,
|
||||||
);
|
);
|
||||||
|
} else if let Some(position) =
|
||||||
|
positions_in_layout
|
||||||
|
.iter()
|
||||||
|
.position(|(layout, _position_and_size)| {
|
||||||
|
Run::is_terminal(&layout.run) && Run::is_terminal(&run_instruction)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let (layout, position_and_size) = positions_in_layout.remove(position);
|
||||||
|
self.tiled_panes.set_geom_for_pane_with_run(
|
||||||
|
run_instruction,
|
||||||
|
position_and_size,
|
||||||
|
layout.borderless,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
log::error!(
|
log::error!(
|
||||||
"Failed to find room for run instruction: {:?}",
|
"Failed to find room for run instruction: {:?}",
|
||||||
|
|
|
||||||
|
|
@ -546,7 +546,7 @@ impl Tab {
|
||||||
auto_layout: bool,
|
auto_layout: bool,
|
||||||
connected_clients_in_app: Rc<RefCell<HashSet<ClientId>>>,
|
connected_clients_in_app: Rc<RefCell<HashSet<ClientId>>>,
|
||||||
session_is_mirrored: bool,
|
session_is_mirrored: bool,
|
||||||
client_id: ClientId,
|
client_id: Option<ClientId>,
|
||||||
copy_options: CopyOptions,
|
copy_options: CopyOptions,
|
||||||
terminal_emulator_colors: Rc<RefCell<Palette>>,
|
terminal_emulator_colors: Rc<RefCell<Palette>>,
|
||||||
terminal_emulator_color_codes: Rc<RefCell<HashMap<usize, String>>>,
|
terminal_emulator_color_codes: Rc<RefCell<HashMap<usize, String>>>,
|
||||||
|
|
@ -564,7 +564,9 @@ impl Tab {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut connected_clients = HashSet::new();
|
let mut connected_clients = HashSet::new();
|
||||||
|
if let Some(client_id) = client_id {
|
||||||
connected_clients.insert(client_id);
|
connected_clients.insert(client_id);
|
||||||
|
}
|
||||||
let viewport: Viewport = display_area.into();
|
let viewport: Viewport = display_area.into();
|
||||||
let viewport = Rc::new(RefCell::new(viewport));
|
let viewport = Rc::new(RefCell::new(viewport));
|
||||||
let display_area = Rc::new(RefCell::new(display_area));
|
let display_area = Rc::new(RefCell::new(display_area));
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ fn create_new_tab(size: Size, default_mode: ModeInfo) -> Tab {
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -322,7 +322,7 @@ fn create_new_tab_with_swap_layouts(
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -403,7 +403,7 @@ fn create_new_tab_with_os_api(
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -470,7 +470,7 @@ fn create_new_tab_with_layout(size: Size, default_mode: ModeInfo, layout: &str)
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -551,7 +551,7 @@ fn create_new_tab_with_mock_pty_writer(
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -623,7 +623,7 @@ fn create_new_tab_with_sixel_support(
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ fn create_new_tab(size: Size) -> Tab {
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -248,7 +248,7 @@ fn create_new_tab_with_layout(size: Size, layout: TiledPaneLayout) -> Tab {
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
@ -318,7 +318,7 @@ fn create_new_tab_with_cell_size(
|
||||||
auto_layout,
|
auto_layout,
|
||||||
connected_clients,
|
connected_clients,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
client_id,
|
Some(client_id),
|
||||||
copy_options,
|
copy_options,
|
||||||
terminal_emulator_colors,
|
terminal_emulator_colors,
|
||||||
terminal_emulator_color_codes,
|
terminal_emulator_color_codes,
|
||||||
|
|
|
||||||
|
|
@ -387,6 +387,7 @@ impl MockScreen {
|
||||||
floating_pane_ids,
|
floating_pane_ids,
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
true,
|
||||||
self.main_client_id,
|
self.main_client_id,
|
||||||
));
|
));
|
||||||
self.last_opened_tab_index = Some(tab_index);
|
self.last_opened_tab_index = Some(tab_index);
|
||||||
|
|
@ -471,6 +472,7 @@ impl MockScreen {
|
||||||
floating_pane_ids,
|
floating_pane_ids,
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
true,
|
||||||
self.main_client_id,
|
self.main_client_id,
|
||||||
));
|
));
|
||||||
self.last_opened_tab_index = Some(tab_index);
|
self.last_opened_tab_index = Some(tab_index);
|
||||||
|
|
@ -502,6 +504,7 @@ impl MockScreen {
|
||||||
vec![], // floating panes ids
|
vec![], // floating panes ids
|
||||||
plugin_ids,
|
plugin_ids,
|
||||||
0,
|
0,
|
||||||
|
true,
|
||||||
self.main_client_id,
|
self.main_client_id,
|
||||||
));
|
));
|
||||||
self.last_opened_tab_index = Some(tab_index);
|
self.last_opened_tab_index = Some(tab_index);
|
||||||
|
|
@ -649,7 +652,7 @@ fn new_tab(screen: &mut Screen, pid: u32, tab_index: usize) {
|
||||||
let new_terminal_ids = vec![(pid, None)];
|
let new_terminal_ids = vec![(pid, None)];
|
||||||
let new_plugin_ids = HashMap::new();
|
let new_plugin_ids = HashMap::new();
|
||||||
screen
|
screen
|
||||||
.new_tab(tab_index, (vec![], vec![]), None, client_id)
|
.new_tab(tab_index, (vec![], vec![]), None, Some(client_id))
|
||||||
.expect("TEST");
|
.expect("TEST");
|
||||||
screen
|
screen
|
||||||
.apply_layout(
|
.apply_layout(
|
||||||
|
|
@ -659,6 +662,7 @@ fn new_tab(screen: &mut Screen, pid: u32, tab_index: usize) {
|
||||||
vec![], // new floating terminal ids
|
vec![], // new floating terminal ids
|
||||||
new_plugin_ids,
|
new_plugin_ids,
|
||||||
tab_index,
|
tab_index,
|
||||||
|
true,
|
||||||
client_id,
|
client_id,
|
||||||
)
|
)
|
||||||
.expect("TEST");
|
.expect("TEST");
|
||||||
|
|
@ -3248,6 +3252,7 @@ pub fn screen_can_break_pane_to_a_new_tab() {
|
||||||
vec![], // floating panes ids
|
vec![], // floating panes ids
|
||||||
Default::default(),
|
Default::default(),
|
||||||
1,
|
1,
|
||||||
|
true,
|
||||||
1,
|
1,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
|
@ -3349,6 +3354,7 @@ pub fn screen_can_break_floating_pane_to_a_new_tab() {
|
||||||
vec![], // floating panes ids
|
vec![], // floating panes ids
|
||||||
Default::default(),
|
Default::default(),
|
||||||
1,
|
1,
|
||||||
|
true,
|
||||||
1,
|
1,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
std::thread::sleep(std::time::Duration::from_millis(200));
|
||||||
|
|
@ -3418,6 +3424,7 @@ pub fn screen_can_break_plugin_pane_to_a_new_tab() {
|
||||||
vec![], // floating panes ids
|
vec![], // floating panes ids
|
||||||
Default::default(),
|
Default::default(),
|
||||||
1,
|
1,
|
||||||
|
true,
|
||||||
1,
|
1,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
|
@ -3491,6 +3498,7 @@ pub fn screen_can_break_floating_plugin_pane_to_a_new_tab() {
|
||||||
vec![], // floating panes ids
|
vec![], // floating panes ids
|
||||||
Default::default(),
|
Default::default(),
|
||||||
1,
|
1,
|
||||||
|
true,
|
||||||
1,
|
1,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 2849
|
assertion_line: 3374
|
||||||
expression: "format!(\"{}\", snapshot)"
|
expression: "format!(\"{}\", snapshot)"
|
||||||
---
|
---
|
||||||
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
|
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -8,18 +8,18 @@ expression: "format!(\"{}\", snapshot)"
|
||||||
02 (C): │ │
|
02 (C): │ │
|
||||||
03 (C): │ │
|
03 (C): │ │
|
||||||
04 (C): │ │
|
04 (C): │ │
|
||||||
05 (C): │ │
|
05 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
|
||||||
06 (C): │ │
|
06 (C): │ │ │ │
|
||||||
07 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
|
07 (C): │ │ │ │
|
||||||
08 (C): │ │ │ │
|
08 (C): │ │ │ │
|
||||||
09 (C): │ │ │ │
|
09 (C): │ │ │ │
|
||||||
10 (C): │ │ │ │
|
10 (C): │ │ │ │
|
||||||
11 (C): │ │ │ │
|
11 (C): │ │ │ │
|
||||||
12 (C): │ │ │ │
|
12 (C): │ │ │ │
|
||||||
13 (C): │ │ │ │
|
13 (C): │ │ │ │
|
||||||
14 (C): │ │ │ │
|
14 (C): │ └──────────────────────────────────────┘ │
|
||||||
15 (C): │ │ │ │
|
15 (C): │ │
|
||||||
16 (C): │ └──────────────────────────────────────┘ │
|
16 (C): │ │
|
||||||
17 (C): │ │
|
17 (C): │ │
|
||||||
18 (C): │ │
|
18 (C): │ │
|
||||||
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 2849
|
assertion_line: 3374
|
||||||
expression: "format!(\"{}\", snapshot)"
|
expression: "format!(\"{}\", snapshot)"
|
||||||
---
|
---
|
||||||
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
|
00 (C): ┌ Pane #2 ─────────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -8,18 +8,18 @@ expression: "format!(\"{}\", snapshot)"
|
||||||
02 (C): │ │
|
02 (C): │ │
|
||||||
03 (C): │ │
|
03 (C): │ │
|
||||||
04 (C): │ │
|
04 (C): │ │
|
||||||
05 (C): │ │
|
05 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
|
||||||
06 (C): │ │
|
06 (C): │ │ │ │
|
||||||
07 (C): │ ┌ floating_pane_to_eject ──────────────┐ │
|
07 (C): │ │ │ │
|
||||||
08 (C): │ │ │ │
|
08 (C): │ │ │ │
|
||||||
09 (C): │ │ │ │
|
09 (C): │ │ │ │
|
||||||
10 (C): │ │ │ │
|
10 (C): │ │ │ │
|
||||||
11 (C): │ │ │ │
|
11 (C): │ │ │ │
|
||||||
12 (C): │ │ │ │
|
12 (C): │ │ │ │
|
||||||
13 (C): │ │ │ │
|
13 (C): │ │ │ │
|
||||||
14 (C): │ │ │ │
|
14 (C): │ └──────────────────────────────────────┘ │
|
||||||
15 (C): │ │ │ │
|
15 (C): │ │
|
||||||
16 (C): │ └──────────────────────────────────────┘ │
|
16 (C): │ │
|
||||||
17 (C): │ │
|
17 (C): │ │
|
||||||
18 (C): │ │
|
18 (C): │ │
|
||||||
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 3512
|
assertion_line: 3516
|
||||||
expression: "format!(\"{}\", snapshot)"
|
expression: "format!(\"{}\", snapshot)"
|
||||||
---
|
---
|
||||||
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -8,18 +8,18 @@ expression: "format!(\"{}\", snapshot)"
|
||||||
02 (C): │ │
|
02 (C): │ │
|
||||||
03 (C): │ │
|
03 (C): │ │
|
||||||
04 (C): │ │
|
04 (C): │ │
|
||||||
05 (C): │ │
|
05 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
||||||
06 (C): │ │
|
06 (C): │ │Loading file:/path/to/fake/plugin │ │
|
||||||
07 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
07 (C): │ │ │ │
|
||||||
08 (C): │ │Loading file:/path/to/fake/plugin │ │
|
08 (C): │ │ │ │
|
||||||
09 (C): │ │ │ │
|
09 (C): │ │ │ │
|
||||||
10 (C): │ │ │ │
|
10 (C): │ │ │ │
|
||||||
11 (C): │ │ │ │
|
11 (C): │ │ │ │
|
||||||
12 (C): │ │ │ │
|
12 (C): │ │ │ │
|
||||||
13 (C): │ │ │ │
|
13 (C): │ │ │ │
|
||||||
14 (C): │ │ │ │
|
14 (C): │ └──────────────────────────────────────┘ │
|
||||||
15 (C): │ │ │ │
|
15 (C): │ │
|
||||||
16 (C): │ └──────────────────────────────────────┘ │
|
16 (C): │ │
|
||||||
17 (C): │ │
|
17 (C): │ │
|
||||||
18 (C): │ │
|
18 (C): │ │
|
||||||
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 3512
|
assertion_line: 3516
|
||||||
expression: "format!(\"{}\", snapshot)"
|
expression: "format!(\"{}\", snapshot)"
|
||||||
---
|
---
|
||||||
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -8,18 +8,18 @@ expression: "format!(\"{}\", snapshot)"
|
||||||
02 (C): │ │
|
02 (C): │ │
|
||||||
03 (C): │ │
|
03 (C): │ │
|
||||||
04 (C): │ │
|
04 (C): │ │
|
||||||
05 (C): │ │
|
05 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
||||||
06 (C): │ │
|
06 (C): │ │Loading file:/path/to/fake/plugin │ │
|
||||||
07 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
07 (C): │ │ │ │
|
||||||
08 (C): │ │Loading file:/path/to/fake/plugin │ │
|
08 (C): │ │ │ │
|
||||||
09 (C): │ │ │ │
|
09 (C): │ │ │ │
|
||||||
10 (C): │ │ │ │
|
10 (C): │ │ │ │
|
||||||
11 (C): │ │ │ │
|
11 (C): │ │ │ │
|
||||||
12 (C): │ │ │ │
|
12 (C): │ │ │ │
|
||||||
13 (C): │ │ │ │
|
13 (C): │ │ │ │
|
||||||
14 (C): │ │ │ │
|
14 (C): │ └──────────────────────────────────────┘ │
|
||||||
15 (C): │ │ │ │
|
15 (C): │ │
|
||||||
16 (C): │ └──────────────────────────────────────┘ │
|
16 (C): │ │
|
||||||
17 (C): │ │
|
17 (C): │ │
|
||||||
18 (C): │ │
|
18 (C): │ │
|
||||||
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 3512
|
assertion_line: 3516
|
||||||
expression: "format!(\"{}\", snapshot)"
|
expression: "format!(\"{}\", snapshot)"
|
||||||
---
|
---
|
||||||
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -8,18 +8,18 @@ expression: "format!(\"{}\", snapshot)"
|
||||||
02 (C): │ │
|
02 (C): │ │
|
||||||
03 (C): │ │
|
03 (C): │ │
|
||||||
04 (C): │ │
|
04 (C): │ │
|
||||||
05 (C): │ │
|
05 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
||||||
06 (C): │ │
|
06 (C): │ │Loading file:/path/to/fake/plugin │ │
|
||||||
07 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
07 (C): │ │ │ │
|
||||||
08 (C): │ │Loading file:/path/to/fake/plugin │ │
|
08 (C): │ │ │ │
|
||||||
09 (C): │ │ │ │
|
09 (C): │ │ │ │
|
||||||
10 (C): │ │ │ │
|
10 (C): │ │ │ │
|
||||||
11 (C): │ │ │ │
|
11 (C): │ │ │ │
|
||||||
12 (C): │ │ │ │
|
12 (C): │ │ │ │
|
||||||
13 (C): │ │ │ │
|
13 (C): │ │ │ │
|
||||||
14 (C): │ │ │ │
|
14 (C): │ └──────────────────────────────────────┘ │
|
||||||
15 (C): │ │ │ │
|
15 (C): │ │
|
||||||
16 (C): │ └──────────────────────────────────────┘ │
|
16 (C): │ │
|
||||||
17 (C): │ │
|
17 (C): │ │
|
||||||
18 (C): │ │
|
18 (C): │ │
|
||||||
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 3512
|
assertion_line: 3516
|
||||||
expression: "format!(\"{}\", snapshot)"
|
expression: "format!(\"{}\", snapshot)"
|
||||||
---
|
---
|
||||||
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
|
||||||
|
|
@ -8,18 +8,18 @@ expression: "format!(\"{}\", snapshot)"
|
||||||
02 (C): │ │
|
02 (C): │ │
|
||||||
03 (C): │ │
|
03 (C): │ │
|
||||||
04 (C): │ │
|
04 (C): │ │
|
||||||
05 (C): │ │
|
05 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
||||||
06 (C): │ │
|
06 (C): │ │Loading file:/path/to/fake/plugin │ │
|
||||||
07 (C): │ ┌ floating_plugin_pane_to_eject ───────┐ │
|
07 (C): │ │ │ │
|
||||||
08 (C): │ │Loading file:/path/to/fake/plugin │ │
|
08 (C): │ │ │ │
|
||||||
09 (C): │ │ │ │
|
09 (C): │ │ │ │
|
||||||
10 (C): │ │ │ │
|
10 (C): │ │ │ │
|
||||||
11 (C): │ │ │ │
|
11 (C): │ │ │ │
|
||||||
12 (C): │ │ │ │
|
12 (C): │ │ │ │
|
||||||
13 (C): │ │ │ │
|
13 (C): │ │ │ │
|
||||||
14 (C): │ │ │ │
|
14 (C): │ └──────────────────────────────────────┘ │
|
||||||
15 (C): │ │ │ │
|
15 (C): │ │
|
||||||
16 (C): │ └──────────────────────────────────────┘ │
|
16 (C): │ │
|
||||||
17 (C): │ │
|
17 (C): │ │
|
||||||
18 (C): │ │
|
18 (C): │ │
|
||||||
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
19 (C): └──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 2246
|
assertion_line: 2665
|
||||||
expression: "format!(\"{:#?}\", new_tab_action)"
|
expression: "format!(\"{:#?}\", new_tab_action)"
|
||||||
---
|
---
|
||||||
Some(
|
Some(
|
||||||
|
|
@ -60,6 +60,7 @@ Some(
|
||||||
),
|
),
|
||||||
[],
|
[],
|
||||||
0,
|
0,
|
||||||
|
true,
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 2292
|
assertion_line: 2711
|
||||||
expression: "format!(\"{:#?}\", new_tab_instruction)"
|
expression: "format!(\"{:#?}\", new_tab_instruction)"
|
||||||
---
|
---
|
||||||
NewTab(
|
NewTab(
|
||||||
|
|
@ -87,5 +87,6 @@ NewTab(
|
||||||
),
|
),
|
||||||
[],
|
[],
|
||||||
1,
|
1,
|
||||||
|
true,
|
||||||
10,
|
10,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 1825
|
assertion_line: 2183
|
||||||
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
|
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
|
||||||
---
|
---
|
||||||
[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), Write([102, 111, 111], 1), ApplyCachedResizes, Exit]
|
[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 58, 18, None, None), ResizePty(1, 59, 18, None, None), ResizePty(0, 59, 18, None, None), ResizePty(1, 58, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), Write([102, 111, 111], 1), ApplyCachedResizes, Exit]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 1065
|
assertion_line: 1423
|
||||||
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
|
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
|
||||||
---
|
---
|
||||||
[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), ApplyCachedResizes, Exit]
|
[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([102, 111, 111], 0), ApplyCachedResizes, Exit]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 1039
|
assertion_line: 1397
|
||||||
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
|
expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())"
|
||||||
---
|
---
|
||||||
[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([105, 110, 112, 117, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 99, 108, 105], 0), ApplyCachedResizes, Exit]
|
[StartCachingResizes, ApplyCachedResizes, StartCachingResizes, ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ResizePty(0, 119, 18, None, None), ApplyCachedResizes, ApplyCachedResizes, StartCachingResizes, ApplyCachedResizes, StartCachingResizes, Write([105, 110, 112, 117, 116, 32, 102, 114, 111, 109, 32, 116, 104, 101, 32, 99, 108, 105], 0), ApplyCachedResizes, Exit]
|
||||||
|
|
|
||||||
|
|
@ -1030,6 +1030,38 @@ where
|
||||||
unsafe { host_run_plugin_command() };
|
unsafe { host_run_plugin_command() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new tab that includes the specified pane ids
|
||||||
|
pub fn break_panes_to_new_tab(
|
||||||
|
pane_ids: &[PaneId],
|
||||||
|
new_tab_name: Option<String>,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
) {
|
||||||
|
let plugin_command = PluginCommand::BreakPanesToNewTab(
|
||||||
|
pane_ids.to_vec(),
|
||||||
|
new_tab_name,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
);
|
||||||
|
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||||
|
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||||
|
unsafe { host_run_plugin_command() };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new tab that includes the specified pane ids
|
||||||
|
pub fn break_panes_to_tab_with_index(
|
||||||
|
pane_ids: &[PaneId],
|
||||||
|
tab_index: usize,
|
||||||
|
should_change_focus_to_new_tab: bool,
|
||||||
|
) {
|
||||||
|
let plugin_command = PluginCommand::BreakPanesToTabWithIndex(
|
||||||
|
pane_ids.to_vec(),
|
||||||
|
tab_index,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
);
|
||||||
|
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||||
|
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||||
|
unsafe { host_run_plugin_command() };
|
||||||
|
}
|
||||||
|
|
||||||
// Utility Functions
|
// Utility Functions
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ pub struct PluginCommand {
|
||||||
pub name: i32,
|
pub name: i32,
|
||||||
#[prost(
|
#[prost(
|
||||||
oneof = "plugin_command::Payload",
|
oneof = "plugin_command::Payload",
|
||||||
tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83"
|
tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85"
|
||||||
)]
|
)]
|
||||||
pub payload: ::core::option::Option<plugin_command::Payload>,
|
pub payload: ::core::option::Option<plugin_command::Payload>,
|
||||||
}
|
}
|
||||||
|
|
@ -164,10 +164,34 @@ pub mod plugin_command {
|
||||||
),
|
),
|
||||||
#[prost(message, tag = "83")]
|
#[prost(message, tag = "83")]
|
||||||
CloseTabWithIndexPayload(super::CloseTabWithIndexPayload),
|
CloseTabWithIndexPayload(super::CloseTabWithIndexPayload),
|
||||||
|
#[prost(message, tag = "84")]
|
||||||
|
BreakPanesToNewTabPayload(super::BreakPanesToNewTabPayload),
|
||||||
|
#[prost(message, tag = "85")]
|
||||||
|
BreakPanesToTabWithIndexPayload(super::BreakPanesToTabWithIndexPayload),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[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 BreakPanesToTabWithIndexPayload {
|
||||||
|
#[prost(message, repeated, tag = "1")]
|
||||||
|
pub pane_ids: ::prost::alloc::vec::Vec<PaneId>,
|
||||||
|
#[prost(uint32, tag = "2")]
|
||||||
|
pub tab_index: u32,
|
||||||
|
#[prost(bool, tag = "3")]
|
||||||
|
pub should_change_focus_to_target_tab: bool,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
|
pub struct BreakPanesToNewTabPayload {
|
||||||
|
#[prost(message, repeated, tag = "1")]
|
||||||
|
pub pane_ids: ::prost::alloc::vec::Vec<PaneId>,
|
||||||
|
#[prost(bool, tag = "2")]
|
||||||
|
pub should_change_focus_to_new_tab: bool,
|
||||||
|
#[prost(string, optional, tag = "3")]
|
||||||
|
pub new_tab_name: ::core::option::Option<::prost::alloc::string::String>,
|
||||||
|
}
|
||||||
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct MovePaneWithPaneIdPayload {
|
pub struct MovePaneWithPaneIdPayload {
|
||||||
#[prost(message, optional, tag = "1")]
|
#[prost(message, optional, tag = "1")]
|
||||||
pub pane_id: ::core::option::Option<PaneId>,
|
pub pane_id: ::core::option::Option<PaneId>,
|
||||||
|
|
@ -634,6 +658,8 @@ pub enum CommandName {
|
||||||
TogglePaneIdFullscreen = 105,
|
TogglePaneIdFullscreen = 105,
|
||||||
TogglePaneEmbedOrEjectForPaneId = 106,
|
TogglePaneEmbedOrEjectForPaneId = 106,
|
||||||
CloseTabWithIndex = 107,
|
CloseTabWithIndex = 107,
|
||||||
|
BreakPanesToNewTab = 108,
|
||||||
|
BreakPanesToTabWithIndex = 109,
|
||||||
}
|
}
|
||||||
impl CommandName {
|
impl CommandName {
|
||||||
/// String value of the enum field names used in the ProtoBuf definition.
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
|
@ -752,6 +778,8 @@ impl CommandName {
|
||||||
"TogglePaneEmbedOrEjectForPaneId"
|
"TogglePaneEmbedOrEjectForPaneId"
|
||||||
}
|
}
|
||||||
CommandName::CloseTabWithIndex => "CloseTabWithIndex",
|
CommandName::CloseTabWithIndex => "CloseTabWithIndex",
|
||||||
|
CommandName::BreakPanesToNewTab => "BreakPanesToNewTab",
|
||||||
|
CommandName::BreakPanesToTabWithIndex => "BreakPanesToTabWithIndex",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
|
@ -867,6 +895,8 @@ impl CommandName {
|
||||||
Some(Self::TogglePaneEmbedOrEjectForPaneId)
|
Some(Self::TogglePaneEmbedOrEjectForPaneId)
|
||||||
}
|
}
|
||||||
"CloseTabWithIndex" => Some(Self::CloseTabWithIndex),
|
"CloseTabWithIndex" => Some(Self::CloseTabWithIndex),
|
||||||
|
"BreakPanesToNewTab" => Some(Self::BreakPanesToNewTab),
|
||||||
|
"BreakPanesToTabWithIndex" => Some(Self::BreakPanesToTabWithIndex),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1836,4 +1836,10 @@ pub enum PluginCommand {
|
||||||
TogglePaneIdFullscreen(PaneId),
|
TogglePaneIdFullscreen(PaneId),
|
||||||
TogglePaneEmbedOrEjectForPaneId(PaneId),
|
TogglePaneEmbedOrEjectForPaneId(PaneId),
|
||||||
CloseTabWithIndex(usize), // usize - tab_index
|
CloseTabWithIndex(usize), // usize - tab_index
|
||||||
|
BreakPanesToNewTab(Vec<PaneId>, Option<String>, bool), // bool -
|
||||||
|
// should_change_focus_to_new_tab,
|
||||||
|
// Option<String> - optional name for
|
||||||
|
// the new tab
|
||||||
|
BreakPanesToTabWithIndex(Vec<PaneId>, usize, bool), // usize - tab_index, bool -
|
||||||
|
// should_change_focus_to_new_tab
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,8 @@ pub enum ScreenContext {
|
||||||
TogglePaneIdFullscreen,
|
TogglePaneIdFullscreen,
|
||||||
TogglePaneEmbedOrEjectForPaneId,
|
TogglePaneEmbedOrEjectForPaneId,
|
||||||
CloseTabWithIndex,
|
CloseTabWithIndex,
|
||||||
|
BreakPanesToNewTab,
|
||||||
|
BreakPanesToTabWithIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
|
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
|
||||||
|
|
|
||||||
|
|
@ -938,7 +938,16 @@ impl TiledPaneLayout {
|
||||||
.len()
|
.len()
|
||||||
.saturating_sub(successfully_ignored)
|
.saturating_sub(successfully_ignored)
|
||||||
{
|
{
|
||||||
if let Some(position) = run_instructions.iter().position(|i| i == &None) {
|
if let Some(position) = run_instructions.iter().position(|i| {
|
||||||
|
match i {
|
||||||
|
// this is because a bare CWD instruction should be overidden by a terminal
|
||||||
|
// in run_instructions_to_ignore (for cases where the cwd for example comes
|
||||||
|
// from a global layout cwd and the pane is actually just a bare pane that
|
||||||
|
// wants to be overidden)
|
||||||
|
Some(Run::Cwd(_)) | None => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}) {
|
||||||
run_instructions.remove(position);
|
run_instructions.remove(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,8 @@ enum CommandName {
|
||||||
TogglePaneIdFullscreen = 105;
|
TogglePaneIdFullscreen = 105;
|
||||||
TogglePaneEmbedOrEjectForPaneId = 106;
|
TogglePaneEmbedOrEjectForPaneId = 106;
|
||||||
CloseTabWithIndex = 107;
|
CloseTabWithIndex = 107;
|
||||||
|
BreakPanesToNewTab = 108;
|
||||||
|
BreakPanesToTabWithIndex = 109;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PluginCommand {
|
message PluginCommand {
|
||||||
|
|
@ -197,9 +199,23 @@ message PluginCommand {
|
||||||
TogglePaneIdFullscreenPayload toggle_pane_id_fullscreen_payload = 81;
|
TogglePaneIdFullscreenPayload toggle_pane_id_fullscreen_payload = 81;
|
||||||
TogglePaneEmbedOrEjectForPaneIdPayload toggle_pane_embed_or_eject_for_pane_id_payload = 82;
|
TogglePaneEmbedOrEjectForPaneIdPayload toggle_pane_embed_or_eject_for_pane_id_payload = 82;
|
||||||
CloseTabWithIndexPayload close_tab_with_index_payload = 83;
|
CloseTabWithIndexPayload close_tab_with_index_payload = 83;
|
||||||
|
BreakPanesToNewTabPayload break_panes_to_new_tab_payload = 84;
|
||||||
|
BreakPanesToTabWithIndexPayload break_panes_to_tab_with_index_payload = 85;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message BreakPanesToTabWithIndexPayload {
|
||||||
|
repeated PaneId pane_ids = 1;
|
||||||
|
uint32 tab_index = 2;
|
||||||
|
bool should_change_focus_to_target_tab = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BreakPanesToNewTabPayload {
|
||||||
|
repeated PaneId pane_ids = 1;
|
||||||
|
bool should_change_focus_to_new_tab = 2;
|
||||||
|
optional string new_tab_name = 3;
|
||||||
|
}
|
||||||
|
|
||||||
message MovePaneWithPaneIdPayload {
|
message MovePaneWithPaneIdPayload {
|
||||||
PaneId pane_id = 1;
|
PaneId pane_id = 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ pub use super::generated_api::api::{
|
||||||
event::{EventNameList as ProtobufEventNameList, Header},
|
event::{EventNameList as ProtobufEventNameList, Header},
|
||||||
input_mode::InputMode as ProtobufInputMode,
|
input_mode::InputMode as ProtobufInputMode,
|
||||||
plugin_command::{
|
plugin_command::{
|
||||||
plugin_command::Payload, ClearScreenForPaneIdPayload, CliPipeOutputPayload,
|
plugin_command::Payload, BreakPanesToNewTabPayload, BreakPanesToTabWithIndexPayload,
|
||||||
CloseTabWithIndexPayload, CommandName, ContextItem, EditScrollbackForPaneWithIdPayload,
|
ClearScreenForPaneIdPayload, CliPipeOutputPayload, CloseTabWithIndexPayload, CommandName,
|
||||||
EnvVariable, ExecCmdPayload, FixedOrPercent as ProtobufFixedOrPercent,
|
ContextItem, EditScrollbackForPaneWithIdPayload, EnvVariable, ExecCmdPayload,
|
||||||
|
FixedOrPercent as ProtobufFixedOrPercent,
|
||||||
FixedOrPercentValue as ProtobufFixedOrPercentValue,
|
FixedOrPercentValue as ProtobufFixedOrPercentValue,
|
||||||
FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HidePaneWithIdPayload,
|
FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HidePaneWithIdPayload,
|
||||||
HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, MessageToPluginPayload,
|
HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, MessageToPluginPayload,
|
||||||
|
|
@ -1174,6 +1175,34 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
|
||||||
),
|
),
|
||||||
_ => Err("Mismatched payload for CloseTabWithIndex"),
|
_ => Err("Mismatched payload for CloseTabWithIndex"),
|
||||||
},
|
},
|
||||||
|
Some(CommandName::BreakPanesToNewTab) => match protobuf_plugin_command.payload {
|
||||||
|
Some(Payload::BreakPanesToNewTabPayload(break_panes_to_new_tab_payload)) => {
|
||||||
|
Ok(PluginCommand::BreakPanesToNewTab(
|
||||||
|
break_panes_to_new_tab_payload
|
||||||
|
.pane_ids
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|p_id| p_id.try_into().ok())
|
||||||
|
.collect(),
|
||||||
|
break_panes_to_new_tab_payload.new_tab_name,
|
||||||
|
break_panes_to_new_tab_payload.should_change_focus_to_new_tab,
|
||||||
|
))
|
||||||
|
},
|
||||||
|
_ => Err("Mismatched payload for BreakPanesToNewTab"),
|
||||||
|
},
|
||||||
|
Some(CommandName::BreakPanesToTabWithIndex) => match protobuf_plugin_command.payload {
|
||||||
|
Some(Payload::BreakPanesToTabWithIndexPayload(
|
||||||
|
break_panes_to_tab_with_index_payload,
|
||||||
|
)) => Ok(PluginCommand::BreakPanesToTabWithIndex(
|
||||||
|
break_panes_to_tab_with_index_payload
|
||||||
|
.pane_ids
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|p_id| p_id.try_into().ok())
|
||||||
|
.collect(),
|
||||||
|
break_panes_to_tab_with_index_payload.tab_index as usize,
|
||||||
|
break_panes_to_tab_with_index_payload.should_change_focus_to_target_tab,
|
||||||
|
)),
|
||||||
|
_ => Err("Mismatched payload for BreakPanesToTabWithIndex"),
|
||||||
|
},
|
||||||
None => Err("Unrecognized plugin command"),
|
None => Err("Unrecognized plugin command"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1922,6 +1951,40 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
}),
|
}),
|
||||||
|
PluginCommand::BreakPanesToNewTab(
|
||||||
|
pane_ids,
|
||||||
|
new_tab_name,
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
) => Ok(ProtobufPluginCommand {
|
||||||
|
name: CommandName::BreakPanesToNewTab as i32,
|
||||||
|
payload: Some(Payload::BreakPanesToNewTabPayload(
|
||||||
|
BreakPanesToNewTabPayload {
|
||||||
|
pane_ids: pane_ids
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|p_id| p_id.try_into().ok())
|
||||||
|
.collect(),
|
||||||
|
should_change_focus_to_new_tab,
|
||||||
|
new_tab_name,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
}),
|
||||||
|
PluginCommand::BreakPanesToTabWithIndex(
|
||||||
|
pane_ids,
|
||||||
|
tab_index,
|
||||||
|
should_change_focus_to_target_tab,
|
||||||
|
) => Ok(ProtobufPluginCommand {
|
||||||
|
name: CommandName::BreakPanesToTabWithIndex as i32,
|
||||||
|
payload: Some(Payload::BreakPanesToTabWithIndexPayload(
|
||||||
|
BreakPanesToTabWithIndexPayload {
|
||||||
|
pane_ids: pane_ids
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|p_id| p_id.try_into().ok())
|
||||||
|
.collect(),
|
||||||
|
tab_index: tab_index as u32,
|
||||||
|
should_change_focus_to_target_tab,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue