pub mod arrows;
pub mod blocks;
pub mod editor;
pub mod file_types;
pub mod git;
pub mod security;
pub mod shapes;
pub mod status;
pub mod symbols;
pub mod ui;
pub use arrows::{Arrow, Navigation};
pub use blocks::Block;
pub use editor::{Cursor, Selection};
pub use file_types::{
get_file_type_from_extension, get_file_type_from_filename, FileType, LanguageType,
};
pub use git::{GitAction, GitBranch, GitDiff, GitStatus};
pub use shapes::Shape;
pub use status::Status;
pub use symbols::Symbol;
pub use ui::{Border, Control, Indicator, Separator};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum UnicodeTheme {
Minimal,
Basic,
#[default]
Rich,
Fancy,
}
pub trait UnicodeProvider {
fn get_char(&self, theme: UnicodeTheme) -> char;
fn get_str(&self, theme: UnicodeTheme) -> &'static str {
#[allow(clippy::match_single_binding)]
match self.get_char(theme) {
c => match c {
' ' => " ",
'!' => "!",
'"' => "\"",
'#' => "#",
'$' => "$",
'%' => "%",
'&' => "&",
'\'' => "'",
'(' => "(",
')' => ")",
'*' => "*",
'+' => "+",
',' => ",",
'-' => "-",
'.' => ".",
'/' => "/",
'0' => "0",
'1' => "1",
'2' => "2",
'3' => "3",
'4' => "4",
'5' => "5",
'6' => "6",
'7' => "7",
'8' => "8",
'9' => "9",
':' => ":",
';' => ";",
'<' => "<",
'=' => "=",
'>' => ">",
'?' => "?",
'@' => "@",
'A' => "A",
'B' => "B",
'C' => "C",
'D' => "D",
'E' => "E",
'F' => "F",
'G' => "G",
'H' => "H",
'I' => "I",
'J' => "J",
'K' => "K",
'L' => "L",
'M' => "M",
'N' => "N",
'O' => "O",
'P' => "P",
'Q' => "Q",
'R' => "R",
'S' => "S",
'T' => "T",
'U' => "U",
'V' => "V",
'W' => "W",
'X' => "X",
'Y' => "Y",
'Z' => "Z",
'[' => "[",
'\\' => "\\",
']' => "]",
'^' => "^",
'_' => "_",
'`' => "`",
'a' => "a",
'b' => "b",
'c' => "c",
'd' => "d",
'e' => "e",
'f' => "f",
'g' => "g",
'h' => "h",
'i' => "i",
'j' => "j",
'k' => "k",
'l' => "l",
'm' => "m",
'n' => "n",
'o' => "o",
'p' => "p",
'q' => "q",
'r' => "r",
's' => "s",
't' => "t",
'u' => "u",
'v' => "v",
'w' => "w",
'x' => "x",
'y' => "y",
'z' => "z",
'{' => "{",
'|' => "|",
'}' => "}",
'~' => "~",
_ => "?", },
}
}
}
#[derive(Debug, Clone)]
pub struct UnicodeConfig {
pub theme: UnicodeTheme,
pub use_fallback: bool,
pub overrides: std::collections::HashMap<String, char>,
}
#[allow(clippy::derivable_impls)]
impl Default for UnicodeConfig {
fn default() -> Self {
Self {
theme: UnicodeTheme::default(),
use_fallback: false,
overrides: std::collections::HashMap::new(),
}
}
}
impl UnicodeConfig {
pub fn with_theme(theme: UnicodeTheme) -> Self {
Self {
theme,
..Default::default()
}
}
pub fn with_fallback(mut self) -> Self {
self.use_fallback = true;
self
}
pub fn with_override(mut self, key: &str, character: char) -> Self {
self.overrides.insert(key.to_string(), character);
self
}
pub fn get_char<T: UnicodeProvider>(&self, provider: &T, key: Option<&str>) -> char {
if let Some(key) = key {
if let Some(&override_char) = self.overrides.get(key) {
return override_char;
}
}
let char = provider.get_char(self.theme);
if self.use_fallback && !char.is_ascii() {
provider.get_char(UnicodeTheme::Minimal)
} else {
char
}
}
}
use std::sync::{Mutex, OnceLock};
static GLOBAL_UNICODE_CONFIG: OnceLock<Mutex<UnicodeConfig>> = OnceLock::new();
pub fn set_global_config(config: UnicodeConfig) {
let mutex = GLOBAL_UNICODE_CONFIG.get_or_init(|| Mutex::new(UnicodeConfig::default()));
if let Ok(mut guard) = mutex.lock() {
*guard = config;
}
}
pub fn get_global_config() -> UnicodeConfig {
let mutex = GLOBAL_UNICODE_CONFIG.get_or_init(|| Mutex::new(UnicodeConfig::default()));
mutex.lock().map(|guard| guard.clone()).unwrap_or_default()
}
pub fn get_char<T: UnicodeProvider>(provider: &T, key: Option<&str>) -> char {
get_global_config().get_char(provider, key)
}
pub fn get_str<T: UnicodeProvider>(provider: &T, key: Option<&str>) -> &'static str {
let char = get_char(provider, key);
match char {
' ' => " ",
_ => "?", }
}