diff options
| author | har7an <99636919+har7an@users.noreply.github.com> | 2026-01-26 18:05:51 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-26 18:05:51 +0000 |
| commit | bdf20eef50f2d68501be708ec5ee38dbe9366a91 (patch) | |
| tree | e97215a9464d322eb65e416b1662c530e44d57f1 /zellij-utils/src/data.rs | |
| parent | fix: get "zellij run --session" to also work on sessions that have no attache... (diff) | |
| download | sl0ppij-bdf20eef50f2d68501be708ec5ee38dbe9366a91.tar.gz sl0ppij-bdf20eef50f2d68501be708ec5ee38dbe9366a91.tar.xz sl0ppij-bdf20eef50f2d68501be708ec5ee38dbe9366a91.zip | |
Fix loading short layouts and custom config dirs (#4640)
* test(e2e): Write a regression test to validate behavior
w.r.t. loading and determining the session layout file. Compared to
release v0.43.1, right now there is a problem where `zellij --layout
NAME`, with `NAME` being the filename of a layout in the
`$ZELLIJ_DATA_DIR/layouts/` subfolder, doesn't resolve to the correct
layout file. Instead, zellij will silently fall back to its default
config. It does, however, recognize nonexistent configuration files.
* fix(utils): Treat bare layout names as file paths first
before defaulting to builtin layout names. This restores the behavior
shown by zellij up until 0.43.1, which was altered in a recent extension
of the server-client API.
* fix: Forward client layout information to startup code
and ensure it isn't ignored along the way. Update a bunch of tests to
react to the new function interface and write new tests to catch
deviations in the future.
* test: Fix misconfigured e2e test
to ensure that a custom `--config-dir` is indeed respected during
application startup.
* test: Rewrite config dir test to not use variable metadata
since the `LayoutInfo` object previously dumped into the snapshot
contains information that isn't platform agnostic, including an absolute
file path and a timestamp.
* docs(CHANGELOG): Mention PR #4640
in the list of changes for the next release.
* fix: Handle bare layouts with name "default" correctly
and assume a "default" layout if no layout name is given during layout
resolution. "default" may not always be the builtin default layout,
since users can write their own "default.kdl" that takes effect when
placed in the layout directory an no other layouts are explicitly
specified.
Diffstat (limited to 'zellij-utils/src/data.rs')
| -rw-r--r-- | zellij-utils/src/data.rs | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs index 68d15725..15d74b54 100644 --- a/zellij-utils/src/data.rs +++ b/zellij-utils/src/data.rs @@ -2006,32 +2006,60 @@ impl LayoutInfo { } pub fn from_config( layout_dir: &Option<PathBuf>, - layout_path: &Option<PathBuf>, + maybe_layout_path: &Option<PathBuf>, ) -> Option<Self> { - match layout_path { - Some(layout_path) => { - if layout_path.extension().is_some() || layout_path.components().count() > 1 { - let Some(layout_dir) = layout_dir - .as_ref() - .map(|l| l.clone()) - .or_else(default_layout_dir) - else { - return None; - }; - let file_path = layout_dir.join(layout_path); - Some(LayoutInfo::File( - // layout_dir.join(layout_path).display().to_string(), + // If we're not given a layout path, fall back to "default". Since we cannot tell ahead of + // time whether the user has a layout named "default.kdl" in their layout directory, we + // cannot blindly assume that this is indeed the builtin default layout. The layout + // resolution below will correctly handle this. + // The docs promise this behavior, so we have to abide: + // <https://zellij.dev/documentation/layouts.html#layout-default-directory> + let layout_path = maybe_layout_path + .clone() + .unwrap_or(PathBuf::from("default")); + + if layout_path.starts_with("http://") || layout_path.starts_with("https://") { + Some(LayoutInfo::Url(layout_path.display().to_string())) + } else if layout_path.extension().is_some() || layout_path.components().count() > 1 { + let Some(layout_dir) = layout_dir + .as_ref() + .map(|l| l.clone()) + .or_else(default_layout_dir) + else { + return None; + }; + let file_path = layout_dir.join(layout_path); + Some(LayoutInfo::File( + // layout_dir.join(layout_path).display().to_string(), + file_path.display().to_string(), + LayoutMetadata::from(&file_path), + )) + } else { + // Attempt to interpret the layout as bare layout name from the layout application + // directory. This is described in the docs: + // <https://zellij.dev/documentation/layouts.html#layout-default-directory> + if let Some(layout_dir) = layout_dir + .as_ref() + .map(|l| l.clone()) + .or_else(default_layout_dir) + { + let file_path = layout_dir.join(&layout_path); + if file_path.exists() { + return Some(LayoutInfo::File( file_path.display().to_string(), LayoutMetadata::from(&file_path), - )) - } else if layout_path.starts_with("http://") || layout_path.starts_with("https://") - { - Some(LayoutInfo::Url(layout_path.display().to_string())) - } else { - Some(LayoutInfo::BuiltIn(layout_path.display().to_string())) + )); } - }, - None => None, + let file_path_with_ext = file_path.with_extension("kdl"); + if file_path_with_ext.exists() { + return Some(LayoutInfo::File( + file_path_with_ext.display().to_string(), + LayoutMetadata::from(&file_path_with_ext), + )); + } + } + // Assume a builtin layout by default + Some(LayoutInfo::BuiltIn(layout_path.display().to_string())) } } } |
