summaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/kdl/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'zellij-utils/src/kdl/mod.rs')
-rw-r--r--zellij-utils/src/kdl/mod.rs134
1 files changed, 97 insertions, 37 deletions
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index f7a6ac4db..f3c7d9fb5 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -66,6 +66,8 @@ macro_rules! parse_kdl_action_arguments {
"Confirm" => Ok(Action::Confirm),
"Deny" => Ok(Action::Deny),
"ToggleMouseMode" => Ok(Action::ToggleMouseMode),
+ "PreviousSwapLayout" => Ok(Action::PreviousSwapLayout),
+ "NextSwapLayout" => Ok(Action::NextSwapLayout),
_ => Err(ConfigError::new_kdl_error(
format!("Unsupported action: {:?}", $action_name),
$action_node.span().offset(),
@@ -452,6 +454,7 @@ impl Action {
Ok(Action::MovePane(Some(direction)))
}
},
+ "MovePaneBackwards" => Ok(Action::MovePaneBackwards),
"DumpScreen" => Ok(Action::DumpScreen(string, false)),
"NewPane" => {
if string.is_empty() {
@@ -729,6 +732,11 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
action_arguments,
kdl_action
),
+ "MovePaneBackwards" => parse_kdl_action_char_or_string_arguments!(
+ action_name,
+ action_arguments,
+ kdl_action
+ ),
"DumpScreen" => parse_kdl_action_char_or_string_arguments!(
action_name,
action_arguments,
@@ -745,7 +753,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
"NewTab" => {
let command_metadata = action_children.iter().next();
if command_metadata.is_none() {
- return Ok(Action::NewTab(None, vec![], None));
+ return Ok(Action::NewTab(None, vec![], None, None, None));
}
let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
@@ -762,7 +770,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
.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) =
+ let (path_to_raw_layout, raw_layout, swap_layouts) =
Layout::stringified_from_path_or_default(layout.as_ref(), None).map_err(
|e| {
ConfigError::new_kdl_error(
@@ -773,14 +781,19 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
},
)?;
- 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 layout = Layout::from_str(
+ &raw_layout,
+ path_to_raw_layout,
+ swap_layouts.as_ref().map(|(f, p)| (f.as_str(), p.as_str())),
+ 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 {
@@ -793,11 +806,23 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
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))
+ Ok(Action::NewTab(
+ Some(layout),
+ floating_panes_layout,
+ None,
+ None,
+ name,
+ ))
} else {
let (layout, floating_panes_layout) = layout.new_tab();
- Ok(Action::NewTab(Some(layout), floating_panes_layout, name))
+ Ok(Action::NewTab(
+ Some(layout),
+ floating_panes_layout,
+ None,
+ None,
+ name,
+ ))
}
},
"GoToTab" => parse_kdl_action_u8_arguments!(action_name, action_arguments, kdl_action),
@@ -847,6 +872,8 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
};
Ok(Action::Run(run_command_action))
},
+ "PreviousSwapLayout" => Ok(Action::PreviousSwapLayout),
+ "NextSwapLayout" => Ok(Action::NextSwapLayout),
_ => Err(ConfigError::new_kdl_error(
format!("Unsupported action: {}", action_name).into(),
kdl_action.span().offset(),
@@ -1273,6 +1300,8 @@ impl Options {
.map(|(string, _entry)| PathBuf::from(string));
let pane_frames =
kdl_property_first_arg_as_bool_or_error!(kdl_options, "pane_frames").map(|(v, _)| v);
+ let auto_layout =
+ kdl_property_first_arg_as_bool_or_error!(kdl_options, "auto_layout").map(|(v, _)| v);
let theme = kdl_property_first_arg_as_string_or_error!(kdl_options, "theme")
.map(|(theme, _entry)| theme.to_string());
let default_mode =
@@ -1337,6 +1366,7 @@ impl Options {
scrollback_editor,
session_name,
attach_to_session,
+ auto_layout,
})
}
}
@@ -1370,36 +1400,66 @@ impl Layout {
pub fn from_kdl(
raw_layout: &str,
file_name: String,
+ raw_swap_layouts: Option<(&str, &str)>, // raw_swap_layouts swap_layouts_file_name
cwd: Option<PathBuf>,
) -> Result<Self, ConfigError> {
- KdlLayoutParser::new(raw_layout, cwd).parse().map_err(|e| {
- match e {
- ConfigError::KdlError(kdl_error) => ConfigError::KdlError(kdl_error.add_src(file_name, String::from(raw_layout))),
- ConfigError::KdlDeserializationError(kdl_error) => {
- let error_message = match kdl_error.kind {
- kdl::KdlErrorKind::Context("valid node terminator") => {
- format!("Failed to deserialize KDL node. \nPossible reasons:\n{}\n{}\n{}\n{}",
- "- Missing `;` after a node name, eg. { node; another_node; }",
- "- Missing quotations (\") around an argument node eg. { first_node \"argument_node\"; }",
- "- Missing an equal sign (=) between node arguments on a title line. eg. argument=\"value\"",
- "- Found an extraneous equal sign (=) between node child arguments and their values. eg. { argument=\"value\" }")
+ let mut kdl_layout_parser = KdlLayoutParser::new(raw_layout, cwd);
+ let layout = kdl_layout_parser.parse().map_err(|e| match e {
+ ConfigError::KdlError(kdl_error) => {
+ ConfigError::KdlError(kdl_error.add_src(file_name, String::from(raw_layout)))
+ },
+ ConfigError::KdlDeserializationError(kdl_error) => {
+ kdl_layout_error(kdl_error, file_name, raw_layout)
+ },
+ e => e,
+ })?;
+ match raw_swap_layouts {
+ Some((raw_swap_layout_filename, raw_swap_layout)) => {
+ // here we use the same parser to parse the swap layout so that we can reuse assets
+ // (eg. pane and tab templates)
+ kdl_layout_parser
+ .parse_external_swap_layouts(raw_swap_layout, layout)
+ .map_err(|e| match e {
+ ConfigError::KdlError(kdl_error) => {
+ ConfigError::KdlError(kdl_error.add_src(
+ String::from(raw_swap_layout_filename),
+ String::from(raw_swap_layout),
+ ))
},
- _ => String::from(kdl_error.help.unwrap_or("Kdl Deserialization Error")),
- };
- let kdl_error = KdlError {
- error_message,
- src: Some(NamedSource::new(file_name, String::from(raw_layout))),
- offset: Some(kdl_error.span.offset()),
- len: Some(kdl_error.span.len()),
- help_message: None,
- };
- ConfigError::KdlError(kdl_error)
- },
- e => e
- }
- })
+ ConfigError::KdlDeserializationError(kdl_error) => kdl_layout_error(
+ kdl_error,
+ raw_swap_layout_filename.into(),
+ raw_swap_layout,
+ ),
+ e => e,
+ })
+ },
+ None => Ok(layout),
+ }
}
}
+
+fn kdl_layout_error(kdl_error: kdl::KdlError, file_name: String, raw_layout: &str) -> ConfigError {
+ let error_message = match kdl_error.kind {
+ kdl::KdlErrorKind::Context("valid node terminator") => {
+ format!("Failed to deserialize KDL node. \nPossible reasons:\n{}\n{}\n{}\n{}",
+ "- Missing `;` after a node name, eg. { node; another_node; }",
+ "- Missing quotations (\") around an argument node eg. { first_node \"argument_node\"; }",
+ "- Missing an equal sign (=) between node arguments on a title line. eg. argument=\"value\"",
+ "- Found an extraneous equal sign (=) between node child arguments and their values. eg. { argument=\"value\" }")
+ },
+ _ => String::from(kdl_error.help.unwrap_or("Kdl Deserialization Error")),
+ };
+ let kdl_error = KdlError {
+ error_message,
+ src: Some(NamedSource::new(file_name, String::from(raw_layout))),
+ offset: Some(kdl_error.span.offset()),
+ len: Some(kdl_error.span.len()),
+ help_message: None,
+ };
+ ConfigError::KdlError(kdl_error)
+}
+
impl EnvironmentVariables {
pub fn from_kdl(kdl_env_variables: &KdlNode) -> Result<Self, ConfigError> {
let mut env: HashMap<String, String> = HashMap::new();