aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2025-02-13 17:12:47 +0100
committerGitHub <noreply@github.com>2025-02-13 17:12:47 +0100
commit7aaa7aea8f9a378660492d03ff5736dbf846978d (patch)
tree2b9884e135d73c82da442d1de649eb2b5df3fc54
parentdocs(changelog): about plugin (diff)
downloadsl0ppij-7aaa7aea8f9a378660492d03ff5736dbf846978d.tar.gz
sl0ppij-7aaa7aea8f9a378660492d03ff5736dbf846978d.tar.xz
sl0ppij-7aaa7aea8f9a378660492d03ff5736dbf846978d.zip
feat(ux): tips on startup (#3988)
* add some tips * refactoring and max tip index * add config to disable release notes and startup tips * allow dismissing startup tips from plugin * random tip at startup * custom launch about * fix tests * style(fmt): rustfmt
-rw-r--r--Cargo.lock122
-rw-r--r--default-plugins/about/Cargo.toml3
-rw-r--r--default-plugins/about/src/main.rs118
-rw-r--r--default-plugins/about/src/pages.rs72
-rw-r--r--default-plugins/about/src/tips.rs852
-rw-r--r--default-plugins/configuration/src/presets.rs42
-rw-r--r--default-plugins/status-bar/src/one_line_ui.rs20
-rw-r--r--example/default.kdl17
-rw-r--r--src/tests/e2e/remote_runner.rs14
-rw-r--r--zellij-server/src/lib.rs52
-rw-r--r--zellij-server/src/plugins/mod.rs12
-rw-r--r--zellij-utils/assets/config/default.kdl17
-rwxr-xr-xzellij-utils/assets/plugins/about.wasmbin1100338 -> 1189241 bytes
-rwxr-xr-xzellij-utils/assets/plugins/compact-bar.wasmbin1017381 -> 1109218 bytes
-rwxr-xr-xzellij-utils/assets/plugins/configuration.wasmbin1146869 -> 1245040 bytes
-rwxr-xr-xzellij-utils/assets/plugins/fixture-plugin-for-tests.wasmbin1051063 -> 1154604 bytes
-rwxr-xr-xzellij-utils/assets/plugins/plugin-manager.wasmbin1030077 -> 1143382 bytes
-rwxr-xr-xzellij-utils/assets/plugins/session-manager.wasmbin1119113 -> 1214771 bytes
-rwxr-xr-xzellij-utils/assets/plugins/status-bar.wasmbin1299307 -> 1375652 bytes
-rwxr-xr-xzellij-utils/assets/plugins/strider.wasmbin1122257 -> 1225990 bytes
-rwxr-xr-xzellij-utils/assets/plugins/tab-bar.wasmbin1089529 -> 1194221 bytes
-rw-r--r--zellij-utils/assets/prost/api.event.rs3
-rw-r--r--zellij-utils/src/data.rs1
-rw-r--r--zellij-utils/src/input/options.rs22
-rw-r--r--zellij-utils/src/kdl/mod.rs64
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string.snap9
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap19
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap12
-rw-r--r--zellij-utils/src/plugin_api/event.proto1
-rw-r--r--zellij-utils/src/plugin_api/event.rs10
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap32
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap32
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap33
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap32
39 files changed, 1563 insertions, 58 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d0804ad5..51661080 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6,8 +6,7 @@ version = 4
name = "about"
version = "0.1.0"
dependencies = [
- "ansi_term",
- "chrono",
+ "rand 0.9.0",
"zellij-tile",
]
@@ -44,7 +43,7 @@ dependencies = [
"cfg-if",
"once_cell",
"version_check",
- "zerocopy",
+ "zerocopy 0.7.34",
]
[[package]]
@@ -458,7 +457,7 @@ dependencies = [
"cap-primitives",
"cap-std",
"io-lifetimes 2.0.3",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -486,7 +485,7 @@ dependencies = [
"ipnet",
"maybe-owned",
"rustix 0.38.44",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
"winx",
]
@@ -497,7 +496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea13372b49df066d1ae654e5c6e41799c1efd9f6b36794b921e877ea4037977"
dependencies = [
"ambient-authority",
- "rand",
+ "rand 0.8.5",
]
[[package]]
@@ -1165,7 +1164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1510,6 +1509,18 @@ dependencies = [
]
[[package]]
+name = "getrandom"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.13.3+wasi-0.2.2",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
name = "ghost"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1834,7 +1845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2285ddfe3054097ef4b2fe909ef8c3bcd1ea52a8f0d274416caebeef39f04a65"
dependencies = [
"io-lifetimes 2.0.3",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -2328,7 +2339,7 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc"
dependencies = [
- "rand",
+ "rand 0.8.5",
]
[[package]]
@@ -2712,7 +2723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf"
dependencies = [
"phf_shared",
- "rand",
+ "rand 0.8.5",
]
[[package]]
@@ -2958,8 +2969,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
- "rand_chacha",
- "rand_core",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.3",
+]
+
+[[package]]
+name = "rand"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
+dependencies = [
+ "rand_chacha 0.9.0",
+ "rand_core 0.9.0",
+ "zerocopy 0.8.17",
]
[[package]]
@@ -2969,7 +2991,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
- "rand_core",
+ "rand_core 0.6.3",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.9.0",
]
[[package]]
@@ -2978,7 +3010,17 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
- "getrandom",
+ "getrandom 0.2.10",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+dependencies = [
+ "getrandom 0.3.1",
+ "zerocopy 0.8.17",
]
[[package]]
@@ -3029,7 +3071,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
- "getrandom",
+ "getrandom 0.2.10",
"redox_syscall 0.2.13",
"thiserror",
]
@@ -3134,7 +3176,7 @@ dependencies = [
"libc",
"linux-raw-sys 0.4.15",
"once_cell",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -3458,7 +3500,7 @@ dependencies = [
"ansi_term",
"colored",
"lazy_static",
- "rand",
+ "rand 0.8.5",
"regex",
"serde",
"serde_json",
@@ -4052,7 +4094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"atomic",
- "getrandom",
+ "getrandom 0.2.10",
"serde",
]
@@ -4147,6 +4189,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
+name = "wasi"
+version = "0.13.3+wasi-0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
name = "wasm-bindgen"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4617,7 +4668,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5a5e0adf7eed68976410def849a4bdab6f6e9f6163f152de9cb89deea9e60b"
dependencies = [
- "getrandom",
+ "getrandom 0.2.10",
"mac_address",
"once_cell",
"sha2",
@@ -5031,6 +5082,15 @@ dependencies = [
]
[[package]]
+name = "wit-bindgen-rt"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+dependencies = [
+ "bitflags 2.5.0",
+]
+
+[[package]]
name = "wit-parser"
version = "0.221.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5120,7 +5180,7 @@ dependencies = [
"insta",
"log",
"names",
- "rand",
+ "rand 0.8.5",
"regex",
"ssh2",
"suggest",
@@ -5255,7 +5315,16 @@ version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [
- "zerocopy-derive",
+ "zerocopy-derive 0.7.34",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713"
+dependencies = [
+ "zerocopy-derive 0.8.17",
]
[[package]]
@@ -5270,6 +5339,17 @@ dependencies = [
]
[[package]]
+name = "zerocopy-derive"
+version = "0.8.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
name = "zeroize"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/default-plugins/about/Cargo.toml b/default-plugins/about/Cargo.toml
index 66a79ac2..536617d6 100644
--- a/default-plugins/about/Cargo.toml
+++ b/default-plugins/about/Cargo.toml
@@ -6,6 +6,5 @@ edition = "2021"
license = "MIT"
[dependencies]
-ansi_term = "0.12.1"
zellij-tile = { path = "../../zellij-tile" }
-chrono = "0.4.0"
+rand = "0.9.0"
diff --git a/default-plugins/about/src/main.rs b/default-plugins/about/src/main.rs
index bd7c28ea..87af9ffd 100644
--- a/default-plugins/about/src/main.rs
+++ b/default-plugins/about/src/main.rs
@@ -1,11 +1,15 @@
mod active_component;
mod pages;
+mod tips;
use zellij_tile::prelude::*;
use pages::Page;
+use rand::prelude::*;
+use rand::rng;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::rc::Rc;
+use tips::MAX_TIP_INDEX;
const UI_ROWS: usize = 20;
const UI_COLUMNS: usize = 90;
@@ -20,6 +24,10 @@ struct App {
tab_columns: usize,
own_plugin_id: Option<u32>,
is_release_notes: bool,
+ is_startup_tip: bool,
+ tip_index: usize,
+ waiting_for_config_to_be_written: bool,
+ error: Option<String>,
}
impl Default for App {
@@ -32,6 +40,7 @@ impl Default for App {
link_executable.clone(),
"".to_owned(),
base_mode.clone(),
+ false,
),
link_executable,
zellij_version,
@@ -40,6 +49,10 @@ impl Default for App {
tab_columns: 0,
own_plugin_id: None,
is_release_notes: false,
+ is_startup_tip: false,
+ tip_index: 0,
+ waiting_for_config_to_be_written: false,
+ error: None,
}
}
}
@@ -52,27 +65,62 @@ impl ZellijPlugin for App {
.get("is_release_notes")
.map(|v| v == "true")
.unwrap_or(false);
+ self.is_startup_tip = configuration
+ .get("is_startup_tip")
+ .map(|v| v == "true")
+ .unwrap_or(false);
subscribe(&[
EventType::Key,
EventType::Mouse,
EventType::ModeUpdate,
EventType::RunCommandResult,
EventType::TabUpdate,
+ EventType::FailedToWriteConfigToDisk,
+ EventType::ConfigWasWrittenToDisk,
]);
let own_plugin_id = get_plugin_ids().plugin_id;
self.own_plugin_id = Some(own_plugin_id);
*self.zellij_version.borrow_mut() = get_zellij_version();
self.change_own_title();
self.query_link_executable();
- self.active_page = Page::new_main_screen(
- self.link_executable.clone(),
- self.zellij_version.borrow().clone(),
- self.base_mode.clone(),
- );
+ self.active_page = if self.is_startup_tip {
+ let mut rng = rng();
+ self.tip_index = rng.random_range(0..=MAX_TIP_INDEX);
+ Page::new_tip_screen(
+ self.link_executable.clone(),
+ self.base_mode.clone(),
+ self.tip_index,
+ )
+ } else {
+ Page::new_main_screen(
+ self.link_executable.clone(),
+ self.zellij_version.borrow().clone(),
+ self.base_mode.clone(),
+ self.is_release_notes,
+ )
+ };
}
fn update(&mut self, event: Event) -> bool {
let mut should_render = false;
match event {
+ Event::FailedToWriteConfigToDisk(file_path) => {
+ if self.waiting_for_config_to_be_written {
+ let error = match file_path {
+ Some(file_path) => {
+ format!("Failed to write config to disk at: {}", file_path)
+ },
+ None => format!("Failed to write config to disk."),
+ };
+ eprintln!("{}", error);
+ self.error = Some(error);
+ should_render = true;
+ }
+ },
+ Event::ConfigWasWrittenToDisk => {
+ if self.waiting_for_config_to_be_written {
+ close_self();
+ }
+ },
Event::TabUpdate(tab_info) => {
self.center_own_pane(tab_info);
},
@@ -98,14 +146,19 @@ impl ZellijPlugin for App {
}
},
Event::Key(key) => {
- should_render = self.handle_key(key);
+ if let Some(_error) = self.error.take() {
+ // dismiss error on any key
+ should_render = true;
+ } else {
+ should_render = self.handle_key(key);
+ }
},
_ => {},
}
should_render
}
fn render(&mut self, rows: usize, cols: usize) {
- self.active_page.render(rows, cols);
+ self.active_page.render(rows, cols, &self.error);
}
}
@@ -162,11 +215,24 @@ impl App {
}
pub fn handle_key(&mut self, key: KeyWithModifier) -> bool {
let mut should_render = false;
- if key.bare_key == BareKey::Enter && key.has_no_modifiers() {
+ if key.bare_key == BareKey::Up && key.has_no_modifiers() && self.is_startup_tip {
+ self.previous_tip();
+ should_render = true;
+ } else if key.bare_key == BareKey::Down && key.has_no_modifiers() && self.is_startup_tip {
+ self.next_tip();
+ should_render = true;
+ } else if key.bare_key == BareKey::Enter && key.has_no_modifiers() {
if let Some(new_page) = self.active_page.handle_selection() {
self.active_page = new_page;
should_render = true;
}
+ } else if key.bare_key == BareKey::Char('c')
+ && key.has_modifiers(&[KeyModifier::Ctrl])
+ && self.is_startup_tip
+ {
+ self.waiting_for_config_to_be_written = true;
+ let save_configuration = true;
+ reconfigure("show_startup_tips false".to_owned(), save_configuration);
} else if key.bare_key == BareKey::Esc && key.has_no_modifiers() {
if self.active_page.is_main_screen {
close_self();
@@ -175,9 +241,21 @@ impl App {
self.link_executable.clone(),
self.zellij_version.borrow().clone(),
self.base_mode.clone(),
+ self.is_release_notes,
);
should_render = true;
}
+ } else if key.bare_key == BareKey::Char('?')
+ && !self.is_release_notes
+ && !self.is_startup_tip
+ {
+ self.is_startup_tip = true;
+ self.active_page = Page::new_tip_screen(
+ self.link_executable.clone(),
+ self.base_mode.clone(),
+ self.tip_index,
+ );
+ should_render = true;
} else {
should_render = self.active_page.handle_key(key);
}
@@ -208,4 +286,28 @@ impl App {
}
}
}
+ fn previous_tip(&mut self) {
+ if self.tip_index == 0 {
+ self.tip_index = MAX_TIP_INDEX;
+ } else {
+ self.tip_index = self.tip_index.saturating_sub(1);
+ }
+ self.active_page = Page::new_tip_screen(
+ self.link_executable.clone(),
+ self.base_mode.clone(),
+ self.tip_index,
+ );
+ }
+ fn next_tip(&mut self) {
+ if self.tip_index == MAX_TIP_INDEX {
+ self.tip_index = 0;
+ } else {
+ self.tip_index += 1;
+ }
+ self.active_page = Page::new_tip_screen(
+ self.link_executable.clone(),
+ self.base_mode.clone(),
+ self.tip_index,
+ );
+ }
}
diff --git a/default-plugins/about/src/pages.rs b/default-plugins/about/src/pages.rs
index 2951c1b0..9bf82200 100644
--- a/default-plugins/about/src/pages.rs
+++ b/default-plugins/about/src/pages.rs
@@ -20,10 +20,11 @@ impl Page {
link_executable: Rc<RefCell<String>>,
zellij_version: String,
base_mode: Rc<RefCell<InputMode>>,
+ is_release_notes: bool,
) -> Self {
Page::new()
.main_screen()
- .with_title(main_screen_title(zellij_version.clone()))
+ .with_title(main_screen_title(zellij_version.clone(), is_release_notes))
.with_bulletin_list(BulletinList::new(whats_new_title()).with_items(vec![
ActiveComponent::new(TextOrCustomRender::Text(main_menu_item(
"Stacked Resize",
@@ -102,9 +103,15 @@ impl Page {
link_executable.clone(),
)),
])])
- .with_help(Box::new(|hovering_over_link, menu_item_is_selected| {
- main_screen_help_text(hovering_over_link, menu_item_is_selected)
- }))
+ .with_help(if is_release_notes {
+ Box::new(|hovering_over_link, menu_item_is_selected| {
+ release_notes_main_help(hovering_over_link, menu_item_is_selected)
+ })
+ } else {
+ Box::new(|hovering_over_link, menu_item_is_selected| {
+ main_screen_help_text(hovering_over_link, menu_item_is_selected)
+ })
+ })
}
pub fn new_stacked_resize(link_executable: Rc<RefCell<String>>) -> Page {
Page::new()
@@ -543,7 +550,7 @@ impl Page {
row_count += self.components_to_render.len();
row_count
}
- pub fn render(&mut self, rows: usize, columns: usize) {
+ pub fn render(&mut self, rows: usize, columns: usize, error: &Option<String>) {
let base_x = columns.saturating_sub(self.ui_column_count()) / 2;
let base_y = rows.saturating_sub(self.ui_row_count()) / 2;
let mut current_y = base_y;
@@ -562,12 +569,23 @@ impl Page {
RenderedComponent::HelpText(_) => true,
_ => false,
};
+ if is_help {
+ if let Some(error) = error {
+ render_error(error, rows);
+ continue;
+ }
+ }
let y = if is_help { rows } else { current_y };
+ let columns = if is_help {
+ columns
+ } else {
+ columns.saturating_sub(base_x * 2)
+ };
let rendered_rows = rendered_component.render(
base_x,
y,
rows,
- columns.saturating_sub(base_x * 2),
+ columns,
self.hovering_over_link,
self.menu_item_is_selected,
);
@@ -576,6 +594,16 @@ impl Page {
}
}
+fn render_error(error: &str, y: usize) {
+ print_text_with_coordinates(
+ Text::new(format!("ERROR: {}", error)).color_range(3, ..),
+ 0,
+ y,
+ None,
+ None,
+ );
+}
+
fn changelog_link_unselected(version: String) -> Text {
let full_changelog_text = format!(
"https://github.com/zellij-org/zellij/releases/tag/v{}",
@@ -647,9 +675,14 @@ fn whats_new_title() -> Text {
Text::new("What's new?")
}
-fn main_screen_title(version: String) -> Text {
- let title_text = format!("Hi there, welcome to Zellij {}!", &version);
- Text::new(title_text).color_range(2, 21..=27 + version.chars().count())
+fn main_screen_title(version: String, is_release_notes: bool) -> Text {
+ if is_release_notes {
+ let title_text = format!("Hi there, welcome to Zellij {}!", &version);
+ Text::new(title_text).color_range(2, 21..=27 + version.chars().count())
+ } else {
+ let title_text = format!("Zellij {}", &version);
+ Text::new(title_text).color_range(2, ..)
+ }
}
fn main_screen_help_text(hovering_over_link: bool, menu_item_is_selected: bool) -> Text {
@@ -665,6 +698,27 @@ fn main_screen_help_text(hovering_over_link: bool, menu_item_is_selected: bool)
.color_range(1, 23..=29)
.color_range(1, 45..=49)
} else {
+ let help_text = format!("Help: <↓↑> - Navigate, <ESC> - Dismiss, <?> - Usage Tips");
+ Text::new(help_text)
+ .color_range(1, 6..=9)
+ .color_range(1, 23..=27)
+ .color_range(1, 40..=42)
+ }
+}
+
+fn release_notes_main_help(hovering_over_link: bool, menu_item_is_selected: bool) -> Text {
+ if hovering_over_link {
+ let help_text = format!("Help: Click or Shift-Click to open in browser");
+ Text::new(help_text)
+ .color_range(3, 6..=10)
+ .color_range(3, 15..=25)
+ } else if menu_item_is_selected {
+ let help_text = format!("Help: <↓↑> - Navigate, <ENTER> - Learn More, <ESC> - Dismiss");
+ Text::new(help_text)
+ .color_range(1, 6..=9)
+ .color_range(1, 23..=29)
+ .color_range(1, 45..=49)
+ } else {
let help_text = format!("Help: <↓↑> - Navigate, <ESC> - Dismiss");
Text::new(help_text)
.color_range(1, 6..=9)
diff --git a/default-plugins/about/src/tips.rs b/default-plugins/about/src/tips.rs
new file mode 100644
index 00000000..3a594e8d
--- /dev/null
+++ b/default-plugins/about/src/tips.rs
@@ -0,0 +1,852 @@
+use zellij_tile::prelude::*;
+
+use std::cell::RefCell;
+use std::rc::Rc;
+
+use crate::active_component::{ActiveComponent, ClickAction};
+use crate::pages::{BulletinList, ComponentLine, Page, TextOrCustomRender};
+
+pub const MAX_TIP_INDEX: usize = 11;
+
+impl Page {
+ pub fn new_tip_screen(
+ link_executable: Rc<RefCell<String>>,
+ base_mode: Rc<RefCell<InputMode>>,
+ tip_index: usize,
+ ) -> Self {
+ if tip_index == 0 {
+ Page::tip_1(link_executable)
+ } else if tip_index == 1 {
+ Page::tip_2(link_executable, base_mode)
+ } else if tip_index == 2 {
+ Page::tip_3(link_executable)
+ } else if tip_index == 3 {
+ Page::tip_4(link_executable, base_mode)
+ } else if tip_index == 4 {
+ Page::tip_5(link_executable)
+ } else if tip_index == 5 {
+ Page::tip_6(link_executable, base_mode)
+ } else if tip_index == 6 {
+ Page::tip_7(link_executable)
+ } else if tip_index == 7 {
+ Page::tip_8(link_executable)
+ } else if tip_index == 8 {
+ Page::tip_9(link_executable)
+ } else if tip_index == 9 {
+ Page::tip_10(link_executable, base_mode)
+ } else if tip_index == 10 {
+ Page::tip_11(link_executable)
+ } else if tip_index == 11 {
+ Page::tip_12(link_executable, base_mode)
+ } else {
+ Page::tip_1(link_executable)
+ }
+ }
+ pub fn tip_1(link_executable: Rc<RefCell<String>>) -> Self {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #1").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Check out the Zellij screencasts/tutorials to learn how to better take advantage")
+ ))
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("of all the Zellij features. Learn about basic usage, layouts, sessions and more!")
+ ))
+ ])
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("Follow this link: ").color_range(2, ..))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://zellij.dev/screencasts")))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(screencasts_link_selected()),
+ Box::new(screencasts_link_selected_len()),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ format!("https://zellij.dev/screencasts"),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_2(link_executable: Rc<RefCell<String>>, base_mode: Rc<RefCell<InputMode>>) -> Self {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #2").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("You can open the terminal contents in your $EDITOR, allowing you to search")
+ .color_range(2, 43..=49)
+ ))
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("through them, copy to your clipboard or even save them for later.")
+ ))
+ ])
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ match *base_mode.borrow() {
+ InputMode::Locked => {
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("While focused on a terminal pane: Ctrl g + s + e")
+ .color_range(0, 34..=39)
+ .color_indices(0, vec![43, 47])
+ ))
+ },
+ _ => {
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("While focused on a terminal pane: Ctrl s + e")
+ .color_range(0, 34..=39)
+ .color_indices(0, vec![43])
+ ))
+ }
+ }
+ ])])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_3(link_executable: Rc<RefCell<String>>) -> Self {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #3").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Want to make your floating pane bigger?"),
+ ))]),
+ ComponentLine::new(vec![ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new(
+ "You can switch to the ENLARGED layout with Alt ] while focused on it.",
+ )
+ .color_range(2, 22..=29)
+ .color_range(0, 43..=47),
+ ))]),
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ fn tip_4(link_executable: Rc<RefCell<String>>, base_mode: Rc<RefCell<InputMode>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij tip #4").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("It's possible to \"pin\" a floating pane so that it will always"),
+ ))]),
+ ComponentLine::new(vec![ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("be visible even if floating panes are hidden."),
+ ))]),
+ ])
+ .with_bulletin_list(
+ BulletinList::new(
+ Text::new(format!("Floating panes can be \"pinned\": ")).color_range(2, ..),
+ )
+ .with_items(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new(format!("With a mouse click on their top right corner"))
+ .color_range(3, 7..=17),
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(match *base_mode.borrow() {
+ InputMode::Locked => Text::new(format!("With Ctrl g + p + i"))
+ .color_range(3, 5..=10)
+ .color_range(3, 14..15)
+ .color_range(3, 18..19),
+ _ => Text::new("With Ctrl p + i")
+ .color_range(3, 5..=10)
+ .color_range(3, 14..15),
+ })),
+ ]),
+ )
+ .with_paragraph(vec![
+ ComponentLine::new(vec![ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("A great use case for these is to tail log files or to show"),
+ ))]),
+ ComponentLine::new(vec![ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new(format!(
+ "real-time compiler output while working in other panes."
+ )),
+ ))]),
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_5(link_executable: Rc<RefCell<String>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #5").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("Panes can be resized into stacks to be managed easier."))),
+ ]),
+ ])
+ .with_bulletin_list(BulletinList::new(Text::new("To try it out:").color_range(2, ..))
+ .with_items(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Hide this pane with Alt f (you can bring it back with Alt f again)")
+ .color_range(3, 20..=24)
+ .color_range(3, 54..=58)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Open 4-5 panes with Alt n")
+ .color_range(3, 20..=24)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Press Alt + until you reach full screen")
+ .color_range(3, 6..=10)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Press Alt - until you are back at the original state")
+ .color_range(3, 6..=10)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("You can always snap back to the built-in swap layouts with Alt <[]>")
+ .color_range(3, 59..=61)
+ .color_range(3, 64..=65)
+ )),
+ ])
+ )
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("To disable this behavior, add stacked_resize false to the Zellij Configuration")
+ .color_range(3, 30..=49)
+ )),
+ ])
+ ])
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("For more details, see: ")
+ .color_range(2, ..)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://zellij.dev/screencasts/stacked-resize")))
+ .with_hover(TextOrCustomRender::CustomRender(Box::new(stacked_resize_screencast_link_selected), Box::new(stacked_resize_screencast_link_selected_len)))
+ .with_left_click_action(ClickAction::new_open_link("https://zellij.dev/screencasts/stacked-resize".to_owned(), link_executable.clone()))
+ ])
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_6(link_executable: Rc<RefCell<String>>, base_mode: Rc<RefCell<InputMode>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #6").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("Are the Zellij keybindings colliding with other applications for you?")))
+ ]),
+ ])
+ .with_bulletin_list(BulletinList::new(Text::new("Check out the non-colliding keybindings preset:"))
+ .with_items(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ match *base_mode.borrow() {
+ InputMode::Locked => {
+ Text::new("Open the Zellij configuration with Ctrl g + o + c")
+ .color_range(3, 35..=40)
+ .color_indices(3, vec![44, 48])
+ },
+ _ => {
+ Text::new("Open the Zellij configuration with Ctrl o + c")
+ .color_range(3, 35..=40)
+ .color_indices(3, vec![44])
+ }
+ }
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Press TAB to go to Chagne Mode Behavior")
+ .color_range(3, 6..=9)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Select non-colliding temporarily with ENTER or permanently with Ctrl a")
+ .color_range(3, 38..=42)
+ .color_range(3, 64..=69)
+ )),
+ ])
+ )
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("For more details, see: ")
+ .color_range(2, ..)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://zellij.dev/tutorials/colliding-keybindings")))
+ .with_hover(TextOrCustomRender::CustomRender(Box::new(colliding_keybindings_link_selected), Box::new(colliding_keybindings_link_selected_len)))
+ .with_left_click_action(ClickAction::new_open_link("https://zellij.dev/tutorials/colliding-keybindings".to_owned(), link_executable.clone()))
+ ])
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_7(link_executable: Rc<RefCell<String>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #7").color_range(0, ..))
+ .with_paragraph(vec![ComponentLine::new(vec![ActiveComponent::new(
+ TextOrCustomRender::Text(Text::new(
+ "Want to customize the appearance and colors of Zellij?",
+ )),
+ )])])
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Check out the built-in themes: ").color_range(2, ..),
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "https://zellij.dev/documentation/theme-list",
+ )))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(theme_list_selected),
+ Box::new(theme_list_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://zellij.dev/documentation/theme-list".to_owned(),
+ link_executable.clone(),
+ )),
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Or create your own theme: ").color_range(2, ..),
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "https://zellij.dev/documentation/themes",
+ )))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(theme_link_selected),
+ Box::new(theme_link_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://zellij.dev/documentation/themes".to_owned(),
+ link_executable.clone(),
+ )),
+ ]),
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_8(link_executable: Rc<RefCell<String>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #8").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("If you change the pane focus with Alt + <←↓↑→> or Alt + <hjkl> beyond the")
+ .color_range(0, 34..=36)
+ .color_range(2, 40..=45)
+ .color_range(0, 50..=52)
+ .color_range(2, 56..=60)
+ ))
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("right or left side of the screen, the next or previous tab will be focused.")))
+ ]),
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_9(link_executable: Rc<RefCell<String>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #9").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("For plugins, integrations and tutorials created by the community, check out the")
+ ))
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Awesome-zellij repository: ")
+ .color_range(2, ..=39)
+ )),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://github.com/zellij-org/awesome-zellij")))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(awesome_zellij_link_text_selected),
+ Box::new(awesome_zellij_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/zellij-org/awesome-zellij".to_owned(),
+ link_executable.clone(),
+ )),
+ ]),
+ ])
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("For community and support:")
+ .color_range(2, ..)
+ ))
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("Discord: "))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://discord.com/invite/CrUAFH3")))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(discord_link_text_selected),
+ Box::new(discord_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://discord.com/invite/CrUAFH3".to_owned(),
+ link_executable.clone(),
+ )),
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("Matrix: "))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://matrix.to/#/#zellij_general:matrix.org")))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(matrix_link_text_selected),
+ Box::new(matrix_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://matrix.to/#/#zellij_general:matrix.org".to_owned(),
+ link_executable.clone(),
+ )),
+ ])
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_10(link_executable: Rc<RefCell<String>>, base_mode: Rc<RefCell<InputMode>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #10").color_range(0, ..))
+ .with_bulletin_list(
+ BulletinList::new(
+ Text::new("The Zellij session-manager can:").color_range(2, 11..=25),
+ )
+ .with_items(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "Create new sessions",
+ ))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "Switch between existing sessions",
+ ))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "Resurrect exited sessions",
+ ))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "Change the session name",
+ ))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new(
+ "Disconnect other users from the current session",
+ ))),
+ ]),
+ )
+ .with_paragraph(vec![ComponentLine::new(vec![ActiveComponent::new(
+ TextOrCustomRender::Text(match *base_mode.borrow() {
+ InputMode::Locked => Text::new("Check it out with with: Ctrl g + o + w")
+ .color_range(3, 24..=29)
+ .color_indices(3, vec![33, 37]),
+ _ => Text::new("Check it out with with: Ctrl o + w")
+ .color_range(3, 24..=29)
+ .color_indices(3, vec![33]),
+ }),
+ )])])
+ .with_paragraph(vec![ComponentLine::new(vec![ActiveComponent::new(
+ TextOrCustomRender::Text(
+ Text::new("You can also use it as a welcome screen with: zellij -l welcome")
+ .color_range(0, 46..=62),
+ ),
+ )])])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_11(link_executable: Rc<RefCell<String>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #11").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("You can change the arrangement of panes on screen with Alt + []")
+ .color_range(0, 55..=57)
+ .color_range(2, 61..=62)
+ )),
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("This works with tiled or floating panes, depending which is visible.")
+ ))
+ ])
+ ])
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Resizing or splitting a pane breaks out of this arrangement. It is then possible")
+ )),
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("to snap back by pressing Alt + [] once more. This status can be seen")
+ .color_range(0, 25..=27)
+ .color_range(2, 31..=32)
+ )),
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("on the top right corner of the screen.")
+ )),
+ ]),
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+ pub fn tip_12(link_executable: Rc<RefCell<String>>, base_mode: Rc<RefCell<InputMode>>) -> Page {
+ Page::new()
+ .main_screen()
+ .with_title(Text::new("Zellij Tip #12").color_range(0, ..))
+ .with_paragraph(vec![
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ Text::new("Zellij plugins can be loaded, reloaded and tracked from the plugin-manager.")
+ )),
+ ]),
+ ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(
+ match *base_mode.borrow() {
+ InputMode::Locked => {
+ Text::new("Check it out with with: Ctrl g + o + p")
+ .color_range(3, 24..=29)
+ .color_indices(3, vec![33, 37])
+ },
+ _ => {
+ Text::new("Check it out with with: Ctrl o + p")
+ .color_range(3, 24..=29)
+ .color_indices(3, vec![33])
+ }
+ }
+ )),
+ ]),
+ ])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("To learn more about plugins: ").color_range(2, ..))),
+ ActiveComponent::new(TextOrCustomRender::Text(Text::new("https://zellij.dev/documentation/plugins")))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(plugin_docs_link_text_selected),
+ Box::new(plugin_docs_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://zellij.dev/documentation/plugins".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_paragraph(vec![ComponentLine::new(vec![
+ ActiveComponent::new(TextOrCustomRender::Text(support_the_developer_text())),
+ ActiveComponent::new(TextOrCustomRender::Text(sponsors_link_text_unselected()))
+ .with_hover(TextOrCustomRender::CustomRender(
+ Box::new(sponsors_link_text_selected),
+ Box::new(sponsors_link_text_selected_len),
+ ))
+ .with_left_click_action(ClickAction::new_open_link(
+ "https://github.com/sponsors/imsnif".to_owned(),
+ link_executable.clone(),
+ )),
+ ])])
+ .with_help(Box::new(|hovering_over_link, _menu_item_is_selected| {
+ tips_help_text(hovering_over_link)
+ }))
+ }
+}
+
+fn sponsors_link_text_unselected() -> Text {
+ Text::new("https://github.com/sponsors/imsnif")
+}
+
+fn sponsors_link_text_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://github.com/sponsors/imsnif",
+ y + 1,
+ x + 1
+ );
+ 34
+}
+
+fn sponsors_link_text_selected_len() -> usize {
+ 34
+}
+
+fn plugin_docs_link_text_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://zellij.dev/documentation/plugins",
+ y + 1,
+ x + 1
+ );
+ 40
+}
+
+fn plugin_docs_link_text_selected_len() -> usize {
+ 40
+}
+
+fn awesome_zellij_link_text_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://github.com/zellij-org/awesome-zellij",
+ y + 1,
+ x + 1
+ );
+ 44
+}
+
+fn awesome_zellij_link_text_selected_len() -> usize {
+ 44
+}
+
+fn discord_link_text_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://discord.com/invite/CrUAFH3",
+ y + 1,
+ x + 1
+ );
+ 34
+}
+
+fn discord_link_text_selected_len() -> usize {
+ 34
+}
+
+fn matrix_link_text_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://matrix.to/#/#zellij_general:matrix.org",
+ y + 1,
+ x + 1
+ );
+ 46
+}
+
+fn matrix_link_text_selected_len() -> usize {
+ 46
+}
+
+fn stacked_resize_screencast_link_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://zellij.dev/screencasts/stacked-resize",
+ y + 1,
+ x + 1
+ );
+ 45
+}
+
+fn stacked_resize_screencast_link_selected_len() -> usize {
+ 45
+}
+
+fn colliding_keybindings_link_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://zellij.dev/tutorials/colliding-keybindings",
+ y + 1,
+ x + 1
+ );
+ 51
+}
+
+fn colliding_keybindings_link_selected_len() -> usize {
+ 51
+}
+
+fn theme_link_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://zellij.dev/documentation/themes",
+ y + 1,
+ x + 1
+ );
+ 39
+}
+fn theme_link_selected_len() -> usize {
+ 39
+}
+
+fn theme_list_selected(x: usize, y: usize) -> usize {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://zellij.dev/documentation/theme-list",
+ y + 1,
+ x + 1
+ );
+ 43
+}
+fn theme_list_selected_len() -> usize {
+ 43
+}
+
+fn support_the_developer_text() -> Text {
+ let support_text = format!("Please support the Zellij developer <3: ");
+ Text::new(support_text).color_range(3, ..)
+}
+
+fn screencasts_link_selected() -> Box<dyn Fn(usize, usize) -> usize> {
+ Box::new(move |x, y| {
+ print!(
+ "\u{1b}[{};{}H\u{1b}[m\u{1b}[1;4mhttps://zellij.dev/screencasts",
+ y + 1,
+ x + 1,
+ );
+ 30
+ })
+}
+
+fn screencasts_link_selected_len() -> Box<dyn Fn() -> usize> {
+ Box::new(move || 30)
+}
+
+fn tips_help_text(hovering_over_link: bool) -> Text {
+ if hovering_over_link {
+ let help_text = format!("Help: Click or Shift-Click to open in browser");
+ Text::new(help_text)
+ .color_range(3, 6..=10)
+ .color_range(3, 15..=25)
+ } else {
+ let help_text = format!(
+ "Help: <ESC> - Dismiss, <↓↑> - Browse tips, <Ctrl c> - Don't show tips on startup"
+ );
+ Text::new(help_text)
+ .color_range(1, 6..=10)
+ .color_range(1, 23..=26)
+ .color_range(1, 43..=50)
+ }
+}
diff --git a/default-plugins/configuration/src/presets.rs b/default-plugins/configuration/src/presets.rs
index eb9a55bb..41d7a79e 100644
--- a/default-plugins/configuration/src/presets.rs
+++ b/default-plugins/configuration/src/presets.rs
@@ -140,6 +140,13 @@ keybinds clear-defaults=true {{
}};
SwitchToMode "Locked"
}}
+ bind "a" {{
+ LaunchOrFocusPlugin "zellij:about" {{
+ floating true
+ move_to_focused_tab true
+ }};
+ SwitchToMode "Locked"
+ }}
}}
shared_except "locked" "renametab" "renamepane" {{
bind "{primary_modifier} g" {{ SwitchToMode "Locked"; }}
@@ -339,6 +346,13 @@ keybinds clear-defaults=true {{
}};
SwitchToMode "Normal"
}}
+ bind "a" {{
+ LaunchOrFocusPlugin "zellij:about" {{
+ floating true
+ move_to_focused_tab true
+ }};
+ SwitchToMode "Normal"
+ }}
}}
tmux {{
bind "[" {{ SwitchToMode "Scroll"; }}
@@ -538,6 +552,13 @@ keybinds clear-defaults=true {{
}};
SwitchToMode "Normal"
}}
+ bind "a" {{
+ LaunchOrFocusPlugin "zellij:about" {{
+ floating true
+ move_to_focused_tab true
+ }};
+ SwitchToMode "Normal"
+ }}
}}
tmux {{
bind "[" {{ SwitchToMode "Scroll"; }}
@@ -718,6 +739,13 @@ keybinds clear-defaults=true {{
}};
SwitchToMode "Normal"
}}
+ bind "a" {{
+ LaunchOrFocusPlugin "zellij:about" {{
+ floating true
+ move_to_focused_tab true
+ }};
+ SwitchToMode "Normal"
+ }}
}}
tmux {{
bind "[" {{ SwitchToMode "Scroll"; }}
@@ -900,6 +928,13 @@ keybinds clear-defaults=true {{
}};
SwitchToMode "Normal"
}}
+ bind "a" {{
+ LaunchOrFocusPlugin "zellij:about" {{
+ floating true
+ move_to_focused_tab true
+ }};
+ SwitchToMode "Normal"
+ }}
}}
tmux {{
bind "[" {{ SwitchToMode "Scroll"; }}
@@ -1077,6 +1112,13 @@ keybinds clear-defaults=true {{
}};
SwitchToMode "Normal"
}}
+ bind "a" {{
+ LaunchOrFocusPlugin "zellij:about" {{
+ floating true
+ move_to_focused_tab true
+ }};
+ SwitchToMode "Normal"
+ }}
}}
tmux {{
bind "[" {{ SwitchToMode "Scroll"; }}
diff --git a/default-plugins/status-bar/src/one_line_ui.rs b/default-plugins/status-bar/src/one_line_ui.rs
index 4d47281e..3b7eec10 100644
--- a/default-plugins/status-bar/src/one_line_ui.rs
+++ b/default-plugins/status-bar/src/one_line_ui.rs
@@ -1276,6 +1276,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
(s("Session Manager"), s("Manager"), session_manager_key(&km)),
(s("Configure"), s("Config"), configuration_key(&km)),
(s("Plugin Manager"), s("Plugins"), plugin_manager_key(&km)),
+ (s("About"), s("About"), about_key(&km)),
(s("Select pane"), s("Select"), to_basemode_key),
]} else if mi.mode == IM::Tmux { vec![
(s("Move focus"), s("Move"), action_key_group(&km, &[
@@ -1385,6 +1386,25 @@ fn plugin_manager_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithM
}
}
+fn about_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithModifier> {
+ let mut matching = keymap.iter().find_map(|(key, acvec)| {
+ let has_match = acvec
+ .iter()
+ .find(|a| a.launches_plugin("zellij:about"))
+ .is_some();
+ if has_match {
+ Some(key.clone())
+ } else {
+ None
+ }
+ });
+ if let Some(matching) = matching.take() {
+ vec![matching]
+ } else {
+ vec![]
+ }
+}
+
fn configuration_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithModifier> {
let mut matching = keymap.iter().find_map(|(key, acvec)| {
let has_match = acvec
diff --git a/example/default.kdl b/example/default.kdl
index 2a4b3f9c..e04601b1 100644
--- a/example/default.kdl
+++ b/example/default.kdl
@@ -135,6 +135,13 @@ keybinds {
};
SwitchToMode "Normal"
}
+ bind "a" {
+ LaunchOrFocusPlugin "zellij:about" {
+ floating true
+ move_to_focused_tab true
+ };
+ SwitchToMode "Normal"
+ }
}
tmux {
bind "[" { SwitchToMode "Scroll"; }
@@ -413,3 +420,13 @@ load_plugins {
// Default: true
//
// stacked_resize false
+
+// Whether to show tips on startup
+// Default: true
+//
+// show_tips_on_startup false
+
+// Whether to show release notes on first version run
+// Default: true
+//
+// show_release_notes false
diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs
index 1c05f502..b3d8b9ac 100644
--- a/src/tests/e2e/remote_runner.rs
+++ b/src/tests/e2e/remote_runner.rs
@@ -81,7 +81,7 @@ fn start_zellij(channel: &mut ssh2::Channel) {
channel
.write_all(
format!(
- "{} {} --session {} --data-dir {}\n",
+ "{} {} --session {} --data-dir {} options --show-release-notes false --show-startup-tips false\n",
SET_ENV_VARIABLES, ZELLIJ_EXECUTABLE_LOCATION, SESSION_NAME, ZELLIJ_DATA_DIR
)
.as_bytes(),
@@ -96,7 +96,7 @@ fn start_zellij_mirrored_session(channel: &mut ssh2::Channel) {
channel
.write_all(
format!(
- "{} {} --session {} --data-dir {} options --mirror-session true --serialization-interval 1\n",
+ "{} {} --session {} --data-dir {} options --show-release-notes false --show-startup-tips false --mirror-session true --serialization-interval 1\n",
SET_ENV_VARIABLES, ZELLIJ_EXECUTABLE_LOCATION, SESSION_NAME, ZELLIJ_DATA_DIR
)
.as_bytes(),
@@ -111,7 +111,7 @@ fn start_zellij_mirrored_session_with_layout(channel: &mut ssh2::Channel, layout
channel
.write_all(
format!(
- "{} {} --session {} --data-dir {} --new-session-with-layout {} options --mirror-session true --serialization-interval 1\n",
+ "{} {} --session {} --data-dir {} --new-session-with-layout {} options --show-release-notes false --show-startup-tips false --mirror-session true --serialization-interval 1\n",
SET_ENV_VARIABLES,
ZELLIJ_EXECUTABLE_LOCATION,
SESSION_NAME,
@@ -133,7 +133,7 @@ fn start_zellij_mirrored_session_with_layout_and_viewport_serialization(
channel
.write_all(
format!(
- "{} {} --session {} --data-dir {} --new-session-with-layout {} options --mirror-session true --serialize-pane-viewport true --serialization-interval 1\n",
+ "{} {} --session {} --data-dir {} --new-session-with-layout {} options --show-release-notes false --show-startup-tips false --mirror-session true --serialize-pane-viewport true --serialization-interval 1\n",
SET_ENV_VARIABLES,
ZELLIJ_EXECUTABLE_LOCATION,
SESSION_NAME,
@@ -152,7 +152,7 @@ fn start_zellij_in_session(channel: &mut ssh2::Channel, session_name: &str, mirr
channel
.write_all(
format!(
- "{} {} --session {} --data-dir {} options --mirror-session {}\n",
+ "{} {} --session {} --data-dir {} options --show-release-notes false --show-startup-tips false --mirror-session {}\n",
SET_ENV_VARIABLES,
ZELLIJ_EXECUTABLE_LOCATION,
session_name,
@@ -185,7 +185,7 @@ fn start_zellij_without_frames(channel: &mut ssh2::Channel) {
channel
.write_all(
format!(
- "{} {} --session {} --data-dir {} options --no-pane-frames\n",
+ "{} {} --session {} --data-dir {} options --show-release-notes false --show-startup-tips false --no-pane-frames\n",
SET_ENV_VARIABLES, ZELLIJ_EXECUTABLE_LOCATION, SESSION_NAME, ZELLIJ_DATA_DIR
)
.as_bytes(),
@@ -200,7 +200,7 @@ fn start_zellij_with_config(channel: &mut ssh2::Channel, config_path: &str) {
channel
.write_all(
format!(
- "{} {} --config {} --session {} --data-dir {}\n",
+ "{} {} --config {} --session {} --data-dir {} options --show-release-notes false --show-startup-tips false\n",
SET_ENV_VARIABLES,
ZELLIJ_EXECUTABLE_LOCATION,
config_path,
diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs
index 0e05fde5..879fd545 100644
--- a/zellij-server/src/lib.rs
+++ b/zellij-server/src/lib.rs
@@ -336,7 +336,11 @@ impl SessionMetaData {
self.current_input_modes.insert(client_id, input_mode);
}
}
- pub fn propagate_configuration_changes(&mut self, config_changes: Vec<(ClientId, Config)>) {
+ pub fn propagate_configuration_changes(
+ &mut self,
+ config_changes: Vec<(ClientId, Config)>,
+ config_was_written_to_disk: bool,
+ ) {
for (client_id, new_config) in config_changes {
self.default_shell = new_config.options.default_shell.as_ref().map(|shell| {
TerminalAction::RunCommand(RunCommand {
@@ -375,6 +379,7 @@ impl SessionMetaData {
keybinds: Some(new_config.keybinds),
default_mode: new_config.options.default_mode,
default_shell: self.default_shell.clone(),
+ was_written_to_disk: config_was_written_to_disk,
})
.unwrap();
self.senders
@@ -706,9 +711,12 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
// intrusive
let setup_wizard = setup_wizard_floating_pane();
floating_panes.push(setup_wizard);
- } else if should_show_release_notes() {
+ } else if should_show_release_notes(runtime_config_options.show_release_notes) {
let about = about_floating_pane();
floating_panes.push(about);
+ } else if should_show_startup_tip(runtime_config_options.show_startup_tips) {
+ let tip = tip_floating_pane();
+ floating_panes.push(tip);
}
spawn_tabs(
None,
@@ -1166,12 +1174,16 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
}
if runtime_config_changed {
+ let config_was_written_to_disk = false;
session_data
.write()
.unwrap()
.as_mut()
.unwrap()
- .propagate_configuration_changes(vec![(client_id, new_config)]);
+ .propagate_configuration_changes(
+ vec![(client_id, new_config)],
+ config_was_written_to_disk,
+ );
}
}
},
@@ -1183,12 +1195,13 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
.unwrap()
.session_configuration
.new_saved_config(client_id, new_config);
+ let config_was_written_to_disk = true;
session_data
.write()
.unwrap()
.as_mut()
.unwrap()
- .propagate_configuration_changes(changes);
+ .propagate_configuration_changes(changes, config_was_written_to_disk);
},
ServerInstruction::FailedToWriteConfigToDisk(_client_id, file_path) => {
session_data
@@ -1227,12 +1240,16 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
}
if runtime_config_changed {
+ let config_was_written_to_disk = false;
session_data
.write()
.unwrap()
.as_mut()
.unwrap()
- .propagate_configuration_changes(vec![(client_id, new_config)]);
+ .propagate_configuration_changes(
+ vec![(client_id, new_config)],
+ config_was_written_to_disk,
+ );
}
}
},
@@ -1506,7 +1523,26 @@ fn about_floating_pane() -> FloatingPaneLayout {
about_pane
}
-fn should_show_release_notes() -> bool {
+fn tip_floating_pane() -> FloatingPaneLayout {
+ let mut about_pane = FloatingPaneLayout::new();
+ let configuration = BTreeMap::from_iter([("is_startup_tip".to_owned(), "true".to_owned())]);
+ about_pane.run = Some(Run::Plugin(RunPluginOrAlias::Alias(PluginAlias::new(
+ "about",
+ &Some(configuration),
+ None,
+ ))));
+ about_pane
+}
+
+fn should_show_release_notes(should_show_release_notes_config: Option<bool>) -> bool {
+ if let Some(should_show_release_notes_config) = should_show_release_notes_config {
+ if !should_show_release_notes_config {
+ // if we were explicitly told not to show release notes, we don't show them,
+ // otherwise we make sure we only show them if they were not seen AND we know
+ // we are able to write to the cache
+ return false;
+ }
+ }
if ZELLIJ_SEEN_RELEASE_NOTES_CACHE_FILE.exists() {
return false;
} else {
@@ -1521,6 +1557,10 @@ fn should_show_release_notes() -> bool {
}
}
+fn should_show_startup_tip(should_show_startup_tip_config: Option<bool>) -> bool {
+ should_show_startup_tip_config.unwrap_or(true)
+}
+
#[cfg(not(feature = "singlepass"))]
fn get_engine() -> Engine {
log::info!("Compiling plugins using Cranelift");
diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs
index fa1fabce..f1d11377 100644
--- a/zellij-server/src/plugins/mod.rs
+++ b/zellij-server/src/plugins/mod.rs
@@ -152,6 +152,7 @@ pub enum PluginInstruction {
keybinds: Option<Keybinds>,
default_mode: Option<InputMode>,
default_shell: Option<TerminalAction>,
+ was_written_to_disk: bool,
},
FailedToWriteConfigToDisk {
file_path: Option<PathBuf>,
@@ -868,12 +869,19 @@ pub(crate) fn plugin_thread_main(
keybinds,
default_mode,
default_shell,
+ was_written_to_disk,
} => {
- // TODO: notify plugins that this happened so that they can eg. rebind temporary keys that
- // were lost
wasm_bridge
.reconfigure(client_id, keybinds, default_mode, default_shell)
.non_fatal();
+ // TODO: notify plugins that this happened so that they can eg. rebind temporary keys that
+ // were lost
+ if was_written_to_disk {
+ let updates = vec![(None, None, Event::ConfigWasWrittenToDisk)];
+ wasm_bridge
+ .update_plugins(updates, shutdown_send.clone())
+ .non_fatal();
+ }
},
PluginInstruction::FailedToWriteConfigToDisk { file_path } => {
let updates = vec![(
diff --git a/zellij-utils/assets/config/default.kdl b/zellij-utils/assets/config/default.kdl
index 616e2452..298127b0 100644
--- a/zellij-utils/assets/config/default.kdl
+++ b/zellij-utils/assets/config/default.kdl
@@ -135,6 +135,13 @@ keybinds {
};
SwitchToMode "Normal"
}
+ bind "a" {
+ LaunchOrFocusPlugin "zellij:about" {
+ floating true
+ move_to_focused_tab true
+ };
+ SwitchToMode "Normal"
+ }
}
tmux {
bind "[" { SwitchToMode "Scroll"; }
@@ -414,3 +421,13 @@ load_plugins {
// Default: true
//
// stacked_resize false
+
+// Whether to show release notes on first version run
+// Default: true
+//
+// show_release_notes false
+
+// Whether to show startup tips on session start
+// Default: true
+//
+// show_startup_tips false
diff --git a/zellij-utils/assets/plugins/about.wasm b/zellij-utils/assets/plugins/about.wasm
index b7fa9e77..e1bb7aae 100755
--- a/zellij-utils/assets/plugins/about.wasm
+++ b/zellij-utils/assets/plugins/about.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/compact-bar.wasm b/zellij-utils/assets/plugins/compact-bar.wasm
index e3d2506e..a0d40d9f 100755
--- a/zellij-utils/assets/plugins/compact-bar.wasm
+++ b/zellij-utils/assets/plugins/compact-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/configuration.wasm b/zellij-utils/assets/plugins/configuration.wasm
index e741588e..51a029aa 100755
--- a/zellij-utils/assets/plugins/configuration.wasm
+++ b/zellij-utils/assets/plugins/configuration.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm b/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm
index 507416c9..991a74fc 100755
--- a/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm
+++ b/zellij-utils/assets/plugins/fixture-plugin-for-tests.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/plugin-manager.wasm b/zellij-utils/assets/plugins/plugin-manager.wasm
index 546c8700..10d05d9b 100755
--- a/zellij-utils/assets/plugins/plugin-manager.wasm
+++ b/zellij-utils/assets/plugins/plugin-manager.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/session-manager.wasm b/zellij-utils/assets/plugins/session-manager.wasm
index 2f5406e0..57dce9b6 100755
--- a/zellij-utils/assets/plugins/session-manager.wasm
+++ b/zellij-utils/assets/plugins/session-manager.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/status-bar.wasm b/zellij-utils/assets/plugins/status-bar.wasm
index 676e74ec..cc7668f5 100755
--- a/zellij-utils/assets/plugins/status-bar.wasm
+++ b/zellij-utils/assets/plugins/status-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/strider.wasm b/zellij-utils/assets/plugins/strider.wasm
index 0e7632b4..15123089 100755
--- a/zellij-utils/assets/plugins/strider.wasm
+++ b/zellij-utils/assets/plugins/strider.wasm
Binary files differ
diff --git a/zellij-utils/assets/plugins/tab-bar.wasm b/zellij-utils/assets/plugins/tab-bar.wasm
index b1f21cb5..db09ceab 100755
--- a/zellij-utils/assets/plugins/tab-bar.wasm
+++ b/zellij-utils/assets/plugins/tab-bar.wasm
Binary files differ
diff --git a/zellij-utils/assets/prost/api.event.rs b/zellij-utils/assets/prost/api.event.rs
index 3378cec9..85db2531 100644
--- a/zellij-utils/assets/prost/api.event.rs
+++ b/zellij-utils/assets/prost/api.event.rs
@@ -507,6 +507,7 @@ pub enum EventType {
HostFolderChanged = 27,
FailedToChangeHostFolder = 28,
PastedText = 29,
+ ConfigWasWrittenToDisk = 30,
}
impl EventType {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -545,6 +546,7 @@ impl EventType {
EventType::HostFolderChanged => "HostFolderChanged",
EventType::FailedToChangeHostFolder => "FailedToChangeHostFolder",
EventType::PastedText => "PastedText",
+ EventType::ConfigWasWrittenToDisk => "ConfigWasWrittenToDisk",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -580,6 +582,7 @@ impl EventType {
"HostFolderChanged" => Some(Self::HostFolderChanged),
"FailedToChangeHostFolder" => Some(Self::FailedToChangeHostFolder),
"PastedText" => Some(Self::PastedText),
+ "ConfigWasWrittenToDisk" => Some(Self::ConfigWasWrittenToDisk),
_ => None,
}
}
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index bbbc47df..5bc1732d 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -932,6 +932,7 @@ pub enum Event {
HostFolderChanged(PathBuf), // PathBuf -> new host folder
FailedToChangeHostFolder(Option<String>), // String -> the error we got when changing
PastedText(String),
+ ConfigWasWrittenToDisk,
}
#[derive(
diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs
index 5ece3c58..a9f82f02 100644
--- a/zellij-utils/src/input/options.rs
+++ b/zellij-utils/src/input/options.rs
@@ -167,6 +167,18 @@ pub struct Options {
#[clap(long, value_parser)]
#[serde(default)]
pub stacked_resize: Option<bool>,
+
+ /// Whether to show startup tips when starting a new session
+ /// default is true
+ #[clap(long, value_parser)]
+ #[serde(default)]
+ pub show_startup_tips: Option<bool>,
+
+ /// Whether to show release notes on first run of a new version
+ /// default is true
+ #[clap(long, value_parser)]
+ #[serde(default)]
+ pub show_release_notes: Option<bool>,
}
#[derive(ArgEnum, Deserialize, Serialize, Debug, Clone, Copy, PartialEq)]
@@ -246,6 +258,8 @@ impl Options {
.support_kitty_keyboard_protocol
.or(self.support_kitty_keyboard_protocol);
let stacked_resize = other.stacked_resize.or(self.stacked_resize);
+ let show_startup_tips = other.show_startup_tips.or(self.show_startup_tips);
+ let show_release_notes = other.show_release_notes.or(self.show_release_notes);
Options {
simplified_ui,
@@ -276,6 +290,8 @@ impl Options {
disable_session_metadata,
support_kitty_keyboard_protocol,
stacked_resize,
+ show_startup_tips,
+ show_release_notes,
}
}
@@ -335,6 +351,8 @@ impl Options {
.support_kitty_keyboard_protocol
.or(self.support_kitty_keyboard_protocol);
let stacked_resize = other.stacked_resize.or(self.stacked_resize);
+ let show_startup_tips = other.show_startup_tips.or(self.show_startup_tips);
+ let show_release_notes = other.show_release_notes.or(self.show_release_notes);
Options {
simplified_ui,
@@ -365,6 +383,8 @@ impl Options {
disable_session_metadata,
support_kitty_keyboard_protocol,
stacked_resize,
+ show_startup_tips,
+ show_release_notes,
}
}
@@ -431,6 +451,8 @@ impl From<CliOptions> for Options {
serialization_interval: opts.serialization_interval,
support_kitty_keyboard_protocol: opts.support_kitty_keyboard_protocol,
stacked_resize: opts.stacked_resize,
+ show_release_notes: opts.show_release_notes,
+ show_startup_tips: opts.show_startup_tips,
..Default::default()
}
}
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index ad4c86db..eeabb520 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -2293,6 +2293,12 @@ impl Options {
.map(|(v, _)| v);
let stacked_resize =
kdl_property_first_arg_as_bool_or_error!(kdl_options, "stacked_resize").map(|(v, _)| v);
+ let show_startup_tips =
+ kdl_property_first_arg_as_bool_or_error!(kdl_options, "show_startup_tips")
+ .map(|(v, _)| v);
+ let show_release_notes =
+ kdl_property_first_arg_as_bool_or_error!(kdl_options, "show_release_notes")
+ .map(|(v, _)| v);
Ok(Options {
simplified_ui,
theme,
@@ -2322,6 +2328,8 @@ impl Options {
disable_session_metadata,
support_kitty_keyboard_protocol,
stacked_resize,
+ show_startup_tips,
+ show_release_notes,
})
}
pub fn from_string(stringified_keybindings: &String) -> Result<Self, ConfigError> {
@@ -3149,6 +3157,56 @@ impl Options {
None
}
}
+ fn show_startup_tips_to_kdl(&self, add_comments: bool) -> Option<KdlNode> {
+ let comment_text = format!(
+ "{}\n{}\n{}\n{}",
+ " ", "// Whether to show tips on startup", "// Default: true", "// ",
+ );
+
+ let create_node = |node_value: bool| -> KdlNode {
+ let mut node = KdlNode::new("show_startup_tips");
+ node.push(KdlValue::Bool(node_value));
+ node
+ };
+ if let Some(show_startup_tips) = self.show_startup_tips {
+ let mut node = create_node(show_startup_tips);
+ if add_comments {
+ node.set_leading(format!("{}\n", comment_text));
+ }
+ Some(node)
+ } else if add_comments {
+ let mut node = create_node(false);
+ node.set_leading(format!("{}\n// ", comment_text));
+ Some(node)
+ } else {
+ None
+ }
+ }
+ fn show_release_notes_to_kdl(&self, add_comments: bool) -> Option<KdlNode> {
+ let comment_text = format!(
+ "{}\n{}\n{}\n{}",
+ " ", "// Whether to show release notes on first version run", "// Default: true", "// ",
+ );
+
+ let create_node = |node_value: bool| -> KdlNode {
+ let mut node = KdlNode::new("show_release_notes");
+ node.push(KdlValue::Bool(node_value));
+ node
+ };
+ if let Some(show_release_notes) = self.show_release_notes {
+ let mut node = create_node(show_release_notes);
+ if add_comments {
+ node.set_leading(format!("{}\n", comment_text));
+ }
+ Some(node)
+ } else if add_comments {
+ let mut node = create_node(false);
+ node.set_leading(format!("{}\n// ", comment_text));
+ Some(node)
+ } else {
+ None
+ }
+ }
pub fn to_kdl(&self, add_comments: bool) -> Vec<KdlNode> {
let mut nodes = vec![];
if let Some(simplified_ui_node) = self.simplified_ui_to_kdl(add_comments) {
@@ -3239,6 +3297,12 @@ impl Options {
if let Some(stacked_resize) = self.stacked_resize_to_kdl(add_comments) {
nodes.push(stacked_resize);
}
+ if let Some(show_startup_tips) = self.show_startup_tips_to_kdl(add_comments) {
+ nodes.push(show_startup_tips);
+ }
+ if let Some(show_release_notes) = self.show_release_notes_to_kdl(add_comments) {
+ nodes.push(show_release_notes);
+ }
nodes
}
}
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string.snap
index 9a2030da..c5e53358 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string.snap
@@ -1,6 +1,6 @@
---
source: zellij-utils/src/kdl/mod.rs
-assertion_line: 5626
+assertion_line: 5922
expression: fake_config_stringified
---
keybinds clear-defaults=true {
@@ -100,6 +100,13 @@ keybinds clear-defaults=true {
bind "w" { SearchToggleOption "Wrap"; }
}
session {
+ bind "a" {
+ LaunchOrFocusPlugin "zellij:about" {
+ floating true
+ move_to_focused_tab true
+ }
+ SwitchToMode "normal"
+ }
bind "c" {
LaunchOrFocusPlugin "configuration" {
floating true
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
index 7c38a7e6..5ace8251 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
@@ -1,6 +1,6 @@
---
source: zellij-utils/src/kdl/mod.rs
-assertion_line: 5638
+assertion_line: 5934
expression: fake_config_stringified
---
keybinds clear-defaults=true {
@@ -100,6 +100,13 @@ keybinds clear-defaults=true {
bind "w" { SearchToggleOption "Wrap"; }
}
session {
+ bind "a" {
+ LaunchOrFocusPlugin "zellij:about" {
+ floating true
+ move_to_focused_tab true
+ }
+ SwitchToMode "normal"
+ }
bind "c" {
LaunchOrFocusPlugin "configuration" {
floating true
@@ -438,4 +445,14 @@ load_plugins {
// Default: true
//
// stacked_resize false
+
+// Whether to show tips on startup
+// Default: true
+//
+// show_startup_tips false
+
+// Whether to show release notes on first version run
+// Default: true
+//
+// show_release_notes false
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
index 61361362..e3c4368e 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
@@ -1,6 +1,6 @@
---
source: zellij-utils/src/kdl/mod.rs
-assertion_line: 5537
+assertion_line: 5873
expression: fake_document.to_string()
---
@@ -185,4 +185,14 @@ support_kitty_keyboard_protocol false
// Default: true
//
// stacked_resize false
+
+// Whether to show tips on startup
+// Default: true
+//
+// show_startup_tips false
+
+// Whether to show release notes on first version run
+// Default: true
+//
+// show_release_notes false
diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto
index f6162b68..b07562e2 100644
--- a/zellij-utils/src/plugin_api/event.proto
+++ b/zellij-utils/src/plugin_api/event.proto
@@ -53,6 +53,7 @@ enum EventType {
HostFolderChanged = 27;
FailedToChangeHostFolder = 28;
PastedText = 29;
+ ConfigWasWrittenToDisk = 30;
}
message EventNameList {
diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs
index 0f570aee..495060a6 100644
--- a/zellij-utils/src/plugin_api/event.rs
+++ b/zellij-utils/src/plugin_api/event.rs
@@ -355,6 +355,10 @@ impl TryFrom<ProtobufEvent> for Event {
},
_ => Err("Malformed payload for the PastedText Event"),
},
+ Some(ProtobufEventType::ConfigWasWrittenToDisk) => match protobuf_event.payload {
+ None => Ok(Event::ConfigWasWrittenToDisk),
+ _ => Err("Malformed payload for the ConfigWasWrittenToDisk Event"),
+ },
None => Err("Unknown Protobuf Event"),
}
}
@@ -725,6 +729,10 @@ impl TryFrom<Event> for ProtobufEvent {
pasted_text,
})),
}),
+ Event::ConfigWasWrittenToDisk => Ok(ProtobufEvent {
+ name: ProtobufEventType::ConfigWasWrittenToDisk as i32,
+ payload: None,
+ }),
}
}
}
@@ -1306,6 +1314,7 @@ impl TryFrom<ProtobufEventType> for EventType {
ProtobufEventType::HostFolderChanged => EventType::HostFolderChanged,
ProtobufEventType::FailedToChangeHostFolder => EventType::FailedToChangeHostFolder,
ProtobufEventType::PastedText => EventType::PastedText,
+ ProtobufEventType::ConfigWasWrittenToDisk => EventType::ConfigWasWrittenToDisk,
})
}
}
@@ -1344,6 +1353,7 @@ impl TryFrom<EventType> for ProtobufEventType {
EventType::HostFolderChanged => ProtobufEventType::HostFolderChanged,
EventType::FailedToChangeHostFolder => ProtobufEventType::FailedToChangeHostFolder,
EventType::PastedText => ProtobufEventType::PastedText,
+ EventType::ConfigWasWrittenToDisk => ProtobufEventType::ConfigWasWrittenToDisk,
})
}
}
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
index 4d2c2fee..51f0eff1 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
@@ -34,4 +34,6 @@ Options {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
}
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
index db16d8ce..ca547f2d 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
@@ -34,4 +34,6 @@ Options {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
}
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
index 621bc4a7..79043ec6 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
@@ -32,4 +32,6 @@ Options {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
}
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
index 11880e19..7fd6ab84 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
@@ -3958,6 +3958,36 @@ Config {
],
KeyWithModifier {
bare_key: Char(
+ 'a',
+ ),
+ key_modifiers: {},
+ }: [
+ LaunchOrFocusPlugin(
+ RunPlugin(
+ RunPlugin {
+ _allow_exec_host_cmd: false,
+ location: Zellij(
+ PluginTag(
+ "about",
+ ),
+ ),
+ configuration: PluginUserConfiguration(
+ {},
+ ),
+ initial_cwd: None,
+ },
+ ),
+ true,
+ true,
+ false,
+ false,
+ ),
+ SwitchToMode(
+ Normal,
+ ),
+ ],
+ KeyWithModifier {
+ bare_key: Char(
'b',
),
key_modifiers: {
@@ -5611,6 +5641,8 @@ Config {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
},
themes: {},
plugins: PluginAliases {
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
index 3c486c5b..cc836b3e 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
@@ -3958,6 +3958,36 @@ Config {
],
KeyWithModifier {
bare_key: Char(
+ 'a',
+ ),
+ key_modifiers: {},
+ }: [
+ LaunchOrFocusPlugin(
+ RunPlugin(
+ RunPlugin {
+ _allow_exec_host_cmd: false,
+ location: Zellij(
+ PluginTag(
+ "about",
+ ),
+ ),
+ configuration: PluginUserConfiguration(
+ {},
+ ),
+ initial_cwd: None,
+ },
+ ),
+ true,
+ true,
+ false,
+ false,
+ ),
+ SwitchToMode(
+ Normal,
+ ),
+ ],
+ KeyWithModifier {
+ bare_key: Char(
'b',
),
key_modifiers: {
@@ -5611,6 +5641,8 @@ Config {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
},
themes: {},
plugins: PluginAliases {
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
index 7bd4a866..c13ecea9 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
@@ -119,6 +119,8 @@ Config {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
},
themes: {},
plugins: PluginAliases {
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
index 46d265d1..59a8e93a 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
@@ -34,4 +34,6 @@ Options {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
}
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
index d94b71c6..c70aff9b 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
@@ -1,5 +1,6 @@
---
source: zellij-utils/src/setup.rs
+assertion_line: 841
expression: "format!(\"{:#?}\", config)"
---
Config {
@@ -3957,6 +3958,36 @@ Config {
],
KeyWithModifier {
bare_key: Char(
+ 'a',
+ ),
+ key_modifiers: {},
+ }: [
+ LaunchOrFocusPlugin(
+ RunPlugin(
+ RunPlugin {
+ _allow_exec_host_cmd: false,
+ location: Zellij(
+ PluginTag(
+ "about",
+ ),
+ ),
+ configuration: PluginUserConfiguration(
+ {},
+ ),
+ initial_cwd: None,
+ },
+ ),
+ true,
+ true,
+ false,
+ false,
+ ),
+ SwitchToMode(
+ Normal,
+ ),
+ ],
+ KeyWithModifier {
+ bare_key: Char(
'b',
),
key_modifiers: {
@@ -5610,6 +5641,8 @@ Config {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
},
themes: {
"other-theme-from-config": Theme {
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
index fb4b78bd..be3ec13f 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
@@ -3958,6 +3958,36 @@ Config {
],
KeyWithModifier {
bare_key: Char(
+ 'a',
+ ),
+ key_modifiers: {},
+ }: [
+ LaunchOrFocusPlugin(
+ RunPlugin(
+ RunPlugin {
+ _allow_exec_host_cmd: false,
+ location: Zellij(
+ PluginTag(
+ "about",
+ ),
+ ),
+ configuration: PluginUserConfiguration(
+ {},
+ ),
+ initial_cwd: None,
+ },
+ ),
+ true,
+ true,
+ false,
+ false,
+ ),
+ SwitchToMode(
+ Normal,
+ ),
+ ],
+ KeyWithModifier {
+ bare_key: Char(
'b',
),
key_modifiers: {
@@ -5611,6 +5641,8 @@ Config {
disable_session_metadata: None,
support_kitty_keyboard_protocol: None,
stacked_resize: None,
+ show_startup_tips: None,
+ show_release_notes: None,
},
themes: {},
plugins: PluginAliases {