mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-22 22:26:54 +03:00
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
This commit is contained in:
parent
5817ebe2d2
commit
00cd33637b
@ -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
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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>,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user