Merge with master.
[gitweb.git] / gitk
diff --git a/gitk b/gitk
index 7a0d766ee1615d228e6458ea4d41c3fd6f98d52a..6a6d4b243593147eaf9d10b23e78a2c1d0c520aa 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -18,7 +18,7 @@ proc gitdir {} {
 
 proc getcommits {rargs} {
     global commits commfd phase canv mainfont env
-    global startmsecs nextupdate
+    global startmsecs nextupdate ncmupdate
     global ctext maincursor textcursor leftover
 
     # check that we can find a .git directory somewhere...
@@ -31,6 +31,7 @@ proc getcommits {rargs} {
     set phase getcommits
     set startmsecs [clock clicks -milliseconds]
     set nextupdate [expr $startmsecs + 100]
+    set ncmupdate 0
     if [catch {
        set parse_args [concat --default HEAD $rargs]
        set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
@@ -49,7 +50,7 @@ proc getcommits {rargs} {
     }
     set leftover {}
     fconfigure $commfd -blocking 0 -translation lf
-    fileevent $commfd readable "getcommitlines $commfd"
+    fileevent $commfd readable [list getcommitlines $commfd]
     $canv delete all
     $canv create text 3 3 -anchor nw -text "Reading commits..." \
        -font $mainfont -tags textitems
@@ -61,6 +62,7 @@ proc getcommitlines {commfd}  {
     global commits parents cdate children nchildren
     global commitlisted phase commitinfo nextupdate
     global stopped redisplaying leftover
+    global numcommits ncmupdate
 
     set stuff [read $commfd]
     if {$stuff == {}} {
@@ -108,8 +110,10 @@ to allow selection of commits to be displayed.)}
        set commitlisted($id) 1
        parsecommit $id $cmit 1
        drawcommit $id
-       if {[clock clicks -milliseconds] >= $nextupdate} {
+       if {[clock clicks -milliseconds] >= $nextupdate
+           && $numcommits >= $ncmupdate + 100} {
            doupdate
+           set ncmupdate $numcommits
        }
        while {$redisplaying} {
            set redisplaying 0
@@ -119,8 +123,10 @@ to allow selection of commits to be displayed.)}
                foreach id $commits {
                    drawcommit $id
                    if {$stopped} break
-                   if {[clock clicks -milliseconds] >= $nextupdate} {
+                   if {[clock clicks -milliseconds] >= $nextupdate
+                       && $numcommits >= $ncmupdate + 100} {
                        doupdate
+                       set ncmupdate $numcommits
                    }
                }
            }
@@ -134,7 +140,7 @@ proc doupdate {} {
     incr nextupdate 100
     fileevent $commfd readable {}
     update
-    fileevent $commfd readable "getcommitlines $commfd"
+    fileevent $commfd readable [list getcommitlines $commfd]
 }
 
 proc readcommit {id} {
@@ -387,7 +393,7 @@ proc makewindow {} {
     set ctext .ctop.cdet.left.ctext
     text $ctext -bg white -state disabled -font $textfont \
        -width $geometry(ctextw) -height $geometry(ctexth) \
-       -yscrollcommand ".ctop.cdet.left.sb set"
+       -yscrollcommand ".ctop.cdet.left.sb set" -wrap none
     scrollbar .ctop.cdet.left.sb -command "$ctext yview"
     pack .ctop.cdet.left.sb -side right -fill y
     pack $ctext -side left -fill both -expand 1
@@ -715,7 +721,7 @@ proc bindline {t id} {
     $canv bind $t <Enter> "lineenter %x %y $id"
     $canv bind $t <Motion> "linemotion %x %y $id"
     $canv bind $t <Leave> "lineleave $id"
-    $canv bind $t <Button-1> "lineclick %x %y $id"
+    $canv bind $t <Button-1> "lineclick %x %y $id 1"
 }
 
 proc drawcommitline {level} {
@@ -1090,7 +1096,7 @@ proc decidenext {{noread 0}} {
 
 proc drawcommit {id} {
     global phase todo nchildren datemode nextupdate
-    global startcommits
+    global startcommits numcommits ncmupdate
 
     if {$phase != "incrdraw"} {
        set phase incrdraw
@@ -1119,8 +1125,10 @@ proc drawcommit {id} {
            if {![info exists commitlisted($id)]} {
                break
            }
-           if {[clock clicks -milliseconds] >= $nextupdate} {
+           if {[clock clicks -milliseconds] >= $nextupdate
+               && $numcommits >= $ncmupdate} {
                doupdate
+               set ncmupdate $numcommits
                if {$stopped} break
            }
        }
@@ -1158,11 +1166,12 @@ proc settextcursor {c} {
 }
 
 proc drawgraph {} {
-    global nextupdate startmsecs startcommits todo
+    global nextupdate startmsecs startcommits todo ncmupdate
 
     if {$startcommits == {}} return
     set startmsecs [clock clicks -milliseconds]
     set nextupdate [expr $startmsecs + 100]
+    set ncmupdate 0
     initgraph
     set todo [lindex $startcommits 0]
     drawrest 0 1
@@ -1171,7 +1180,7 @@ proc drawgraph {} {
 proc drawrest {level startix} {
     global phase stopped redisplaying selectedline
     global datemode currentparents todo
-    global numcommits
+    global numcommits ncmupdate
     global nextupdate startmsecs startcommits idline
 
     if {$level >= 0} {
@@ -1200,9 +1209,11 @@ proc drawrest {level startix} {
                if {$level < 0} break
                drawslants $level
            }
-           if {[clock clicks -milliseconds] >= $nextupdate} {
+           if {[clock clicks -milliseconds] >= $nextupdate
+               && $numcommits >= $ncmupdate + 100} {
                update
                incr nextupdate 100
+               set ncmupdate $numcommits
            }
        }
     }
@@ -1687,7 +1698,7 @@ proc unmarkmatches {} {
 }
 
 proc selcanvline {w x y} {
-    global canv canvy0 ctext linespc selectedline
+    global canv canvy0 ctext linespc
     global lineid linehtag linentag linedtag rowtextx
     set ymax [lindex [$canv cget -scrollregion] 3]
     if {$ymax == {}} return
@@ -1704,13 +1715,21 @@ proc selcanvline {w x y} {
     selectline $l 1
 }
 
+proc commit_descriptor {p} {
+    global commitinfo
+    set l "..."
+    if {[info exists commitinfo($p)]} {
+       set l [lindex $commitinfo($p) 0]
+    }
+    return "$p ($l)"
+}
+
 proc selectline {l isnew} {
     global canv canv2 canv3 ctext commitinfo selectedline
     global lineid linehtag linentag linedtag
-    global canvy0 linespc parents nparents
+    global canvy0 linespc parents nparents children nchildren
     global cflist currentid sha1entry
     global commentend idtags idline
-    global history historyindex
 
     $canv delete hover
     if {![info exists lineid($l)] || ![info exists linehtag($l)]} return
@@ -1761,19 +1780,8 @@ proc selectline {l isnew} {
        allcanvs yview moveto [expr $newtop * 1.0 / $ymax]
     }
 
-    if {$isnew && (![info exists selectedline] || $selectedline != $l)} {
-       if {$historyindex < [llength $history]} {
-           set history [lreplace $history $historyindex end $l]
-       } else {
-           lappend history $l
-       }
-       incr historyindex
-       if {$historyindex > 1} {
-           .ctop.top.bar.leftbut conf -state normal
-       } else {
-           .ctop.top.bar.leftbut conf -state disabled
-       }
-       .ctop.top.bar.rightbut conf -state disabled
+    if {$isnew} {
+       addtohistory [list selectline $l 0]
     }
 
     set selectedline $l
@@ -1802,15 +1810,15 @@ proc selectline {l isnew} {
  
     set commentstart [$ctext index "end - 1c"]
     set comment {}
-    foreach p $parents($id) {
-       set l "..."
-       if {[info exists commitinfo($p)]} {
-           set l [lindex $commitinfo($p) 0]
-           if {[string length $l] > 32} {
-               set l "[string range $l 0 28] ..."
-           }
+    if {[info exists parents($id)]} {
+       foreach p $parents($id) {
+           append comment "Parent: [commit_descriptor $p]\n"
+       }
+    }
+    if {[info exists children($id)]} {
+       foreach c $children($id) {
+           append comment "Child:  [commit_descriptor $c]\n"
        }
-       append comment "Parent: $p  ($l)\n"
     }
     append comment "\n"
     append comment [lindex $info 5]
@@ -1857,12 +1865,42 @@ proc selnextline {dir} {
     selectline $l 1
 }
 
+proc unselectline {} {
+    global selectedline
+
+    catch {unset selectedline}
+    allcanvs delete secsel
+}
+
+proc addtohistory {cmd} {
+    global history historyindex
+
+    if {$historyindex > 0
+       && [lindex $history [expr {$historyindex - 1}]] == $cmd} {
+       return
+    }
+
+    if {$historyindex < [llength $history]} {
+       set history [lreplace $history $historyindex end $cmd]
+    } else {
+       lappend history $cmd
+    }
+    incr historyindex
+    if {$historyindex > 1} {
+       .ctop.top.bar.leftbut conf -state normal
+    } else {
+       .ctop.top.bar.leftbut conf -state disabled
+    }
+    .ctop.top.bar.rightbut conf -state disabled
+}
+
 proc goback {} {
     global history historyindex
 
     if {$historyindex > 1} {
        incr historyindex -1
-       selectline [lindex $history [expr {$historyindex - 1}]] 0
+       set cmd [lindex $history [expr {$historyindex - 1}]]
+       eval $cmd
        .ctop.top.bar.rightbut conf -state normal
     }
     if {$historyindex <= 1} {
@@ -1874,9 +1912,9 @@ proc goforw {} {
     global history historyindex
 
     if {$historyindex < [llength $history]} {
-       set l [lindex $history $historyindex]
+       set cmd [lindex $history $historyindex]
        incr historyindex
-       selectline $l 0
+       eval $cmd
        .ctop.top.bar.leftbut conf -state normal
     }
     if {$historyindex >= [llength $history]} {
@@ -2624,7 +2662,7 @@ proc setcoords {} {
 }
 
 proc redisplay {} {
-    global selectedline stopped redisplaying phase
+    global stopped redisplaying phase
     if {$stopped > 1} return
     if {$phase == "getcommits"} return
     set redisplaying 1
@@ -2636,7 +2674,7 @@ proc redisplay {} {
 }
 
 proc incrfont {inc} {
-    global mainfont namefont textfont selectedline ctext canv phase
+    global mainfont namefont textfont ctext canv phase
     global stopped entries
     unmarkmatches
     set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
@@ -2778,34 +2816,40 @@ proc linehover {} {
     $canv raise $t
 }
 
-proc lineclick {x y id} {
+proc lineclick {x y id isnew} {
     global ctext commitinfo children cflist canv
 
     unmarkmatches
+    unselectline
+    if {$isnew} {
+       addtohistory [list lineclick $x $x $id 0]
+    }
     $canv delete hover
     # fill the details pane with info about this line
     $ctext conf -state normal
     $ctext delete 0.0 end
-    $ctext insert end "Parent:\n "
-    catch {destroy $ctext.$id}
-    button $ctext.$id -text "Go:" -command "selbyid $id" \
-       -padx 4 -pady 0
-    $ctext window create end -window $ctext.$id -align center
+    $ctext tag conf link -foreground blue -underline 1
+    $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+    $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+    $ctext insert end "Parent:\t"
+    $ctext insert end $id [list link link0]
+    $ctext tag bind link0 <1> [list selbyid $id]
     set info $commitinfo($id)
-    $ctext insert end "\t[lindex $info 0]\n"
+    $ctext insert end "\n\t[lindex $info 0]\n"
     $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
     $ctext insert end "\tDate:\t[lindex $info 2]\n"
-    $ctext insert end "\tID:\t$id\n"
     if {[info exists children($id)]} {
        $ctext insert end "\nChildren:"
+       set i 0
        foreach child $children($id) {
-           $ctext insert end "\n "
-           catch {destroy $ctext.$child}
-           button $ctext.$child -text "Go:" -command "selbyid $child" \
-               -padx 4 -pady 0
-           $ctext window create end -window $ctext.$child -align center
+           incr i
            set info $commitinfo($child)
-           $ctext insert end "\t[lindex $info 0]"
+           $ctext insert end "\n\t"
+           $ctext insert end $child [list link link$i]
+           $ctext tag bind link$i <1> [list selbyid $child]
+           $ctext insert end "\n\t[lindex $info 0]"
+           $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
+           $ctext insert end "\n\tDate:\t[lindex $info 2]\n"
        }
     }
     $ctext conf -state disabled
@@ -2845,8 +2889,6 @@ proc rowmenu {x y id} {
 
 proc diffvssel {dirn} {
     global rowmenuid selectedline lineid
-    global ctext cflist
-    global commitinfo
 
     if {![info exists selectedline]} return
     if {$dirn} {
@@ -2856,15 +2898,32 @@ proc diffvssel {dirn} {
        set oldid $rowmenuid
        set newid $lineid($selectedline)
     }
+    addtohistory [list doseldiff $oldid $newid]
+    doseldiff $oldid $newid
+}
+
+proc doseldiff {oldid newid} {
+    global ctext cflist
+    global commitinfo
+
     $ctext conf -state normal
     $ctext delete 0.0 end
     $ctext mark set fmark.0 0.0
     $ctext mark gravity fmark.0 left
     $cflist delete 0 end
     $cflist insert end "Top"
-    $ctext insert end "From $oldid\n     "
+    $ctext insert end "From "
+    $ctext tag conf link -foreground blue -underline 1
+    $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+    $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+    $ctext tag bind link0 <1> [list selbyid $oldid]
+    $ctext insert end $oldid [list link link0]
+    $ctext insert end "\n     "
     $ctext insert end [lindex $commitinfo($oldid) 0]
-    $ctext insert end "\n\nTo   $newid\n     "
+    $ctext insert end "\n\nTo   "
+    $ctext tag bind link1 <1> [list selbyid $newid]
+    $ctext insert end $newid [list link link1]
+    $ctext insert end "\n     "
     $ctext insert end [lindex $commitinfo($newid) 0]
     $ctext insert end "\n"
     $ctext conf -state disabled