mirror of
https://github.com/zellij-org/zellij.git
synced 2026-10-12 08:02:45 +00:00
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.
This commit is contained in:
@@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
* fix: allow disabling automatic OSC8 hyperlink formatting (https://github.com/zellij-org/zellij/pull/4624)
|
||||
* fix: properly set cwd for new sessions started from the `session-manager` (https://github.com/zellij-org/zellij/pull/4625)
|
||||
* fix: get `zellij run --session <X>` to work even when the specified session has no connected users (https://github.com/zellij-org/zellij/pull/4626)
|
||||
* fix: resolve short layout names as files if possible (https://github.com/zellij-org/zellij/pull/4640)
|
||||
|
||||
|
||||
## [0.43.1] - 2025-08-08
|
||||
|
||||
+2
-2
@@ -596,7 +596,7 @@ pub(crate) fn start_client(opts: CliArgs) {
|
||||
convert_old_yaml_files(&opts);
|
||||
let (
|
||||
config,
|
||||
_layout,
|
||||
client_layout_info,
|
||||
config_options,
|
||||
mut config_without_layout,
|
||||
mut config_options_without_layout,
|
||||
@@ -622,7 +622,7 @@ pub(crate) fn start_client(opts: CliArgs) {
|
||||
let mut opts = opts.clone();
|
||||
let mut is_a_reconnect = false;
|
||||
let mut should_create_detached = false;
|
||||
let mut layout_info = None;
|
||||
let mut layout_info = client_layout_info.clone();
|
||||
let mut new_session_cwd = None;
|
||||
|
||||
if let Some(reconnect_to_session) = &reconnect_to_session {
|
||||
|
||||
@@ -2898,3 +2898,37 @@ pub fn override_layout_from_default_to_compact() {
|
||||
let last_snapshot = account_for_races_in_snapshot(last_snapshot);
|
||||
assert_snapshot!(last_snapshot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
pub fn use_custom_layout_with_relative_path() {
|
||||
let fake_win_size = Size {
|
||||
cols: 120,
|
||||
rows: 24,
|
||||
};
|
||||
// Should resolve to $fixtures/layouts/upside-down.kdl
|
||||
let config_dir_name = "e2e-upside-down";
|
||||
let mut test_attempts = 10;
|
||||
let last_snapshot = loop {
|
||||
RemoteRunner::kill_running_sessions(fake_win_size);
|
||||
let mut runner = RemoteRunner::new_with_config_dir(fake_win_size, config_dir_name);
|
||||
runner.run_all_steps();
|
||||
let last_snapshot = runner.take_snapshot_after(Step {
|
||||
name: "Wait for app to start",
|
||||
instruction: |remote_terminal: RemoteTerminal| -> bool {
|
||||
let lines = remote_terminal.lines();
|
||||
lines.len() > 2
|
||||
&& lines[0].trim().starts_with("Ctrl +")
|
||||
&& lines[1].trim().starts_with("Tip:")
|
||||
},
|
||||
});
|
||||
if runner.test_timed_out && test_attempts > 0 {
|
||||
test_attempts -= 1;
|
||||
continue;
|
||||
} else {
|
||||
break last_snapshot;
|
||||
}
|
||||
};
|
||||
let last_snapshot = account_for_races_in_snapshot(last_snapshot);
|
||||
assert_snapshot!(last_snapshot);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use std::rc::Rc;
|
||||
const ZELLIJ_EXECUTABLE_LOCATION: &str = "/usr/src/zellij/x86_64-unknown-linux-musl/release/zellij";
|
||||
const SET_ENV_VARIABLES: &str = "EDITOR=/usr/bin/vi";
|
||||
const ZELLIJ_CONFIG_PATH: &str = "/usr/src/zellij/fixtures/configs";
|
||||
const ZELLIJ_CONFIG_DIRS_PATH: &str = "/usr/src/zellij/fixtures/config-dirs";
|
||||
const ZELLIJ_DATA_DIR: &str = "/usr/src/zellij/e2e-data";
|
||||
const ZELLIJ_FIXTURE_PATH: &str = "/usr/src/zellij/fixtures";
|
||||
const CONNECTION_STRING: &str = "127.0.0.1:2222";
|
||||
@@ -91,6 +92,21 @@ fn start_zellij(channel: &mut ssh2::Channel) {
|
||||
std::thread::sleep(std::time::Duration::from_secs(3)); // wait until Zellij stops parsing startup ANSI codes from the terminal STDIN
|
||||
}
|
||||
|
||||
fn start_zellij_with_config_dir(channel: &mut ssh2::Channel, config_dir: &str) {
|
||||
stop_zellij(channel);
|
||||
channel
|
||||
.write_all(
|
||||
format!(
|
||||
"{} {} --session {} --data-dir {} --config-dir {} options --show-release-notes false --show-startup-tips false\n",
|
||||
SET_ENV_VARIABLES, ZELLIJ_EXECUTABLE_LOCATION, SESSION_NAME, ZELLIJ_DATA_DIR, format!("{}/{}", ZELLIJ_CONFIG_DIRS_PATH, config_dir)
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.unwrap();
|
||||
channel.flush().unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_secs(3)); // wait until Zellij stops parsing startup ANSI codes from the terminal STDIN
|
||||
}
|
||||
|
||||
fn start_zellij_mirrored_session(channel: &mut ssh2::Channel) {
|
||||
stop_zellij(channel);
|
||||
channel
|
||||
@@ -384,6 +400,10 @@ impl RemoteTerminal {
|
||||
pub fn snapshot_contains(&self, text: &str) -> bool {
|
||||
self.last_snapshot.lock().unwrap().contains(text)
|
||||
}
|
||||
pub fn lines(&self) -> Vec<String> {
|
||||
let s = self.last_snapshot.lock().unwrap();
|
||||
s.lines().map(|s| s.to_owned()).collect::<Vec<_>>()
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub fn current_snapshot(&self) -> String {
|
||||
// convenience method for writing tests,
|
||||
@@ -527,6 +547,44 @@ impl RemoteRunner {
|
||||
reader_thread,
|
||||
}
|
||||
}
|
||||
pub fn new_with_config_dir(win_size: Size, config_dir_name: &str) -> Self {
|
||||
let sess = ssh_connect();
|
||||
let mut channel = sess.channel_session().unwrap();
|
||||
let mut rows = Dimension::fixed(win_size.rows);
|
||||
let mut cols = Dimension::fixed(win_size.cols);
|
||||
rows.set_inner(win_size.rows);
|
||||
cols.set_inner(win_size.cols);
|
||||
let pane_geom = PaneGeom {
|
||||
x: 0,
|
||||
y: 0,
|
||||
rows,
|
||||
cols,
|
||||
stacked: None,
|
||||
is_pinned: false,
|
||||
logical_position: None,
|
||||
};
|
||||
setup_remote_environment(&mut channel, win_size);
|
||||
start_zellij_with_config_dir(&mut channel, config_dir_name);
|
||||
let channel = Arc::new(Mutex::new(channel));
|
||||
let last_snapshot = Arc::new(Mutex::new(String::new()));
|
||||
let cursor_coordinates = Arc::new(Mutex::new((0, 0)));
|
||||
sess.set_blocking(false);
|
||||
let reader_thread =
|
||||
read_from_channel(&channel, &last_snapshot, &cursor_coordinates, &pane_geom);
|
||||
RemoteRunner {
|
||||
steps: vec![],
|
||||
channel,
|
||||
currently_running_step: None,
|
||||
current_step_index: 0,
|
||||
retries_left: RETRIES,
|
||||
retry_pause_ms: 100,
|
||||
test_timed_out: false,
|
||||
panic_on_no_retries_left: true,
|
||||
last_snapshot,
|
||||
cursor_coordinates,
|
||||
reader_thread,
|
||||
}
|
||||
}
|
||||
pub fn new_mirrored_session(win_size: Size) -> Self {
|
||||
let sess = ssh_connect();
|
||||
let mut channel = sess.channel_session().unwrap();
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
---
|
||||
source: src/tests/e2e/cases.rs
|
||||
expression: last_snapshot
|
||||
---
|
||||
Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SEARCH <o> SESSION <q> QUIT
|
||||
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.
|
||||
┌ Pane #1 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│$ █ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
Zellij (e2e-test) Tab #1
|
||||
@@ -0,0 +1 @@
|
||||
default_layout "upside-down"
|
||||
@@ -0,0 +1,13 @@
|
||||
layout {
|
||||
pane size=2 borderless=true {
|
||||
plugin location="status-bar" {
|
||||
classic true
|
||||
}
|
||||
}
|
||||
pane focus=true
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar" {
|
||||
hide_swap_layout_indication true
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
-22
@@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+66
-19
@@ -8,6 +8,7 @@ use crate::{
|
||||
FEATURES, SYSTEM_DEFAULT_CONFIG_DIR, SYSTEM_DEFAULT_DATA_DIR_PREFIX, VERSION,
|
||||
ZELLIJ_CACHE_DIR, ZELLIJ_DEFAULT_THEMES, ZELLIJ_PROJ_DIR,
|
||||
},
|
||||
data::LayoutInfo,
|
||||
errors::prelude::*,
|
||||
home::*,
|
||||
input::{
|
||||
@@ -368,7 +369,7 @@ impl Setup {
|
||||
/// 3. config options (`config.kdl`)
|
||||
pub fn from_cli_args(
|
||||
cli_args: &CliArgs,
|
||||
) -> Result<(Config, Layout, Options, Config, Options), ConfigError> {
|
||||
) -> Result<(Config, Option<LayoutInfo>, Options, Config, Options), ConfigError> {
|
||||
// note that this can potentially exit the process
|
||||
Setup::handle_setup_commands(cli_args);
|
||||
let config = Config::try_from(cli_args)?;
|
||||
@@ -384,7 +385,7 @@ impl Setup {
|
||||
let cli_config_options = merge_attach_command_options(cli_config_options, &cli_args);
|
||||
|
||||
let mut config_without_layout = config.clone();
|
||||
let (layout, mut config) =
|
||||
let (layout_info, mut config) =
|
||||
Setup::parse_layout_and_override_config(cli_config_options.as_ref(), config, cli_args)?;
|
||||
|
||||
let config_options =
|
||||
@@ -426,7 +427,7 @@ impl Setup {
|
||||
};
|
||||
Ok((
|
||||
config,
|
||||
layout,
|
||||
layout_info,
|
||||
config_options,
|
||||
config_without_layout,
|
||||
config_options_without_layout,
|
||||
@@ -666,15 +667,16 @@ impl Setup {
|
||||
cli_config_options: Option<&Options>,
|
||||
config: Config,
|
||||
cli_args: &CliArgs,
|
||||
) -> Result<(Layout, Config), ConfigError> {
|
||||
) -> Result<(Option<LayoutInfo>, Config), ConfigError> {
|
||||
// find the layout folder relative to which we'll look for our layout
|
||||
let layout_dir = cli_config_options
|
||||
.as_ref()
|
||||
.and_then(|cli_options| cli_options.layout_dir.clone())
|
||||
.or_else(|| config.options.layout_dir.clone())
|
||||
.or_else(|| {
|
||||
get_layout_dir(cli_args.config_dir.clone().or_else(find_default_config_dir))
|
||||
});
|
||||
.or_else(|| get_layout_dir(cli_args.config_dir.clone()))
|
||||
.or_else(|| get_layout_dir(find_default_config_dir()))
|
||||
// Try to get an absolute path, else let the resolution code figure this out.
|
||||
.map(|d| d.canonicalize().unwrap_or(d));
|
||||
// the chosen layout can either be a path relative to the layout_dir or a name of one
|
||||
// of our assets, this distinction is made when parsing the layout - TODO: ideally, this
|
||||
// logic should not be split up and all the decisions should happen here
|
||||
@@ -687,6 +689,7 @@ impl Setup {
|
||||
.and_then(|cli_options| cli_options.default_layout.clone())
|
||||
})
|
||||
.or_else(|| config.options.default_layout.clone());
|
||||
let layout_info = LayoutInfo::from_config(&layout_dir, &chosen_layout);
|
||||
if let Some(layout_url) = chosen_layout
|
||||
.as_ref()
|
||||
.and_then(|l| l.to_str())
|
||||
@@ -698,11 +701,12 @@ impl Setup {
|
||||
}
|
||||
})
|
||||
{
|
||||
Layout::from_url(layout_url, config)
|
||||
Layout::from_url(layout_url, config).map(|(_layout, config)| (layout_info, config))
|
||||
} else {
|
||||
// we merge-override the config here because the layout might contain configuration
|
||||
// that needs to take precedence
|
||||
Layout::from_path_or_default(chosen_layout.as_ref(), layout_dir.clone(), config)
|
||||
.map(|(_layout, config)| (layout_info, config))
|
||||
}
|
||||
}
|
||||
fn handle_setup_commands(cli_args: &CliArgs) {
|
||||
@@ -744,6 +748,7 @@ fn merge_attach_command_options(
|
||||
mod setup_test {
|
||||
use super::Setup;
|
||||
use crate::cli::{CliArgs, Command};
|
||||
use crate::data::LayoutInfo;
|
||||
use crate::input::options::Options;
|
||||
use insta::assert_snapshot;
|
||||
use std::path::PathBuf;
|
||||
@@ -751,9 +756,9 @@ mod setup_test {
|
||||
#[test]
|
||||
fn default_config_with_no_cli_arguments() {
|
||||
let cli_args = CliArgs::default();
|
||||
let (config, layout, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (config, layout_info, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", config));
|
||||
assert_snapshot!(format!("{:#?}", layout));
|
||||
assert_snapshot!(format!("{:#?}", layout_info));
|
||||
assert_snapshot!(format!("{:#?}", options));
|
||||
}
|
||||
#[test]
|
||||
@@ -763,7 +768,7 @@ mod setup_test {
|
||||
simplified_ui: Some(true),
|
||||
..Default::default()
|
||||
}));
|
||||
let (_config, _layout, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (_config, _layout_info, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", options));
|
||||
}
|
||||
#[test]
|
||||
@@ -773,9 +778,9 @@ mod setup_test {
|
||||
"{}/src/test-fixtures/layout-with-options.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)));
|
||||
let (_config, layout, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (_config, layout_info, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", options));
|
||||
assert_snapshot!(format!("{:#?}", layout));
|
||||
assert_snapshot!(format!("{:#?}", layout_info));
|
||||
}
|
||||
#[test]
|
||||
fn cli_arguments_override_layout_options() {
|
||||
@@ -788,9 +793,9 @@ mod setup_test {
|
||||
pane_frames: Some(true),
|
||||
..Default::default()
|
||||
}));
|
||||
let (_config, layout, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (_config, layout_info, options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", options));
|
||||
assert_snapshot!(format!("{:#?}", layout));
|
||||
assert_snapshot!(format!("{:#?}", layout_info));
|
||||
}
|
||||
#[test]
|
||||
fn layout_env_vars_override_config_env_vars() {
|
||||
@@ -803,7 +808,7 @@ mod setup_test {
|
||||
"{}/src/test-fixtures/layout-with-env-vars.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)));
|
||||
let (config, _layout, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (config, _layout_info, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", config));
|
||||
}
|
||||
#[test]
|
||||
@@ -817,7 +822,7 @@ mod setup_test {
|
||||
"{}/src/test-fixtures/layout-with-ui-config.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)));
|
||||
let (config, _layout, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (config, _layout_info, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", config));
|
||||
}
|
||||
#[test]
|
||||
@@ -831,7 +836,7 @@ mod setup_test {
|
||||
"{}/src/test-fixtures/layout-with-themes-config.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)));
|
||||
let (config, _layout, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (config, _layout_info, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", config));
|
||||
}
|
||||
#[test]
|
||||
@@ -845,7 +850,49 @@ mod setup_test {
|
||||
"{}/src/test-fixtures/layout-with-keybindings-config.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)));
|
||||
let (config, _layout, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let (config, _layout_info, _options, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
assert_snapshot!(format!("{:#?}", config));
|
||||
}
|
||||
#[test]
|
||||
fn cli_config_dir_overrides_defaults() {
|
||||
let cli_args = CliArgs {
|
||||
config_dir: Some(PathBuf::from(format!(
|
||||
"{}/src/test-fixtures/config-dirs/layout-upside-down",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
))),
|
||||
..Default::default()
|
||||
};
|
||||
let (_, layout_info, _, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let Some(LayoutInfo::File(layout_path, _)) = layout_info else {
|
||||
panic!("layout info has unexpected format");
|
||||
};
|
||||
assert_eq!(
|
||||
layout_path,
|
||||
format!(
|
||||
"{}/src/test-fixtures/config-dirs/layout-upside-down/layouts/upside-down.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn cli_config_dir_finds_custom_default() {
|
||||
let cli_args = CliArgs {
|
||||
config_dir: Some(PathBuf::from(format!(
|
||||
"{}/src/test-fixtures/config-dirs/custom-default-layout",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
))),
|
||||
..Default::default()
|
||||
};
|
||||
let (_, layout_info, _, _, _) = Setup::from_cli_args(&cli_args).unwrap();
|
||||
let Some(LayoutInfo::File(layout_path, _)) = layout_info else {
|
||||
panic!("layout info has unexpected format");
|
||||
};
|
||||
assert_eq!(
|
||||
layout_path,
|
||||
format!(
|
||||
"{}/src/test-fixtures/config-dirs/custom-default-layout/layouts/default.kdl",
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-29
@@ -1,32 +1,5 @@
|
||||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
expression: "format!(\"{:#?}\", layout)"
|
||||
expression: "format!(\"{:#?}\", layout_info)"
|
||||
---
|
||||
Layout {
|
||||
tabs: [],
|
||||
focused_tab_index: None,
|
||||
template: Some(
|
||||
(
|
||||
TiledPaneLayout {
|
||||
children_split_direction: Horizontal,
|
||||
name: None,
|
||||
children: [],
|
||||
split_size: None,
|
||||
run: None,
|
||||
borderless: None,
|
||||
focus: None,
|
||||
external_children_index: None,
|
||||
children_are_stacked: false,
|
||||
is_expanded_in_stack: false,
|
||||
exclude_from_sync: None,
|
||||
run_instructions_to_ignore: [],
|
||||
hide_floating_panes: false,
|
||||
pane_initial_contents: None,
|
||||
},
|
||||
[],
|
||||
),
|
||||
),
|
||||
swap_layouts: [],
|
||||
swap_tiled_layouts: [],
|
||||
swap_floating_layouts: [],
|
||||
}
|
||||
None
|
||||
|
||||
+5
-2286
File diff suppressed because it is too large
Load Diff
+2
-29
@@ -1,32 +1,5 @@
|
||||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
expression: "format!(\"{:#?}\", layout)"
|
||||
expression: "format!(\"{:#?}\", layout_info)"
|
||||
---
|
||||
Layout {
|
||||
tabs: [],
|
||||
focused_tab_index: None,
|
||||
template: Some(
|
||||
(
|
||||
TiledPaneLayout {
|
||||
children_split_direction: Horizontal,
|
||||
name: None,
|
||||
children: [],
|
||||
split_size: None,
|
||||
run: None,
|
||||
borderless: None,
|
||||
focus: None,
|
||||
external_children_index: None,
|
||||
children_are_stacked: false,
|
||||
is_expanded_in_stack: false,
|
||||
exclude_from_sync: None,
|
||||
run_instructions_to_ignore: [],
|
||||
hide_floating_panes: false,
|
||||
pane_initial_contents: None,
|
||||
},
|
||||
[],
|
||||
),
|
||||
),
|
||||
swap_layouts: [],
|
||||
swap_tiled_layouts: [],
|
||||
swap_floating_layouts: [],
|
||||
}
|
||||
None
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
layout {
|
||||
// Double the tab bar, weee!
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar"
|
||||
}
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar"
|
||||
}
|
||||
pane size=1 borderless=true {
|
||||
plugin location="status-bar"
|
||||
}
|
||||
pane
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
default_layout "upside-down"
|
||||
@@ -0,0 +1,13 @@
|
||||
layout {
|
||||
pane size=2 borderless=true {
|
||||
plugin location="status-bar" {
|
||||
classic true
|
||||
}
|
||||
}
|
||||
pane focus=true
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar" {
|
||||
hide_swap_layout_indication true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user