pub mod appearance;
pub mod loader;
use std::collections::BTreeMap;
pub use appearance::Appearance;
use crate::keymap::Keymap;
use crate::theme::{
Color, ColorOverrides, DEFAULT_THEME, Palette, Skin, ThemeColors,
ThemeRegistry,
};
pub const DEFAULT_EDITOR_EXTENSIONS: &[&str] = &[
"txt", "text", "md", "markdown", "rst", "org", "rs", "toml", "json",
"jsonc", "yaml", "yml", "ini", "cfg", "conf", "config", "env", "py", "js",
"mjs", "cjs", "ts", "tsx", "jsx", "sh", "bash", "zsh", "fish", "c", "h",
"cpp", "hpp", "cc", "hh", "go", "rb", "java", "kt", "kts", "swift", "php",
"pl", "lua", "vim", "html", "htm", "css", "scss", "sass", "xml", "csv",
"tsv", "sql", "tex", "log", "make", "mk",
];
pub const DEFAULT_ZIP_EXCLUDE_DIRS: &[&str] = &[
"target",
"node_modules",
"dist",
"build",
"out",
"bin",
"obj",
".next",
".nuxt",
".turbo",
".parcel-cache",
"__pycache__",
".venv",
"venv",
".mypy_cache",
".pytest_cache",
".ruff_cache",
".tox",
".gradle",
".build",
"DerivedData",
"Pods",
".cache",
];
const HOP_DEFAULT_THEME: ThemeColors = ThemeColors {
accent: Color::hex("#f7a3bd"),
foreground: Color::hex("#e5e5e5"),
background: Color::hex("#151515"),
header: Color::hex("#0e0c12"),
footer: Color::hex("#0e0c12"),
panel: Color::hex("#1c1a20"),
surface: Color::hex("#26222b"),
border: Color::hex("#4a4652"),
border_focus: Color::hex("#74707d"),
success: Color::hex("#8fbf7f"),
warning: Color::hex("#dcbe5a"),
error: Color::hex("#d05050"),
info: Color::hex("#7fb3d4"),
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ColumnWidth {
pub min: usize,
pub max: Option<usize>,
}
impl ColumnWidth {
pub const fn min(min: usize) -> Self {
ColumnWidth { min, max: None }
}
pub const fn range(min: usize, max: usize) -> Self {
ColumnWidth {
min,
max: Some(max),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ColumnWidths {
pub name: ColumnWidth,
pub current_branch_name: ColumnWidth,
pub status: ColumnWidth,
pub github_repo_name: ColumnWidth,
pub zip_backup: ColumnWidth,
}
impl Default for ColumnWidths {
fn default() -> Self {
ColumnWidths {
name: ColumnWidth::min(30),
current_branch_name: ColumnWidth::range(10, 14),
status: ColumnWidth::min(6),
github_repo_name: ColumnWidth::min(20),
zip_backup: ColumnWidth::min(10),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Config {
pub git_program: Option<String>,
pub github_username: Option<String>,
pub example_mode: bool,
pub fetch_on_start: bool,
pub confirm_quit: bool,
pub editor: Option<String>,
pub editor_extensions: Vec<String>,
pub appearance: Appearance,
pub themes: Vec<(String, ThemeColors)>,
pub keys: BTreeMap<String, Vec<String>>,
pub column_widths: ColumnWidths,
pub zip_backup_folder: Option<String>,
pub zip_exclude_dirs: Vec<String>,
}
impl Default for Config {
fn default() -> Self {
Config {
git_program: Some("lazygit".to_string()),
github_username: None,
example_mode: false,
fetch_on_start: false,
confirm_quit: false,
editor: None,
editor_extensions: DEFAULT_EDITOR_EXTENSIONS
.iter()
.map(|ext| (*ext).to_string())
.collect(),
appearance: Appearance::default(),
themes: Vec::new(),
keys: BTreeMap::new(),
column_widths: ColumnWidths::default(),
zip_backup_folder: None,
zip_exclude_dirs: DEFAULT_ZIP_EXCLUDE_DIRS
.iter()
.map(|dir| (*dir).to_string())
.collect(),
}
}
}
impl Config {
pub fn theme_registry(&self) -> ThemeRegistry {
ThemeRegistry::builtin()
.with_custom([(DEFAULT_THEME.to_string(), HOP_DEFAULT_THEME)])
.with_custom(self.themes.iter().cloned())
}
pub fn color_overrides(&self) -> ColorOverrides<'_> {
ColorOverrides::from_lookup(|name| {
self.appearance.colors.get(name).map_or("", String::as_str)
})
}
pub fn palette(&self) -> Palette {
let base = self.theme_registry().resolve(&self.appearance.theme);
Palette::resolve(base, &self.color_overrides())
}
pub fn skin(&self) -> Skin {
Skin::new(self.palette(), self.glyphs())
}
pub fn glyphs(&self) -> crate::theme::Glyphs {
crate::theme::Glyphs::new(self.appearance.glyphs)
}
pub fn keymap(&self) -> Keymap {
Keymap::from_overrides(&self.keys)
}
}