summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJae-Heon Ji <32578710+jaeheonji@users.noreply.github.com>2023-02-16 22:32:27 +0900
committerGitHub <noreply@github.com>2023-02-16 22:32:27 +0900
commit00cd33637bd43e1c0980254a04ce18f0dedb2b57 (patch)
treecff9f7d0ea630ca198f24de51f5712d9cbad046d
parent5817ebe2d2bb873e7dd32b662dbb38c2d05e7e1e (diff)
feat: add args to new-tab action (#2072)
* fix(themes): missing tokyo-night-dark theme * feat: add args to new-tab action * fix: name can be set without layout * feat: pass config options to action parser * chore: remove unnecessary default values * chore: update snapshots * fix(status-bar): add exception for NewTab * fix: update code review * feat: add shallow_eq for action
-rw-r--r--default-plugins/status-bar/src/main.rs8
-rw-r--r--zellij-utils/assets/plugins/compact-bar.wasmbin387952 -> 397489 bytes
-rw-r--r--zellij-utils/assets/plugins/status-bar.wasmbin476653 -> 485616 bytes
-rw-r--r--zellij-utils/assets/plugins/strider.wasmbin404184 -> 413509 bytes
-rw-r--r--zellij-utils/assets/plugins/tab-bar.wasmbin364104 -> 373679 bytes
-rw-r--r--zellij-utils/src/input/actions.rs8
-rw-r--r--zellij-utils/src/kdl/mod.rs93
7 files changed, 94 insertions, 15 deletions
diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs
index 9a110310a..603cdf351 100644
--- a/default-plugins/status-bar/src/main.rs
+++ b/default-plugins/status-bar/src/main.rs
@@ -351,7 +351,13 @@ pub fn action_key(keymap: &[(Key, Vec<Action>)], action: &[Action]) -> Vec<Key>
keymap
.iter()
.filter_map(|(key, acvec)| {
- if acvec.as_slice() == action {
+ let matching = acvec
+ .iter()
+ .zip(action)
+ .filter(|(a, b)| a.shallow_eq(b))
+ .count();
+
+ if matching == acvec.len() && matching == action.len() {
Some(*key)
} else {
None
diff --git a/zellij-utils/assets/plugins/compact-bar.wasm b/zellij-utils/assets/plugins/compact-bar.wasm
index f9bd5d630..46267f5e7 100644
--- a/zellij-utils/assets/plugins/compact-bar.wasm
+++ b/zellij-utils/assets/plugins/compact-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/status-bar.wasm b/zellij-utils/assets/plugins/status-bar.wasm
index 99fcb027c..5b4f6eb06 100644
--- a/zellij-utils/assets/plugins/status-bar.wasm
+++ b/zellij-utils/assets/plugins/status-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/strider.wasm b/zellij-utils/assets/plugins/strider.wasm
index 1df8a13d8..0af68b2f2 100644
--- a/zellij-utils/assets/plugins/strider.wasm
+++ b/zellij-utils/assets/plugins/strider.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/tab-bar.wasm b/zellij-utils/assets/plugins/tab-bar.wasm
index 51f215d13..1166de83c 100644
--- a/zellij-utils/assets/plugins/tab-bar.wasm
+++ b/zellij-utils/assets/plugins/tab-bar.wasm
Binary files differ
diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs
index b5d6acb13..7db0e4f3f 100644
--- a/zellij-utils/src/input/actions.rs
+++ b/zellij-utils/src/input/actions.rs
@@ -208,6 +208,14 @@ pub enum Action {
}
impl Action {
+ /// Checks that two Action are match except their mutable attributes.
+ pub fn shallow_eq(&self, other_action: &Action) -> bool {
+ match (self, other_action) {
+ (Action::NewTab(_, _, _), Action::NewTab(_, _, _)) => true,
+ _ => self == other_action,
+ }
+ }
+
pub fn actions_from_cli(
cli_action: CliAction,
get_current_dir: Box<dyn Fn() -> PathBuf>,
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index 2a81300ca..f7a6ac4db 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -301,10 +301,10 @@ macro_rules! keys_from_kdl {
#[macro_export]
macro_rules! actions_from_kdl {
- ( $kdl_node:expr ) => {
+ ( $kdl_node:expr, $config_options:expr ) => {
kdl_children_nodes_or_error!($kdl_node, "no actions found for key_block")
.iter()
- .map(|kdl_action| Action::try_from(kdl_action))
+ .map(|kdl_action| Action::try_from((kdl_action, $config_options)))
.collect::<Result<_, _>>()?
};
}
@@ -614,9 +614,9 @@ impl TryFrom<(&str, &KdlDocument)> for PaletteColor {
}
}
-impl TryFrom<&KdlNode> for Action {
+impl TryFrom<(&KdlNode, &Options)> for Action {
type Error = ConfigError;
- fn try_from(kdl_action: &KdlNode) -> Result<Self, Self::Error> {
+ fn try_from((kdl_action, config_options): (&KdlNode, &Options)) -> Result<Self, Self::Error> {
let action_name = kdl_name!(kdl_action);
let action_arguments: Vec<&KdlEntry> = kdl_argument_values!(kdl_action);
let action_children: Vec<&KdlDocument> = kdl_children!(kdl_action);
@@ -742,7 +742,64 @@ impl TryFrom<&KdlNode> for Action {
"PaneNameInput" => {
parse_kdl_action_u8_arguments!(action_name, action_arguments, kdl_action)
},
- "NewTab" => Ok(Action::NewTab(None, vec![], None)),
+ "NewTab" => {
+ let command_metadata = action_children.iter().next();
+ if command_metadata.is_none() {
+ return Ok(Action::NewTab(None, vec![], None));
+ }
+
+ let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
+
+ let layout = command_metadata
+ .and_then(|c_m| kdl_child_string_value_for_entry(c_m, "layout"))
+ .map(|layout_string| PathBuf::from(layout_string))
+ .or_else(|| config_options.default_layout.clone());
+ let cwd = command_metadata
+ .and_then(|c_m| kdl_child_string_value_for_entry(c_m, "cwd"))
+ .map(|cwd_string| PathBuf::from(cwd_string))
+ .map(|cwd| current_dir.join(cwd));
+ let name = command_metadata
+ .and_then(|c_m| kdl_child_string_value_for_entry(c_m, "name"))
+ .map(|name_string| name_string.to_string());
+
+ let (path_to_raw_layout, raw_layout) =
+ Layout::stringified_from_path_or_default(layout.as_ref(), None).map_err(
+ |e| {
+ ConfigError::new_kdl_error(
+ format!("Failed to load layout: {}", e),
+ kdl_action.span().offset(),
+ kdl_action.span().len(),
+ )
+ },
+ )?;
+
+ let layout =
+ Layout::from_str(&raw_layout, path_to_raw_layout, cwd).map_err(|e| {
+ ConfigError::new_kdl_error(
+ format!("Failed to load layout: {}", e),
+ kdl_action.span().offset(),
+ kdl_action.span().len(),
+ )
+ })?;
+
+ let mut tabs = layout.tabs();
+ if tabs.len() > 1 {
+ return Err(ConfigError::new_kdl_error(
+ "Tab layout cannot itself have tabs".to_string(),
+ kdl_action.span().offset(),
+ kdl_action.span().len(),
+ ));
+ } else if !tabs.is_empty() {
+ let (tab_name, layout, floating_panes_layout) = tabs.drain(..).next().unwrap();
+ let name = tab_name.or(name);
+
+ Ok(Action::NewTab(Some(layout), floating_panes_layout, name))
+ } else {
+ let (layout, floating_panes_layout) = layout.new_tab();
+
+ Ok(Action::NewTab(Some(layout), floating_panes_layout, name))
+ }
+ },
"GoToTab" => parse_kdl_action_u8_arguments!(action_name, action_arguments, kdl_action),
"TabNameInput" => {
parse_kdl_action_u8_arguments!(action_name, action_arguments, kdl_action)
@@ -1370,12 +1427,13 @@ impl Keybinds {
fn bind_keys_in_block(
block: &KdlNode,
input_mode_keybinds: &mut HashMap<Key, Vec<Action>>,
+ config_options: &Options,
) -> Result<(), ConfigError> {
let all_nodes = kdl_children_nodes_or_error!(block, "no keybinding block for mode");
let bind_nodes = all_nodes.iter().filter(|n| kdl_name!(n) == "bind");
let unbind_nodes = all_nodes.iter().filter(|n| kdl_name!(n) == "unbind");
for key_block in bind_nodes {
- Keybinds::bind_actions_for_each_key(key_block, input_mode_keybinds)?;
+ Keybinds::bind_actions_for_each_key(key_block, input_mode_keybinds, config_options)?;
}
// we loop a second time so that the unbinds always happen after the binds
for key_block in unbind_nodes {
@@ -1392,7 +1450,11 @@ impl Keybinds {
}
Ok(())
}
- pub fn from_kdl(kdl_keybinds: &KdlNode, base_keybinds: Keybinds) -> Result<Self, ConfigError> {
+ pub fn from_kdl(
+ kdl_keybinds: &KdlNode,
+ base_keybinds: Keybinds,
+ config_options: &Options,
+ ) -> Result<Self, ConfigError> {
let clear_defaults = kdl_arg_is_truthy!(kdl_keybinds, "clear-defaults");
let mut keybinds_from_config = if clear_defaults {
Keybinds::default()
@@ -1416,7 +1478,7 @@ impl Keybinds {
continue;
}
let mut input_mode_keybinds = keybinds_from_config.get_input_mode_mut(&mode);
- Keybinds::bind_keys_in_block(block, &mut input_mode_keybinds)?;
+ Keybinds::bind_keys_in_block(block, &mut input_mode_keybinds, config_options)?;
}
}
if kdl_name!(block) == "shared_among" {
@@ -1429,7 +1491,7 @@ impl Keybinds {
continue;
}
let mut input_mode_keybinds = keybinds_from_config.get_input_mode_mut(&mode);
- Keybinds::bind_keys_in_block(block, &mut input_mode_keybinds)?;
+ Keybinds::bind_keys_in_block(block, &mut input_mode_keybinds, config_options)?;
}
}
}
@@ -1443,7 +1505,7 @@ impl Keybinds {
}
let mut input_mode_keybinds =
Keybinds::input_mode_keybindings(mode, &mut keybinds_from_config)?;
- Keybinds::bind_keys_in_block(mode, &mut input_mode_keybinds)?;
+ Keybinds::bind_keys_in_block(mode, &mut input_mode_keybinds, config_options)?;
}
if let Some(global_unbind) = kdl_keybinds.children().and_then(|c| c.get("unbind")) {
Keybinds::unbind_keys_in_all_modes(global_unbind, &mut keybinds_from_config)?;
@@ -1453,9 +1515,10 @@ impl Keybinds {
fn bind_actions_for_each_key(
key_block: &KdlNode,
input_mode_keybinds: &mut HashMap<Key, Vec<Action>>,
+ config_options: &Options,
) -> Result<(), ConfigError> {
let keys: Vec<Key> = keys_from_kdl!(key_block);
- let actions: Vec<Action> = actions_from_kdl!(key_block);
+ let actions: Vec<Action> = actions_from_kdl!(key_block, config_options);
for key in keys {
input_mode_keybinds.insert(key, actions.clone());
}
@@ -1508,13 +1571,15 @@ impl Config {
pub fn from_kdl(kdl_config: &str, base_config: Option<Config>) -> Result<Config, ConfigError> {
let mut config = base_config.unwrap_or_else(|| Config::default());
let kdl_config: KdlDocument = kdl_config.parse()?;
+
+ let config_options = Options::from_kdl(&kdl_config)?;
+ config.options = config.options.merge(config_options);
+
// TODO: handle cases where we have more than one of these blocks (eg. two "keybinds")
// this should give an informative parsing error
if let Some(kdl_keybinds) = kdl_config.get("keybinds") {
- config.keybinds = Keybinds::from_kdl(&kdl_keybinds, config.keybinds)?;
+ config.keybinds = Keybinds::from_kdl(&kdl_keybinds, config.keybinds, &config.options)?;
}
- let config_options = Options::from_kdl(&kdl_config)?;
- config.options = config.options.merge(config_options);
if let Some(kdl_themes) = kdl_config.get("themes") {
let config_themes = Themes::from_kdl(kdl_themes)?;
config.themes = config.themes.merge(config_themes);