fix(tabs): allow setting cwd without a layout (#4273)

* working for cli and keybinding

* working for plugin API

* style(fmt): rustfmt

* docs(changelog): add PR
This commit is contained in:
Aram Drevekenin 2025-07-08 11:06:03 +02:00 committed by GitHub
parent 2b9884645d
commit 358caa180c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 99 additions and 33 deletions

View file

@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* feat: add "stack" keybinding and CLI action to add a stacked pane to the current pane (https://github.com/zellij-org/zellij/pull/4255) * feat: add "stack" keybinding and CLI action to add a stacked pane to the current pane (https://github.com/zellij-org/zellij/pull/4255)
* fix: support multiline hyperlinks (https://github.com/zellij-org/zellij/pull/4264) * fix: support multiline hyperlinks (https://github.com/zellij-org/zellij/pull/4264)
* fix: use terminal title when spawning terminal panes from plugin (https://github.com/zellij-org/zellij/pull/4272) * fix: use terminal title when spawning terminal panes from plugin (https://github.com/zellij-org/zellij/pull/4272)
* fix: allow specifying CWD for tabs without necessitating a layout (https://github.com/zellij-org/zellij/pull/4273)
## [0.42.2] - 2025-04-15 ## [0.42.2] - 2025-04-15
* refactor(terminal): track scroll_region as tuple rather than Option (https://github.com/zellij-org/zellij/pull/4082) * refactor(terminal): track scroll_region as tuple rather than Option (https://github.com/zellij-org/zellij/pull/4082)

View file

@ -348,7 +348,10 @@ impl KeybindProcessor {
|action: &Action| matches!(action, Action::GoToPreviousTab), |action: &Action| matches!(action, Action::GoToPreviousTab),
|action: &Action| matches!(action, Action::GoToNextTab), |action: &Action| matches!(action, Action::GoToNextTab),
|action: &Action| { |action: &Action| {
matches!(action, Action::NewTab(None, _, None, None, None, true)) matches!(
action,
Action::NewTab(None, _, None, None, None, true, None)
)
}, },
|action: &Action| matches!(action, Action::CloseTab), |action: &Action| matches!(action, Action::CloseTab),
|action: &Action| matches!(action, Action::SwitchToMode(InputMode::RenameTab)), |action: &Action| matches!(action, Action::SwitchToMode(InputMode::RenameTab)),

View file

@ -92,7 +92,9 @@ impl ZellijPlugin for State {
}", }",
); );
}, },
BareKey::Char('c') if key.has_no_modifiers() => new_tab(), BareKey::Char('c') if key.has_no_modifiers() => {
new_tab(Some("new_tab_name"), Some("/path/to/my/cwd"))
},
BareKey::Char('d') if key.has_no_modifiers() => go_to_next_tab(), BareKey::Char('d') if key.has_no_modifiers() => go_to_next_tab(),
BareKey::Char('e') if key.has_no_modifiers() => go_to_previous_tab(), BareKey::Char('e') if key.has_no_modifiers() => go_to_previous_tab(),
BareKey::Char('f') if key.has_no_modifiers() => { BareKey::Char('f') if key.has_no_modifiers() => {

View file

@ -1296,7 +1296,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
}; };
vec![ vec![
(s("New"), s("New"), single_action_key(&km, &[A::NewTab(None, vec![], None, None, None, true), TO_NORMAL])), (s("New"), s("New"), single_action_key(&km, &[A::NewTab(None, vec![], None, None, None, true, None), TO_NORMAL])),
(s("Change focus"), s("Move"), focus_keys), (s("Change focus"), s("Move"), focus_keys),
(s("Close"), s("Close"), single_action_key(&km, &[A::CloseTab, TO_NORMAL])), (s("Close"), s("Close"), single_action_key(&km, &[A::CloseTab, TO_NORMAL])),
(s("Rename"), s("Rename"), (s("Rename"), s("Rename"),
@ -1381,7 +1381,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
(s("Split down"), s("Down"), action_key(&km, &[A::NewPane(Some(Dir::Down), None, false), TO_NORMAL])), (s("Split down"), s("Down"), action_key(&km, &[A::NewPane(Some(Dir::Down), None, false), TO_NORMAL])),
(s("Split right"), s("Right"), action_key(&km, &[A::NewPane(Some(Dir::Right), None, false), TO_NORMAL])), (s("Split right"), s("Right"), action_key(&km, &[A::NewPane(Some(Dir::Right), None, false), TO_NORMAL])),
(s("Fullscreen"), s("Fullscreen"), action_key(&km, &[A::ToggleFocusFullscreen, TO_NORMAL])), (s("Fullscreen"), s("Fullscreen"), action_key(&km, &[A::ToggleFocusFullscreen, TO_NORMAL])),
(s("New tab"), s("New"), action_key(&km, &[A::NewTab(None, vec![], None, None, None, true), TO_NORMAL])), (s("New tab"), s("New"), action_key(&km, &[A::NewTab(None, vec![], None, None, None, true, None), TO_NORMAL])),
(s("Rename tab"), s("Rename"), (s("Rename tab"), s("Rename"),
action_key(&km, &[A::SwitchToMode(IM::RenameTab), A::TabNameInput(vec![0])])), action_key(&km, &[A::SwitchToMode(IM::RenameTab), A::TabNameInput(vec![0])])),
(s("Previous Tab"), s("Previous"), action_key(&km, &[A::GoToPreviousTab, TO_NORMAL])), (s("Previous Tab"), s("Previous"), action_key(&km, &[A::GoToPreviousTab, TO_NORMAL])),

View file

@ -173,7 +173,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
}; };
vec![ vec![
(s("New"), s("New"), action_key(&km, &[A::NewTab(None, vec![], None, None, None, true), TO_NORMAL])), (s("New"), s("New"), action_key(&km, &[A::NewTab(None, vec![], None, None, None, true, None), TO_NORMAL])),
(s("Change focus"), s("Move"), focus_keys), (s("Change focus"), s("Move"), focus_keys),
(s("Close"), s("Close"), action_key(&km, &[A::CloseTab, TO_NORMAL])), (s("Close"), s("Close"), action_key(&km, &[A::CloseTab, TO_NORMAL])),
(s("Rename"), s("Rename"), (s("Rename"), s("Rename"),
@ -253,7 +253,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
(s("Split down"), s("Down"), action_key(&km, &[A::NewPane(Some(Dir::Down), None, false), TO_NORMAL])), (s("Split down"), s("Down"), action_key(&km, &[A::NewPane(Some(Dir::Down), None, false), TO_NORMAL])),
(s("Split right"), s("Right"), action_key(&km, &[A::NewPane(Some(Dir::Right), None, false), TO_NORMAL])), (s("Split right"), s("Right"), action_key(&km, &[A::NewPane(Some(Dir::Right), None, false), TO_NORMAL])),
(s("Fullscreen"), s("Fullscreen"), action_key(&km, &[A::ToggleFocusFullscreen, TO_NORMAL])), (s("Fullscreen"), s("Fullscreen"), action_key(&km, &[A::ToggleFocusFullscreen, TO_NORMAL])),
(s("New tab"), s("New"), action_key(&km, &[A::NewTab(None, vec![], None, None, None, true), TO_NORMAL])), (s("New tab"), s("New"), action_key(&km, &[A::NewTab(None, vec![], None, None, None, true, None), TO_NORMAL])),
(s("Rename tab"), s("Rename"), (s("Rename tab"), s("Rename"),
action_key(&km, &[A::SwitchToMode(IM::RenameTab), A::TabNameInput(vec![0])])), action_key(&km, &[A::SwitchToMode(IM::RenameTab), A::TabNameInput(vec![0])])),
(s("Previous Tab"), s("Previous"), action_key(&km, &[A::GoToPreviousTab, TO_NORMAL])), (s("Previous Tab"), s("Previous"), action_key(&km, &[A::GoToPreviousTab, TO_NORMAL])),

View file

@ -4,11 +4,15 @@ expression: "format!(\"{:#?}\", new_tab_event)"
--- ---
Some( Some(
NewTab( NewTab(
None, Some(
"/path/to/my/cwd",
),
None, None,
None, None,
[], [],
None, Some(
"new_tab_name",
),
( (
[], [],
[], [],

View file

@ -179,7 +179,7 @@ fn host_run_plugin_command(mut caller: Caller<'_, PluginEnv>) {
PluginCommand::NewTabsWithLayoutInfo(layout_info) => { PluginCommand::NewTabsWithLayoutInfo(layout_info) => {
new_tabs_with_layout_info(env, layout_info)? new_tabs_with_layout_info(env, layout_info)?
}, },
PluginCommand::NewTab => new_tab(env), PluginCommand::NewTab { name, cwd } => new_tab(env, name, cwd),
PluginCommand::GoToNextTab => go_to_next_tab(env), PluginCommand::GoToNextTab => go_to_next_tab(env),
PluginCommand::GoToPreviousTab => go_to_previous_tab(env), PluginCommand::GoToPreviousTab => go_to_previous_tab(env),
PluginCommand::Resize(resize_payload) => resize(env, resize_payload), PluginCommand::Resize(resize_payload) => resize(env, resize_payload),
@ -1451,6 +1451,7 @@ fn new_tabs_with_layout_info(env: &PluginEnv, layout_info: LayoutInfo) -> Result
fn apply_layout(env: &PluginEnv, layout: Layout) { fn apply_layout(env: &PluginEnv, layout: Layout) {
let mut tabs_to_open = vec![]; let mut tabs_to_open = vec![];
let tabs = layout.tabs(); let tabs = layout.tabs();
let cwd = None; // TODO: add this to the plugin API
if tabs.is_empty() { if tabs.is_empty() {
let swap_tiled_layouts = Some(layout.swap_tiled_layouts.clone()); let swap_tiled_layouts = Some(layout.swap_tiled_layouts.clone());
let swap_floating_layouts = Some(layout.swap_floating_layouts.clone()); let swap_floating_layouts = Some(layout.swap_floating_layouts.clone());
@ -1461,6 +1462,7 @@ fn apply_layout(env: &PluginEnv, layout: Layout) {
swap_floating_layouts, swap_floating_layouts,
None, None,
true, true,
cwd,
); );
tabs_to_open.push(action); tabs_to_open.push(action);
} else { } else {
@ -1478,6 +1480,7 @@ fn apply_layout(env: &PluginEnv, layout: Layout) {
swap_floating_layouts, swap_floating_layouts,
tab_name, tab_name,
should_focus_tab, should_focus_tab,
cwd.clone(),
); );
tabs_to_open.push(action); tabs_to_open.push(action);
} }
@ -1488,8 +1491,9 @@ fn apply_layout(env: &PluginEnv, layout: Layout) {
} }
} }
fn new_tab(env: &PluginEnv) { fn new_tab(env: &PluginEnv, name: Option<String>, cwd: Option<String>) {
let action = Action::NewTab(None, vec![], None, None, None, true); let cwd = cwd.map(|c| PathBuf::from(c));
let action = Action::NewTab(None, vec![], None, None, name, true, cwd);
let error_msg = || format!("Failed to open new tab"); let error_msg = || format!("Failed to open new tab");
apply_action!(action, error_msg, env); apply_action!(action, error_msg, env);
} }
@ -2575,7 +2579,7 @@ fn check_command_permission(
| PluginCommand::SwitchToMode(..) | PluginCommand::SwitchToMode(..)
| PluginCommand::NewTabsWithLayout(..) | PluginCommand::NewTabsWithLayout(..)
| PluginCommand::NewTabsWithLayoutInfo(..) | PluginCommand::NewTabsWithLayoutInfo(..)
| PluginCommand::NewTab | PluginCommand::NewTab { .. }
| PluginCommand::GoToNextTab | PluginCommand::GoToNextTab
| PluginCommand::GoToPreviousTab | PluginCommand::GoToPreviousTab
| PluginCommand::Resize(..) | PluginCommand::Resize(..)

View file

@ -462,6 +462,7 @@ pub(crate) fn route_action(
swap_floating_layouts, swap_floating_layouts,
tab_name, tab_name,
should_change_focus_to_new_tab, should_change_focus_to_new_tab,
cwd,
) => { ) => {
let shell = default_shell.clone(); let shell = default_shell.clone();
let swap_tiled_layouts = let swap_tiled_layouts =
@ -471,7 +472,7 @@ pub(crate) fn route_action(
let is_web_client = false; // actions cannot be initiated directly from the web let is_web_client = false; // actions cannot be initiated directly from the web
senders senders
.send_to_screen(ScreenInstruction::NewTab( .send_to_screen(ScreenInstruction::NewTab(
None, cwd,
shell, shell,
tab_layout, tab_layout,
floating_panes_layout, floating_panes_layout,

View file

@ -434,8 +434,13 @@ pub fn new_tabs_with_layout_info(layout_info: LayoutInfo) {
} }
/// Open a new tab with the default layout /// Open a new tab with the default layout
pub fn new_tab() { pub fn new_tab<S: AsRef<str>>(name: Option<S>, cwd: Option<S>)
let plugin_command = PluginCommand::NewTab; where
S: ToString,
{
let name = name.map(|s| s.to_string());
let cwd = cwd.map(|s| s.to_string());
let plugin_command = PluginCommand::NewTab { name, cwd };
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec()); object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() }; unsafe { host_run_plugin_command() };

View file

@ -3,7 +3,7 @@
pub struct PluginCommand { pub struct PluginCommand {
#[prost(enumeration="CommandName", tag="1")] #[prost(enumeration="CommandName", tag="1")]
pub name: i32, pub name: i32,
#[prost(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, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111")] #[prost(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, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112")]
pub payload: ::core::option::Option<plugin_command::Payload>, pub payload: ::core::option::Option<plugin_command::Payload>,
} }
/// Nested message and enum types in `PluginCommand`. /// Nested message and enum types in `PluginCommand`.
@ -213,10 +213,20 @@ pub mod plugin_command {
RenameWebLoginTokenPayload(super::RenameWebLoginTokenPayload), RenameWebLoginTokenPayload(super::RenameWebLoginTokenPayload),
#[prost(message, tag="111")] #[prost(message, tag="111")]
ReplacePaneWithExistingPanePayload(super::ReplacePaneWithExistingPanePayload), ReplacePaneWithExistingPanePayload(super::ReplacePaneWithExistingPanePayload),
#[prost(message, tag="112")]
NewTabPayload(super::NewTabPayload),
} }
} }
#[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 NewTabPayload {
#[prost(string, optional, tag="1")]
pub name: ::core::option::Option<::prost::alloc::string::String>,
#[prost(string, optional, tag="2")]
pub cwd: ::core::option::Option<::prost::alloc::string::String>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ReplacePaneWithExistingPanePayload { pub struct ReplacePaneWithExistingPanePayload {
#[prost(message, optional, tag="1")] #[prost(message, optional, tag="1")]
pub pane_id_to_replace: ::core::option::Option<PaneId>, pub pane_id_to_replace: ::core::option::Option<PaneId>,

View file

@ -722,7 +722,7 @@ pub enum CliAction {
name: Option<String>, name: Option<String>,
/// Change the working directory of the new tab /// Change the working directory of the new tab
#[clap(short, long, value_parser, requires("layout"))] #[clap(short, long, value_parser)]
cwd: Option<PathBuf>, cwd: Option<PathBuf>,
}, },
/// Move the focused tab in the specified direction. [right|left] /// Move the focused tab in the specified direction. [right|left]

View file

@ -2344,7 +2344,10 @@ pub enum PluginCommand {
ShowSelf(bool), // bool - should float if hidden ShowSelf(bool), // bool - should float if hidden
SwitchToMode(InputMode), SwitchToMode(InputMode),
NewTabsWithLayout(String), // raw kdl layout NewTabsWithLayout(String), // raw kdl layout
NewTab, NewTab {
name: Option<String>,
cwd: Option<String>,
},
GoToNextTab, GoToNextTab,
GoToPreviousTab, GoToPreviousTab,
Resize(Resize), Resize(Resize),

View file

@ -199,6 +199,7 @@ pub enum Action {
Option<Vec<SwapFloatingLayout>>, Option<Vec<SwapFloatingLayout>>,
Option<String>, Option<String>,
bool, // should_change_focus_to_new_tab bool, // should_change_focus_to_new_tab
Option<PathBuf>, // cwd
), // the String is the tab name ), // the String is the tab name
/// Do nothing. /// Do nothing.
NoOp, NoOp,
@ -621,6 +622,7 @@ impl Action {
swap_floating_layouts.clone(), swap_floating_layouts.clone(),
name, name,
should_change_focus_to_new_tab, should_change_focus_to_new_tab,
None, // the cwd is done through the layout
)); ));
} }
Ok(new_tab_actions) Ok(new_tab_actions)
@ -636,6 +638,7 @@ impl Action {
swap_floating_layouts, swap_floating_layouts,
name, name,
should_change_focus_to_new_tab, should_change_focus_to_new_tab,
None, // the cwd is done through the layout
)]) )])
} }
} else { } else {
@ -647,6 +650,7 @@ impl Action {
None, None,
name, name,
should_change_focus_to_new_tab, should_change_focus_to_new_tab,
cwd,
)]) )])
} }
}, },

