summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsushi-shi <47691267+sushi-shi@users.noreply.github.com>2024-02-13 22:00:19 +0000
committerGitHub <noreply@github.com>2024-02-13 17:00:19 -0500
commit96418c064ef617f62618a1baee518a823915955b (patch)
treeb1c3eafc17ab784668c45f896d7672b4e21e31ea
parent203bd8977b56218d3972de007d403a3fdf9d95f7 (diff)
Add command for printing embedded configs (#487)
* Add command for printing embedded configs * Typo * Use doccomments instead of procmacro * Typo
-rw-r--r--config/joshuto.toml2
-rw-r--r--config/theme.toml2
-rw-r--r--src/commands/bookmark.rs13
-rw-r--r--src/config/clean/app/config.rs9
-rw-r--r--src/config/clean/app/mod.rs4
-rw-r--r--src/config/clean/bookmarks.rs10
-rw-r--r--src/config/clean/icon/config.rs8
-rw-r--r--src/config/clean/icon/mod.rs5
-rw-r--r--src/config/clean/keymap/config.rs8
-rw-r--r--src/config/clean/keymap/mod.rs4
-rw-r--r--src/config/clean/mimetype/config.rs10
-rw-r--r--src/config/clean/preview/config.rs8
-rw-r--r--src/config/clean/theme/config.rs8
-rw-r--r--src/config/clean/theme/mod.rs4
-rw-r--r--src/config/config_type.rs75
-rw-r--r--src/config/mod.rs33
-rw-r--r--src/error/error_type.rs10
-rw-r--r--src/main.rs55
18 files changed, 185 insertions, 83 deletions
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<path::PathBuf> {
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::<AppConfigRaw, AppConfig>(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<Event, String>;
impl TomlConfigFile for Bookmarks {
- fn get_config(file_name: &str) -> Self {
- parse_config_or_default::<BookmarksRaw, Bookmarks>(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::<IconsRaw, Icons>(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<AppKeyMappingRaw> for AppKeyMapping {
}
impl TomlConfigFile for AppKeyMapping {
- fn get_config(file_name: &str) -> Self {
- parse_config_or_default::<AppKeyMappingRaw, AppKeyMapping>(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<AppProgramRegistryRaw> for AppProgramRegistry {
}
impl TomlConfigFile for AppProgramRegistry {
- fn get_config(file_name: &str) -> Self {
- parse_config_or_default::<AppProgramRegistryRaw, AppProgramRegistry>(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::<FileEntryPreviewRaw, FileEntryPreview>(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::<AppThemeRaw, AppTheme>(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<clap::builder::PossibleValue> {
+ 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<Self> + DeserializeOwned;
+
+ fn get_type() -> config_type::ConfigType;
+
+ fn get_config() -> Self {
+ parse_config_or_default::<Self::Raw, Self>(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<P>(file_name: &str, directories: &[P]) -> Option<PathB
where
P: AsRef<Path>,
{
- 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<PathBuf> {
@@ -32,18 +38,17 @@ pub fn search_config_directories(file_name: &str) -> Option<PathBuf> {
fn parse_file_to_config<T, S>(file_path: &Path) -> AppResult<S>
where
- T: DeserializeOwned,
- S: From<T>,
+ T: DeserializeOwned + Into<S>,
{
let file_contents = fs::read_to_string(file_path)?;
let config = toml::from_str::<T>(&file_contents)?;
- Ok(S::from(config))
+ Ok(config.into())
}
pub fn parse_config_or_default<T, S>(file_name: &str) -> S
where
- T: DeserializeOwned,
- S: From<T> + std::default::Default,
+ T: DeserializeOwned + Into<S>,
+ S: std::default::Default,
{
match search_config_directories(file_name) {
Some(file_path) => match parse_file_to_config::<T, S>(&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<T>(cause: impl ToString) -> Result<T, AppError> {
+ 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<PathBuf> = {
@@ -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<Bookmarks> = 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<Bookmarks> = Mutex::new(Bookmarks::get_config());
+ static ref ICONS_T: Icons = Icons::get_config();
static ref HOME_DIR: Option<PathBuf> = 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<i32, AppError> {
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<i32, AppError> {
}
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);