mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-22 13:02:12 +03:00
add(plugin): compact-bar
& compact
layout (#1450)
* add(plugin): `compact-bar` & `compact` layout * add(nix): `compact-bar` plugin * add(config): `compact-bar` to the config * add(workspace): `compact-bar` to workspace members * add(assets): `compact-bar` * chore(fmt): rustfmt * add(nix): add `compact-bar` * add: compact layout to dump command * nix(build): fix destination of copy command * add(makefile): add `compact-bar` to `plugin-build` * add(layout): `compact-bar` to layout * add: install `compact-bar` plugin * fix(test): update input plugin test * fix(plugin): default colors for compact-bar
This commit is contained in:
parent
ad9ba8ab24
commit
d62e6fb57e
460
Cargo.lock
generated
460
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -34,6 +34,7 @@ members = [
|
||||
"zellij-utils",
|
||||
"zellij-tile",
|
||||
"zellij-tile-utils",
|
||||
"default-plugins/compact-bar",
|
||||
"default-plugins/status-bar",
|
||||
"default-plugins/strider",
|
||||
"default-plugins/tab-bar",
|
||||
|
@ -109,6 +109,7 @@ end
|
||||
|
||||
[tasks.build-plugins-release]
|
||||
env = { "CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS" = [
|
||||
"default-plugins/compact-bar",
|
||||
"default-plugins/status-bar",
|
||||
"default-plugins/strider",
|
||||
"default-plugins/tab-bar",
|
||||
@ -117,6 +118,7 @@ run_task = { name = "build-release", fork = true }
|
||||
|
||||
[tasks.build-plugins]
|
||||
env = { "CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS" = [
|
||||
"default-plugins/compact-bar",
|
||||
"default-plugins/status-bar",
|
||||
"default-plugins/strider",
|
||||
"default-plugins/tab-bar",
|
||||
|
BIN
assets/plugins/compact-bar.wasm
Executable file
BIN
assets/plugins/compact-bar.wasm
Executable file
Binary file not shown.
2
default-plugins/compact-bar/.cargo/config.toml
Normal file
2
default-plugins/compact-bar/.cargo/config.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[build]
|
||||
target = "wasm32-wasi"
|
13
default-plugins/compact-bar/Cargo.toml
Normal file
13
default-plugins/compact-bar/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "compact-bar"
|
||||
version = "0.1.0"
|
||||
authors = ["Alexander Kenji Berthold <aks.kenji@protonmail.com>" ]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
colored = "2"
|
||||
ansi_term = "0.12"
|
||||
unicode-width = "0.1.8"
|
||||
zellij-tile = { path = "../../zellij-tile" }
|
||||
zellij-tile-utils = { path = "../../zellij-tile-utils" }
|
1
default-plugins/compact-bar/LICENSE.md
Symbolic link
1
default-plugins/compact-bar/LICENSE.md
Symbolic link
@ -0,0 +1 @@
|
||||
../../LICENSE.md
|
243
default-plugins/compact-bar/src/line.rs
Normal file
243
default-plugins/compact-bar/src/line.rs
Normal file
@ -0,0 +1,243 @@
|
||||
use ansi_term::ANSIStrings;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{LinePart, ARROW_SEPARATOR};
|
||||
use zellij_tile::prelude::*;
|
||||
use zellij_tile_utils::style;
|
||||
|
||||
fn get_current_title_len(current_title: &[LinePart]) -> usize {
|
||||
current_title.iter().map(|p| p.len).sum()
|
||||
}
|
||||
|
||||
// move elements from before_active and after_active into tabs_to_render while they fit in cols
|
||||
// adds collapsed_tabs to the left and right if there's left over tabs that don't fit
|
||||
fn populate_tabs_in_tab_line(
|
||||
tabs_before_active: &mut Vec<LinePart>,
|
||||
tabs_after_active: &mut Vec<LinePart>,
|
||||
tabs_to_render: &mut Vec<LinePart>,
|
||||
cols: usize,
|
||||
palette: Palette,
|
||||
capabilities: PluginCapabilities,
|
||||
) {
|
||||
let mut middle_size = get_current_title_len(tabs_to_render);
|
||||
|
||||
let mut total_left = 0;
|
||||
let mut total_right = 0;
|
||||
loop {
|
||||
let left_count = tabs_before_active.len();
|
||||
let right_count = tabs_after_active.len();
|
||||
let collapsed_left = left_more_message(left_count, palette, tab_separator(capabilities));
|
||||
let collapsed_right = right_more_message(right_count, palette, tab_separator(capabilities));
|
||||
|
||||
let total_size = collapsed_left.len + middle_size + collapsed_right.len;
|
||||
|
||||
if total_size > cols {
|
||||
// break and dont add collapsed tabs to tabs_to_render, they will not fit
|
||||
break;
|
||||
}
|
||||
|
||||
let left = if let Some(tab) = tabs_before_active.last() {
|
||||
tab.len
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
|
||||
let right = if let Some(tab) = tabs_after_active.first() {
|
||||
tab.len
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
|
||||
// total size is shortened if the next tab to be added is the last one, as that will remove the collapsed tab
|
||||
let size_by_adding_left =
|
||||
left.saturating_add(total_size)
|
||||
.saturating_sub(if left_count == 1 {
|
||||
collapsed_left.len
|
||||
} else {
|
||||
0
|
||||
});
|
||||
let size_by_adding_right =
|
||||
right
|
||||
.saturating_add(total_size)
|
||||
.saturating_sub(if right_count == 1 {
|
||||
collapsed_right.len
|
||||
} else {
|
||||
0
|
||||
});
|
||||
|
||||
let left_fits = size_by_adding_left <= cols;
|
||||
let right_fits = size_by_adding_right <= cols;
|
||||
// active tab is kept in the middle by adding to the side that
|
||||
// has less width, or if the tab on the other side doesn' fit
|
||||
if (total_left <= total_right || !right_fits) && left_fits {
|
||||
// add left tab
|
||||
let tab = tabs_before_active.pop().unwrap();
|
||||
middle_size += tab.len;
|
||||
total_left += tab.len;
|
||||
tabs_to_render.insert(0, tab);
|
||||
} else if right_fits {
|
||||
// add right tab
|
||||
let tab = tabs_after_active.remove(0);
|
||||
middle_size += tab.len;
|
||||
total_right += tab.len;
|
||||
tabs_to_render.push(tab);
|
||||
} else {
|
||||
// there's either no space to add more tabs or no more tabs to add, so we're done
|
||||
tabs_to_render.insert(0, collapsed_left);
|
||||
tabs_to_render.push(collapsed_right);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn left_more_message(tab_count_to_the_left: usize, palette: Palette, separator: &str) -> LinePart {
|
||||
if tab_count_to_the_left == 0 {
|
||||
return LinePart::default();
|
||||
}
|
||||
let more_text = if tab_count_to_the_left < 10000 {
|
||||
format!(" ← +{} ", tab_count_to_the_left)
|
||||
} else {
|
||||
" ← +many ".to_string()
|
||||
};
|
||||
// 238
|
||||
// chars length plus separator length on both sides
|
||||
let more_text_len = more_text.width() + 2 * separator.width();
|
||||
let text_color = match palette.theme_hue {
|
||||
ThemeHue::Dark => palette.white,
|
||||
ThemeHue::Light => palette.black,
|
||||
};
|
||||
let left_separator = style!(text_color, palette.orange).paint(separator);
|
||||
let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text);
|
||||
let right_separator = style!(palette.orange, text_color).paint(separator);
|
||||
let more_styled_text =
|
||||
ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string();
|
||||
LinePart {
|
||||
part: more_styled_text,
|
||||
len: more_text_len,
|
||||
}
|
||||
}
|
||||
|
||||
fn right_more_message(
|
||||
tab_count_to_the_right: usize,
|
||||
palette: Palette,
|
||||
separator: &str,
|
||||
) -> LinePart {
|
||||
if tab_count_to_the_right == 0 {
|
||||
return LinePart::default();
|
||||
};
|
||||
let more_text = if tab_count_to_the_right < 10000 {
|
||||
format!(" +{} → ", tab_count_to_the_right)
|
||||
} else {
|
||||
" +many → ".to_string()
|
||||
};
|
||||
// chars length plus separator length on both sides
|
||||
let more_text_len = more_text.width() + 2 * separator.width();
|
||||
let text_color = match palette.theme_hue {
|
||||
ThemeHue::Dark => palette.white,
|
||||
ThemeHue::Light => palette.black,
|
||||
};
|
||||
let left_separator = style!(text_color, palette.orange).paint(separator);
|
||||
let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text);
|
||||
let right_separator = style!(palette.orange, text_color).paint(separator);
|
||||
let more_styled_text =
|
||||
ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string();
|
||||
LinePart {
|
||||
part: more_styled_text,
|
||||
len: more_text_len,
|
||||
}
|
||||
}
|
||||
|
||||
fn tab_line_prefix(
|
||||
session_name: Option<&str>,
|
||||
mode: InputMode,
|
||||
palette: Palette,
|
||||
cols: usize,
|
||||
) -> Vec<LinePart> {
|
||||
let prefix_text = " Zellij ".to_string();
|
||||
|
||||
let prefix_text_len = prefix_text.chars().count();
|
||||
let text_color = match palette.theme_hue {
|
||||
ThemeHue::Dark => palette.white,
|
||||
ThemeHue::Light => palette.black,
|
||||
};
|
||||
let bg_color = match palette.theme_hue {
|
||||
ThemeHue::Dark => palette.black,
|
||||
ThemeHue::Light => palette.white,
|
||||
};
|
||||
let prefix_styled_text = style!(text_color, bg_color).bold().paint(prefix_text);
|
||||
let mut parts = vec![LinePart {
|
||||
part: prefix_styled_text.to_string(),
|
||||
len: prefix_text_len,
|
||||
}];
|
||||
if let Some(name) = session_name {
|
||||
let name_part = format!("({}) ", name);
|
||||
let name_part_len = name_part.width();
|
||||
let text_color = match palette.theme_hue {
|
||||
ThemeHue::Dark => palette.white,
|
||||
ThemeHue::Light => palette.black,
|
||||
};
|
||||
let name_part_styled_text = style!(text_color, bg_color).bold().paint(name_part);
|
||||
if cols.saturating_sub(prefix_text_len) >= name_part_len {
|
||||
parts.push(LinePart {
|
||||
part: name_part_styled_text.to_string(),
|
||||
len: name_part_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
let mode_part = format!("({:?})", mode);
|
||||
let mode_part_len = mode_part.width();
|
||||
let mode_part_styled_text = style!(text_color, bg_color).bold().paint(mode_part);
|
||||
if cols.saturating_sub(prefix_text_len) >= mode_part_len {
|
||||
parts.push(LinePart {
|
||||
part: format!("({:^6})", mode_part_styled_text),
|
||||
len: mode_part_len,
|
||||
})
|
||||
}
|
||||
parts
|
||||
}
|
||||
|
||||
pub fn tab_separator(capabilities: PluginCapabilities) -> &'static str {
|
||||
if !capabilities.arrow_fonts {
|
||||
ARROW_SEPARATOR
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tab_line(
|
||||
session_name: Option<&str>,
|
||||
mut all_tabs: Vec<LinePart>,
|
||||
active_tab_index: usize,
|
||||
cols: usize,
|
||||
palette: Palette,
|
||||
capabilities: PluginCapabilities,
|
||||
mode: InputMode,
|
||||
) -> Vec<LinePart> {
|
||||
let mut tabs_after_active = all_tabs.split_off(active_tab_index);
|
||||
let mut tabs_before_active = all_tabs;
|
||||
let active_tab = if !tabs_after_active.is_empty() {
|
||||
tabs_after_active.remove(0)
|
||||
} else {
|
||||
tabs_before_active.pop().unwrap()
|
||||
};
|
||||
let mut prefix = tab_line_prefix(session_name, mode, palette, cols);
|
||||
let prefix_len = get_current_title_len(&prefix);
|
||||
|
||||
// if active tab alone won't fit in cols, don't draw any tabs
|
||||
if prefix_len + active_tab.len > cols {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
let mut tabs_to_render = vec![active_tab];
|
||||
|
||||
populate_tabs_in_tab_line(
|
||||
&mut tabs_before_active,
|
||||
&mut tabs_after_active,
|
||||
&mut tabs_to_render,
|
||||
cols.saturating_sub(prefix_len),
|
||||
palette,
|
||||
capabilities,
|
||||
);
|
||||
prefix.append(&mut tabs_to_render);
|
||||
prefix
|
||||
}
|
137
default-plugins/compact-bar/src/main.rs
Normal file
137
default-plugins/compact-bar/src/main.rs
Normal file
@ -0,0 +1,137 @@
|
||||
mod line;
|
||||
mod tab;
|
||||
|
||||
use std::cmp::{max, min};
|
||||
use std::convert::TryInto;
|
||||
|
||||
use zellij_tile::prelude::*;
|
||||
|
||||
use crate::line::tab_line;
|
||||
use crate::tab::tab_style;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct LinePart {
|
||||
part: String,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
tabs: Vec<TabInfo>,
|
||||
active_tab_idx: usize,
|
||||
mode_info: ModeInfo,
|
||||
mouse_click_pos: usize,
|
||||
should_render: bool,
|
||||
}
|
||||
|
||||
static ARROW_SEPARATOR: &str = "";
|
||||
|
||||
register_plugin!(State);
|
||||
|
||||
impl ZellijPlugin for State {
|
||||
fn load(&mut self) {
|
||||
set_selectable(false);
|
||||
subscribe(&[
|
||||
EventType::TabUpdate,
|
||||
EventType::ModeUpdate,
|
||||
EventType::Mouse,
|
||||
]);
|
||||
}
|
||||
|
||||
fn update(&mut self, event: Event) {
|
||||
match event {
|
||||
Event::ModeUpdate(mode_info) => self.mode_info = mode_info,
|
||||
Event::TabUpdate(tabs) => {
|
||||
if let Some(active_tab_index) = tabs.iter().position(|t| t.active) {
|
||||
// tabs are indexed starting from 1 so we need to add 1
|
||||
self.active_tab_idx = active_tab_index + 1;
|
||||
self.tabs = tabs;
|
||||
} else {
|
||||
eprintln!("Could not find active tab.");
|
||||
}
|
||||
}
|
||||
Event::Mouse(me) => match me {
|
||||
Mouse::LeftClick(_, col) => {
|
||||
self.mouse_click_pos = col;
|
||||
self.should_render = true;
|
||||
}
|
||||
Mouse::ScrollUp(_) => {
|
||||
switch_tab_to(min(self.active_tab_idx + 1, self.tabs.len()) as u32);
|
||||
}
|
||||
Mouse::ScrollDown(_) => {
|
||||
switch_tab_to(max(self.active_tab_idx.saturating_sub(1), 1) as u32);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {
|
||||
eprintln!("Got unrecognized event: {:?}", event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&mut self, _rows: usize, cols: usize) {
|
||||
if self.tabs.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut all_tabs: Vec<LinePart> = vec![];
|
||||
let mut active_tab_index = 0;
|
||||
for t in &mut self.tabs {
|
||||
let mut tabname = t.name.clone();
|
||||
if t.active && self.mode_info.mode == InputMode::RenameTab {
|
||||
if tabname.is_empty() {
|
||||
tabname = String::from("Enter name...");
|
||||
}
|
||||
active_tab_index = t.position;
|
||||
} else if t.active {
|
||||
active_tab_index = t.position;
|
||||
}
|
||||
let tab = tab_style(
|
||||
tabname,
|
||||
t.active,
|
||||
t.is_sync_panes_active,
|
||||
self.mode_info.style.colors,
|
||||
self.mode_info.capabilities,
|
||||
t.other_focused_clients.as_slice(),
|
||||
);
|
||||
all_tabs.push(tab);
|
||||
}
|
||||
let tab_line = tab_line(
|
||||
self.mode_info.session_name.as_deref(),
|
||||
all_tabs,
|
||||
active_tab_index,
|
||||
cols.saturating_sub(1),
|
||||
self.mode_info.style.colors,
|
||||
self.mode_info.capabilities,
|
||||
self.mode_info.mode,
|
||||
);
|
||||
let mut s = String::new();
|
||||
let mut len_cnt = 0;
|
||||
for (idx, bar_part) in tab_line.iter().enumerate() {
|
||||
s = format!("{}{}", s, &bar_part.part);
|
||||
|
||||
if self.should_render
|
||||
&& self.mouse_click_pos > len_cnt
|
||||
&& self.mouse_click_pos <= len_cnt + bar_part.len
|
||||
&& idx > 2
|
||||
{
|
||||
// First three elements of tab_line are "Zellij", session name and empty thing, hence the idx > 2 condition.
|
||||
// Tabs are indexed starting from 1, therefore we need subtract 2 below.
|
||||
switch_tab_to(TryInto::<u32>::try_into(idx).unwrap() - 2);
|
||||
}
|
||||
len_cnt += bar_part.len;
|
||||
}
|
||||
let background = match self.mode_info.style.colors.theme_hue {
|
||||
ThemeHue::Dark => self.mode_info.style.colors.black,
|
||||
ThemeHue::Light => self.mode_info.style.colors.white,
|
||||
};
|
||||
match background {
|
||||
PaletteColor::Rgb((r, g, b)) => {
|
||||
println!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", s, r, g, b);
|
||||
}
|
||||
PaletteColor::EightBit(color) => {
|
||||
println!("{}\u{1b}[48;5;{}m\u{1b}[0K", s, color);
|
||||
}
|
||||
}
|
||||
self.should_render = false;
|
||||
}
|
||||
}
|
84
default-plugins/compact-bar/src/tab.rs
Normal file
84
default-plugins/compact-bar/src/tab.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use crate::{line::tab_separator, LinePart};
|
||||
use ansi_term::{ANSIString, ANSIStrings};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use zellij_tile::prelude::*;
|
||||
use zellij_tile_utils::style;
|
||||
|
||||
fn cursors(focused_clients: &[ClientId], palette: Palette) -> (Vec<ANSIString>, usize) {
|
||||
// cursor section, text length
|
||||
let mut len = 0;
|
||||
let mut cursors = vec![];
|
||||
for client_id in focused_clients.iter() {
|
||||
if let Some(color) = client_id_to_colors(*client_id, palette) {
|
||||
cursors.push(style!(color.1, color.0).paint(" "));
|
||||
len += 1;
|
||||
}
|
||||
}
|
||||
(cursors, len)
|
||||
}
|
||||
|
||||
pub fn render_tab(
|
||||
text: String,
|
||||
palette: Palette,
|
||||
separator: &str,
|
||||
focused_clients: &[ClientId],
|
||||
active: bool,
|
||||
) -> LinePart {
|
||||
let background_color = if active { palette.green } else { palette.fg };
|
||||
let foreground_color = match palette.theme_hue {
|
||||
ThemeHue::Dark => palette.black,
|
||||
ThemeHue::Light => palette.white,
|
||||
};
|
||||
let left_separator = style!(foreground_color, background_color).paint(separator);
|
||||
let mut tab_text_len = text.width() + 2 + separator.width() * 2; // 2 for left and right separators, 2 for the text padding
|
||||
|
||||
let tab_styled_text = style!(foreground_color, background_color)
|
||||
.bold()
|
||||
.paint(format!(" {} ", text));
|
||||
|
||||
let right_separator = style!(background_color, foreground_color).paint(separator);
|
||||
let tab_styled_text = if !focused_clients.is_empty() {
|
||||
let (cursor_section, extra_length) = cursors(focused_clients, palette);
|
||||
tab_text_len += extra_length;
|
||||
let mut s = String::new();
|
||||
let cursor_beginning = style!(foreground_color, background_color)
|
||||
.bold()
|
||||
.paint("[")
|
||||
.to_string();
|
||||
let cursor_section = ANSIStrings(&cursor_section).to_string();
|
||||
let cursor_end = style!(foreground_color, background_color)
|
||||
.bold()
|
||||
.paint("]")
|
||||
.to_string();
|
||||
s.push_str(&left_separator.to_string());
|
||||
s.push_str(&tab_styled_text.to_string());
|
||||
s.push_str(&cursor_beginning);
|
||||
s.push_str(&cursor_section);
|
||||
s.push_str(&cursor_end);
|
||||
s.push_str(&right_separator.to_string());
|
||||
s
|
||||
} else {
|
||||
ANSIStrings(&[left_separator, tab_styled_text, right_separator]).to_string()
|
||||
};
|
||||
|
||||
LinePart {
|
||||
part: tab_styled_text,
|
||||
len: tab_text_len,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tab_style(
|
||||
text: String,
|
||||
is_active_tab: bool,
|
||||
is_sync_panes_active: bool,
|
||||
palette: Palette,
|
||||
capabilities: PluginCapabilities,
|
||||
focused_clients: &[ClientId],
|
||||
) -> LinePart {
|
||||
let separator = tab_separator(capabilities);
|
||||
let mut tab_text = text;
|
||||
if is_sync_panes_active {
|
||||
tab_text.push_str(" (Sync)");
|
||||
}
|
||||
render_tab(tab_text, palette, separator, focused_clients, is_active_tab)
|
||||
}
|
@ -69,6 +69,7 @@ flake-utils.lib.eachSystem [
|
||||
];
|
||||
|
||||
defaultPlugins = [
|
||||
plugins.compact-bar
|
||||
plugins.status-bar
|
||||
plugins.tab-bar
|
||||
plugins.strider
|
||||
@ -123,6 +124,7 @@ flake-utils.lib.eachSystem [
|
||||
cp ${plugins.tab-bar}/bin/tab-bar.wasm assets/plugins/tab-bar.wasm
|
||||
cp ${plugins.status-bar}/bin/status-bar.wasm assets/plugins/status-bar.wasm
|
||||
cp ${plugins.strider}/bin/strider.wasm assets/plugins/strider.wasm
|
||||
cp ${plugins.compact-bar}/bin/compact-bar.wasm assets/plugins/compact-bar.wasm
|
||||
'';
|
||||
|
||||
desktopItems = [
|
||||
|
@ -50,4 +50,5 @@ in {
|
||||
status-bar = makeDefaultPlugin "status-bar";
|
||||
tab-bar = makeDefaultPlugin "tab-bar";
|
||||
strider = makeDefaultPlugin "strider";
|
||||
compact-bar = makeDefaultPlugin "compact-bar";
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ macro_rules! asset_map {
|
||||
pub(crate) fn populate_data_dir(data_dir: &Path) {
|
||||
// First run installation of default plugins & layouts
|
||||
let mut assets = asset_map! {
|
||||
"assets/plugins/compact-bar.wasm" => "plugins/compact-bar.wasm",
|
||||
"assets/plugins/status-bar.wasm" => "plugins/status-bar.wasm",
|
||||
"assets/plugins/tab-bar.wasm" => "plugins/tab-bar.wasm",
|
||||
"assets/plugins/strider.wasm" => "plugins/strider.wasm",
|
||||
|
@ -479,6 +479,8 @@ plugins:
|
||||
tag: status-bar
|
||||
- path: strider
|
||||
tag: strider
|
||||
- path: compact-bar
|
||||
tag: compact-bar
|
||||
|
||||
# Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
|
||||
# eg. when terminal window with an active zellij session is closed
|
||||
|
13
zellij-utils/assets/layouts/compact.yaml
Normal file
13
zellij-utils/assets/layouts/compact.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
template:
|
||||
direction: Horizontal
|
||||
parts:
|
||||
- direction: Vertical
|
||||
body: true
|
||||
- direction: Vertical
|
||||
borderless: true
|
||||
split_size:
|
||||
Fixed: 1
|
||||
run:
|
||||
plugin:
|
||||
location: "zellij:compact-bar"
|
@ -288,6 +288,7 @@ impl LayoutFromYamlIntermediate {
|
||||
Some("default") => Self::default_from_assets(),
|
||||
Some("strider") => Self::strider_from_assets(),
|
||||
Some("disable-status-bar") => Self::disable_status_from_assets(),
|
||||
Some("compact") => Self::compact_from_assets(),
|
||||
None | Some(_) => Err(ConfigError::IoPath(
|
||||
std::io::Error::new(std::io::ErrorKind::Other, "The layout was not found"),
|
||||
path.into(),
|
||||
@ -314,6 +315,12 @@ impl LayoutFromYamlIntermediate {
|
||||
serde_yaml::from_str(&String::from_utf8(setup::NO_STATUS_LAYOUT.to_vec())?)?;
|
||||
Ok(layout)
|
||||
}
|
||||
|
||||
pub fn compact_from_assets() -> LayoutFromYamlIntermediateResult {
|
||||
let layout: LayoutFromYamlIntermediate =
|
||||
serde_yaml::from_str(&String::from_utf8(setup::COMPACT_BAR_LAYOUT.to_vec())?)?;
|
||||
Ok(layout)
|
||||
}
|
||||
}
|
||||
|
||||
type LayoutFromYamlResult = Result<LayoutFromYaml, ConfigError>;
|
||||
|
@ -271,7 +271,7 @@ mod tests {
|
||||
)?;
|
||||
let plugins = PluginsConfig::get_plugins_with_default(plugins.try_into()?);
|
||||
|
||||
assert_eq!(plugins.iter().count(), 4);
|
||||
assert_eq!(plugins.iter().count(), 5);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,12 @@ pub const NO_STATUS_LAYOUT: &[u8] = include_bytes!(concat!(
|
||||
"assets/layouts/disable-status-bar.yaml"
|
||||
));
|
||||
|
||||
pub const COMPACT_BAR_LAYOUT: &[u8] = include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/",
|
||||
"assets/layouts/compact.yaml"
|
||||
));
|
||||
|
||||
pub const FISH_EXTRA_COMPLETION: &[u8] = include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/",
|
||||
@ -141,6 +147,7 @@ pub fn dump_specified_layout(layout: &str) -> std::io::Result<()> {
|
||||
match layout {
|
||||
"strider" => dump_asset(STRIDER_LAYOUT),
|
||||
"default" => dump_asset(DEFAULT_LAYOUT),
|
||||
"compact" => dump_asset(COMPACT_BAR_LAYOUT),
|
||||
"disable-status" => dump_asset(NO_STATUS_LAYOUT),
|
||||
not_found => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
|
Loading…
Reference in New Issue
Block a user