Skip to content

Commit

Permalink
Change bg color of whitespace-only hunks
Browse files Browse the repository at this point in the history
With the default color-words diff formatting, if a diff hunk (a
sequence of removed and/or added characters) consists only of whitespace
characters, it will not be visible on a terminal because the default
configuration only changes their foreground color (which has no effect
because all these characters are whitespace).

Therefore, change the background color of these diff hunks. The user
may further customize their appearance by configuring the "removed
whitespace" and "added whitespace" formats.
  • Loading branch information
jonathantanmy committed Jun 18, 2024
1 parent a6d470d commit 524f67e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* New command `jj branch move` let you update branches by name pattern or source
revision.

* In diffs, whitespace-only hunks are marked with a background color. (If a
hunk contains printable characters, it is displayed with a foreground color
as usual.)

### Fixed bugs

## [0.18.0] - 2024-06-05
Expand Down
2 changes: 2 additions & 0 deletions cli/src/config/colors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@
"diff file_header" = { bold = true }
"diff hunk_header" = "cyan"
"diff removed" = "red"
"diff removed whitespace" = { bg = "red" }
"diff added" = "green"
"diff added whitespace" = { bg = "green" }
"diff modified" = "cyan"
"diff access-denied" = { bg = "red" }

Expand Down
20 changes: 13 additions & 7 deletions cli/src/diff_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,13 +387,19 @@ fn show_color_words_diff_line(
formatter.write_all(data)?;
}
DiffHunk::Different(data) => {
let before = data[0];
let after = data[1];
if !before.is_empty() {
formatter.with_label("removed", |formatter| formatter.write_all(before))?;
}
if !after.is_empty() {
formatter.with_label("added", |formatter| formatter.write_all(after))?;
let labels = ["removed", "added"];
for (index, label) in labels.iter().enumerate() {
let hunk_part = data[index];
if !hunk_part.is_empty() {
formatter.with_label(label, |formatter| {
if hunk_part.iter().all(|byte| u8::is_ascii_whitespace(byte)) {
formatter
.with_label("whitespace", |formatter| formatter.write_all(hunk_part))
} else {
formatter.write_all(hunk_part)
}
})?;
}
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions cli/tests/test_diff_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,35 @@ fn test_diff_basic() {
insta::assert_snapshot!(stderr, @"");
}

#[test]
fn test_diff_whitespace_only_label() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let repo_path = test_env.env_root().join("repo");

std::fs::write(
repo_path.join("file"),
" first \n second \n third \nfourth\n",
)
.unwrap();
test_env.jj_cmd_ok(&repo_path, &["new"]);
std::fs::write(
repo_path.join("file"),
"first \n second \n third\n\nfifth\n",
)
.unwrap();

let stdout = test_env.jj_cmd_success(&repo_path, &["--color=debug", "diff"]);
insta::assert_snapshot!(stdout, @r###"
<<diff header::Modified regular file>><<diff header:: >><<diff header::file>><<diff header:::>>
<<diff removed:: >><<diff removed:: >><<diff removed:: >><<diff removed::1>><<diff:: >><<diff added:: >><<diff added:: >><<diff added:: >><<diff added::1>><<diff::: >><<diff removed whitespace:: >><<diff::first >>
<<diff removed:: >><<diff removed:: >><<diff removed:: >><<diff removed::2>><<diff:: >><<diff added:: >><<diff added:: >><<diff added:: >><<diff added::2>><<diff::: >><<diff:: >><<diff added whitespace:: >><<diff::second >><<diff added whitespace:: >><<diff::>>
<<diff removed:: >><<diff removed:: >><<diff removed:: >><<diff removed::3>><<diff:: >><<diff added:: >><<diff added:: >><<diff added:: >><<diff added::3>><<diff::: >><<diff:: third>><<diff removed whitespace:: >><<diff::>>
<<diff removed:: >><<diff removed:: >><<diff removed:: >><<diff removed::4>><<diff:: >><<diff added:: >><<diff added:: >><<diff added:: >><<diff added::4>><<diff::: >><<diff removed::fourth>><<diff::>>
<<diff:: >><<diff added:: >><<diff added:: >><<diff added:: >><<diff added::5>><<diff::: >><<diff added::fifth>>
"###);
}

#[test]
fn test_diff_empty() {
let test_env = TestEnvironment::default();
Expand Down

0 comments on commit 524f67e

Please sign in to comment.