+proc getblobdiffs {id} {
+ global parents diffopts blobdifffd env curdifftag curtagstart
+ set p [lindex $parents($id) 0]
+ set env(GIT_DIFF_OPTS) $diffopts
+ if [catch {set bdf [open "|git-diff-tree -r -p $p $id" r]} err] {
+ puts "error getting diffs: $err"
+ return
+ }
+ fconfigure $bdf -blocking 0
+ set blobdifffd($id) $bdf
+ set curdifftag Comments
+ set curtagstart 0.0
+ fileevent $bdf readable "getblobdiffline $bdf $id"
+}
+
+proc getblobdiffline {bdf id} {
+ global currentid blobdifffd ctext curdifftag curtagstart
+ set n [gets $bdf line]
+ if {$n < 0} {
+ if {[eof $bdf]} {
+ close $bdf
+ if {$id == $currentid && $bdf == $blobdifffd($id)} {
+ $ctext tag add $curdifftag $curtagstart end
+ }
+ }
+ return
+ }
+ if {$id != $currentid || $bdf != $blobdifffd($id)} {
+ return
+ }
+ $ctext conf -state normal
+ if {[regexp {^---[ \t]+([^/])+/(.*)} $line match s1 fname]} {
+ # start of a new file
+ $ctext insert end "\n"
+ $ctext tag add $curdifftag $curtagstart end
+ set curtagstart [$ctext index "end - 1c"]
+ set curdifftag "f:$fname"
+ $ctext tag delete $curdifftag
+ set l [expr {(78 - [string length $fname]) / 2}]
+ set pad [string range "----------------------------------------" 1 $l]
+ $ctext insert end "$pad $fname $pad\n" filesep
+ } elseif {[string range $line 0 2] == "+++"} {
+ # no need to do anything with this
+ } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
+ $line match f1l f1c f2l f2c rest]} {
+ $ctext insert end "\t" hunksep
+ $ctext insert end " $f1l " d0 " $f2l " d1
+ $ctext insert end " $rest \n" hunksep
+ } else {
+ set x [string range $line 0 0]
+ if {$x == "-" || $x == "+"} {
+ set tag [expr {$x == "+"}]
+ set line [string range $line 1 end]
+ $ctext insert end "$line\n" d$tag
+ } elseif {$x == " "} {
+ set line [string range $line 1 end]
+ $ctext insert end "$line\n"
+ } else {
+ # Something else we don't recognize
+ if {$curdifftag != "Comments"} {
+ $ctext insert end "\n"
+ $ctext tag add $curdifftag $curtagstart end
+ set curtagstart [$ctext index "end - 1c"]
+ set curdifftag Comments
+ }
+ $ctext insert end "$line\n" filesep
+ }
+ }
+ $ctext conf -state disabled
+}
+
+proc listboxsel {} {
+ global ctext cflist currentid treediffs
+ set sel [$cflist curselection]
+ if {$sel == {} || [lsearch -exact $sel 0] >= 0} {
+ # show everything
+ $ctext tag conf Comments -elide 0
+ foreach f $treediffs($currentid) {
+ $ctext tag conf "f:$f" -elide 0
+ }
+ } else {
+ # just show selected files
+ $ctext tag conf Comments -elide 1
+ set i 1
+ foreach f $treediffs($currentid) {
+ set elide [expr {[lsearch -exact $sel $i] < 0}]
+ $ctext tag conf "f:$f" -elide $elide
+ incr i
+ }
+ }