aboutsummaryrefslogtreecommitdiffstats
path: root/default-plugins
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 /default-plugins
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
Diffstat (limited to 'default-plugins')
-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
6 files changed, 1088 insertions, 19 deletions
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