Repository: dandavison/delta
Pull request #436 (2020-12-07 14:06:19)

Make file style to be colored with same structure while color_only #405
This pr changes below.

- Make file style to be colored with same structure while color_only

<img width="696" alt="ss 4" src="https://user-images.githubusercontent.com/41639488/101360009-67c92f80-38e0-11eb-8931-ac1b4a117153.png">

<img width="673" alt="ss 6" src="https://user-images.githubusercontent.com/41639488/101360897-9dbae380-38e1-11eb-9f8d-dc3acc364594.png">


I confirmed below apart from test.

- `git -c 'interactive.diffFilter="./target/release/delta" --color-only' add -p` still works.

Remarks.

- Related to #405 
- I still need to resolve `commit-style` and `hunk-header-style`.
- Already ready for pr of `commit-style` and `hunk-header-style`, but they depend on this pr.


dandavison: Great! Thanks for working on this @ulwlu.

> Already ready for pr of commit-style and hunk-header-style, but they depend on this pr.

You could open a second PR and use the PR target branch selector so that the second PR targets this branch. Unless I imagined it, I think GitHub is clever enough nowadays that the second one automatically switches to target master when the first merges.
ulwlu: @dandavison 
Sure!

> You could open a second PR and use the PR target branch selector so that the second PR targets this branch. Unless I imagined it

Right, but I was not sure if this approach will be changed, and need to fix 2nd branch entirely or fix conflict (and I don't want so).

> do you think you could add a failing test that demonstrates the problem that you are fixing?

Sure, just a minute.
ulwlu: @dandavison 

Add test here.
b48fa01

confirmed it's succeed now, and failed before the first commit.

Patch:
diff --git a/src/config.rs b/src/config.rs
index a8718c5..b2cd2ea 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -21,6 +21,7 @@ pub struct Config {
     pub available_terminal_width: usize,
     pub background_color_extends_to_terminal_width: bool,
     pub commit_style: Style,
+    pub color_only: bool,
     pub decorations_width: cli::Width,
     pub file_added_label: String,
     pub file_copied_label: String,
@@ -150,6 +151,7 @@ impl From<cli::Opt> for Config {
                 .computed
                 .background_color_extends_to_terminal_width,
             commit_style,
+            color_only: opt.color_only,
             decorations_width: opt.computed.decorations_width,
             file_added_label: opt.file_added_label,
             file_copied_label: opt.file_copied_label,
diff --git a/src/delta.rs b/src/delta.rs
index 94b7265..d772480 100644
--- a/src/delta.rs
+++ b/src/delta.rs
@@ -115,6 +115,10 @@ where
                     &minus_file,
                 ));
             }
+            if config.color_only {
+                handle_generic_file_meta_header_line(&mut painter, &line, &raw_line, config)?;
+                continue;
+            }
         } else if (state == State::FileMeta || source == Source::DiffUnified)
             && (line.starts_with("+++ ")
                 || line.starts_with("rename to ")
@@ -127,6 +131,10 @@ where
                 &plus_file,
             ));
             current_file_pair = Some((minus_file.clone(), plus_file.clone()));
+            if config.color_only {
+                handle_generic_file_meta_header_line(&mut painter, &line, &raw_line, config)?;
+                continue;
+            }
             if should_handle(&State::FileMeta, config)
                 && handled_file_meta_header_line_file_pair != current_file_pair
             {
@@ -181,7 +189,8 @@ where
             continue;
         }
 
-        if state == State::FileMeta && should_handle(&State::FileMeta, config) {
+        if state == State::FileMeta && should_handle(&State::FileMeta, config) && !config.color_only
+        {
             // The file metadata section is 4 lines. Skip them under non-plain file-styles.
             continue;
         } else {
@@ -318,7 +327,8 @@ fn handle_generic_file_meta_header_line(
     raw_line: &str,
     config: &Config,
 ) -> std::io::Result<()> {
-    if config.file_style.is_omitted {
+    // FIXME: this may be able to be refactored by moving to should_handle.
+    if config.file_style.is_omitted && !config.color_only {
         return Ok(());
     }
     let decoration_ansi_term_style;
@@ -361,7 +371,9 @@ fn handle_generic_file_meta_header_line(
             draw::write_no_decoration
         }
     };
-    writeln!(painter.writer)?;
+    if !config.color_only {
+        writeln!(painter.writer)?;
+    }
     draw_fn(
         painter.writer,
         &format!("{}{}", line, if pad { " " } else { "" }),
diff --git a/src/options/set.rs b/src/options/set.rs
index 1fc8b4d..eda89ad 100644
--- a/src/options/set.rs
+++ b/src/options/set.rs
@@ -190,13 +190,13 @@ pub fn set_options(
         compute_line_numbers_mode(opt, &builtin_features, git_config, &option_names);
     opt.computed.paging_mode = parse_paging_mode(&opt.paging_mode);
 
-    // --color-only is used for interactive.diffFilter (git add -p) and side-by-side cannot be used
-    // there (does not emit lines in 1-1 correspondence with raw git output). See #274.
+    // --color-only is used for interactive.diffFilter (git add -p). side-by-side, and
+    // **-decoration-style cannot be used there (does not emit lines in 1-1 correspondence with raw git output).
+    // See #274.
     if opt.color_only {
         opt.side_by_side = false;
         opt.file_decoration_style = "none".to_string();
         opt.commit_decoration_style = "none".to_string();
-        opt.file_style = "raw".to_string();
         opt.commit_style = "raw".to_string();
         opt.hunk_header_style = "raw".to_string();
         opt.hunk_header_decoration_style = "none".to_string();


Test patch:
diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs
index 6668acc..e9a265d 100644
--- a/src/tests/test_example_diffs.rs
+++ b/src/tests/test_example_diffs.rs
@@ -971,6 +971,24 @@ src/align.rs
         }
     }
 
+    #[test]
+    // TODO: commit-style and hunk-header-style are required to add.
+    fn test_file_style_with_color_only_has_style() {
+        let config =
+            integration_test_utils::make_config_from_args(&["--color-only", "--file-style", "red"]);
+        let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config);
+
+        ansi_test_utils::assert_line_has_style(&output, 8, "--- a/src/align.rs", "red", &config);
+        ansi_test_utils::assert_line_has_style(&output, 9, "+++ b/src/align.rs", "red", &config);
+        let output = strip_ansi_codes(&output);
+        assert!(output.contains(
+            "\
+--- a/src/align.rs
++++ b/src/align.rs
+"
+        ));
+    }
+
     #[test]
     fn test_hunk_header_style_colored_input_color_is_stripped_under_normal() {
         let config = integration_test_utils::make_config_from_args(&[