gitk: Further speedups
[git.git] / gitk
diff --git a/gitk b/gitk
index cca9d35..8d7b258 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -35,6 +35,7 @@ proc parse_args {rargs} {
 proc start_rev_list {rlargs} {
     global startmsecs nextupdate ncmupdate
     global commfd leftover tclencoding datemode
+    global commitdata
 
     set startmsecs [clock clicks -milliseconds]
     set nextupdate [expr {$startmsecs + 100}]
@@ -52,6 +53,7 @@ proc start_rev_list {rlargs} {
        exit 1
     }
     set leftover {}
+    set commitdata {}
     fconfigure $commfd -blocking 0 -translation lf
     if {$tclencoding != {}} {
        fconfigure $commfd -encoding $tclencoding
@@ -72,11 +74,9 @@ proc getcommits {rargs} {
 }
 
 proc getcommitlines {commfd}  {
-    global parents cdate children nchildren
-    global commitlisted commitinfo phase nextupdate
-    global stopped leftover
-    global canv
-    global displayorder commitidx commitrow
+    global commitlisted nextupdate
+    global leftover
+    global displayorder commitidx commitrow commitdata
 
     set stuff [read $commfd]
     if {$stuff == {}} {
@@ -136,12 +136,9 @@ proc getcommitlines {commfd}  {
        }
        set id [lindex $ids 0]
        set olds [lrange $ids 1 end]
-       set cmit [string range $cmit [expr {$j + 1}] end]
        set commitlisted($id) 1
        updatechildren $id [lrange $ids 1 end]
-       if {![info exists commitinfo($id)]} {
-           parsecommit $id $cmit 1
-       }
+       lappend commitdata [string range $cmit [expr {$j + 1}] end]
        set commitrow($id) $commitidx
        incr commitidx
        lappend displayorder $id
@@ -269,6 +266,25 @@ proc parsecommit {id contents listed} {
                             $comname $comdate $comment]
 }
 
+proc getcommit {id {row {}}} {
+    global commitdata commitrow commitinfo nparents
+
+    if {$row eq {}} {
+       if {![info exists commitrow($id)]} {return 0}
+       set row $commitrow($id)
+    }
+    if {$row < [llength $commitdata]} {
+       parsecommit $id [lindex $commitdata $row] 1
+    } else {
+       readcommit $id
+       if {![info exists commitinfo($id)]} {
+           set commitinfo($id) {"No commit information available"}
+           set nparents($id) 0
+       }
+    }
+    return 1
+}
+
 proc readrefs {} {
     global tagids idtags headids idheads tagcontents
     global otherrefids idotherrefs
@@ -1317,6 +1333,7 @@ proc drawcmitrow {row} {
     global displayorder rowidlist
     global idrowranges idrangedrawn iddrawn
     global commitinfo commitlisted parents numcommits
+    global commitdata
 
     if {$row >= $numcommits} return
     foreach id [lindex $rowidlist $row] {
@@ -1344,11 +1361,7 @@ proc drawcmitrow {row} {
        return
     }
     if {![info exists commitinfo($id)]} {
-       readcommit $id
-       if {![info exists commitinfo($id)]} {
-           set commitinfo($id) {"No commit information available"}
-           set nparents($id) 0
-       }
+       getcommit $id $row
     }
     assigncolor $id
     if {[info exists commitlisted($id)] && [info exists parents($id)]
@@ -1604,19 +1617,19 @@ proc xcoord {i level ln} {
 }
 
 proc finishcommits {} {
-    global phase
+    global commitidx phase
     global canv mainfont ctext maincursor textcursor
 
-    if {$phase == "incrdraw"} {
+    if {$commitidx > 0} {
        drawrest
     } else {
        $canv delete all
        $canv create text 3 3 -anchor nw -text "No commits selected" \
            -font $mainfont -tags textitems
-       set phase {}
     }
     . config -cursor $maincursor
     settextcursor $textcursor
+    set phase {}
 }
 
 # Don't change the text pane cursor if it is currently the hand cursor,
@@ -1672,7 +1685,8 @@ proc dofind {} {
     global findtype findloc findstring markedmatches commitinfo
     global numcommits displayorder linehtag linentag linedtag
     global mainfont namefont canv canv2 canv3 selectedline
-    global matchinglines foundstring foundstrlen
+    global matchinglines foundstring foundstrlen matchstring
+    global commitdata
 
     stopfindproc
     unmarkmatches
@@ -1689,6 +1703,8 @@ proc dofind {} {
     }
     set foundstrlen [string length $findstring]
     if {$foundstrlen == 0} return
+    regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
+    set matchstring "*$matchstring*"
     if {$findloc == "Files"} {
        findfiles
        return
@@ -1700,8 +1716,21 @@ proc dofind {} {
     }
     set didsel 0
     set fldtypes {Headline Author Date Committer CDate Comment}
-    for {set l 0} {$l < $numcommits} {incr l} {
+    set l -1
+    foreach d $commitdata {
+       incr l
+       if {$findtype == "Regexp"} {
+           set doesmatch [regexp $foundstring $d]
+       } elseif {$findtype == "IgnCase"} {
+           set doesmatch [string match -nocase $matchstring $d]
+       } else {
+           set doesmatch [string match $matchstring $d]
+       }
+       if {!$doesmatch} continue
        set id [lindex $displayorder $l]
+       if {![info exists commitinfo($id)]} {
+           getcommit $id $l
+       }
        set info $commitinfo($id)
        set doesmatch 0
        foreach f $info ty $fldtypes {
@@ -2069,7 +2098,7 @@ proc findcont {id} {
 # mark a commit as matching by putting a yellow background
 # behind the headline
 proc markheadline {l id} {
-    global canv mainfont linehtag commitinfo
+    global canv mainfont linehtag
 
     drawcmitrow $l
     set bbox [$canv bbox $linehtag($l)]
@@ -2725,9 +2754,9 @@ proc gotocommit {} {
        set id [string tolower $sha1string]
        if {[regexp {^[0-9a-f]{4,39}$} $id]} {
            set matches {}
-           for {set l 0} {$l < $numcommits} {incr l} {
-               if {[string match $id* [lindex $displayorder $l]]} {
-                   lappend matches [lindex $displayorder $l]
+           foreach i $displayorder {
+               if {[string match $id* $i]} {
+                   lappend matches $i
                }
            }
            if {$matches ne {}} {
@@ -2755,7 +2784,7 @@ proc lineenter {x y id} {
     global hoverx hovery hoverid hovertimer
     global commitinfo canv
 
-    if {![info exists commitinfo($id)]} return
+    if {![info exists commitinfo($id)] && ![getcommit $id]} return
     set hoverx $x
     set hovery $y
     set hoverid $id
@@ -2849,6 +2878,7 @@ proc arrowjump {id n y} {
 proc lineclick {x y id isnew} {
     global ctext commitinfo children cflist canv thickerline
 
+    if {![info exists commitinfo($id)] && ![getcommit $id]} return
     unmarkmatches
     unselectline
     normalline
@@ -2890,6 +2920,7 @@ proc lineclick {x y id isnew} {
        set i 0
        foreach child $children($id) {
            incr i
+           if {![info exists commitinfo($child)] && ![getcommit $child]} continue
            set info $commitinfo($child)
            $ctext insert end "\n\t"
            $ctext insert end $child [list link link$i]