Repository: dandavison/delta
Pull request #696 (2021-08-21 01:30:31)

Refactoring for #693


Patch:
diff --git a/src/cli.rs b/src/cli.rs
index 70ecd09..c711673 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -13,7 +13,7 @@ use crate::bat_utils::output::PagingMode;
 use crate::git_config::{GitConfig, GitConfigEntry};
 use crate::options;
 
-#[derive(StructOpt, Clone, Default)]
+#[derive(StructOpt, Default)]
 #[structopt(
     name = "delta",
     about = "A viewer for git and diff output",
@@ -490,6 +490,10 @@ pub struct Opt {
     /// Text to display in front of a renamed file path.
     pub file_renamed_label: String,
 
+    #[structopt(long = "hunk-label", default_value = "")]
+    /// Text to display in front of a hunk header.
+    pub hunk_label: String,
+
     #[structopt(long = "max-line-length", default_value = "512")]
     /// Truncate lines longer than this. To prevent any truncation, set to zero. Note that
     /// syntax-highlighting very long lines (e.g. minified .js) will be very slow if they are not
@@ -674,13 +678,13 @@ impl Default for PagingMode {
 
 impl Opt {
     pub fn from_args_and_git_config(
-        git_config: &mut Option<GitConfig>,
+        git_config: Option<GitConfig>,
         assets: HighlightingAssets,
     ) -> Self {
         Self::from_clap_and_git_config(Self::clap().get_matches(), git_config, assets)
     }
 
-    pub fn from_iter_and_git_config<I>(iter: I, git_config: &mut Option<GitConfig>) -> Self
+    pub fn from_iter_and_git_config<I>(iter: I, git_config: Option<GitConfig>) -> Self
     where
         I: IntoIterator,
         I::Item: Into<OsString> + Clone,
@@ -691,12 +695,12 @@ impl Opt {
 
     fn from_clap_and_git_config(
         arg_matches: clap::ArgMatches,
-        git_config: &mut Option<GitConfig>,
+        mut git_config: Option<GitConfig>,
         assets: HighlightingAssets,
     ) -> Self {
         let mut opt = Opt::from_clap(&arg_matches);
         options::rewrite::apply_rewrite_rules(&mut opt, &arg_matches);
-        options::set::set_options(&mut opt, git_config, &arg_matches, assets);
+        options::set::set_options(&mut opt, &mut git_config, &arg_matches, assets);
         opt
     }
 
diff --git a/src/config.rs b/src/config.rs
index 9dfea5d..1972fa4 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -33,6 +33,7 @@ pub struct Config {
     pub file_modified_label: String,
     pub file_removed_label: String,
     pub file_renamed_label: String,
+    pub hunk_label: String,
     pub file_style: Style,
     pub git_config_entries: HashMap<String, GitConfigEntry>,
     pub hunk_header_file_style: Style,
@@ -178,6 +179,7 @@ impl From<cli::Opt> for Config {
         let file_modified_label = opt.file_modified_label;
         let file_removed_label = opt.file_removed_label;
         let file_renamed_label = opt.file_renamed_label;
+        let hunk_label = opt.hunk_label;
 
         let navigate_regexp = if opt.navigate || opt.show_themes {
             Some(navigate::make_navigate_regexp(
@@ -186,6 +188,7 @@ impl From<cli::Opt> for Config {
                 &file_added_label,
                 &file_removed_label,
                 &file_renamed_label,
+                &hunk_label,
             ))
         } else {
             None
@@ -208,6 +211,7 @@ impl From<cli::Opt> for Config {
             file_modified_label,
             file_removed_label,
             file_renamed_label,
+            hunk_label,
             file_style,
             git_config_entries: opt.git_config_entries,
             hunk_header_file_style,
diff --git a/src/features/mod.rs b/src/features/mod.rs
index 1fe2091..8b169fc 100644
--- a/src/features/mod.rs
+++ b/src/features/mod.rs
@@ -102,7 +102,7 @@ pub mod tests {
         let builtin_features = make_builtin_features();
         let mut args = vec!["delta".to_string()];
         args.extend(builtin_features.keys().map(|s| format!("--{}", s)));
-        let opt = cli::Opt::from_iter_and_git_config(args, &mut None);
+        let opt = cli::Opt::from_iter_and_git_config(args, None);
         let features: HashSet<&str> = opt.features.split_whitespace().collect();
         for feature in builtin_features.keys() {
             assert!(features.contains(feature.as_str()))
diff --git a/src/features/navigate.rs b/src/features/navigate.rs
index 4e1e062..09cfc47 100644
--- a/src/features/navigate.rs
+++ b/src/features/navigate.rs
@@ -19,6 +19,12 @@ pub fn make_feature() -> Vec<(String, OptionValueFunction)> {
             String,
             None,
             _opt => "Δ"
+        ),
+        (
+            "hunk-label",
+            String,
+            None,
+            _opt => "δ"
         )
     ])
 }
@@ -30,13 +36,18 @@ pub fn make_navigate_regexp(
     file_added_label: &str,
     file_removed_label: &str,
     file_renamed_label: &str,
+    hunk_label: &str,
 ) -> String {
     if show_themes {
         "^Theme:".to_string()
     } else {
         format!(
-            "^(commit|{}|{}|{}|{})",
-            file_modified_label, file_added_label, file_removed_label, file_renamed_label,
+            "^(commit|{}|{}|{}|{}|{})",
+            regex::escape(file_added_label),
+            regex::escape(file_removed_label),
+            regex::escape(file_renamed_label),
+            regex::escape(file_modified_label),
+            regex::escape(hunk_label),
         )
     }
 }
diff --git a/src/hunk_header.rs b/src/hunk_header.rs
index 0889f41..3a19252 100644
--- a/src/hunk_header.rs
+++ b/src/hunk_header.rs
@@ -94,10 +94,10 @@ fn get_painted_file_with_line_number(
     config: &Config,
 ) -> String {
     let mut file_with_line_number = Vec::new();
-    let modified_label;
+    let hunk_label;
     if config.navigate {
-        modified_label = format!("{} ", config.file_modified_label);
-        file_with_line_number.push(config.hunk_header_file_style.paint(&modified_label));
+        hunk_label = format!("{} ", config.hunk_label);
+        file_with_line_number.push(config.hunk_header_file_style.paint(&hunk_label));
     }
     let plus_line_number = line_numbers[line_numbers.len() - 1].0;
     if config.hunk_header_style_include_file_path {
diff --git a/src/main.rs b/src/main.rs
index 1b77808..3fb223e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -58,7 +58,7 @@ pub mod errors {
 // arguments and without standard input; 2 is used to report a real problem.
 fn run_app() -> std::io::Result<i32> {
     let assets = HighlightingAssets::new();
-    let opt = cli::Opt::from_args_and_git_config(&mut git_config::GitConfig::try_create(), assets);
+    let opt = cli::Opt::from_args_and_git_config(git_config::GitConfig::try_create(), assets);
 
     if opt.list_languages {
         list_languages()?;
@@ -351,19 +351,17 @@ fn show_themes(dark: bool, light: bool, computed_theme_is_light: bool) -> std::i
         }
     };
 
-    let mut git_config = git_config::GitConfig::try_create();
-    let opt = cli::Opt::from_iter_and_git_config(
-        &["", "", "--navigate", "--show-themes"],
-        &mut git_config,
-    );
+    let git_config = git_config::GitConfig::try_create();
+    let opt =
+        cli::Opt::from_iter_and_git_config(&["", "", "--navigate", "--show-themes"], git_config);
     let mut output_type =
         OutputType::from_mode(PagingMode::Always, None, &config::Config::from(opt)).unwrap();
     let title_style = ansi_term::Style::new().bold();
     let writer = output_type.handle().unwrap();
 
     for theme in &get_themes(git_config::GitConfig::try_create()) {
-        let opt =
-            cli::Opt::from_iter_and_git_config(&["", "", "--features", theme], &mut git_config);
+        let git_config = git_config::GitConfig::try_create();
+        let opt = cli::Opt::from_iter_and_git_config(&["", "", "--features", theme], git_config);
         let is_dark_theme = opt.dark;
         let is_light_theme = opt.light;
         let config = config::Config::from(opt);
@@ -389,7 +387,6 @@ fn show_themes(dark: bool, light: bool, computed_theme_is_light: bool) -> std::i
 
 #[cfg(not(tarpaulin_include))]
 fn show_syntax_themes() -> std::io::Result<()> {
-    let mut opt = cli::Opt::from_args();
     let assets = HighlightingAssets::new();
     let mut output_type = OutputType::from_mode(
         PagingMode::QuitIfOneScreen,
@@ -398,7 +395,6 @@ fn show_syntax_themes() -> std::io::Result<()> {
     )
     .unwrap();
     let mut writer = output_type.handle().unwrap();
-    opt.computed.syntax_set = assets.syntax_set;
 
     let stdin_data = if !atty::is(atty::Stream::Stdin) {
         let mut buf = Vec::new();
@@ -412,9 +408,16 @@ fn show_syntax_themes() -> std::io::Result<()> {
         None
     };
 
+    let make_opt = || {
+        let mut opt = cli::Opt::from_args();
+        opt.computed.syntax_set = assets.syntax_set.clone();
+        opt
+    };
+    let opt = make_opt();
+
     if !(opt.dark || opt.light) {
-        _show_syntax_themes(opt.clone(), false, &mut writer, stdin_data.as_ref())?;
-        _show_syntax_themes(opt, true, &mut writer, stdin_data.as_ref())?;
+        _show_syntax_themes(opt, false, &mut writer, stdin_data.as_ref())?;
+        _show_syntax_themes(make_opt(), true, &mut writer, stdin_data.as_ref())?;
     } else if opt.light {
         _show_syntax_themes(opt, true, &mut writer, stdin_data.as_ref())?;
     } else {
diff --git a/src/options/set.rs b/src/options/set.rs
index cf17e2b..4fc0a1f 100644
--- a/src/options/set.rs
+++ b/src/options/set.rs
@@ -132,6 +132,7 @@ pub fn set_options(
             file_modified_label,
             file_removed_label,
             file_renamed_label,
+            hunk_label,
             file_style,
             hunk_header_decoration_style,
             hunk_header_file_style,


Test patch:
diff --git a/src/tests/integration_test_utils.rs b/src/tests/integration_test_utils.rs
index 7cab6f8..bdb2851 100644
--- a/src/tests/integration_test_utils.rs
+++ b/src/tests/integration_test_utils.rs
@@ -38,14 +38,14 @@ fn _make_options_from_args_and_git_config(
     let mut args: Vec<&str> = itertools::chain(&["/dev/null", "/dev/null"], args)
         .map(|s| *s)
         .collect();
-    let mut git_config = match (git_config_contents, git_config_path) {
+    let git_config = match (git_config_contents, git_config_path) {
         (Some(contents), Some(path)) => Some(make_git_config(contents, path, honor_env_var)),
         _ => {
             args.push("--no-gitconfig");
             None
         }
     };
-    cli::Opt::from_iter_and_git_config(args, &mut git_config)
+    cli::Opt::from_iter_and_git_config(args, git_config)
 }
 
 pub fn make_options_from_args(args: &[&str]) -> cli::Opt {