Code

gitk: New algorithm for drawing the graph lines
authorPaul Mackerras <paulus@samba.org>
Sun, 15 Oct 2006 08:03:46 +0000 (18:03 +1000)
committerPaul Mackerras <paulus@samba.org>
Sat, 23 Jun 2007 10:55:57 +0000 (20:55 +1000)
This only draws as much of the graph lines as is visible.  This can
happen by adding coordinates on to an existing graph line or by
creating a new line.  This means that we only need to have laid out
and optimized as much of the graph as is actually visible in order to
draw it, including the lines (previously we didn't draw a graph
line until we had laid out and optimized to the end of a segment of
the line, i.e. down to a down-arrow or to the row where the line's
commit is displayed).  This also lets us get rid of the linesegends
list, and gives us an easy workaround for the X server bug that
causes long lines to be misdrawn.  This also gets rid of the use
of rowoffsets in drawlineseg et al.

Signed-off-by: Paul Mackerras <paulus@samba.org>
gitk

diff --git a/gitk b/gitk
index 023205a3b141e5961d17ba1f5fd04f09de13cbdf..21eefc40a8d11758a4b1233fb04ec4eea8a0e02b 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -1750,7 +1750,7 @@ proc showview {n} {
     global selectedline currentid canv canvy0
     global matchinglines treediffs
     global pending_select phase
-    global commitidx rowlaidout rowoptim linesegends
+    global commitidx rowlaidout rowoptim
     global commfd
     global selectedview selectfirst
     global vparentlist vchildlist vdisporder vcmitlisted
@@ -1786,7 +1786,7 @@ proc showview {n} {
            set viewdata($curview) \
                [list $phase $rowidlist $rowoffsets $rowrangelist \
                     [flatten idrowranges] [flatten idinlist] \
-                    $rowlaidout $rowoptim $numcommits $linesegends]
+                    $rowlaidout $rowoptim $numcommits]
        } elseif {![info exists viewdata($curview)]
                  || [lindex $viewdata($curview) 0] ne {}} {
            set viewdata($curview) \
@@ -1832,7 +1832,6 @@ proc showview {n} {
        set rowlaidout [lindex $v 6]
        set rowoptim [lindex $v 7]
        set numcommits [lindex $v 8]
-       set linesegends [lindex $v 9]
     }
 
     catch {unset colormap}
@@ -2506,7 +2505,7 @@ proc initlayout {} {
     global nextcolor
     global parentlist childlist children
     global colormap rowtextx
-    global linesegends selectfirst
+    global selectfirst
 
     set numcommits 0
     set displayorder {}
@@ -2525,7 +2524,6 @@ proc initlayout {} {
     catch {unset colormap}
     catch {unset rowtextx}
     catch {unset idrowranges}
-    set linesegends {}
     set selectfirst 1
 }
 
@@ -2608,8 +2606,7 @@ proc layoutmore {tmax allread} {
 }
 
 proc showstuff {canshow} {
-    global numcommits commitrow pending_select selectedline
-    global linesegends idrangedrawn curview
+    global numcommits commitrow pending_select selectedline curview
     global displayorder selectfirst
 
     if {$numcommits == 0} {
@@ -2617,33 +2614,16 @@ proc showstuff {canshow} {
        set phase "incrdraw"
        allcanvs delete all
     }
-    set row $numcommits
+    set r0 $numcommits
     set numcommits $canshow
     setcanvscroll
     set rows [visiblerows]
-    set r0 [lindex $rows 0]
     set r1 [lindex $rows 1]
-    set selrow -1
-    for {set r $row} {$r < $canshow} {incr r} {
-       foreach id [lindex $linesegends [expr {$r+1}]] {
-           set i -1
-           set ranges [rowranges $id]
-           foreach {s e} $ranges {
-               incr i
-               if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
-                   && ![info exists idrangedrawn($id,$i)]} {
-                   drawlineseg $id $i $ranges
-                   set idrangedrawn($id,$i) 1
-               }
-           }
-       }
+    if {$r1 >= $canshow} {
+       set r1 [expr {$canshow - 1}]
     }
-    if {$canshow > $r1} {
-       set canshow $r1
-    }
-    while {$row < $canshow} {
-       drawcmitrow $row
-       incr row
+    if {$r0 <= $r1} {
+       drawcommits $r0 $r1
     }
     if {[info exists pending_select] &&
        [info exists commitrow($curview,$pending_select)] &&
@@ -2664,7 +2644,7 @@ proc layoutrows {row endrow last} {
     global rowidlist rowoffsets displayorder
     global uparrowlen downarrowlen maxwidth mingaplen
     global childlist parentlist
-    global idrowranges linesegends
+    global idrowranges
     global commitidx curview
     global idinlist rowchk rowrangelist
 
@@ -2681,7 +2661,6 @@ proc layoutrows {row endrow last} {
                lappend oldolds $p
            }
        }
-       set lse {}
        set nev [expr {[llength $idlist] + [llength $newolds]
                       + [llength $oldolds] - $maxwidth + 1}]
        if {$nev > 0} {
@@ -2698,7 +2677,6 @@ proc layoutrows {row endrow last} {
                        set offs [incrange $offs $x 1]
                        set idinlist($i) 0
                        set rm1 [expr {$row - 1}]
-                       lappend lse $i
                        lappend idrowranges($i) [lindex $displayorder $rm1]
                        if {[incr nev -1] <= 0} break
                        continue
@@ -2709,7 +2687,6 @@ proc layoutrows {row endrow last} {
            lset rowidlist $row $idlist
            lset rowoffsets $row $offs
        }
-       lappend linesegends $lse
        set col [lsearch -exact $idlist $id]
        if {$col < 0} {
            set col [llength $idlist]
@@ -3004,95 +2981,206 @@ proc rowranges {id} {
     return $linenos
 }
 
-proc drawlineseg {id i ranges} {
-    global rowoffsets rowidlist
-    global displayorder
-    global canv colormap linespc
-    global numcommits commitrow curview
+# work around tk8.4 refusal to draw arrows on diagonal segments
+proc adjarrowhigh {coords} {
+    global linespc
 
-    set downarrow 1
-    if {[info exists commitrow($curview,$id)]
-       && $commitrow($curview,$id) < $numcommits} {
-       set downarrow [expr {$i < [llength $ranges] / 2 - 1}]
-    } else {
-       set downarrow 1
-    }
-    set startrow [lindex $ranges [expr {2 * $i}]]
-    set row [lindex $ranges [expr {2 * $i + 1}]]
-    if {$startrow == $row} return
-    assigncolor $id
-    set coords {}
-    set col [lsearch -exact [lindex $rowidlist $row] $id]
-    if {$col < 0} {
-       puts "oops: drawline: id $id not on row $row"
-       return
+    set x0 [lindex $coords 0]
+    set x1 [lindex $coords 2]
+    if {$x0 != $x1} {
+       set y0 [lindex $coords 1]
+       set y1 [lindex $coords 3]
+       if {$y0 - $y1 <= 2 * $linespc && $x1 == [lindex $coords 4]} {
+           # we have a nearby vertical segment, just trim off the diag bit
+           set coords [lrange $coords 2 end]
+       } else {
+           set slope [expr {($x0 - $x1) / ($y0 - $y1)}]
+           set xi [expr {$x0 - $slope * $linespc / 2}]
+           set yi [expr {$y0 - $linespc / 2}]
+           set coords [lreplace $coords 0 1 $xi $y0 $xi $yi]
+       }
     }
-    set lasto {}
-    set ns 0
+    return $coords
+}
+
+proc drawlineseg {id row endrow arrowlow} {
+    global rowidlist displayorder iddrawn linesegs
+    global canv colormap linespc curview maxlinelen
+
+    set cols [list [lsearch -exact [lindex $rowidlist $row] $id]]
+    set le [expr {$row + 1}]
+    set arrowhigh 1
     while {1} {
-       set o [lindex $rowoffsets $row $col]
-       if {$o eq {}} break
-       if {$o ne $lasto} {
-           # changing direction
-           set x [xc $row $col]
-           set y [yc $row]
-           lappend coords $x $y
-           set lasto $o
+       set c [lsearch -exact [lindex $rowidlist $le] $id]
+       if {$c < 0} {
+           incr le -1
+           break
+       }
+       lappend cols $c
+       set x [lindex $displayorder $le]
+       if {$x eq $id} {
+           set arrowhigh 0
+           break
        }
-       incr col $o
-       incr row -1
+       if {[info exists iddrawn($x)] || $le == $endrow} {
+           set c [lsearch -exact [lindex $rowidlist [expr {$le+1}]] $id]
+           if {$c >= 0} {
+               lappend cols $c
+               set arrowhigh 0
+           }
+           break
+       }
+       incr le
     }
-    set x [xc $row $col]
-    set y [yc $row]
-    lappend coords $x $y
-    if {$i == 0} {
-       # draw the link to the first child as part of this line
-       incr row -1
-       set child [lindex $displayorder $row]
-       set ccol [lsearch -exact [lindex $rowidlist $row] $child]
-       if {$ccol >= 0} {
-           set x [xc $row $ccol]
-           set y [yc $row]
-           if {$ccol < $col - 1} {
-               lappend coords [xc $row [expr {$col - 1}]] [yc $row]
-           } elseif {$ccol > $col + 1} {
-               lappend coords [xc $row [expr {$col + 1}]] [yc $row]
+    if {$le <= $row} {
+       return $row
+    }
+
+    set lines {}
+    set i 0
+    set joinhigh 0
+    if {[info exists linesegs($id)]} {
+       set lines $linesegs($id)
+       foreach li $lines {
+           set r0 [lindex $li 0]
+           if {$r0 > $row} {
+               if {$r0 == $le && [lindex $li 1] - $row <= $maxlinelen} {
+                   set joinhigh 1
+               }
+               break
+           }
+           incr i
+       }
+    }
+    set joinlow 0
+    if {$i > 0} {
+       set li [lindex $lines [expr {$i-1}]]
+       set r1 [lindex $li 1]
+       if {$r1 == $row && $le - [lindex $li 0] <= $maxlinelen} {
+           set joinlow 1
+       }
+    }
+
+    set x [lindex $cols [expr {$le - $row}]]
+    set xp [lindex $cols [expr {$le - 1 - $row}]]
+    set dir [expr {$xp - $x}]
+    if {$joinhigh} {
+       set ith [lindex $lines $i 2]
+       set coords [$canv coords $ith]
+       set ah [$canv itemcget $ith -arrow]
+       set arrowhigh [expr {$ah eq "first" || $ah eq "both"}]
+       set x2 [lindex $cols [expr {$le + 1 - $row}]]
+       if {$x2 ne {} && $x - $x2 == $dir} {
+           set coords [lrange $coords 0 end-2]
+       }
+    } else {
+       set coords [list [xc $le $x] [yc $le]]
+    }
+    if {$joinlow} {
+       set itl [lindex $lines [expr {$i-1}] 2]
+       set al [$canv itemcget $itl -arrow]
+       set arrowlow [expr {$al eq "last" || $al eq "both"}]
+    } elseif {$arrowlow &&
+             [lsearch -exact [lindex $rowidlist [expr {$row-1}]] $id] >= 0} {
+       set arrowlow 0
+    }
+    set arrow [lindex {none first last both} [expr {$arrowhigh + 2*$arrowlow}]]
+    for {set y $le} {[incr y -1] > $row} {} {
+       set x $xp
+       set xp [lindex $cols [expr {$y - 1 - $row}]]
+       set ndir [expr {$xp - $x}]
+       if {$dir != $ndir || $xp < 0} {
+           lappend coords [xc $y $x] [yc $y]
+       }
+       set dir $ndir
+    }
+    if {!$joinlow} {
+       if {$xp < 0} {
+           # join parent line to first child
+           set ch [lindex $displayorder $row]
+           set xc [lsearch -exact [lindex $rowidlist $row] $ch]
+           if {$xc < 0} {
+               puts "oops: drawlineseg: child $ch not on row $row"
+           } else {
+               if {$xc < $x - 1} {
+                   lappend coords [xc $row [expr {$x-1}]] [yc $row]
+               } elseif {$xc > $x + 1} {
+                   lappend coords [xc $row [expr {$x+1}]] [yc $row]
+               }
+               set x $xc
            }
-           lappend coords $x $y
-       }
-    }
-    if {[llength $coords] < 4} return
-    if {$downarrow} {
-       # This line has an arrow at the lower end: check if the arrow is
-       # on a diagonal segment, and if so, work around the Tk 8.4
-       # refusal to draw arrows on diagonal lines.
-       set x0 [lindex $coords 0]
-       set x1 [lindex $coords 2]
-       if {$x0 != $x1} {
-           set y0 [lindex $coords 1]
-           set y1 [lindex $coords 3]
-           if {$y0 - $y1 <= 2 * $linespc && $x1 == [lindex $coords 4]} {
-               # we have a nearby vertical segment, just trim off the diag bit
-               set coords [lrange $coords 2 end]
+           lappend coords [xc $row $x] [yc $row]
+       } else {
+           set xn [xc $row $xp]
+           set yn [yc $row]
+           # work around tk8.4 refusal to draw arrows on diagonal segments
+           if {$arrowlow && $xn != [lindex $coords end-1]} {
+               if {[llength $coords] < 4 ||
+                   [lindex $coords end-3] != [lindex $coords end-1] ||
+                   [lindex $coords end] - $yn > 2 * $linespc} {
+                   set xn [xc $row [expr {$xp - 0.5 * $dir}]]
+                   set yo [yc [expr {$row + 0.5}]]
+                   lappend coords $xn $yo $xn $yn
+               }
            } else {
-               set slope [expr {($x0 - $x1) / ($y0 - $y1)}]
-               set xi [expr {$x0 - $slope * $linespc / 2}]
-               set yi [expr {$y0 - $linespc / 2}]
-               set coords [lreplace $coords 0 1 $xi $y0 $xi $yi]
+               lappend coords $xn $yn
+           }
+       }
+       if {!$joinhigh} {
+           if {$arrowhigh} {
+               set coords [adjarrowhigh $coords]
+           }
+           assigncolor $id
+           set t [$canv create line $coords -width [linewidth $id] \
+                      -fill $colormap($id) -tags lines.$id -arrow $arrow]
+           $canv lower $t
+           bindline $t $id
+           set lines [linsert $lines $i [list $row $le $t]]
+       } else {
+           $canv coords $ith $coords
+           if {$arrow ne $ah} {
+               $canv itemconf $ith -arrow $arrow
+           }
+           lset lines $i 0 $row
+       }
+    } else {
+       set xo [lsearch -exact [lindex $rowidlist [expr {$row - 1}]] $id]
+       set ndir [expr {$xo - $xp}]
+       set clow [$canv coords $itl]
+       if {$dir == $ndir} {
+           set clow [lrange $clow 2 end]
+       }
+       set coords [concat $coords $clow]
+       if {!$joinhigh} {
+           lset lines [expr {$i-1}] 1 $le
+           if {$arrowhigh} {
+               set coords [adjarrowhigh $coords]
            }
+       } else {
+           # coalesce two pieces
+           $canv delete $ith
+           set b [lindex $lines [expr {$i-1}] 0]
+           set e [lindex $lines $i 1]
+           set lines [lreplace $lines [expr {$i-1}] $i [list $b $e $itl]]
+       }
+       $canv coords $itl $coords
+       if {$arrow ne $al} {
+           $canv itemconf $itl -arrow $arrow
        }
     }
-    set arrow [expr {2 * ($i > 0) + $downarrow}]
-    set arrow [lindex {none first last both} $arrow]
-    set t [$canv create line $coords -width [linewidth $id] \
-              -fill $colormap($id) -tags lines.$id -arrow $arrow]
-    $canv lower $t
-    bindline $t $id
+
+    set linesegs($id) $lines
+    return $le
 }
 
-proc drawparentlinks {id row col olds} {
-    global rowidlist canv colormap
+proc drawparentlinks {id row} {
+    global rowidlist canv colormap curview parentlist
+    global idpos
 
+    set rowids [lindex $rowidlist $row]
+    set col [lsearch -exact $rowids $id]
+    if {$col < 0} return
+    set olds [lindex $parentlist $row]
     set row2 [expr {$row + 1}]
     set x [xc $row $col]
     set y [yc $row]
@@ -3110,9 +3198,7 @@ proc drawparentlinks {id row col olds} {
        if {$x2 > $rmx} {
            set rmx $x2
        }
-       set ranges [rowranges $p]
-       if {$ranges ne {} && $row2 == [lindex $ranges 0]
-           && $row2 < [lindex $ranges 1]} {
+       if {[lsearch -exact $rowids $p] < 0} {
            # drawlineseg will do this one for us
            continue
        }
@@ -3130,36 +3216,21 @@ proc drawparentlinks {id row col olds} {
        $canv lower $t
        bindline $t $p
     }
-    return $rmx
+    if {$rmx > [lindex $idpos($id) 1]} {
+       lset idpos($id) 1 $rmx
+       redrawtags $id
+    }
 }
 
 proc drawlines {id} {
-    global colormap canv
-    global idrangedrawn
-    global children iddrawn commitrow rowidlist curview
+    global canv
 
-    $canv delete lines.$id
-    set ranges [rowranges $id]
-    set nr [expr {[llength $ranges] / 2}]
-    for {set i 0} {$i < $nr} {incr i} {
-       if {[info exists idrangedrawn($id,$i)]} {
-           drawlineseg $id $i $ranges
-       }
-    }
-    foreach child $children($curview,$id) {
-       if {[info exists iddrawn($child)]} {
-           set row $commitrow($curview,$child)
-           set col [lsearch -exact [lindex $rowidlist $row] $child]
-           if {$col >= 0} {
-               drawparentlinks $child $row $col [list $id]
-           }
-       }
-    }
+    $canv itemconf lines.$id -width [linewidth $id]
 }
 
-proc drawcmittext {id row col rmx} {
+proc drawcmittext {id row col} {
     global linespc canv canv2 canv3 canvy0 fgcolor
-    global commitlisted commitinfo rowidlist
+    global commitlisted commitinfo rowidlist parentlist
     global rowtextx idpos idtags idheads idotherrefs
     global linehtag linentag linedtag
     global mainfont canvxmax boldrows boldnamerows fgcolor
@@ -3173,10 +3244,18 @@ proc drawcmittext {id row col rmx} {
               -fill $ofill -outline $fgcolor -width 1 -tags circle]
     $canv raise $t
     $canv bind $t <1> {selcanvline {} %x %y}
-    set xt [xc $row [llength [lindex $rowidlist $row]]]
-    if {$xt < $rmx} {
-       set xt $rmx
+    set rmx [llength [lindex $rowidlist $row]]
+    set olds [lindex $parentlist $row]
+    if {$olds ne {}} {
+       set nextids [lindex $rowidlist [expr {$row + 1}]]
+       foreach p $olds {
+           set i [lsearch -exact $nextids $p]
+           if {$i > $rmx} {
+               set rmx $i
+           }
+       }
     }
+    set xt [xc $row $rmx]
     set rowtextx($row) $xt
     set idpos($id) [list $x $xt $y]
     if {[info exists idtags($id)] || [info exists idheads($id)]
@@ -3214,30 +3293,13 @@ proc drawcmittext {id row col rmx} {
 
 proc drawcmitrow {row} {
     global displayorder rowidlist
-    global idrangedrawn iddrawn
+    global iddrawn
     global commitinfo parentlist numcommits
     global filehighlight fhighlights findstring nhighlights
     global hlview vhighlights
     global highlight_related rhighlights
 
     if {$row >= $numcommits} return
-    foreach id [lindex $rowidlist $row] {
-       if {$id eq {}} continue
-       set i -1
-       set ranges [rowranges $id]
-       foreach {s e} $ranges {
-           incr i
-           if {$row < $s} continue
-           if {$e eq {}} break
-           if {$row <= $e} {
-               if {$e < $numcommits && ![info exists idrangedrawn($id,$i)]} {
-                   drawlineseg $id $i $ranges
-                   set idrangedrawn($id,$i) 1
-               }
-               break
-           }
-       }
-    }
 
     set id [lindex $displayorder $row]
     if {[info exists hlview] && ![info exists vhighlights($row)]} {
@@ -3262,49 +3324,99 @@ proc drawcmitrow {row} {
        getcommit $id
     }
     assigncolor $id
-    set olds [lindex $parentlist $row]
-    if {$olds ne {}} {
-       set rmx [drawparentlinks $id $row $col $olds]
-    } else {
-       set rmx 0
-    }
-    drawcmittext $id $row $col $rmx
+    drawcmittext $id $row $col
     set iddrawn($id) 1
 }
 
-proc drawfrac {f0 f1} {
-    global numcommits canv
-    global linespc
+proc drawcommits {row {endrow {}}} {
+    global numcommits iddrawn displayorder curview
+    global parentlist rowidlist
 
-    set ymax [lindex [$canv cget -scrollregion] 3]
-    if {$ymax eq {} || $ymax == 0} return
-    set y0 [expr {int($f0 * $ymax)}]
-    set row [expr {int(($y0 - 3) / $linespc) - 1}]
     if {$row < 0} {
        set row 0
     }
-    set y1 [expr {int($f1 * $ymax)}]
-    set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
+    if {$endrow eq {}} {
+       set endrow $row
+    }
     if {$endrow >= $numcommits} {
        set endrow [expr {$numcommits - 1}]
     }
-    for {} {$row <= $endrow} {incr row} {
-       drawcmitrow $row
+
+    # make the lines join to already-drawn rows either side
+    set r [expr {$row - 1}]
+    if {$r < 0 || ![info exists iddrawn([lindex $displayorder $r])]} {
+       set r $row
+    }
+    set er [expr {$endrow + 1}]
+    if {$er >= $numcommits ||
+       ![info exists iddrawn([lindex $displayorder $er])]} {
+       set er $endrow
+    }
+    for {} {$r <= $er} {incr r} {
+       set id [lindex $displayorder $r]
+       set wasdrawn [info exists iddrawn($id)]
+       if {!$wasdrawn} {
+           drawcmitrow $r
+       }
+       if {$r == $er} break
+       set nextid [lindex $displayorder [expr {$r + 1}]]
+       if {$wasdrawn && [info exists iddrawn($nextid)]} {
+           catch {unset prevlines}
+           continue
+       }
+       drawparentlinks $id $r
+
+       if {[info exists lineends($r)]} {
+           foreach lid $lineends($r) {
+               unset prevlines($lid)
+           }
+       }
+       set rowids [lindex $rowidlist $r]
+       foreach lid $rowids {
+           if {$lid eq {}} continue
+           if {$lid eq $id} {
+               # see if this is the first child of any of its parents
+               foreach p [lindex $parentlist $r] {
+                   if {[lsearch -exact $rowids $p] < 0} {
+                       # make this line extend up to the child
+                       set le [drawlineseg $p $r $er 0]
+                       lappend lineends($le) $p
+                       set prevlines($p) 1
+                   }
+               }
+           } elseif {![info exists prevlines($lid)]} {
+               set le [drawlineseg $lid $r $er 1]
+               lappend lineends($le) $lid
+               set prevlines($lid) 1
+           }
+       }
     }
 }
 
+proc drawfrac {f0 f1} {
+    global canv linespc
+
+    set ymax [lindex [$canv cget -scrollregion] 3]
+    if {$ymax eq {} || $ymax == 0} return
+    set y0 [expr {int($f0 * $ymax)}]
+    set row [expr {int(($y0 - 3) / $linespc) - 1}]
+    set y1 [expr {int($f1 * $ymax)}]
+    set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
+    drawcommits $row $endrow
+}
+
 proc drawvisible {} {
     global canv
     eval drawfrac [$canv yview]
 }
 
 proc clear_display {} {
-    global iddrawn idrangedrawn
+    global iddrawn linesegs
     global vhighlights fhighlights nhighlights rhighlights
 
     allcanvs delete all
     catch {unset iddrawn}
-    catch {unset idrangedrawn}
+    catch {unset linesegs}
     catch {unset vhighlights}
     catch {unset fhighlights}
     catch {unset nhighlights}
@@ -3538,7 +3650,7 @@ proc insertrow {row newcmit} {
     global displayorder parentlist childlist commitlisted
     global commitrow curview rowidlist rowoffsets numcommits
     global rowrangelist rowlaidout rowoptim numcommits
-    global linesegends selectedline
+    global selectedline
 
     if {$row >= $numcommits} {
        puts "oops, inserting new row $row but only have $numcommits rows"
@@ -3592,8 +3704,6 @@ proc insertrow {row newcmit} {
        lset rowrangelist $rp1 $ranges
     }
 
-    set linesegends [linsert $linesegends $row {}]
-
     incr rowlaidout
     incr rowoptim
     incr numcommits
@@ -3708,13 +3818,13 @@ proc dofind {} {
            if {$matches == {}} continue
            set doesmatch 1
            if {$ty == "Headline"} {
-               drawcmitrow $l
+               drawcommits $l
                markmatches $canv $l $f $linehtag($l) $matches $mainfont
            } elseif {$ty == "Author"} {
-               drawcmitrow $l
+               drawcommits $l
                markmatches $canv2 $l $f $linentag($l) $matches $mainfont
            } elseif {$ty == "Date"} {
-               drawcmitrow $l
+               drawcommits $l
                markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
            }
        }
@@ -3807,7 +3917,7 @@ proc stopfindproc {{done 0}} {
 proc markheadline {l id} {
     global canv mainfont linehtag
 
-    drawcmitrow $l
+    drawcommits $l
     set bbox [$canv bbox $linehtag($l)]
     set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
     $canv lower $t
@@ -5302,10 +5412,11 @@ proc domktag {} {
 
 proc redrawtags {id} {
     global canv linehtag commitrow idpos selectedline curview
-    global mainfont canvxmax
+    global mainfont canvxmax iddrawn
 
     if {![info exists commitrow($curview,$id)]} return
-    drawcmitrow $commitrow($curview,$id)
+    if {![info exists iddrawn($id)]} return
+    drawcommits $commitrow($curview,$id)
     $canv delete tag.$id
     set xt [eval drawtags $id $idpos($id)]
     $canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2]
@@ -6947,6 +7058,7 @@ set cmitmode "patch"
 set wrapcomment "none"
 set showneartags 1
 set maxrefs 20
+set maxlinelen 200
 
 set colors {green red blue magenta darkgrey brown orange}
 set bgcolor white