View file

@ -696,11 +696,10 @@ impl Action {
Some(node) Some(node)
}, },
Action::UndoRenamePane => Some(KdlNode::new("UndoRenamePane")), Action::UndoRenamePane => Some(KdlNode::new("UndoRenamePane")),
Action::NewTab(_, _, _, _, name, should_change_focus_to_new_tab) => { Action::NewTab(_, _, _, _, name, should_change_focus_to_new_tab, cwd) => {
log::warn!("Converting new tab action without arguments, original action saved to .bak.kdl file");
let mut node = KdlNode::new("NewTab"); let mut node = KdlNode::new("NewTab");
if let Some(name) = name {
let mut children = KdlDocument::new(); let mut children = KdlDocument::new();
if let Some(name) = name {
let mut name_node = KdlNode::new("name"); let mut name_node = KdlNode::new("name");
if !should_change_focus_to_new_tab { if !should_change_focus_to_new_tab {
let mut should_change_focus_to_new_tab_node = let mut should_change_focus_to_new_tab_node =
@ -712,6 +711,13 @@ impl Action {
} }
name_node.push(name.clone()); name_node.push(name.clone());
children.nodes_mut().push(name_node); children.nodes_mut().push(name_node);
}
if let Some(cwd) = cwd {
let mut cwd_node = KdlNode::new("cwd");
cwd_node.push(cwd.display().to_string());
children.nodes_mut().push(cwd_node);
}
if name.is_some() || cwd.is_some() {
node.set_children(children); node.set_children(children);
} }
Some(node) Some(node)
@ -1472,7 +1478,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
"NewTab" => { "NewTab" => {
let command_metadata = action_children.iter().next(); let command_metadata = action_children.iter().next();
if command_metadata.is_none() { if command_metadata.is_none() {
return Ok(Action::NewTab(None, vec![], None, None, None, true)); return Ok(Action::NewTab(None, vec![], None, None, None, true, None));
} }
let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
@ -1508,7 +1514,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
&raw_layout, &raw_layout,
path_to_raw_layout, path_to_raw_layout,
swap_layouts.as_ref().map(|(f, p)| (f.as_str(), p.as_str())), swap_layouts.as_ref().map(|(f, p)| (f.as_str(), p.as_str())),
cwd, cwd.clone(),
) )
.map_err(|e| { .map_err(|e| {
ConfigError::new_kdl_error( ConfigError::new_kdl_error(
@ -1540,6 +1546,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
swap_floating_layouts, swap_floating_layouts,
name, name,
should_change_focus_to_new_tab, should_change_focus_to_new_tab,
cwd,
)) ))
} else { } else {
let (layout, floating_panes_layout) = layout.new_tab(); let (layout, floating_panes_layout) = layout.new_tab();
@ -1552,6 +1559,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
swap_floating_layouts, swap_floating_layouts,
name, name,
should_change_focus_to_new_tab, should_change_focus_to_new_tab,
cwd,
)) ))
} }
}, },

