summaryrefslogtreecommitdiffstats
path: root/default-plugins
diff options
context:
space:
mode:
authorJae-Heon Ji <32578710+jaeheonji@users.noreply.github.com>2021-12-10 02:53:46 +0900
committerGitHub <noreply@github.com>2021-12-09 18:53:46 +0100
commitd79060f69a99e73215533c1acbdff79af99af8f9 (patch)
tree626603f9756db04a41218cb3da9b02e6069bab1f /default-plugins
parent2096cafe1d9d3858f6ccd18c6898ea1e9cf837ba (diff)
feat(status-bar): add multiple tips (#848)
* feat(status-bar): add draft for multiple tips * feat: add TIPS_MAP * Simplified 'tip' function. * chore: update file structure * feat(status-bar): update method of Tip rendering * feat(status-bar): change type of tip in State * refactor(status-bar): related to random tip selection * feat(status-bar): add simple local cache for testing * feat(status-bar): add cache system for tip data * Add mpadir to wasm for plugin to access zellij temp folder. * refactor(status-bar): update cache and utils * fix(status-bar): update file read error * refactor(status-bar): update macros * chore(status-bar): delete test data * chore(status-bar): update missing fixes * feat(status-bar): add detailed error * style: make clippy
Diffstat (limited to 'default-plugins')
-rw-r--r--default-plugins/status-bar/Cargo.toml5
-rw-r--r--default-plugins/status-bar/src/main.rs11
-rw-r--r--default-plugins/status-bar/src/second_line.rs216
-rw-r--r--default-plugins/status-bar/src/tip/cache.rs119
-rw-r--r--default-plugins/status-bar/src/tip/consts.rs2
-rw-r--r--default-plugins/status-bar/src/tip/data.rs100
-rw-r--r--default-plugins/status-bar/src/tip/mod.rs16
-rw-r--r--default-plugins/status-bar/src/tip/utils.rs68
8 files changed, 335 insertions, 202 deletions
diff --git a/default-plugins/status-bar/Cargo.toml b/default-plugins/status-bar/Cargo.toml
index ebcc743f7..78f89ab8d 100644
--- a/default-plugins/status-bar/Cargo.toml
+++ b/default-plugins/status-bar/Cargo.toml
@@ -8,5 +8,10 @@ license = "MIT"
[dependencies]
colored = "2"
ansi_term = "0.12"
+lazy_static = "1.4.0"
+rand = "0.8.4"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+thiserror = "1.0.30"
zellij-tile = { path = "../../zellij-tile" }
zellij-tile-utils = { path = "../../zellij-tile-utils" } \ No newline at end of file
diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs
index ce80dab14..bc322e6a8 100644
--- a/default-plugins/status-bar/src/main.rs
+++ b/default-plugins/status-bar/src/main.rs
@@ -1,5 +1,6 @@
mod first_line;
mod second_line;
+mod tip;
use ansi_term::Style;
@@ -11,6 +12,7 @@ use first_line::{ctrl_keys, superkey};
use second_line::{
fullscreen_panes_to_hide, keybinds, locked_fullscreen_panes_to_hide, text_copied_hint,
};
+use tip::utils::get_cached_tip_name;
// for more of these, copy paste from: https://en.wikipedia.org/wiki/Box-drawing_character
static ARROW_SEPARATOR: &str = "";
@@ -19,6 +21,7 @@ static MORE_MSG: &str = " ... ";
#[derive(Default)]
struct State {
tabs: Vec<TabInfo>,
+ tip_name: String,
mode_info: ModeInfo,
diplay_text_copied_hint: bool,
}
@@ -131,6 +134,8 @@ fn color_elements(palette: Palette) -> ColoredElements {
impl ZellijPlugin for State {
fn load(&mut self) {
+ // TODO: Should be able to choose whether to use the cache through config.
+ self.tip_name = get_cached_tip_name();
set_selectable(false);
subscribe(&[
EventType::ModeUpdate,
@@ -190,7 +195,7 @@ impl ZellijPlugin for State {
second_line = if self.diplay_text_copied_hint {
text_copied_hint(&self.mode_info.palette)
} else {
- keybinds(&self.mode_info, cols)
+ keybinds(&self.mode_info, &self.tip_name, cols)
}
}
}
@@ -208,7 +213,7 @@ impl ZellijPlugin for State {
second_line = if self.diplay_text_copied_hint {
text_copied_hint(&self.mode_info.palette)
} else {
- keybinds(&self.mode_info, cols)
+ keybinds(&self.mode_info, &self.tip_name, cols)
}
}
}
@@ -216,7 +221,7 @@ impl ZellijPlugin for State {
second_line = if self.diplay_text_copied_hint {
text_copied_hint(&self.mode_info.palette)
} else {
- keybinds(&self.mode_info, cols)
+ keybinds(&self.mode_info, &self.tip_name, cols)
}
}
}
diff --git a/default-plugins/status-bar/src/second_line.rs b/default-plugins/status-bar/src/second_line.rs
index 9cc978a61..82806e5f5 100644
--- a/default-plugins/status-bar/src/second_line.rs
+++ b/default-plugins/status-bar/src/second_line.rs
@@ -5,7 +5,10 @@ use ansi_term::{
};
use zellij_tile::prelude::*;
-use crate::{LinePart, MORE_MSG};
+use crate::{
+ tip::{data::TIPS, TipFn},
+ LinePart, MORE_MSG,
+};
fn full_length_shortcut(
is_first_shortcut: bool,
@@ -82,194 +85,6 @@ fn first_word_shortcut(
len,
}
}
-fn quicknav_full(palette: Palette) -> LinePart {
- let text_first_part = " Tip: ";
- let alt = "Alt";
- let text_second_part = " + ";
- let new_pane_shortcut = "<n>";
- let text_third_part = " => open new pane. ";
- let second_alt = "Alt";
- let text_fourth_part = " + ";
- let brackets_navigation = "<[]";
- let text_fifth_part = " or ";
- let hjkl_navigation = "hjkl>";
- let text_sixths_part = " => navigate between panes. ";
- let third_alt = "Alt";
- let text_seventh_parth = " + ";
- let increase_decrease_parth = "<+->";
- let text_eighth_parth = " => increase/decrease pane size.";
- let len = text_first_part.chars().count()
- + alt.chars().count()
- + text_second_part.chars().count()
- + new_pane_shortcut.chars().count()
- + text_third_part.chars().count()
- + second_alt.chars().count()
- + text_fourth_part.chars().count()
- + brackets_navigation.chars().count()
- + text_fifth_part.chars().count()
- + hjkl_navigation.chars().count()
- + text_sixths_part.chars().count()
- + third_alt.chars().count()
- + text_seventh_parth.chars().count()
- + increase_decrease_parth.chars().count()
- + text_eighth_parth.chars().count();
- let green_color = match palette.green {
- PaletteColor::Rgb((r, g, b)) => RGB(r, g, b),
- PaletteColor::EightBit(color) => Fixed(color),
- };
- let orange_color = match palette.orange {
- PaletteColor::Rgb((r, g, b)) => RGB(r, g, b),
- PaletteColor::EightBit(color) => Fixed(color),
- };
- LinePart {
- part: format!(
- "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
- text_first_part,
- Style::new().fg(orange_color).bold().paint(alt),
- text_second_part,
- Style::new().fg(green_color).bold().paint(new_pane_shortcut),
- text_third_part,
- Style::new().fg(orange_color).bold().paint(second_alt),
- text_fourth_part,
- Style::new()
- .fg(green_color)
- .bold()
- .paint(brackets_navigation),
- text_fifth_part,
- Style::new().fg(green_color).bold().paint(hjkl_navigation),
- text_sixths_part,
- Style::new().fg(orange_color).bold().paint(third_alt),
- text_seventh_parth,
- Style::new()
- .fg(green_color)
- .bold()
- .paint(increase_decrease_parth),
- text_eighth_parth,
- ),
- len,
- }
-}
-
-fn quicknav_medium(palette: Palette) -> LinePart {
- let text_first_part = " Tip: ";
- let alt = "Alt";
- let text_second_part = " + ";
- let new_pane_shortcut = "<n>";
- let text_third_part = " => new pane. ";
- let second_alt = "Alt";
- let text_fourth_part = " + ";
- let brackets_navigation = "<[]";
- let text_fifth_part = " or ";
- let hjkl_navigation = "hjkl>";
- let text_sixths_part = " => navigate. ";
- let third_alt = "Alt";
- let text_seventh_parth = " + ";
- let increase_decrease_parth = "<+->";
- let text_eighth_parth = " => resize pane. ";
- let len = text_first_part.chars().count()
- + alt.chars().count()
- + text_second_part.chars().count()
- + new_pane_shortcut.chars().count()
- + text_third_part.chars().count()
- + second_alt.chars().count()
- + text_fourth_part.chars().count()
- + brackets_navigation.chars().count()
- + text_fifth_part.chars().count()
- + hjkl_navigation.chars().count()
- + text_sixths_part.chars().count()
- + third_alt.chars().count()
- + text_seventh_parth.chars().count()
- + increase_decrease_parth.chars().count()
- + text_eighth_parth.chars().count();
- let green_color = match palette.green {
- PaletteColor::Rgb((r, g, b)) => RGB(r, g, b),
- PaletteColor::EightBit(color) => Fixed(color),
- };
- let orange_color = match palette.orange {
- PaletteColor::Rgb((r, g, b)) => RGB(r, g, b),
- PaletteColor::EightBit(color) => Fixed(color),
- };
- LinePart {
- part: format!(
- "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
- text_first_part,
- Style::new().fg(orange_color).bold().paint(alt),
- text_second_part,
- Style::new().fg(green_color).bold().paint(new_pane_shortcut),
- text_third_part,
- Style::new().fg(orange_color).bold().paint(second_alt),
- text_fourth_part,
- Style::new()
- .fg(green_color)
- .bold()
- .paint(brackets_navigation),
- text_fifth_part,
- Style::new().fg(green_color).bold().paint(hjkl_navigation),
- text_sixths_part,
- Style::new().fg(orange_color).bold().paint(third_alt),
- text_seventh_parth,
- Style::new()
- .fg(green_color)
- .bold()
- .paint(increase_decrease_parth),
- text_eighth_parth,
- ),
- len,
- }
-}
-
-fn quicknav_short(palette: Palette) -> LinePart {
- let text_first_part = " QuickNav: ";
- let alt = "Alt";
- let text_second_part = " + ";
- let new_pane_shortcut = "n";
- let text_third_part = "/";
- let brackets_navigation = "[]";
- let text_fifth_part = "/";
- let hjkl_navigation = "hjkl";
- let text_sixth_part = "/";
- let increase_decrease_part = "+-";
- let len = text_first_part.chars().count()
- + alt.chars().count()
- + text_second_part.chars().count()
- + new_pane_shortcut.chars().count()
- + text_third_part.chars().count()
- + brackets_navigation.chars().count()
- + text_fifth_part.chars().count()
- + hjkl_navigation.chars().count()
- + text_sixth_part.chars().count()
- + increase_decrease_part.chars().count();
- let green_color = match palette.green {
- PaletteColor::Rgb((r, g, b)) => RGB(r, g, b),
- PaletteColor::EightBit(color) => Fixed(color),
- };
- let orange_color = match palette.orange {
- PaletteColor::Rgb((r, g, b)) => RGB(r, g, b),
- PaletteColor::EightBit(color) => Fixed(color),
- };
- LinePart {
- part: format!(
- "{}{}{}{}{}{}{}{}{}{}",
- text_first_part,
- Style::new().fg(orange_color).bold().paint(alt),
- text_second_part,
- Style::new().fg(green_color).bold().paint(new_pane_shortcut),
- text_third_part,
- Style::new()
- .fg(green_color)
- .bold()
- .paint(brackets_navigation),
- text_fifth_part,
- Style::new().fg(green_color).bold().paint(hjkl_navigation),
- text_sixth_part,
- Style::new()
- .fg(green_color)
- .bold()
- .paint(increase_decrease_part),
- ),
- len,
- }
-}
fn locked_interface_indication(palette: Palette) -> LinePart {
let locked_text = " -- INTERFACE LOCKED -- ";
@@ -318,9 +133,9 @@ fn select_pane_shortcut(is_first_shortcut: bool, palette: Palette) -> LinePart {
}
}
-fn full_shortcut_list(help: &ModeInfo) -> LinePart {
+fn full_shortcut_list(help: &ModeInfo, tip: TipFn) -> LinePart {
match help.mode {
- InputMode::Normal => quicknav_full(help.palette),
+ InputMode::Normal => tip(help.palette),
InputMode::Locked => locked_interface_indication(help.palette),
_ => {
let mut line_part = LinePart::default();
@@ -337,9 +152,9 @@ fn full_shortcut_list(help: &ModeInfo) -> LinePart {
}
}
-fn shortened_shortcut_list(help: &ModeInfo) -> LinePart {
+fn shortened_shortcut_list(help: &ModeInfo, tip: TipFn) -> LinePart {
match help.mode {
- InputMode::Normal => quicknav_medium(help.palette),
+ InputMode::Normal => tip(help.palette),
InputMode::Locked => locked_interface_indication(help.palette),
_ => {
let mut line_part = LinePart::default();
@@ -356,10 +171,10 @@ fn shortened_shortcut_list(help: &ModeInfo) -> LinePart {
}
}
-fn best_effort_shortcut_list(help: &ModeInfo, max_len: usize) -> LinePart {
+fn best_effort_shortcut_list(help: &ModeInfo, tip: TipFn, max_len: usize) -> LinePart {
match help.mode {
InputMode::Normal => {
- let line_part = quicknav_short(help.palette);
+ let line_part = tip(help.palette);
if line_part.len <= max_len {
line_part
} else {
@@ -397,16 +212,19 @@ fn best_effort_shortcut_list(help: &ModeInfo, max_len: usize) -> LinePart {
}
}
-pub fn keybinds(help: &ModeInfo, max_width: usize) -> LinePart {
- let full_shortcut_list = full_shortcut_list(help);
+pub fn keybinds(help: &ModeInfo, tip_name: &str, max_width: usize) -> LinePart {
+ // It is assumed that there is at least one TIP data in the TIPS HasMap.
+ let tip_body = TIPS.get(tip_name).unwrap();
+
+ let full_shortcut_list = full_shortcut_list(help, tip_body.full);
if full_shortcut_list.len <= max_width {
return full_shortcut_list;
}
- let shortened_shortcut_list = shortened_shortcut_list(help);
+ let shortened_shortcut_list = shortened_shortcut_list(help, tip_body.medium);
if shortened_shortcut_list.len <= max_width {
return shortened_shortcut_list;
}
- best_effort_shortcut_list(help, max_width)
+ best_effort_shortcut_list(help, tip_body.short, max_width)
}
pub fn text_copied_hint(palette: &Palette) -> LinePart {
diff --git a/default-plugins/status-bar/src/tip/cache.rs b/default-plugins/status-bar/src/tip/cache.rs
new file mode 100644
index 000000000..dece82437
--- /dev/null
+++ b/default-plugins/status-bar/src/tip/cache.rs
@@ -0,0 +1,119 @@
+use std::collections::{HashMap, HashSet};
+use std::fs::{File, OpenOptions};
+use std::io::{self, Read, Write};
+use std::path::PathBuf;
+
+use serde::{Deserialize, Serialize};
+use thiserror::Error;
+
+use zellij_tile::prelude::get_zellij_version;
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Metadata {
+ zellij_version: String,
+ cached_data: HashMap<String, usize>,
+}
+
+#[derive(Debug)]
+pub struct LocalCache {
+ path: PathBuf,
+ metadata: Metadata,
+}
+
+pub type LocalCacheResult = Result<LocalCache, LocalCacheError>;
+
+#[derive(Error, Debug)]
+pub enum LocalCacheError {
+ // Io error
+ #[error("IoError: {0}")]
+ Io(#[from] io::Error),
+ // Io error with path context
+ #[error("IoError: {0}, File: {1}")]
+ IoPath(io::Error, PathBuf),
+ // Deserialization error
+ #[error("Deserialization error: {0}")]
+ Serde(#[from] serde_json::Error),
+}
+
+impl LocalCache {
+ fn from_json(json_cache: &str) -> Result<Metadata, LocalCacheError> {
+ match serde_json::from_str::<Metadata>(json_cache) {
+ Ok(metadata) => Ok(metadata),
+ Err(err) => {
+ if json_cache.is_empty() {
+ return Ok(Metadata {
+ zellij_version: get_zellij_version(),
+ cached_data: HashMap::new(),
+ });
+ }
+ Err(LocalCacheError::Serde(err))
+ }
+ }
+ }
+
+ pub fn new(path: PathBuf) -> LocalCacheResult {
+ match OpenOptions::new()
+ .read(true)
+ .create(true)
+ .open(path.as_path())
+ {
+ Ok(mut file) => {
+ let mut json_cache = String::new();
+ file.read_to_string(&mut json_cache)
+ .map_err(LocalCacheError::Io)?;
+
+ let metadata = LocalCache::from_json(&json_cache)?;
+ Ok(LocalCache { path, metadata })
+ }
+ Err(e) => Err(LocalCacheError::IoPath(e, path)),
+ }
+ }
+
+ pub fn flush(&mut self) -> Result<(), LocalCacheError> {
+ match serde_json::to_string(&self.metadata) {
+ Ok(json_cache) => {
+ let mut file = File::create(self.path.as_path())
+ .map_err(|e| LocalCacheError::IoPath(e, self.path.clone()))?;
+ file.write_all(json_cache.as_bytes())
+ .map_err(LocalCacheError::Io)?;
+ Ok(())
+ }
+ Err(e) => Err(LocalCacheError::Serde(e)),
+ }
+ }
+
+ pub fn clear(&mut self) -> Result<(), LocalCacheError> {
+ self.metadata.cached_data.clear();
+ self.flush()
+ }
+
+ pub fn get_version(&self) -> &String {
+ &self.metadata.zellij_version
+ }
+
+ pub fn set_version<S: Into<String>>(&mut self, version: S) {
+ self.metadata.zellij_version = version.into();
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.metadata.cached_data.is_empty()
+ }
+
+ pub fn get_cached_data(&self) -> &HashMap<String, usize> {
+ &self.metadata.cached_data
+ }
+
+ pub fn get_cached_data_set(&self) -> HashSet<String> {
+ self.get_cached_data().keys().cloned().collect()
+ }
+
+ pub fn caching<S: Into<String>>(&mut self, key: S) -> Result<(), LocalCacheError> {
+ let key = key.into();
+ if let Some(item) = self.metadata.cached_data.get_mut(&key) {
+ *item += 1;
+ } else {
+ self.metadata.cached_data.insert(key, 1);
+ }
+ self.flush()
+ }
+}
diff --git a/default-plugins/status-bar/src/tip/consts.rs b/default-plugins/status-bar/src/tip/consts.rs
new file mode 100644
index 000000000..62bbeaa9c
--- /dev/null
+++ b/default-plugins/status-bar/src/tip/consts.rs
@@ -0,0 +1,2 @@
+pub const DEFAULT_CACHE_FILE_PATH: &str = "/tmp/status-bar-tips.cache";
+pub const MAX_CACHE_HITS: usize = 10;
diff --git a/default-plugins/status-bar/src/tip/data.rs b/default-plugins/status-bar/src/tip/data.rs
new file mode 100644
index 000000000..c0ea2242d
--- /dev/null
+++ b/default-plugins/status-bar/src/tip/data.rs
@@ -0,0 +1,100 @@
+use std::collections::HashMap;
+
+use ansi_term::{
+ unstyled_len, ANSIString, ANSIStrings,
+ Color::{Fixed, RGB},
+ Style,
+};
+use lazy_static::lazy_static;
+
+use crate::{tip::TipBody, LinePart};
+use zellij_tile::prelude::*;
+use zellij_tile_utils::palette_match;
+
+macro_rules! strings {
+ ($ANSIStrings:expr) => {{
+ let strings: &[ANSIString<'static>] = $ANSIStrings;
+
+ let ansi_strings = ANSIStrings(strings);
+
+ LinePart {
+ part: format!("{}", ansi_strings),
+ len: unstyled_len(&ansi_strings),
+ }
+ }};
+}
+
+lazy_static! {
+ pub static ref TIPS: HashMap<&'static str, TipBody> = HashMap::from([(
+ "quicknav",
+ TipBody {
+ short: quicknav_short,
+ medium: quicknav_medium,
+ full: quicknav_full,
+ }
+ )]);
+}
+
+fn quicknav_full(palette: Palette) -> LinePart {
+ let green_color = palette_match!(palette.green);
+ let orange_color = palette_match!(palette.orange);
+
+ strings!(&[
+ Style::new().paint(" Tip: "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("<n>"),
+ Style::new().paint(" => open new pane. "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("<[]"),
+ Style::new().paint(" or "),
+ Style::new().fg(green_color).bold().paint("hjkl>"),
+ Style::new().paint(" => navigate between panes. "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("<+->"),
+ Style::new().paint(" => increase/decrease pane size."),
+ ])
+}
+
+fn quicknav_medium(palette: Palette) -> LinePart {
+ let green_color = palette_match!(palette.green);
+ let orange_color = palette_match!(palette.orange);
+
+ strings!(&[
+ Style::new().paint(" Tip: "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("<n>"),
+ Style::new().paint(" => new pane. "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("<[]"),
+ Style::new().paint(" or "),
+ Style::new().fg(green_color).bold().paint("hjkl>"),
+ Style::new().paint(" => navigate. "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("<+->"),
+ Style::new().paint(" => resize pane."),
+ ])
+}
+
+fn quicknav_short(palette: Palette) -> LinePart {
+ let green_color = palette_match!(palette.green);
+ let orange_color = palette_match!(palette.orange);
+
+ strings!(&[
+ Style::new().paint(" QuickNav: "),
+ Style::new().fg(orange_color).bold().paint("Alt"),
+ Style::new().paint(" + "),
+ Style::new().fg(green_color).bold().paint("n"),
+ Style::new().paint("/"),
+ Style::new().fg(green_color).bold().paint("[]"),
+ Style::new().paint("/"),
+ Style::new().fg(green_color).bold().paint("hjkl"),
+ Style::new().paint("/"),
+ Style::new().fg(green_color).bold().paint("+-"),
+ ])
+}
diff --git a/default-plugins/status-bar/src/tip/mod.rs b/default-plugins/status-bar/src/tip/mod.rs
new file mode 100644
index 000000000..1249195f9
--- /dev/null
+++ b/default-plugins/status-bar/src/tip/mod.rs
@@ -0,0 +1,16 @@
+pub mod cache;
+pub mod consts;
+pub mod data;
+pub mod utils;
+
+use crate::LinePart;
+use zellij_tile::prelude::*;
+
+pub type TipFn = fn(Palette) -> LinePart;
+
+#[derive(Debug)]
+pub struct TipBody {
+ pub short: TipFn,
+ pub medium: TipFn,
+ pub full: TipFn,
+}
diff --git a/default-plugins/status-bar/src/tip/utils.rs b/default-plugins/status-bar/src/tip/utils.rs
new file mode 100644
index 000000000..3dd4c5a8e
--- /dev/null
+++ b/default-plugins/status-bar/src/tip/utils.rs
@@ -0,0 +1,68 @@
+use std::path::PathBuf;
+
+use rand::prelude::{IteratorRandom, SliceRandom};
+
+use zellij_tile::prelude::get_zellij_version;
+
+use super::cache::LocalCache;
+use super::consts::{DEFAULT_CACHE_FILE_PATH, MAX_CACHE_HITS};
+use super::data::TIPS;
+
+macro_rules! get_name_and_caching {
+ ($cache:expr) => {{
+ let name = get_random_tip_name();
+ $cache.caching(name.clone()).unwrap();
+ return name;
+ }};
+ ($cache:expr, $from:expr) => {{
+ let name = $from.choose(&mut rand::thread_rng()).unwrap().to_string();
+ $cache.caching(name.clone()).unwrap();
+ return name;
+ }};
+}
+
+pub fn get_random_tip_name() -> String {
+ TIPS.keys()
+ .choose(&mut rand::thread_rng())
+ .unwrap()
+ .to_string()
+}
+
+pub fn get_cached_tip_name() -> String {
+ let mut local_cache = LocalCache::new(PathBuf::from(DEFAULT_CACHE_FILE_PATH)).unwrap();
+
+ let zellij_version = get_zellij_version();
+ if zellij_version.ne(local_cache.get_version()) {
+ local_cache.set_version(zellij_version);
+ local_cache.clear().unwrap();
+ }
+
+ if local_cache.is_empty() {
+ get_name_and_caching!(local_cache);
+ }
+
+ let usable_tips = local_cache
+ .get_cached_data()
+ .iter()
+ .filter(|(_, &v)| v < MAX_CACHE_HITS)
+ .map(|(k, _)| k.to_string())
+ .collect::<Vec<String>>();
+
+ if usable_tips.is_empty() {
+ let cached_set = local_cache.get_cached_data_set();
+ let diff = TIPS
+ .keys()
+ .cloned()
+ .filter(|k| !cached_set.contains(&k.to_string(