# [PATCH v4' 2/2] gitk: add the equivalent of diff --color-words

4 messages from 2010-04-19 to 2010-04-20. Participants: Thomas Rast, Jens Lehmann.
Thread: https://gitlist.dev/t/23528

## Thomas Rast, 2010-04-19 16:27

Subject: [PATCH v4' 1/2] gitk: do not parse " >" context as submodule change
Message-ID: <671110fcac73c5fc8a935b82d88f8553c510c50c.1271694102.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/671110fcac73c5fc8a935b82d88f8553c510c50c.1271694102.git.trast%40student.ethz.ch
In-Reply-To: <20100419010819.GA4386@brick.ozlabs.ibm.com>

```
Since 5c838d2 (gitk: Use the --submodule option for displaying diffs
when available, 2009-10-28) gitk erroneously matches "  >" and "  <"
at the beginning of a line in the submodule code even if we're in the
diff text section and the lines should be treated as context.

Fix by (ab)using the $diffinhdr variable also in the 'Submodule...'
case, and move the "  >"/"  <" specific code inside the $diffinhdr
test.  The existing code will set $diffinhdr to 0 when it hits a
"+++", so that it is always 0 when we can hit a context line.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

> Thanks, but now that I have applied Jens Lehmann's patch that also
> touches this area, your patch doesn't apply.  Could you rebase it and
> send it again?

Sure.


 gitk |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/gitk b/gitk
index 1b0e09a..6513ef8 100755
--- a/gitk
+++ b/gitk
@@ -7706,14 +7706,8 @@ proc getblobdiffline {bdf ids} {
 	    } else {
 		$ctext insert end "$line\n" filesep
 	    }
-	} elseif {![string compare -length 3 "  >" $line]} {
-	    set $currdiffsubmod ""
-	    set line [encoding convertfrom $diffencoding $line]
-	    $ctext insert end "$line\n" dresult
-	} elseif {![string compare -length 3 "  <" $line]} {
-	    set $currdiffsubmod ""
-	    set line [encoding convertfrom $diffencoding $line]
-	    $ctext insert end "$line\n" d0
+	    # pretend we're in a file header to correctly parse "  [><]"
+	    set diffinhdr 1
 	} elseif {$diffinhdr} {
 	    if {![string compare -length 12 "rename from " $line]} {
 		set fname [string range $line [expr 6 + [string first " from " $line] ] end]
@@ -7732,6 +7726,14 @@ proc getblobdiffline {bdf ids} {
 		    set fname [lindex $fname 0]
 		}
 		makediffhdr $fname $ids
+	    } elseif {![string compare -length 3 "  >" $line]} {
+		set line [encoding convertfrom $diffencoding $line]
+		$ctext insert end "$line\n" dresult
+		continue
+	    } elseif {![string compare -length 3 "  <" $line]} {
+		set line [encoding convertfrom $diffencoding $line]
+		$ctext insert end "$line\n" d0
+		continue
 	    } elseif {[string compare -length 3 $line "---"] == 0} {
 		# do nothing
 		continue
-- 
1.7.1.rc1.284.g4b2e3

```

## Thomas Rast, 2010-04-19 16:27

Subject: [PATCH v4' 2/2] gitk: add the equivalent of diff --color-words
Message-ID: <34692bfb072d02aaa0dea01515fa89d4a1f175b8.1271694102.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/34692bfb072d02aaa0dea01515fa89d4a1f175b8.1271694102.git.trast%40student.ethz.ch
In-Reply-To: <671110fcac73c5fc8a935b82d88f8553c510c50c.1271694102.git.trast@student.ethz.ch>

```
Use the newly added 'diff --word-diff=porcelain' to teach gitk a
color-words mode, with two different modes analogous to the
--word-diff=plain and --word-diff=color settings.  These are selected
by a dropdown box.

As an extra twist, automatically enable this word-diff support when
the user mentions a word-diff related option on the command line.
These options were previously ignored because they would break diff
parsing.

Both of these features are only enabled if we have a version of git
that supports --word-diff=porcelain, tentatively set to 1.7.2.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 gitk |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/gitk b/gitk
index 6513ef8..46d1b0e 100755
--- a/gitk
+++ b/gitk
@@ -131,6 +131,7 @@ proc unmerged_files {files} {
 
 proc parseviewargs {n arglist} {
     global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env
+    global worddiff git_version
 
     set vdatemode($n) 0
     set vmergeonly($n) 0
@@ -168,7 +169,7 @@ proc parseviewargs {n arglist} {
 		lappend diffargs $arg
 	    }
 	    "--raw" - "--patch-with-raw" - "--patch-with-stat" -
-	    "--name-only" - "--name-status" - "--color" - "--color-words" -
+	    "--name-only" - "--name-status" - "--color" -
 	    "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
 	    "--cc" - "-z" - "--header" - "--parents" - "--boundary" -
 	    "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
@@ -177,6 +178,18 @@ proc parseviewargs {n arglist} {
 		# These cause our parsing of git log's output to fail, or else
 		# they're options we want to set ourselves, so ignore them.
 	    }
+	    "--color-words*" - "--word-diff=color" {
+		# These trigger a word diff in the console interface,
+		# so help the user by enabling our own support
+		if {[package vcompare $git_version "1.7.2"] >= 0} {
+		    set worddiff [mc "Color words"]
+		}
+	    }
+	    "--word-diff*" {
+		if {[package vcompare $git_version "1.7.2"] >= 0} {
+		    set worddiff [mc "Markup words"]
+		}
+	    }
 	    "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
 	    "--check" - "--exit-code" - "--quiet" - "--topo-order" -
 	    "--full-history" - "--dense" - "--sparse" -
@@ -1970,6 +1983,8 @@ proc makewindow {} {
     global fprogitem fprogcoord lastprogupdate progupdatepending
     global rprogitem rprogcoord rownumsel numcommits
     global have_tk85 use_ttk NS
+    global git_version
+    global worddiff
 
     # The "mc" arguments here are purely so that xgettext
     # sees the following string as needing to be translated
@@ -2243,6 +2258,15 @@ proc makewindow {} {
     ${NS}::checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
 	-command changeignorespace -variable ignorespace
     pack .bleft.mid.ignspace -side left -padx 5
+
+    set worddiff [mc "Line diff"]
+    if {[package vcompare $git_version "1.7.2"] >= 0} {
+	makedroplist .bleft.mid.worddiff worddiff [mc "Line diff"] \
+	    [mc "Markup words"] [mc "Color words"]
+	trace add variable worddiff write changeworddiff
+	pack .bleft.mid.worddiff -side left -padx 5
+    }
+
     set ctext .bleft.bottom.ctext
     text $ctext -background $bgcolor -foreground $fgcolor \
 	-state disabled -font textfont \
@@ -7502,11 +7526,16 @@ proc changeignorespace {} {
     reselectline
 }
 
+proc changeworddiff {name ix op} {
+    reselectline
+}
+
 proc getblobdiffs {ids} {
     global blobdifffd diffids env
     global diffinhdr treediffs
     global diffcontext
     global ignorespace
+    global worddiff
     global limitdiffs vfilelimit curview
     global diffencoding targetline diffnparents
     global git_version currdiffsubmod
@@ -7523,6 +7552,9 @@ proc getblobdiffs {ids} {
     if {$ignorespace} {
 	append cmd " -w"
     }
+    if {$worddiff ne [mc "Line diff"]} {
+	append cmd " --word-diff=porcelain"
+    }
     if {$limitdiffs && $vfilelimit($curview) ne {}} {
 	set cmd [concat $cmd -- $vfilelimit($curview)]
     }
@@ -7608,6 +7640,7 @@ proc getblobdiffline {bdf ids} {
     global ctext_file_names ctext_file_lines
     global diffinhdr treediffs mergemax diffnparents
     global diffencoding jump_to_here targetline diffline currdiffsubmod
+    global worddiff
 
     set nr 0
     $ctext conf -state normal
@@ -7749,15 +7782,28 @@ proc getblobdiffline {bdf ids} {
 	    # parse the prefix - one ' ', '-' or '+' for each parent
 	    set prefix [string range $line 0 [expr {$diffnparents - 1}]]
 	    set tag [expr {$diffnparents > 1? "m": "d"}]
+	    set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
+	    set words_pre_markup ""
+	    set words_post_markup ""
 	    if {[string trim $prefix " -+"] eq {}} {
 		# prefix only has " ", "-" and "+" in it: normal diff line
 		set num [string first "-" $prefix]
+		if {$dowords} {
+		    set line [string range $line 1 end]
+		}
 		if {$num >= 0} {
 		    # removed line, first parent with line is $num
 		    if {$num >= $mergemax} {
 			set num "max"
 		    }
-		    $ctext insert end "$line\n" $tag$num
+		    if {$dowords && $worddiff eq [mc "Markup words"]} {
+			$ctext insert end "\[-$line-\]" $tag$num
+		    } else {
+			$ctext insert end "$line" $tag$num
+		    }
+		    if {!$dowords} {
+			$ctext insert end "\n" $tag$num
+		    }
 		} else {
 		    set tags {}
 		    if {[string first "+" $prefix] >= 0} {
@@ -7772,6 +7818,8 @@ proc getblobdiffline {bdf ids} {
 				lappend tags m$num
 			    }
 			}
+			set words_pre_markup "{+"
+			set words_post_markup "+}"
 		    }
 		    if {$targetline ne {}} {
 			if {$diffline == $targetline} {
@@ -7781,8 +7829,17 @@ proc getblobdiffline {bdf ids} {
 			    incr diffline
 			}
 		    }
-		    $ctext insert end "$line\n" $tags
+		    if {$dowords && $worddiff eq [mc "Markup words"]} {
+			$ctext insert end "$words_pre_markup$line$words_post_markup" $tags
+		    } else {
+			$ctext insert end "$line" $tags
+		    }
+		    if {!$dowords} {
+			$ctext insert end "\n" $tags
+		    }
 		}
+	    } elseif {$dowords && $prefix eq "~"} {
+		$ctext insert end "\n" {}
 	    } else {
 		# "\ No newline at end of file",
 		# or something else we don't recognize
@@ -11393,6 +11450,7 @@ if {[tk windowingsystem] eq "win32"} {
 set diffcolors {red "#00a000" blue}
 set diffcontext 3
 set ignorespace 0
+set worddiff ""
 set markbgcolor "#e0e0ff"
 
 set circlecolors {white blue gray blue blue}
-- 
1.7.1.rc1.284.g4b2e3

```

## Jens Lehmann, 2010-04-19 17:22

Subject: Re: [PATCH v4' 1/2] gitk: do not parse " >" context as submodule change
Message-ID: <4BCC9164.3080301@web.de>
URL: https://gitlist.dev/e/4BCC9164.3080301%40web.de
In-Reply-To: <671110fcac73c5fc8a935b82d88f8553c510c50c.1271694102.git.trast@student.ethz.ch>

```
Am 19.04.2010 18:27, schrieb Thomas Rast:
>> Thanks, but now that I have applied Jens Lehmann's patch that also
>> touches this area, your patch doesn't apply.  Could you rebase it and
>> send it again?
> 
> Sure.

There might be a problem with this rebase. Unfortunately I am very
short on time, so I can't test this today.

I think setting the $currdiffsubmod variable to the empty string
has to show up in the two sections formatting the lines with
"  >" & "  <".


>  gitk |   18 ++++++++++--------
>  1 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/gitk b/gitk
> index 1b0e09a..6513ef8 100755
> --- a/gitk
> +++ b/gitk
> @@ -7706,14 +7706,8 @@ proc getblobdiffline {bdf ids} {
>  	    } else {
>  		$ctext insert end "$line\n" filesep
>  	    }
> -	} elseif {![string compare -length 3 "  >" $line]} {
> -	    set $currdiffsubmod ""
> -	    set line [encoding convertfrom $diffencoding $line]
> -	    $ctext insert end "$line\n" dresult
> -	} elseif {![string compare -length 3 "  <" $line]} {
> -	    set $currdiffsubmod ""
> -	    set line [encoding convertfrom $diffencoding $line]
> -	    $ctext insert end "$line\n" d0
> +	    # pretend we're in a file header to correctly parse "  [><]"
> +	    set diffinhdr 1
>  	} elseif {$diffinhdr} {
>  	    if {![string compare -length 12 "rename from " $line]} {
>  		set fname [string range $line [expr 6 + [string first " from " $line] ] end]
> @@ -7732,6 +7726,14 @@ proc getblobdiffline {bdf ids} {
>  		    set fname [lindex $fname 0]
>  		}
>  		makediffhdr $fname $ids
> +	    } elseif {![string compare -length 3 "  >" $line]} {

I suspect we need a 'set $currdiffsubmod ""' here

> +		set line [encoding convertfrom $diffencoding $line]
> +		$ctext insert end "$line\n" dresult
> +		continue
> +	    } elseif {![string compare -length 3 "  <" $line]} {

and here.

> +		set line [encoding convertfrom $diffencoding $line]
> +		$ctext insert end "$line\n" d0
> +		continue
>  	    } elseif {[string compare -length 3 $line "---"] == 0} {
>  		# do nothing
>  		continue

If you can wait until tomorrow I can check that.

```

## Jens Lehmann, 2010-04-20 17:05

Subject: Re: [PATCH v4' 1/2] gitk: do not parse " >" context as submodule change
Message-ID: <4BCDDEDC.7040507@web.de>
URL: https://gitlist.dev/e/4BCDDEDC.7040507%40web.de
In-Reply-To: <4BCC9164.3080301@web.de>

```
Am 19.04.2010 19:22, schrieb Jens Lehmann:
> Am 19.04.2010 18:27, schrieb Thomas Rast:
>>> Thanks, but now that I have applied Jens Lehmann's patch that also
>>> touches this area, your patch doesn't apply.  Could you rebase it and
>>> send it again?
>>
>> Sure.
> 
> There might be a problem with this rebase. Unfortunately I am very
> short on time, so I can't test this today.

I successfully tested this patch, this was a false alarm from my side.
Sorry for the noise.

Tested-by: Jens.Lehmann@web.de

```