View file

@ -315,7 +315,7 @@ impl TryFrom<ProtobufAction> for Action {
Some(_) => Err("NewTab should not have a payload"), Some(_) => Err("NewTab should not have a payload"),
None => { None => {
// we do not serialize the layouts of this action // we do not serialize the layouts of this action
Ok(Action::NewTab(None, vec![], None, None, None, true)) Ok(Action::NewTab(None, vec![], None, None, None, true, None))
}, },
} }
}, },

View file

@ -265,9 +265,15 @@ message PluginCommand {
RevokeWebLoginTokenPayload revoke_web_login_token_payload = 109; RevokeWebLoginTokenPayload revoke_web_login_token_payload = 109;
RenameWebLoginTokenPayload rename_web_login_token_payload = 110; RenameWebLoginTokenPayload rename_web_login_token_payload = 110;
ReplacePaneWithExistingPanePayload replace_pane_with_existing_pane_payload = 111; ReplacePaneWithExistingPanePayload replace_pane_with_existing_pane_payload = 111;
NewTabPayload new_tab_payload = 112;
} }
} }
message NewTabPayload {
optional string name = 1;
optional string cwd = 2;
}
message ReplacePaneWithExistingPanePayload { message ReplacePaneWithExistingPanePayload {
PaneId pane_id_to_replace = 1; PaneId pane_id_to_replace = 1;
PaneId existing_pane_id = 2; PaneId existing_pane_id = 2;

View file

@ -16,7 +16,7 @@ pub use super::generated_api::api::{
HttpVerb as ProtobufHttpVerb, IdAndNewName, KeyToRebind, KeyToUnbind, KillSessionsPayload, HttpVerb as ProtobufHttpVerb, IdAndNewName, KeyToRebind, KeyToUnbind, KillSessionsPayload,
ListTokensResponse, LoadNewPluginPayload, MessageToPluginPayload, ListTokensResponse, LoadNewPluginPayload, MessageToPluginPayload,
MovePaneWithPaneIdInDirectionPayload, MovePaneWithPaneIdPayload, MovePayload, MovePaneWithPaneIdInDirectionPayload, MovePaneWithPaneIdPayload, MovePayload,
NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload, NewPluginArgs as ProtobufNewPluginArgs, NewTabPayload, NewTabsWithLayoutInfoPayload,
OpenCommandPaneFloatingNearPluginPayload, OpenCommandPaneInPlaceOfPluginPayload, OpenCommandPaneFloatingNearPluginPayload, OpenCommandPaneInPlaceOfPluginPayload,
OpenCommandPaneNearPluginPayload, OpenCommandPanePayload, OpenCommandPaneNearPluginPayload, OpenCommandPanePayload,
OpenFileFloatingNearPluginPayload, OpenFileInPlaceOfPluginPayload, OpenFileFloatingNearPluginPayload, OpenFileInPlaceOfPluginPayload,
@ -474,11 +474,18 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
}, },
_ => Err("Mismatched payload for NewTabsWithLayout"), _ => Err("Mismatched payload for NewTabsWithLayout"),
}, },
Some(CommandName::NewTab) => { Some(CommandName::NewTab) => match protobuf_plugin_command.payload {
if protobuf_plugin_command.payload.is_some() { Some(Payload::NewTabPayload(protobuf_new_tab_payload)) => {
return Err("NewTab should not have a payload"); Ok(PluginCommand::NewTab {
} name: protobuf_new_tab_payload.name,
Ok(PluginCommand::NewTab) cwd: protobuf_new_tab_payload.cwd,
})
},
None => Ok(PluginCommand::NewTab {
name: None,
cwd: None,
}),
_ => Err("Mismatched payload for NewTab"),
}, },
Some(CommandName::GoToNextTab) => { Some(CommandName::GoToNextTab) => {
if protobuf_plugin_command.payload.is_some() { if protobuf_plugin_command.payload.is_some() {
@ -1886,9 +1893,9 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
name: CommandName::NewTabsWithLayout as i32, name: CommandName::NewTabsWithLayout as i32,
payload: Some(Payload::NewTabsWithLayoutPayload(raw_layout)), payload: Some(Payload::NewTabsWithLayoutPayload(raw_layout)),
}), }),
PluginCommand::NewTab => Ok(ProtobufPluginCommand { PluginCommand::NewTab { name, cwd } => Ok(ProtobufPluginCommand {
name: CommandName::NewTab as i32, name: CommandName::NewTab as i32,
payload: None, payload: Some(Payload::NewTabPayload(NewTabPayload { name, cwd })),
}), }),
PluginCommand::GoToNextTab => Ok(ProtobufPluginCommand { PluginCommand::GoToNextTab => Ok(ProtobufPluginCommand {
name: CommandName::GoToNextTab as i32, name: CommandName::GoToNextTab as i32,

View file

@ -1852,6 +1852,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,
@ -5582,6 +5583,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,

View file

@ -1852,6 +1852,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,
@ -5582,6 +5583,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,

View file

@ -1852,6 +1852,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,
@ -5582,6 +5583,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,

View file

@ -1852,6 +1852,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,
@ -5582,6 +5583,7 @@ Config {
None, None,
None, None,
true, true,
None,
), ),
SwitchToMode( SwitchToMode(
Normal, Normal,