From 8275b0436d9501614f29b831b164687b3bc281c0 Mon Sep 17 00:00:00 2001 From: sharkdp Date: Sun, 7 Oct 2018 23:22:42 +0200 Subject: [PATCH] Add simple configuration file This allows users to create simple configuration file (`~/.config/bat/config` on Linux) that has the following format: ```bash --flag1 --flag2 --option1=value1 # lines beginning with '#' are ignored --option2=value2 # empty lines and trailing whitespace are also ignored --option3=value3 ``` --- src/app.rs | 22 ++++++++++++++++- src/assets.rs | 5 ---- src/clap_app.rs | 2 ++ src/config.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ src/dirs.rs | 6 +++++ src/main.rs | 2 ++ 6 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 src/config.rs create mode 100644 src/dirs.rs diff --git a/src/app.rs b/src/app.rs index 91a87975..19f489a4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -14,6 +14,7 @@ use console::Term; use ansi_term; use assets::BAT_THEME_DEFAULT; +use config::get_args_from_config_file; use errors::*; use inputfile::InputFile; use line_range::LineRange; @@ -97,7 +98,26 @@ impl App { } fn matches(interactive_output: bool) -> ArgMatches<'static> { - clap_app::build_app(interactive_output).get_matches_from(wild::args()) + let args = if wild::args_os().nth(1) == Some("cache".into()) { + // Skip the arguments in bats config file + + wild::args_os().collect::>() + } else { + let mut cli_args = wild::args_os(); + + // Read arguments from bats config file + let mut args = get_args_from_config_file(); + + // Put the zero-th CLI argument (program name) first + args.insert(0, cli_args.next().unwrap()); + + // .. and the rest at the end + cli_args.for_each(|a| args.push(a)); + + args + }; + + clap_app::build_app(interactive_output).get_matches_from(args) } pub fn config(&self) -> Result { diff --git a/src/assets.rs b/src/assets.rs index be4fe3ef..f6b47091 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -13,11 +13,6 @@ use directories::ProjectDirs; use errors::*; use inputfile::{InputFile, InputFileReader}; -lazy_static! { - static ref PROJECT_DIRS: ProjectDirs = - ProjectDirs::from("", "", crate_name!()).expect("Could not get home directory"); -} - pub const BAT_THEME_DEFAULT: &str = "Monokai Extended"; pub struct HighlightingAssets { diff --git a/src/clap_app.rs b/src/clap_app.rs index ab1881db..f98ff1ac 100644 --- a/src/clap_app.rs +++ b/src/clap_app.rs @@ -84,6 +84,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> { .value_name("style-components") .use_delimiter(true) .takes_value(true) + .overrides_with("style") .possible_values(&[ "auto", "full", "plain", "changes", "header", "grid", "numbers", ]) @@ -207,6 +208,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> { .arg( Arg::with_name("tabs") .long("tabs") + .overrides_with("tabs") .takes_value(true) .value_name("T") .validator( diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 00000000..673bd46e --- /dev/null +++ b/src/config.rs @@ -0,0 +1,65 @@ +use std::ffi::OsString; +use std::fs; + +use dirs::PROJECT_DIRS; + +pub fn get_args_from_config_file() -> Vec { + let config_file = PROJECT_DIRS.config_dir().join("config"); + fs::read_to_string(config_file) + .map(|content| get_args_from_str(&content)) + .unwrap_or(vec![]) +} + +fn get_args_from_str<'a>(content: &'a str) -> Vec { + content + .split('\n') + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .filter(|line| !line.starts_with("#")) + .map(|line| line.into()) + .collect() +} + +#[test] +fn empty() { + let args = get_args_from_str(""); + println!("{:?}", args); + assert!(args.is_empty()); +} + +#[test] +fn single() { + assert_eq!(vec!["--plain"], get_args_from_str("--plain")); +} + +#[test] +fn multiple() { + let config = " + -p + --style numbers,changes + + --color=always + "; + assert_eq!( + vec!["-p", "--style numbers,changes", "--color=always"], + get_args_from_str(config) + ); +} + +#[test] +fn comments() { + let config = " + # plain style + -p + + # show line numbers and Git modifications + --style numbers,changes + + # Always show ANSI colors + --color=always + "; + assert_eq!( + vec!["-p", "--style numbers,changes", "--color=always"], + get_args_from_str(config) + ); +} diff --git a/src/dirs.rs b/src/dirs.rs new file mode 100644 index 00000000..3335dec7 --- /dev/null +++ b/src/dirs.rs @@ -0,0 +1,6 @@ +use directories::ProjectDirs; + +lazy_static! { + pub static ref PROJECT_DIRS: ProjectDirs = + ProjectDirs::from("", "", crate_name!()).expect("Could not get home directory"); +} diff --git a/src/main.rs b/src/main.rs index 00d7339e..2391e6e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,9 +23,11 @@ extern crate wild; mod app; mod assets; mod clap_app; +mod config; mod controller; mod decorations; mod diff; +mod dirs; mod inputfile; mod line_range; mod output;