Highlight direct code change (diff, vimdiff, meld)

94 Views Asked by At

In a diff the changes are marked in red and green per line. Is there a way to mark the text changes within the line?

That would be a comparison with diff:

diff \
    <(printf "same\nsame-colored changed-bold-colored same-colored\nsame") \
    <(printf "same\nsame-colored CHANGED-BOLD-COLORED same-colored\nsame") 

I would like an output like vimdiff or meld. Only very simple and output directly in the terminal.

Like this output for example:

red='\033[0;31m'; redDark='\033[7;31m'; green='\033[0;32m'; greenDark='\033[7;32m'; noColor='\033[0m'
printf "${red}same-colored ${redDark}changed-bold-colored${red} same-colored${noColor}\n"
printf "${green}same-colored ${greenDark}changed-bold-colored${green} same-colored${noColor}\n"

enter image description here

Is this possible without much effort?

1

There are 1 best solutions below

6
Ed Morton On BEST ANSWER

This doesn't produce the output you asked for but it's output may give you the information you need:

git diff -U0 --no-index --word-diff=color --word-diff-regex=. file1 file2

You do not need to be in a git repo to use that command.

Here's the same command run 3 times with the output displayed in different ways to make sure it can be seen here:

enter image description here

$ git diff -U0 --no-index --word-diff=color --word-diff-regex=. \
    <(printf "same\nsame-colored changed-bold-colored same-colored\nsame") \
    <(printf "same\nsame-colored CHANGED-BOLD-COLORED same-colored\nsame")
diff --git a/dev/fd/63 b/dev/fd/62
--- a/dev/fd/63
+++ b/dev/fd/62
@@ -2 +2 @@ same
same-colored changedCHANGED-boldBOLD-coloredCOLORED same-colored
$

$ git diff -U0 --no-index --word-diff=color --word-diff-regex=. \
    <(printf "same\nsame-colored changed-bold-colored same-colored\nsame") \
    <(printf "same\nsame-colored CHANGED-BOLD-COLORED same-colored\nsame") \
        | cat -A
^[[1mdiff --git a/dev/fd/63 b/dev/fd/62^[[m$
^[[1m--- a/dev/fd/63^[[m$
^[[1m+++ b/dev/fd/62^[[m$
^[[36m@@ -2 +2 @@^[[m ^[[msame^[[m$
same-colored ^[[31mchanged^[[m^[[32mCHANGED^[[m-^[[31mbold^[[m^[[32mBOLD^[[m-^[[31mcolored^[[m^[[32mCOLORED^[[m same-colored$
$

If you have the kind of problems using process substitution with git diff as described by the OP in comments below or like this:

$ git diff -U0 --no-index --word-diff=color --word-diff-regex=. \
    <(printf "same\nsame-colored changed-bold-colored same-colored\nsame") \
    <(printf "same\nsame-colored CHANGED-BOLD-COLORED same-colored\nsame" )
error: Could not access '/proc/2063/fd/63'

then you could write a command like this to ensure that git diff always gets regular files to operate on:

$ cat $HOME/bin/colordiff
#!/usr/bin/env bash

tmpDir=$(mktemp -d)  || exit 1
trap 'rm -rf "$tmpDir"; exit' EXIT

tmpFiles=()
for file; do
    tmpFile="$tmpDir/$file"
    mkdir -p -- "$tmpDir/${file%/*}"
    cp -- "$file" "$tmpFile"
    tmpFiles+=( "$tmpFile" )
done

git diff -U0 --no-index --word-diff=color --word-diff-regex=. "${tmpFiles[@]}"

which you'd then call as:

$ colordiff \
    <(printf "same\nsame-colored changed-bold-colored same-colored\nsame") \
    <(printf "same\nsame-colored CHANGED-BOLD-COLORED same-colored\nsame")
diff --git a/C:/Some/Path/Temp/tmp.E5Pv4qtlnH/dev/fd/63 b/C:/Some/Path/Temp/tmp.E5Pv4qtlnH/dev/fd/62
index 078906c..275fedd 100644
--- a/C:/Some/Path/Temp/tmp.E5Pv4qtlnH/dev/fd/63
+++ b/C:/Some/Path/Temp/tmp.E5Pv4qtlnH/dev/fd/62
@@ -2 +2 @@ same
same-colored changedCHANGED-boldBOLD-coloredCOLORED same-colored