diff options
author | Dan Davison <dandavison7@gmail.com> | 2020-06-10 21:20:08 -0400 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2020-06-10 21:58:20 -0400 |
commit | ea91be31180d48b6d19870d3a5470552f9606357 (patch) | |
tree | 0b881c1c23b7dcc04fe24e2ede7e4d296f46c8ec | |
parent | 11788656767aa6044ed71d212adf0dcde4c5e5d5 (diff) |
Refactor: Config::from_args
-rw-r--r-- | src/bat/output.rs | 12 | ||||
-rw-r--r-- | src/cli.rs | 107 | ||||
-rw-r--r-- | src/config.rs | 342 | ||||
-rw-r--r-- | src/gitconfig.rs | 23 | ||||
-rw-r--r-- | src/main.rs | 23 | ||||
-rw-r--r-- | src/rewrite.rs | 3 | ||||
-rw-r--r-- | src/style.rs | 2 | ||||
-rw-r--r-- | src/tests/integration_test_utils.rs | 5 |
8 files changed, 253 insertions, 264 deletions
diff --git a/src/bat/output.rs b/src/bat/output.rs index d1f9636f..efb3fafa 100644 --- a/src/bat/output.rs +++ b/src/bat/output.rs @@ -10,7 +10,7 @@ use shell_words; use super::less::retrieve_less_version; -use crate::config::Config; +use crate::config; use crate::env; #[derive(Debug, Clone, Copy, PartialEq)] @@ -28,7 +28,11 @@ pub enum OutputType { } impl OutputType { - pub fn from_mode(mode: PagingMode, pager: Option<&str>, config: &Config) -> Result<Self> { + pub fn from_mode( + mode: PagingMode, + pager: Option<&str>, + config: &config::Config, + ) -> Result<Self> { use self::PagingMode::*; Ok(match mode { Always => OutputType::try_pager(false, pager, config)?, @@ -41,7 +45,7 @@ impl OutputType { fn try_pager( quit_if_one_screen: bool, pager_from_config: Option<&str>, - config: &Config, + config: &config::Config, ) -> Result<Self> { let mut replace_arguments_to_less = false; @@ -121,7 +125,7 @@ impl OutputType { p }; if config.navigate { - process.args(&["--pattern", &config.make_navigate_regexp()]); + process.args(&["--pattern", &config::make_navigate_regexp(&config)]); } Ok(process .env("LESSANSIENDCHARS", "mK") @@ -1,16 +1,7 @@ use std::path::PathBuf; -use std::process; -use git2; use structopt::clap::AppSettings::{ColorAlways, ColoredHelp, DeriveDisplayOrder}; -use structopt::{clap, StructOpt}; - -use crate::bat::assets::HighlightingAssets; -use crate::bat::output::PagingMode; -use crate::config; -use crate::env; -use crate::rewrite; -use crate::syntax_theme; +use structopt::StructOpt; #[derive(StructOpt, Clone, Debug, PartialEq)] #[structopt( @@ -447,99 +438,3 @@ pub struct Opt { /// Deprecated: use --syntax-theme. pub deprecated_theme: Option<String>, } - -pub fn process_command_line_arguments<'a>( - arg_matches: clap::ArgMatches, - git_config: &mut Option<git2::Config>, -) -> config::Config<'a> { - let mut opt = Opt::from_clap(&arg_matches); - let assets = HighlightingAssets::new(); - - _check_validity(&opt, &assets); - - rewrite::apply_rewrite_rules(&mut opt, arg_matches, git_config); - - let paging_mode = match opt.paging_mode.as_ref() { - "always" => PagingMode::Always, - "never" => PagingMode::Never, - "auto" => PagingMode::QuitIfOneScreen, - _ => { - eprintln!( - "Invalid value for --paging option: {} (valid values are \"always\", \"never\", and \"auto\")", - opt.paging_mode - ); - process::exit(1); - } - }; - - let true_color = match opt.true_color.as_ref() { - "always" => true, - "never" => false, - "auto" => is_truecolor_terminal(), - _ => { - eprintln!( - "Invalid value for --24-bit-color option: {} (valid values are \"always\", \"never\", and \"auto\")", - opt.true_color - ); - process::exit(1); - } - }; - - config::get_config( - opt, - assets.syntax_set, - assets.theme_set, - true_color, - paging_mode, - ) -} - -/// Did the user supply `option` on the command line? -pub fn user_supplied_option(option: &str, arg_matches: &clap::ArgMatches) -> bool { - arg_matches.occurrences_of(option) > 0 -} - -fn _check_validity(opt: &Opt, assets: &HighlightingAssets) { - if opt.light && opt.dark { - eprintln!("--light and --dark cannot be used together."); - process::exit(1); - } - if let Some(ref syntax_theme) = opt.syntax_theme { - if !syntax_theme::is_no_syntax_highlighting_theme_name(&syntax_theme) { - if !assets.theme_set.themes.contains_key(syntax_theme.as_str()) { - return; - } - let is_light_syntax_theme = syntax_theme::is_light_theme(&syntax_theme); - if is_light_syntax_theme && opt.dark { - eprintln!( - "{} is a light syntax theme, but you supplied --dark. \ - If you use --syntax-theme, you do not need to supply --light or --dark.", - syntax_theme - ); - process::exit(1); - } else if !is_light_syntax_theme && opt.light { - eprintln!( - "{} is a dark syntax theme, but you supplied --light. \ - If you use --syntax-theme, you do not need to supply --light or --dark.", - syntax_theme - ); - process::exit(1); - } - } - } -} - -pub fn unreachable(message: &str) -> ! { - eprintln!( - "{} This should not be possible. \ - Please report the bug at https://github.com/dandavison/delta/issues.", - message - ); - process::exit(1); -} - -fn is_truecolor_terminal() -> bool { - env::get_env_var("COLORTERM") - .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit") - .unwrap_or(false) -} diff --git a/src/config.rs b/src/config.rs index 938ba7f5..61369c7f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,15 +3,19 @@ use std::path::PathBuf; use std::process; use console::Term; +use git2; +use structopt::{clap, StructOpt}; use syntect::highlighting::Style as SyntectStyle; -use syntect::highlighting::{Theme as SyntaxTheme, ThemeSet as SyntaxThemeSet}; +use syntect::highlighting::Theme as SyntaxTheme; use syntect::parsing::SyntaxSet; +use crate::bat::assets::HighlightingAssets; use crate::bat::output::PagingMode; -use crate::cli::{self, unreachable}; +use crate::cli; use crate::color; use crate::delta::State; use crate::env; +use crate::rewrite; use crate::style::Style; use crate::syntax_theme; @@ -68,6 +72,19 @@ pub struct Config<'a> { } impl<'a> Config<'a> { + pub fn from_args(args: &[&str], git_config: &mut Option<git2::Config>) -> Self { + Self::from_arg_matches(cli::Opt::clap().get_matches_from(args), git_config) + } + + pub fn from_arg_matches( + arg_matches: clap::ArgMatches, + git_config: &mut Option<git2::Config>, + ) -> Self { + let mut opt = cli::Opt::from_clap(&arg_matches); + rewrite::apply_rewrite_rules(&mut opt, arg_matches, git_config); + Self::from(opt) + } + pub fn get_style(&self, state: &State) -> &Style { match state { State::CommitMeta => &self.commit_style, @@ -76,140 +93,207 @@ impl<'a> Config<'a> { _ => unreachable("Unreachable code reached in get_style."), } } - - pub fn make_navigate_regexp(&self) -> String { - format!( - "^(commit|{}|{}|{}|{})", - self.file_modified_label, - self.file_added_label, - self.file_removed_label, - self.file_renamed_label - ) - } } -pub fn get_config<'a>( - opt: cli::Opt, - syntax_set: SyntaxSet, - syntax_theme_set: SyntaxThemeSet, - true_color: bool, - paging_mode: PagingMode, -) -> Config<'a> { - // Allow one character for e.g. `less --status-column` is in effect. See #41 and #10. - let available_terminal_width = (Term::stdout().size().1 - 1) as usize; - let (decorations_width, background_color_extends_to_terminal_width) = match opt.width.as_deref() - { - Some("variable") => (Width::Variable, false), - Some(width) => { - let width = width.parse().unwrap_or_else(|_| { - eprintln!("Could not parse width as a positive integer: {:?}", width); +fn _check_validity(opt: &cli::Opt, assets: &HighlightingAssets) { + if opt.light && opt.dark { + eprintln!("--light and --dark cannot be used together."); + process::exit(1); + } + if let Some(ref syntax_theme) = opt.syntax_theme { + if !syntax_theme::is_no_syntax_highlighting_theme_name(&syntax_theme) { + if !assets.theme_set.themes.contains_key(syntax_theme.as_str()) { + return; + } + let is_light_syntax_theme = syntax_theme::is_light_theme(&syntax_theme); + if is_light_syntax_theme && opt.dark { + eprintln!( + "{} is a light syntax theme, but you supplied --dark. \ + If you use --syntax-theme, you do not need to supply --light or --dark.", + syntax_theme + ); + process::exit(1); + } else if !is_light_syntax_theme && opt.light { + eprintln!( + "{} is a dark syntax theme, but you supplied --light. \ + If you use --syntax-theme, you do not need to supply --light or --dark.", + syntax_theme + ); process::exit(1); - }); - (Width::Fixed(min(width, available_terminal_width)), true) + } } - None => (Width::Fixed(available_terminal_width), true), - }; + } +} - let syntax_theme_name_from_bat_theme = env::get_env_var("BAT_THEME"); - let (is_light_mode, syntax_theme_name) = syntax_theme::get_is_light_mode_and_theme_name( - opt.syntax_theme.as_ref(), - syntax_theme_name_from_bat_theme.as_ref(), - opt.light, - &syntax_theme_set, +/// Did the user supply `option` on the command line? +pub fn user_supplied_option(option: &str, arg_matches: &clap::ArgMatches) -> bool { + arg_matches.occurrences_of(option) > 0 +} + +pub fn unreachable(message: &str) -> ! { + eprintln!( + "{} This should not be possible. \ + Please report the bug at https://github.com/dandavison/delta/issues.", + message ); + process::exit(1); +} - let ( - minus_style, - minus_emph_style, - minus_non_emph_style, - zero_style, - plus_style, - plus_emph_style, - plus_non_emph_style, - ) = make_hunk_styles(&opt, is_light_mode, true_color); +fn is_truecolor_terminal() -> bool { + env::get_env_var("COLORTERM") + .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit") + .unwrap_or(false) +} - let (commit_style, file_style, hunk_header_style) = - make_commit_file_hunk_header_styles(&opt, true_color); +impl<'a> From<cli::Opt> for Config<'a> { + fn from(opt: cli::Opt) -> Self { + let assets = HighlightingAssets::new(); - let ( - number_minus_format_style, - number_minus_style, - number_plus_format_style, - number_plus_style, - ) = make_line_number_styles( - &opt, - hunk_header_style.decoration_ansi_term_style(), - true_color, - ); + _check_validity(&opt, &assets); - let syntax_theme = if syntax_theme::is_no_syntax_highlighting_theme_name(&syntax_theme_name) { - None - } else { - Some(syntax_theme_set.themes[&syntax_theme_name].clone()) - }; - let syntax_dummy_theme = syntax_theme_set.themes.values().next().unwrap().clone(); + let paging_mode = match opt.paging_mode.as_ref() { + "always" => PagingMode::Always, + "never" => PagingMode::Never, + "auto" => PagingMode::QuitIfOneScreen, + _ => { + eprintln!( + "Invalid value for --paging option: {} (valid values are \"always\", \"never\", and \"auto\")", + opt.paging_mode + ); + process::exit(1); + } + }; - let minus_line_marker = if opt.keep_plus_minus_markers { - "-" - } else { - " " - }; - let plus_line_marker = if opt.keep_plus_minus_markers { - "+" - } else { - " " - }; + let true_color = match opt.true_color.as_ref() { + "always" => true, + "never" => false, + "auto" => is_truecolor_terminal(), + _ => { + eprintln!( + "Invalid value for --24-bit-color option: {} (valid values are \"always\", \"never\", and \"auto\")", + opt.true_color + ); + process::exit(1); + } + }; - let max_line_distance_for_naively_paired_lines = - env::get_env_var("DELTA_EXPERIMENTAL_MAX_LINE_DISTANCE_FOR_NAIVELY_PAIRED_LINES") - .map(|s| s.parse::<f64>().unwrap_or(0.0)) - .unwrap_or(0.0); - - Config { - background_color_extends_to_terminal_width, - commit_style, - decorations_width, - file_added_label: opt.file_added_label, - file_modified_label: opt.file_modified_label, - file_removed_label: opt.file_removed_label, - file_renamed_label: opt.file_renamed_label, - file_style, - hunk_header_style, - list_languages: opt.list_languages, - list_syntax_theme_names: opt.list_syntax_theme_names, - list_syntax_themes: opt.list_syntax_themes, - max_buffered_lines: 32, - max_line_distance: opt.max_line_distance, - max_line_distance_for_naively_paired_lines, - minus_emph_style, - minus_file: opt.minus_file.map(|s| s.clone()), - minus_line_marker, - minus_non_emph_style, - minus_style, - navigate: opt.navigate, - null_style: Style::new(), - null_syntect_style: SyntectStyle::default(), - number_minus_format: opt.number_minus_format, - number_minus_format_style: number_minus_format_style, - number_minus_style: number_minus_style, - number_plus_format: opt.number_plus_format, - number_plus_format_style: number_plus_format_style, - number_plus_style: number_plus_style, - paging_mode, - plus_emph_style, - plus_file: opt.plus_file.map(|s| s.clone()), - plus_line_marker, - plus_non_emph_style, - plus_style, - show_background_colors: opt.show_background_colors, - show_line_numbers: opt.show_line_numbers, - syntax_dummy_theme, - syntax_set, - syntax_theme, - syntax_theme_name, - tab_width: opt.tab_width, - true_color, - zero_style, + // Allow one character in case e.g. `less --status-column` is in effect. See #41 and #10. + let available_terminal_width = (Term::stdout().size().1 - 1) as usize; + let (decorations_width, background_color_extends_to_terminal_width) = + match opt.width.as_deref() { + Some("variable") => (Width::Variable, false), + Some(width) => { + let width = width.parse().unwrap_or_else(|_| { + eprintln!("Could not parse width as a positive integer: {:?}", width); + process::exit(1); + }); + (Width::Fixed(min(width, available_terminal_width)), true) + } + None => (Width::Fixed(available_terminal_width), true), + }; + + let syntax_theme_name_from_bat_theme = env::get_env_var("BAT_THEME"); + let (is_light_mode, syntax_theme_name) = syntax_theme::get_is_light_mode_and_theme_name( + opt.syntax_theme.as_ref(), + syntax_theme_name_from_bat_theme.as_ref(), + opt.light, + &assets.theme_set, + ); + + let ( + minus_style, + minus_emph_style, + minus_non_emph_style, + zero_style, + plus_style, + plus_emph_style, + plus_non_emph_style, + ) = make_hunk_styles(&opt, is_light_mode, true_color); + + let (commit_style, file_style, hunk_header_style) = + make_commit_file_hunk_header_styles(&opt, true_color); + + let ( + number_minus_format_style, + number_minus_style, + number_plus_format_style, + number_plus_style, + ) = make_line_number_styles( + &opt, + hunk_header_style.decoration_ansi_term_style(), + true_color, + ); + + let syntax_theme = if syntax_theme::is_no_syntax_highlighting_theme_name(&syntax_theme_name) + { + None + } else { + Some(assets.theme_set.themes[&syntax_theme_name].clone()) + }; + let syntax_dummy_theme = assets.theme_set.themes.values().next().unwrap().clone(); + + let minus_line_marker = if opt.keep_plus_minus_markers { + "-" + } else { + " " + }; + let plus_line_marker = if opt.keep_plus_minus_markers { + "+" + } else { + " " + }; + + let max_line_distance_for_naively_paired_lines = + env::get_env_var("DELTA_EXPERIMENTAL_MAX_LINE_DISTANCE_FOR_NAIVELY_PAIRED_LINES") + .map(|s| s.parse::<f64>().unwrap_or(0.0)) + .unwrap_or(0.0); + + Self { + background_color_extends_to_terminal_width, + commit_style, + decorations_width, + file_added_label: opt.file_added_label, + file_modified_label: opt.file_modified_label, + file_removed_label: opt.file_removed_label, + file_renamed_label: opt.file_renamed_label, + file_style, + hunk_header_style, + list_languages: opt.list_languages, + list_syntax_theme_names: opt.list_syntax_theme_names, + list_syntax_themes: opt.list_syntax_themes, + max_buffered_lines: 32, + max_line_distance: opt.max_line_distance, + max_line_distance_for_naively_paired_lines, + minus_emph_style, + minus_file: opt.minus_file.map(|s| s.clone()), + minus_line_marker, + minus_non_emph_style, + minus_style, + navigate: opt.navigate, + null_style: Style::new(), + null_syntect_style: SyntectStyle::default(), + number_minus_format: opt.number_minus_format, + number_minus_format_style, + number_minus_style, + number_plus_format: opt.number_plus_format, + number_plus_format_style, + number_plus_style, + paging_mode, + plus_emph_style, + plus_file: opt.plus_file.map(|s| s.clone()), + plus_line_marker, + plus_non_emph_style, + plus_style, + show_background_colors: opt.show_background_colors, + show_line_numbers: opt.show_line_numbers, + syntax_dummy_theme, + syntax_set: assets.syntax_set, + syntax_theme, + syntax_theme_name, + tab_width: opt.tab_width, + true_color, + zero_style, + } } } @@ -383,6 +467,16 @@ fn make_commit_file_hunk_header_styles(opt: &cli::Opt, true_color: bool) -> (Sty ) } +pub fn make_navigate_regexp(config: &Config) -> String { + format!( + "^(commit|{}|{}|{}|{})", + config.file_modified_label, + config.file_added_label, + config.file_removed_label, + config.file_renamed_label + ) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/gitconfig.rs b/src/gitconfig.rs index e6b27089..6d9cca12 100644 --- a/src/gitconfig.rs +++ b/src/gitconfig.rs @@ -13,7 +13,7 @@ mod set_options { ([$( ($opt_name:expr, $field_ident:ident, $keys:expr, $default:expr) ),* ], $opt:expr, $arg_matches:expr, $git_config:expr) => { $( - if !$crate::cli::user_supplied_option($opt_name, $arg_matches) { + if !$crate::config::user_supplied_option($opt_name, $arg_matches) { $opt.$field_ident = $crate::gitconfig::git_config_get::_string($keys, $git_config) .unwrap_or_else(|| $default.to_string()); @@ -26,7 +26,7 @@ mod set_options { ([$( ($opt_name:expr, $field_ident:ident, $keys:expr, $default:expr) ),* ], $opt:expr, $arg_matches:expr, $git_config:expr) => { $( - if !$crate::cli::user_supplied_option($opt_name, $arg_matches) { + if !$crate::config::user_supplied_option($opt_name, $arg_matches) { $opt.$field_ident = match ($crate::gitconfig::git_config_get::_string($keys, $git_config), $default) { (Some(s), _) => Some(s), (None, Some(default)) => Some(default.to_string()), @@ -41,7 +41,7 @@ mod set_options { ([$( ($opt_name:expr, $field_ident:ident, $keys:expr, $default:expr) ),* ], $opt:expr, $arg_matches:expr, $git_config:expr) => { $( - if !$crate::cli::user_supplied_option($opt_name, $arg_matches) { + if !$crate::config::user_supplied_option($opt_name, $arg_matches) { $opt.$field_ident = $crate::gitconfig::git_config_get::_bool($keys, $git_config) .unwrap_or_else(|| $default); @@ -54,7 +54,7 @@ mod set_options { ([$( ($opt_name:expr, $field_ident:ident, $keys:expr, $default:expr) ),* ], $opt:expr, $arg_matches:expr, $git_config:expr) => { $( - if !$crate::cli::user_supplied_option($opt_name, $arg_matches) { + if !$crate::config::user_supplied_option($opt_name, $arg_matches) { $opt.$field_ident = match $crate::gitconfig::git_config_get::_string($keys, $git_config) { Some(s) => s.parse::<f64>().unwrap_or($default), None => $default, @@ -68,7 +68,7 @@ mod set_options { ([$( ($opt_name:expr, $field_ident:ident, $keys:expr, $default:expr) ),* ], $opt:expr, $arg_matches:expr, $git_config:expr) => { $( - if !$crate::cli::user_supplied_option($opt_name, $arg_matches) { + if !$crate::config::user_supplied_option($opt_name, $arg_matches) { $opt.$field_ident = match $crate::gitconfig::git_config_get::_i64($keys, $git_config) { Some(int) => int as usize, None => $default, @@ -242,9 +242,7 @@ mod tests { use git2; use itertools; - use structopt::StructOpt; - use crate::cli; use crate::config; use crate::style::{DecorationStyle, Style}; @@ -423,17 +421,16 @@ mod tests { git_config_contents: Option<&[u8]>, path: Option<&str>, ) -> config::Config<'a> { - let args = itertools::chain( + let args: Vec<&str> = itertools::chain( &["/dev/null", "/dev/null", "--24-bit-color", "always"], args, - ); + ) + .map(|s| *s) + .collect(); let mut git_config = match (git_config_contents, path) { (Some(contents), Some(path)) => Some(make_git_config(contents, path)), _ => None, }; - cli::process_command_line_arguments( - cli::Opt::clap().get_matches_from(args), - &mut git_config, - ) + config::Config::from_args(&args, &mut git_config) } } diff --git a/src/main.rs b/src/main.rs index 8c48cddb..79a5376e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,8 +57,7 @@ fn main() -> std::io::Result<()> { Err(_) => None, }; - let config = - cli::process_command_line_arguments(cli::Opt::clap().get_matches(), &mut git_config); + let config = config::Config::from_arg_matches(cli::Opt::clap().get_matches(), &mut git_config); if atty::is(atty::Stream::Stdin) { return diff( @@ -191,15 +190,17 @@ index f38589a..0f1bb83 100644 } writeln!(stdout, "\n\nTheme: {}\n", style.paint(syntax_theme))?; - let arg_matches = cli::Opt::clap().get_matches_from(vec![ - "--syntax-theme", - syntax_theme, - "--file-style", - "omit", - "--hunk-header-style", - "omit", - ]); - let config = cli::process_command_line_arguments(arg_matches, &mut None); + let config = config::Config::from_args( + &[ + "--syntax-theme", + syntax_theme, + "--file-style", + "omit", + "--hunk-header-style", + "omit", + ], + &mut None, + ); let mut output_type = OutputType::from_mode(PagingMode::QuitIfOneScreen, None, &config).unwrap(); let mut writer = output_type.handle().unwrap(); diff --git a/src/rewrite.rs b/src/rewrite.rs index 57ce7d5d..aeb7b976 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -6,7 +6,8 @@ use std::process; use structopt::clap; -use crate::cli::{self, user_supplied_option}; +use crate::cli; +use crate::config::user_supplied_option; pub fn apply_rewrite_rules( opt: &mut cli::Opt, diff --git a/src/style.rs b/src/style.rs index e2b68d5d..6b11725f 100644 --- a/src/style.rs +++ b/src/style.rs @@ -3,8 +3,8 @@ use std::process; use ansi_term; use bitflags::bitflags; -use crate::cli::unreachable; use crate::color; +use crate::config::unreachable; #[derive(Clone, Copy, Debug, PartialEq)] pub struct Style { diff --git a/src/tests/integration_test_utils.rs b/src/tests/integration_test_utils.rs index cfbd8877..01f08a4f 100644 --- a/src/tests/integration_test_utils.rs +++ b/src/tests/integration_test_utils.rs @@ -4,9 +4,7 @@ pub mod integration_test_utils { use bytelines::ByteLines; use console::strip_ansi_codes; - use structopt::StructOpt; - use crate::cli; use crate::config; use crate::delta::delta; @@ -19,8 +17,7 @@ pub mod integration_test_utils { args.push(arg); } args.push("--no-gitconfig"); - let arg_matches = cli::Opt::clap().get_matches_from(args); - cli::process_command_line_arguments(arg_matches, &mut None) + config::Config::from_args(&args, &mut None) } pub fn get_line_of_code_from_delta<'a>( |