From 203bd8977b56218d3972de007d403a3fdf9d95f7 Mon Sep 17 00:00:00 2001 From: pantosaur <44764250+pantosaur@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:56:22 -0500 Subject: fix overflow bug on bookmark widget when area is too small (#483) --- src/commands/bookmark.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/commands/bookmark.rs b/src/commands/bookmark.rs index 4372a58..2371c44 100644 --- a/src/commands/bookmark.rs +++ b/src/commands/bookmark.rs @@ -108,19 +108,20 @@ fn poll_for_bookmark_key(context: &mut AppContext, backend: &mut AppBackend) -> frame.render_widget(view, area); } - let menu_widget = TuiMenu::new(bookmarks_str.as_slice()); - let menu_len = menu_widget.len(); - let menu_y = if menu_len + 1 > area.height as usize { - 0 + let (menu_widget, menu_y) = if bookmarks_str.len() > area.height as usize - 1 { + (TuiMenu::new(&bookmarks_str[0..area.height as usize - 1]), 0) } else { - (area.height as usize - menu_len - 1) as u16 + ( + TuiMenu::new(bookmarks_str.as_slice()), + (area.height as usize - bookmarks_str.len() - 1) as u16, + ) }; let menu_rect = Rect { x: 0, - y: menu_y - 1, + y: menu_y, width: area.width, - height: menu_len as u16 + 1, + height: menu_widget.len() as u16 + 1, }; frame.render_widget(Clear, menu_rect); frame.render_widget(menu_widget, menu_rect); -- cgit v1.2.3 From 96418c064ef617f62618a1baee518a823915955b Mon Sep 17 00:00:00 2001 From: sushi-shi <47691267+sushi-shi@users.noreply.github.com> Date: Tue, 13 Feb 2024 22:00:19 +0000 Subject: Add command for printing embedded configs (#487) * Add command for printing embedded configs * Typo * Use doccomments instead of procmacro * Typo --- config/joshuto.toml | 2 +- config/theme.toml | 2 +- src/commands/bookmark.rs | 13 ++++--- src/config/clean/app/config.rs | 9 +++-- src/config/clean/app/mod.rs | 4 +- src/config/clean/bookmarks.rs | 10 ++--- src/config/clean/icon/config.rs | 8 ++-- src/config/clean/icon/mod.rs | 5 ++- src/config/clean/keymap/config.rs | 8 ++-- src/config/clean/keymap/mod.rs | 4 +- src/config/clean/mimetype/config.rs | 10 ++--- src/config/clean/preview/config.rs | 8 ++-- src/config/clean/theme/config.rs | 8 ++-- src/config/clean/theme/mod.rs | 4 +- src/config/config_type.rs | 75 +++++++++++++++++++++++++++++++++++++ src/config/mod.rs | 33 +++++++++------- src/error/error_type.rs | 10 ++++- src/main.rs | 55 ++++++++++++++------------- 18 files changed, 185 insertions(+), 83 deletions(-) create mode 100644 src/config/config_type.rs diff --git a/config/joshuto.toml b/config/joshuto.toml index b7d4626..4ab9cbc 100644 --- a/config/joshuto.toml +++ b/config/joshuto.toml @@ -23,7 +23,7 @@ show_icons = true # none, absolute, relative line_number_style = "none" -# size, mtime, user, gourp, perm. can be combined with |. +# size, mtime, user, gourp, perm. can be combined with |. # `none` to disable, `all` to enable all # all and none can't be combined with other options linemode = "size" diff --git a/config/theme.toml b/config/theme.toml index fce3633..5d11e39 100644 --- a/config/theme.toml +++ b/config/theme.toml @@ -85,7 +85,7 @@ bold = true ########################################## ## File list - Override style by extension ########################################## -# This sections allows to override the basic +# This sections allows to override the basic # style with a specific style for the file's # extension. diff --git a/src/commands/bookmark.rs b/src/commands/bookmark.rs index 2371c44..ce83d95 100644 --- a/src/commands/bookmark.rs +++ b/src/commands/bookmark.rs @@ -7,7 +7,7 @@ use ratatui::widgets::Clear; use termion::event::Event; use crate::config::raw::bookmarks::{BookmarkRaw, BookmarksRaw}; -use crate::config::search_directories; +use crate::config::{search_directories, ConfigType}; use crate::context::AppContext; use crate::error::AppResult; use crate::event::{process_event, AppEvent}; @@ -17,7 +17,7 @@ use crate::ui::widgets::TuiMenu; use crate::ui::AppBackend; use crate::util::unix; -use crate::{BOOKMARKS_FILE, BOOKMARKS_T, CONFIG_HIERARCHY}; +use crate::{BOOKMARKS_T, CONFIG_HIERARCHY}; use super::change_directory::change_directory; @@ -33,10 +33,11 @@ fn find_bookmark_file() -> Option { pub fn add_bookmark(context: &mut AppContext, backend: &mut AppBackend) -> AppResult { let cwd = std::env::current_dir()?; - let bookmark_path = match search_directories(BOOKMARKS_FILE, &CONFIG_HIERARCHY) { - Some(file_path) => Some(file_path), - None => find_bookmark_file(), - }; + let bookmark_path = + match search_directories(ConfigType::Bookmarks.as_filename(), &CONFIG_HIERARCHY) { + Some(file_path) => Some(file_path), + None => find_bookmark_file(), + }; if let Some(bookmark_path) = bookmark_path { let key = poll_for_bookmark_key(context, backend); diff --git a/src/config/clean/app/config.rs b/src/config/clean/app/config.rs index 0995e8d..60b088d 100644 --- a/src/config/clean/app/config.rs +++ b/src/config/clean/app/config.rs @@ -2,9 +2,8 @@ use std::collections::HashMap; use crate::{ config::{ - parse_config_or_default, raw::app::{AppConfigRaw, CustomCommand}, - TomlConfigFile, + ConfigType, TomlConfigFile, }, error::AppResult, }; @@ -71,8 +70,10 @@ impl std::default::Default for AppConfig { } impl TomlConfigFile for AppConfig { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = AppConfigRaw; + + fn get_type() -> ConfigType { + ConfigType::App } } diff --git a/src/config/clean/app/mod.rs b/src/config/clean/app/mod.rs index 11fb46a..d517b31 100644 --- a/src/config/clean/app/mod.rs +++ b/src/config/clean/app/mod.rs @@ -7,7 +7,7 @@ pub mod tab; pub use config::*; #[cfg(not(target_os = "windows"))] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/joshuto.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/joshuto.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\joshuto.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\joshuto.toml"); diff --git a/src/config/clean/bookmarks.rs b/src/config/clean/bookmarks.rs index 370fef2..155755d 100644 --- a/src/config/clean/bookmarks.rs +++ b/src/config/clean/bookmarks.rs @@ -3,16 +3,16 @@ use termion::event::Event; use std::collections::HashMap; use crate::config::raw::bookmarks::BookmarksRaw; -use crate::config::TomlConfigFile; +use crate::config::{ConfigType, TomlConfigFile}; use crate::util::keyparse; -use crate::config::parse_config_or_default; - pub type Bookmarks = HashMap; impl TomlConfigFile for Bookmarks { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = BookmarksRaw; + + fn get_type() -> ConfigType { + ConfigType::Bookmarks } } diff --git a/src/config/clean/icon/config.rs b/src/config/clean/icon/config.rs index 02a80c3..a0c25af 100644 --- a/src/config/clean/icon/config.rs +++ b/src/config/clean/icon/config.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::{ - config::{parse_config_or_default, raw::icon::IconsRaw, TomlConfigFile}, + config::{raw::icon::IconsRaw, ConfigType, TomlConfigFile}, error::AppResult, }; @@ -30,8 +30,10 @@ impl std::default::Default for Icons { } impl TomlConfigFile for Icons { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = IconsRaw; + + fn get_type() -> ConfigType { + ConfigType::Icons } } diff --git a/src/config/clean/icon/mod.rs b/src/config/clean/icon/mod.rs index ac4a11a..e23656d 100644 --- a/src/config/clean/icon/mod.rs +++ b/src/config/clean/icon/mod.rs @@ -2,7 +2,8 @@ mod config; pub use config::*; -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/icons.toml"); +#[cfg(not(target_os = "windows"))] +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/icons.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\icons.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\icons.toml"); diff --git a/src/config/clean/keymap/config.rs b/src/config/clean/keymap/config.rs index 55e1bf9..c51721a 100644 --- a/src/config/clean/keymap/config.rs +++ b/src/config/clean/keymap/config.rs @@ -5,7 +5,7 @@ use std::str::FromStr; use termion::event::Event; use crate::config::raw::keymap::{AppKeyMappingRaw, CommandKeymap}; -use crate::config::{parse_config_or_default, TomlConfigFile}; +use crate::config::{ConfigType, TomlConfigFile}; use crate::error::AppResult; use crate::key_command::{Command, CommandKeybind}; use crate::traits::ToString; @@ -113,8 +113,10 @@ impl From for AppKeyMapping { } impl TomlConfigFile for AppKeyMapping { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = AppKeyMappingRaw; + + fn get_type() -> ConfigType { + ConfigType::Keymap } } diff --git a/src/config/clean/keymap/mod.rs b/src/config/clean/keymap/mod.rs index f68fbef..4398f8d 100644 --- a/src/config/clean/keymap/mod.rs +++ b/src/config/clean/keymap/mod.rs @@ -3,7 +3,7 @@ mod config; pub use self::config::*; #[cfg(not(target_os = "windows"))] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/keymap.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/keymap.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\keymap.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\keymap.toml"); diff --git a/src/config/clean/mimetype/config.rs b/src/config/clean/mimetype/config.rs index 166e7e2..2419f88 100644 --- a/src/config/clean/mimetype/config.rs +++ b/src/config/clean/mimetype/config.rs @@ -1,8 +1,6 @@ use std::collections::HashMap; -use crate::config::{ - parse_config_or_default, raw::mimetype::AppProgramRegistryRaw, TomlConfigFile, -}; +use crate::config::{raw::mimetype::AppProgramRegistryRaw, ConfigType, TomlConfigFile}; use super::{ExtensionAppList, MimetypeAppList}; @@ -69,7 +67,9 @@ impl From for AppProgramRegistry { } impl TomlConfigFile for AppProgramRegistry { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = AppProgramRegistryRaw; + + fn get_type() -> ConfigType { + ConfigType::Mimetype } } diff --git a/src/config/clean/preview/config.rs b/src/config/clean/preview/config.rs index 0588c5f..1490cb3 100644 --- a/src/config/clean/preview/config.rs +++ b/src/config/clean/preview/config.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use serde::Deserialize; -use crate::config::{parse_config_or_default, raw::preview::FileEntryPreviewRaw, TomlConfigFile}; +use crate::config::{raw::preview::FileEntryPreviewRaw, ConfigType, TomlConfigFile}; #[derive(Debug, Deserialize)] pub struct FileEntryPreviewEntry { @@ -17,8 +17,10 @@ pub struct FileEntryPreview { } impl TomlConfigFile for FileEntryPreview { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = FileEntryPreviewRaw; + + fn get_type() -> ConfigType { + ConfigType::Preview } } diff --git a/src/config/clean/theme/config.rs b/src/config/clean/theme/config.rs index 9028490..5be88fc 100644 --- a/src/config/clean/theme/config.rs +++ b/src/config/clean/theme/config.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::config::raw::theme::AppThemeRaw; -use crate::config::{parse_config_or_default, TomlConfigFile}; +use crate::config::{ConfigType, TomlConfigFile}; use crate::error::AppResult; use super::style::AppStyle; @@ -30,8 +30,10 @@ impl AppTheme { } impl TomlConfigFile for AppTheme { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::(file_name) + type Raw = AppThemeRaw; + + fn get_type() -> ConfigType { + ConfigType::Theme } } diff --git a/src/config/clean/theme/mod.rs b/src/config/clean/theme/mod.rs index a9f7cbb..a6694c9 100644 --- a/src/config/clean/theme/mod.rs +++ b/src/config/clean/theme/mod.rs @@ -5,7 +5,7 @@ pub mod tab; pub use config::*; #[cfg(not(target_os = "windows"))] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/theme.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/theme.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\theme.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\theme.toml"); diff --git a/src/config/config_type.rs b/src/config/config_type.rs new file mode 100644 index 0000000..7a4755a --- /dev/null +++ b/src/config/config_type.rs @@ -0,0 +1,75 @@ +#[derive(Copy, Clone, Debug)] +pub enum ConfigType { + App, + Mimetype, + Keymap, + Theme, + Preview, + Bookmarks, + Icons, +} + +impl std::fmt::Display for ConfigType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_str()) + } +} + +impl clap::ValueEnum for ConfigType { + fn value_variants<'a>() -> &'a [Self] { + Self::enumerate() + } + + fn to_possible_value(&self) -> Option { + Some(clap::builder::PossibleValue::new(self.as_str())) + } +} + +impl ConfigType { + pub const fn enumerate() -> &'static [Self] { + &[ + Self::App, + Self::Mimetype, + Self::Keymap, + Self::Theme, + Self::Preview, + Self::Bookmarks, + Self::Icons, + ] + } + + pub const fn as_str(&self) -> &'static str { + match self { + Self::App => "joshuto", + Self::Mimetype => "mimetype", + Self::Keymap => "keymap", + Self::Theme => "theme", + Self::Preview => "preview", + Self::Bookmarks => "bookmarks", + Self::Icons => "icons", + } + } + + pub const fn as_filename(&self) -> &'static str { + match self { + Self::App => "joshuto.toml", + Self::Mimetype => "mimetype.toml", + Self::Keymap => "keymap.toml", + Self::Theme => "theme.toml", + Self::Preview => "preview.toml", + Self::Bookmarks => "bookmarks.toml", + Self::Icons => "icons.toml", + } + } + + pub const fn embedded_config(&self) -> Option<&'static str> { + use super::clean; + match self { + Self::App => Some(clean::app::DEFAULT_CONFIG_FILE_PATH), + Self::Keymap => Some(clean::keymap::DEFAULT_CONFIG_FILE_PATH), + Self::Theme => Some(clean::theme::DEFAULT_CONFIG_FILE_PATH), + Self::Icons => Some(clean::icon::DEFAULT_CONFIG_FILE_PATH), + Self::Mimetype | Self::Preview | Self::Bookmarks => None, + } + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 1f468ef..58d3f40 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,9 @@ pub mod clean; pub mod raw; +pub mod config_type; +pub use config_type::ConfigType; + use serde::de::DeserializeOwned; use std::fs; use std::path::{Path, PathBuf}; @@ -8,8 +11,14 @@ use std::path::{Path, PathBuf}; use crate::error::AppResult; use crate::CONFIG_HIERARCHY; -pub trait TomlConfigFile { - fn get_config(file_name: &str) -> Self; +pub trait TomlConfigFile: Sized + Default { + type Raw: Into + DeserializeOwned; + + fn get_type() -> config_type::ConfigType; + + fn get_config() -> Self { + parse_config_or_default::(Self::get_type().as_filename()) + } } // searches a list of folders for a given file in order of preference @@ -17,13 +26,10 @@ pub fn search_directories

(file_name: &str, directories: &[P]) -> Option, { - for path in directories.iter() { - let file_path = path.as_ref().join(file_name); - if file_path.exists() { - return Some(file_path); - } - } - None + directories + .iter() + .map(|path| path.as_ref().join(file_name)) + .find(|path| path.exists()) } pub fn search_config_directories(file_name: &str) -> Option { @@ -32,18 +38,17 @@ pub fn search_config_directories(file_name: &str) -> Option { fn parse_file_to_config(file_path: &Path) -> AppResult where - T: DeserializeOwned, - S: From, + T: DeserializeOwned + Into, { let file_contents = fs::read_to_string(file_path)?; let config = toml::from_str::(&file_contents)?; - Ok(S::from(config)) + Ok(config.into()) } pub fn parse_config_or_default(file_name: &str) -> S where - T: DeserializeOwned, - S: From + std::default::Default, + T: DeserializeOwned + Into, + S: std::default::Default, { match search_config_directories(file_name) { Some(file_path) => match parse_file_to_config::(&file_path) { diff --git a/src/error/error_type.rs b/src/error/error_type.rs index 9eef287..4913d76 100644 --- a/src/error/error_type.rs +++ b/src/error/error_type.rs @@ -9,12 +9,20 @@ pub struct AppError { _cause: String, } -#[allow(dead_code)] impl AppError { pub fn new(_kind: AppErrorKind, _cause: String) -> Self { Self { _kind, _cause } } + pub fn error(cause: impl ToString) -> Self { + Self::new(AppErrorKind::UnknownError, cause.to_string()) + } + + pub fn fail(cause: impl ToString) -> Result { + Err(Self::error(cause)) + } + + #[allow(dead_code)] pub fn kind(&self) -> &AppErrorKind { &self._kind } diff --git a/src/main.rs b/src/main.rs index 04a2a93..7a5d44d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ use lazy_static::lazy_static; use config::clean::bookmarks::Bookmarks; use config::clean::mimetype::AppProgramRegistry; use config::clean::theme::AppTheme; -use config::TomlConfigFile; +use config::{ConfigType, TomlConfigFile}; use util::cwd; use crate::commands::quit::QuitAction; @@ -42,14 +42,6 @@ use crate::error::AppError; const PROGRAM_NAME: &str = "joshuto"; const CONFIG_HOME: &str = "JOSHUTO_CONFIG_HOME"; -const CONFIG_FILE: &str = "joshuto.toml"; -const MIMETYPE_FILE: &str = "mimetype.toml"; -const KEYMAP_FILE: &str = "keymap.toml"; -const THEME_FILE: &str = "theme.toml"; -const PREVIEW_FILE: &str = "preview.toml"; -const BOOKMARKS_FILE: &str = "bookmarks.toml"; -const ICONS_FILE: &str = "icons.toml"; - lazy_static! { // dynamically builds the config hierarchy static ref CONFIG_HIERARCHY: Vec = { @@ -76,11 +68,11 @@ lazy_static! { config_dirs }; - static ref THEME_T: AppTheme = AppTheme::get_config(THEME_FILE); - static ref MIMETYPE_T: AppProgramRegistry = AppProgramRegistry::get_config(MIMETYPE_FILE); - static ref PREVIEW_T: FileEntryPreview = FileEntryPreview::get_config(PREVIEW_FILE); - static ref BOOKMARKS_T: Mutex = Mutex::new(Bookmarks::get_config(BOOKMARKS_FILE)); - static ref ICONS_T: Icons = Icons::get_config(ICONS_FILE); + static ref THEME_T: AppTheme = AppTheme::get_config(); + static ref MIMETYPE_T: AppProgramRegistry = AppProgramRegistry::get_config(); + static ref PREVIEW_T: FileEntryPreview = FileEntryPreview::get_config(); + static ref BOOKMARKS_T: Mutex = Mutex::new(Bookmarks::get_config()); + static ref ICONS_T: Icons = Icons::get_config(); static ref HOME_DIR: Option = dirs_next::home_dir(); static ref USERNAME: String = whoami::username(); @@ -120,24 +112,38 @@ pub struct Args { #[derive(Clone, Debug, Subcommand)] pub enum Commands { - #[command(about = "Show shell completions")] + /// Print completions for a given shell. Completions { shell: clap_complete::Shell }, - #[command(about = "Show version")] + /// Print embedded toml configuration for a given config type. + Config { + /// Filename of the given config without '.toml' extension. + config_type: ConfigType, + }, + + /// Print 'joshuto' build version. Version, } fn run_main(args: Args) -> Result { if let Some(command) = args.commands { - match command { + let result = match command { Commands::Completions { shell } => { let mut app = Args::command(); let bin_name = app.get_name().to_string(); clap_complete::generate(shell, &mut app, bin_name, &mut std::io::stdout()); - return Ok(0); + Ok(0) } - Commands::Version => return print_version(), - } + Commands::Config { config_type } => match config_type.embedded_config() { + None => AppError::fail("no default config"), + Some(config) => { + println!("{config}"); + Ok(0) + } + }, + Commands::Version => print_version(), + }; + return result; } if args.version { @@ -145,15 +151,12 @@ fn run_main(args: Args) -> Result { } if let Some(path) = args.rest.first() { - if let Err(err) = cwd::set_current_dir(path) { - eprintln!("{err}"); - process::exit(1); - } + cwd::set_current_dir(path)?; } // make sure all configs have been loaded before starting - let config = AppConfig::get_config(CONFIG_FILE); - let keymap = AppKeyMapping::get_config(KEYMAP_FILE); + let config = AppConfig::get_config(); + let keymap = AppKeyMapping::get_config(); lazy_static::initialize(&THEME_T); lazy_static::initialize(&MIMETYPE_T); lazy_static::initialize(&PREVIEW_T); -- cgit v1.2.3 From 4acace666d3d87bccf42e12e298bc0995c2e77e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 18:00:20 -0500 Subject: Bump libgit2-sys from 0.16.1+1.7.1 to 0.16.2+1.7.2 (#491) Bumps [libgit2-sys](https://github.com/rust-lang/git2-rs) from 0.16.1+1.7.1 to 0.16.2+1.7.2. - [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/git2-rs/commits) --- updated-dependencies: - dependency-name: libgit2-sys dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36385a0..10cf9e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,9 +698,9 @@ checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libgit2-sys" -version = "0.16.1+1.7.1" +version = "0.16.2+1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" dependencies = [ "cc", "libc", -- cgit v1.2.3 From 8d334cbe73ade11a0b48eea41971ab24644d43ab Mon Sep 17 00:00:00 2001 From: Ben Webb Date: Thu, 15 Feb 2024 12:12:12 -0500 Subject: feat lscolors support (#489) * feat lscolors support Adds support for styling entries using the LS_COLORS environment variable. This styling is gated behind a configuration variable. If its enabled, any other styling for entries based on theme configuration is ignored. * feat lscolors apply cargo fmt and clippy edits --- Cargo.lock | 19 +++++++++++++++++++ Cargo.toml | 1 + src/config/clean/theme/config.rs | 10 ++++++++++ src/config/raw/theme/config.rs | 2 ++ src/util/style.rs | 31 +++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 10cf9e8..c115364 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -632,6 +632,7 @@ dependencies = [ "globset", "lazy_static", "libc", + "lscolors", "nix 0.27.1", "notify", "open", @@ -763,6 +764,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "lscolors" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53304fff6ab1e597661eee37e42ea8c47a146fca280af902bb76bff8a896e523" +dependencies = [ + "nu-ansi-term", +] + [[package]] name = "memchr" version = "2.6.4" @@ -847,6 +857,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd2800e1520bdc966782168a627aa5d1ad92e33b984bf7c7615d31280c83ff14" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "num-traits" version = "0.2.17" diff --git a/Cargo.toml b/Cargo.toml index 9f1cdd6..bbacca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ filetime = "^0" globset = "^0" lazy_static = "^1" libc = "^0" +lscolors = { version = "0.17.0", features = ["nu-ansi-term"] } notify = "^6" open = "^5" phf = { version = "^0", features = ["macros"], optional = true } diff --git a/src/config/clean/theme/config.rs b/src/config/clean/theme/config.rs index 5be88fc..7fd25cd 100644 --- a/src/config/clean/theme/config.rs +++ b/src/config/clean/theme/config.rs @@ -1,3 +1,4 @@ +use lscolors::LsColors; use std::collections::HashMap; use crate::config::raw::theme::AppThemeRaw; @@ -20,6 +21,7 @@ pub struct AppTheme { pub link_invalid: AppStyle, pub socket: AppStyle, pub ext: HashMap, + pub lscolors: Option, } impl AppTheme { @@ -64,6 +66,13 @@ impl From for AppTheme { (k.clone(), style) }) .collect(); + let lscolors = if raw.lscolors_enabled { + let lscolors = LsColors::from_env(); + let default = Some(LsColors::default()); + lscolors.or(default) + } else { + None + }; Self { selection, @@ -76,6 +85,7 @@ impl From for AppTheme { socket, ext, tabs: TabTheme::from(tabs), + lscolors, } } } diff --git a/src/config/raw/theme/config.rs b/src/config/raw/theme/config.rs index 86ea538..cef58a5 100644 --- a/src/config/raw/theme/config.rs +++ b/src/config/raw/theme/config.rs @@ -26,4 +26,6 @@ pub struct AppThemeRaw { pub socket: AppStyleRaw, #[serde(default)] pub ext: HashMap, + #[serde(default)] + pub lscolors_enabled: bool, } diff --git a/src/util/style.rs b/src/util/style.rs index 96d111c..47ea9fd 100644 --- a/src/util/style.rs +++ b/src/util/style.rs @@ -1,4 +1,7 @@ +use ansi_to_tui::IntoText; +use lscolors::LsColors; use ratatui::style::Style; +use std::path::Path; use crate::fs::{FileType, JoshutoDirEntry, LinkType}; use crate::util::unix; @@ -23,6 +26,13 @@ impl PathStyleIfSome for Style { } pub fn entry_style(entry: &JoshutoDirEntry) -> Style { + match &THEME_T.lscolors { + Some(lscolors) => entry_lscolors_style(lscolors, entry), + None => entry_theme_style(entry), + } +} + +fn entry_theme_style(entry: &JoshutoDirEntry) -> Style { let metadata = &entry.metadata; let filetype = &metadata.file_type(); let linktype = &metadata.link_type(); @@ -84,3 +94,24 @@ fn file_style(entry: &JoshutoDirEntry) -> Style { .unwrap_or(regular_style) } } + +fn entry_lscolors_style(lscolors: &LsColors, entry: &JoshutoDirEntry) -> Style { + let path = &entry.file_path(); + let default = Style::default(); + lscolors_style(lscolors, path).unwrap_or(default) +} + +fn lscolors_style(lscolors: &LsColors, path: &Path) -> Option