From 50b44eceed2105db0bee194904649249cc5f0308 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 4 Apr 2006 10:16:22 +1000 Subject: [PATCH 1/8] gitk: Implement multiple views With this, gitk can know about the graphs for multiple sets of files and directories of interest. Each set of files/dirs and its graph is called a "view". There is always the "All files" view, which is the complete graph showing all commits. If files or dirs are specified on the command line, a "Command line" view is automatically created. Users can create new views and switch between them, and can delete any view except the "All files" view. This required a bit of reengineering. In particular, some more things that were arrays have now become lists. The idrowranges array is still used while the graph is being laid out, but for rows that have been laid out we use the rowrangelist list instead. The cornercrossings and crossings arrays no longer exist, and instead we compute the crossings when needed (in assigncolor). Still to be done: make the back/forward buttons switch views as necessary; make the updatecommits function work right; preserve the selection if possible when the new view has to be read in; fix the case when the user switches away from the current view while we are still reading it in and laying it out; further optimizations. Signed-off-by: Paul Mackerras --- gitk | 452 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 334 insertions(+), 118 deletions(-) diff --git a/gitk b/gitk index 90afec92d..961b582a4 100755 --- a/gitk +++ b/gitk @@ -17,19 +17,38 @@ proc gitdir {} { } proc parse_args {rargs} { - global parsed_args + global parsed_args cmdline_files + set parsed_args {} + set cmdline_files {} if {[catch { set parse_args [concat --default HEAD $rargs] - set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"] + set args [split [eval exec git-rev-parse $parse_args] "\n"] + set i 0 + foreach arg $args { + if {![regexp {^[0-9a-f]{40}$} $arg]} { + if {$arg eq "--"} { + incr i + } + set cmdline_files [lrange $args $i end] + break + } + lappend parsed_args $arg + incr i + } }]} { # if git-rev-parse failed for some reason... + set i [lsearch -exact $rargs "--"] + if {$i >= 0} { + set cmdline_files [lrange $rargs [expr {$i+1}] end] + set rargs [lrange $rargs 0 [expr {$i-1}]] + } if {$rargs == {}} { - set rargs HEAD + set parsed_args HEAD + } else { + set parsed_args $rargs } - set parsed_args $rargs } - return $parsed_args } proc start_rev_list {rlargs} { @@ -65,7 +84,7 @@ proc getcommits {rargs} { global phase canv mainfont set phase getcommits - start_rev_list [parse_args $rargs] + start_rev_list $rargs $canv delete all $canv create text 3 3 -anchor nw -text "Reading commits..." \ -font $mainfont -tags textitems @@ -141,11 +160,12 @@ proc getcommitlines {commfd} { set id [lindex $ids 0] if {$listed} { set olds [lrange $ids 1 end] - if {[llength $olds] > 1} { - set olds [lsort -unique $olds] - } + set i 0 foreach p $olds { - lappend children($p) $id + if {$i == 0 || [lsearch -exact $olds $p] >= $i} { + lappend children($p) $id + } + incr i } } else { set olds {} @@ -196,18 +216,18 @@ proc readcommit {id} { parsecommit $id $contents 0 } -proc updatecommits {rargs} { +proc updatecommits {} { + global parsed_args + + unselectline stopfindproc - foreach v {colormap selectedline matchinglines treediffs - mergefilelist currentid rowtextx commitrow - rowidlist rowoffsets idrowranges idrangedrawn iddrawn - linesegends crossings cornercrossings} { + foreach v {matchinglines treediffs currentid} { global $v catch {unset $v} } - allcanvs delete all + clear_display readrefs - getcommits $rargs + getcommits $parsed_args } proc parsecommit {id contents listed} { @@ -344,12 +364,18 @@ proc makewindow {rargs} { menu .bar .bar add cascade -label "File" -menu .bar.file menu .bar.file - .bar.file add command -label "Update" -command [list updatecommits $rargs] + .bar.file add command -label "Update" -command updatecommits .bar.file add command -label "Reread references" -command rereadrefs .bar.file add command -label "Quit" -command doquit menu .bar.edit .bar add cascade -label "Edit" -menu .bar.edit .bar.edit add command -label "Preferences" -command doprefs + menu .bar.view + .bar add cascade -label "View" -menu .bar.view + .bar.view add command -label "New view..." -command newview + .bar.view add command -label "Delete view" -command delview -state disabled + .bar.view add separator + .bar.view add command -label "All files" -command {showview 0} menu .bar.help .bar add cascade -label "Help" -menu .bar.help .bar.help add command -label "About gitk" -command about @@ -718,6 +744,169 @@ Use and redistribute under the terms of the GNU General Public License} \ pack $w.ok -side bottom } +proc newview {} { + global newviewname nextviewnum newviewtop + + set top .gitkview + if {[winfo exists $top]} { + raise $top + return + } + set newviewtop $top + toplevel $top + wm title $top "Gitk view definition" + label $top.nl -text "Name" + entry $top.name -width 20 -textvariable newviewname + set newviewname "View $nextviewnum" + grid $top.nl $top.name -sticky w + label $top.l -text "Files and directories to include:" + grid $top.l - -sticky w -pady 10 + text $top.t -width 30 -height 10 + grid $top.t - -sticky w + frame $top.buts + button $top.buts.ok -text "OK" -command newviewok + button $top.buts.can -text "Cancel" -command newviewcan + grid $top.buts.ok $top.buts.can + grid columnconfigure $top.buts 0 -weight 1 -uniform a + grid columnconfigure $top.buts 1 -weight 1 -uniform a + grid $top.buts - -pady 10 -sticky ew + focus $top.t +} + +proc newviewok {} { + global newviewtop nextviewnum + global viewname viewfiles + + set n $nextviewnum + incr nextviewnum + set viewname($n) [$newviewtop.name get] + set files {} + foreach f [split [$newviewtop.t get 0.0 end] "\n"] { + set ft [string trim $f] + if {$ft ne {}} { + lappend files $ft + } + } + set viewfiles($n) $files + catch {destroy $newviewtop} + unset newviewtop + .bar.view add command -label $viewname($n) -command [list showview $n] + after idle showview $n +} + +proc newviewcan {} { + global newviewtop + + catch {destroy $newviewtop} + unset newviewtop +} + +proc delview {} { + global curview viewdata + + if {$curview == 0} return + set nmenu [.bar.view index end] + set targetcmd [list showview $curview] + for {set i 5} {$i <= $nmenu} {incr i} { + if {[.bar.view entrycget $i -command] eq $targetcmd} { + .bar.view delete $i + break + } + } + set viewdata($curview) {} + showview 0 +} + +proc saveview {} { + global curview viewdata + global displayorder parentlist childlist rowidlist rowoffsets + global rowrangelist commitlisted + +} + +proc showview {n} { + global curview viewdata viewfiles + global displayorder parentlist childlist rowidlist rowoffsets + global colormap rowtextx commitrow + global numcommits rowrangelist commitlisted idrowranges + global selectedline currentid canv canvy0 + global matchinglines treediffs + global parsed_args + + if {$n == $curview} return + set selid {} + if {[info exists selectedline]} { + set selid $currentid + set y [yc $selectedline] + set ymax [lindex [$canv cget -scrollregion] 3] + set span [$canv yview] + set ytop [expr {[lindex $span 0] * $ymax}] + set ybot [expr {[lindex $span 1] * $ymax}] + if {$ytop < $y && $y < $ybot} { + set yscreen [expr {$y - $ytop}] + } else { + set yscreen [expr {($ybot - $ytop) / 2}] + } + } + unselectline + stopfindproc + if {![info exists viewdata($curview)]} { + set viewdata($curview) \ + [list $displayorder $parentlist $childlist $rowidlist \ + $rowoffsets $rowrangelist $commitlisted] + } + catch {unset matchinglines} + catch {unset treediffs} + clear_display + + set curview $n + .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] + + if {![info exists viewdata($n)]} { + set args $parsed_args + if {$viewfiles($n) ne {}} { + set args [concat $args "--" $viewfiles($n)] + } + getcommits $args + return + } + + set displayorder [lindex $viewdata($n) 0] + set parentlist [lindex $viewdata($n) 1] + set childlist [lindex $viewdata($n) 2] + set rowidlist [lindex $viewdata($n) 3] + set rowoffsets [lindex $viewdata($n) 4] + set rowrangelist [lindex $viewdata($n) 5] + set commitlisted [lindex $viewdata($n) 6] + set numcommits [llength $displayorder] + catch {unset colormap} + catch {unset rowtextx} + catch {unset commitrow} + catch {unset idrowranges} + set curview $n + set row 0 + foreach id $displayorder { + set commitrow($id) $row + incr row + } + setcanvscroll + set yf 0 + set row 0 + if {$selid ne {} && [info exists commitrow($selid)]} { + set row $commitrow($selid) + # try to get the selected row in the same position on the screen + set ymax [lindex [$canv cget -scrollregion] 3] + set ytop [expr {[yc $row] - $yscreen}] + if {$ytop < 0} { + set ytop 0 + } + set yf [expr {$ytop * 1.0 / $ymax}] + } + allcanvs yview moveto $yf + drawvisible + selectline $row 0 +} + proc shortids {ids} { set res {} foreach id $ids { @@ -834,10 +1023,12 @@ proc makeuparrow {oid x y z} { proc initlayout {} { global rowidlist rowoffsets displayorder commitlisted global rowlaidout rowoptim - global idinlist rowchk + global idinlist rowchk rowrangelist idrowranges global commitidx numcommits canvxmax canv global nextcolor global parentlist childlist children + global colormap rowtextx commitrow + global linesegends set commitidx 0 set numcommits 0 @@ -845,6 +1036,7 @@ proc initlayout {} { set commitlisted {} set parentlist {} set childlist {} + set rowrangelist {{}} catch {unset children} set nextcolor 0 set rowidlist {{}} @@ -854,6 +1046,11 @@ proc initlayout {} { set rowlaidout 0 set rowoptim 0 set canvxmax [$canv cget -width] + catch {unset colormap} + catch {unset rowtextx} + catch {unset commitrow} + catch {unset idrowranges} + catch {unset linesegends} } proc setcanvscroll {} { @@ -892,7 +1089,6 @@ proc layoutmore {} { set rowlaidout [layoutrows $row $commitidx 0] set orow [expr {$rowlaidout - $uparrowlen - 1}] if {$orow > $rowoptim} { - checkcrossings $rowoptim $orow optimize_rows $rowoptim 0 $orow set rowoptim $orow } @@ -947,7 +1143,7 @@ proc layoutrows {row endrow last} { global childlist parentlist global idrowranges linesegends global commitidx - global idinlist rowchk + global idinlist rowchk rowrangelist set idlist [lindex $rowidlist $row] set offs [lindex $rowoffsets $row] @@ -1008,6 +1204,7 @@ proc layoutrows {row endrow last} { } if {[info exists idrowranges($id)]} { lappend idrowranges($id) $row + lappend rowrangelist $idrowranges($id) } incr row set offs [ntimes [llength $idlist] 0] @@ -1068,7 +1265,7 @@ proc addextraid {id row} { proc layouttail {} { global rowidlist rowoffsets idinlist commitidx - global idrowranges + global idrowranges rowrangelist set row $commitidx set idlist [lindex $rowidlist $row] @@ -1078,6 +1275,7 @@ proc layouttail {} { addextraid $id $row unset idinlist($id) lappend idrowranges($id) $row + lappend rowrangelist $idrowranges($id) incr row set offs [ntimes $col 0] set idlist [lreplace $idlist $col $col] @@ -1091,6 +1289,7 @@ proc layouttail {} { lset rowoffsets $row 0 makeuparrow $id 0 $row 0 lappend idrowranges($id) $row + lappend rowrangelist $idrowranges($id) incr row lappend rowidlist {} lappend rowoffsets {} @@ -1107,7 +1306,7 @@ proc insert_pad {row col npad} { } proc optimize_rows {row col endrow} { - global rowidlist rowoffsets idrowranges linesegends displayorder + global rowidlist rowoffsets idrowranges displayorder for {} {$row < $endrow} {incr row} { set idlist [lindex $rowidlist $row] @@ -1240,13 +1439,33 @@ proc linewidth {id} { return $wid } +proc rowranges {id} { + global idrowranges commitrow numcommits rowrangelist + + set ranges {} + if {[info exists commitrow($id)] && $commitrow($id) < $numcommits} { + set ranges [lindex $rowrangelist $commitrow($id)] + } elseif {[info exists idrowranges($id)]} { + set ranges $idrowranges($id) + } + return $ranges +} + proc drawlineseg {id i} { - global rowoffsets rowidlist idrowranges + global rowoffsets rowidlist global displayorder global canv colormap linespc + global numcommits commitrow - set startrow [lindex $idrowranges($id) [expr {2 * $i}]] - set row [lindex $idrowranges($id) [expr {2 * $i + 1}]] + set ranges [rowranges $id] + set downarrow 1 + if {[info exists commitrow($id)] && $commitrow($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 {} @@ -1290,8 +1509,7 @@ proc drawlineseg {id i} { } } if {[llength $coords] < 4} return - set last [expr {[llength $idrowranges($id)] / 2 - 1}] - if {$i < $last} { + 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. @@ -1311,7 +1529,7 @@ proc drawlineseg {id i} { } } } - set arrow [expr {2 * ($i > 0) + ($i < $last)}] + 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] @@ -1320,7 +1538,7 @@ proc drawlineseg {id i} { } proc drawparentlinks {id row col olds} { - global rowidlist canv colormap idrowranges + global rowidlist canv colormap set row2 [expr {$row + 1}] set x [xc $row $col] @@ -1339,9 +1557,9 @@ proc drawparentlinks {id row col olds} { if {$x2 > $rmx} { set rmx $x2 } - if {[info exists idrowranges($p)] && - $row2 == [lindex $idrowranges($p) 0] && - $row2 < [lindex $idrowranges($p) 1]} { + set ranges [rowranges $p] + if {$ranges ne {} && $row2 == [lindex $ranges 0] + && $row2 < [lindex $ranges 1]} { # drawlineseg will do this one for us continue } @@ -1364,11 +1582,11 @@ proc drawparentlinks {id row col olds} { proc drawlines {id} { global colormap canv - global idrowranges idrangedrawn + global idrangedrawn global childlist iddrawn commitrow rowidlist $canv delete lines.$id - set nr [expr {[llength $idrowranges($id)] / 2}] + set nr [expr {[llength [rowranges $id]] / 2}] for {set i 0} {$i < $nr} {incr i} { if {[info exists idrangedrawn($id,$i)]} { drawlineseg $id $i @@ -1431,14 +1649,13 @@ proc drawcmittext {id row col rmx} { proc drawcmitrow {row} { global displayorder rowidlist - global idrowranges idrangedrawn iddrawn + global idrangedrawn iddrawn global commitinfo commitlisted parentlist numcommits if {$row >= $numcommits} return foreach id [lindex $rowidlist $row] { - if {![info exists idrowranges($id)]} continue set i -1 - foreach {s e} $idrowranges($id) { + foreach {s e} [rowranges $id] { incr i if {$row < $s} continue if {$e eq {}} break @@ -1507,10 +1724,50 @@ proc clear_display {} { catch {unset idrangedrawn} } +proc findcrossings {id} { + global rowidlist parentlist numcommits rowoffsets displayorder + + set cross {} + set ccross {} + foreach {s e} [rowranges $id] { + if {$e >= $numcommits} { + set e [expr {$numcommits - 1}] + if {$e < $s} continue + } + set x [lsearch -exact [lindex $rowidlist $e] $id] + if {$x < 0} { + puts "findcrossings: oops, no [shortids $id] in row $e" + continue + } + for {set row $e} {[incr row -1] >= $s} {} { + set olds [lindex $parentlist $row] + set kid [lindex $displayorder $row] + set kidx [lsearch -exact [lindex $rowidlist $row] $kid] + if {$kidx < 0} continue + set nextrow [lindex $rowidlist [expr {$row + 1}]] + foreach p $olds { + set px [lsearch -exact $nextrow $p] + if {$px < 0} continue + if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} { + if {[lsearch -exact $ccross $p] >= 0} continue + if {$x == $px + ($kidx < $px? -1: 1)} { + lappend ccross $p + } elseif {[lsearch -exact $cross $p] < 0} { + lappend cross $p + } + } + } + set inc [lindex $rowoffsets $row $x] + if {$inc eq {}} break + incr x $inc + } + } + return [concat $ccross {{}} $cross] +} + proc assigncolor {id} { global colormap colors nextcolor global commitrow parentlist children childlist - global cornercrossings crossings if {[info exists colormap($id)]} return set ncolors [llength $colors] @@ -1530,32 +1787,22 @@ proc assigncolor {id} { } } set badcolors {} - if {[info exists cornercrossings($id)]} { - foreach x $cornercrossings($id) { - if {[info exists colormap($x)] - && [lsearch -exact $badcolors $colormap($x)] < 0} { - lappend badcolors $colormap($x) - } + set origbad {} + foreach x [findcrossings $id] { + if {$x eq {}} { + # delimiter between corner crossings and other crossings + if {[llength $badcolors] >= $ncolors - 1} break + set origbad $badcolors } - if {[llength $badcolors] >= $ncolors} { - set badcolors {} + if {[info exists colormap($x)] + && [lsearch -exact $badcolors $colormap($x)] < 0} { + lappend badcolors $colormap($x) } } - set origbad $badcolors - if {[llength $badcolors] < $ncolors - 1} { - if {[info exists crossings($id)]} { - foreach x $crossings($id) { - if {[info exists colormap($x)] - && [lsearch -exact $badcolors $colormap($x)] < 0} { - lappend badcolors $colormap($x) - } - } - if {[llength $badcolors] >= $ncolors} { - set badcolors $origbad - } - } - set origbad $badcolors + if {[llength $badcolors] >= $ncolors} { + set badcolors $origbad } + set origbad $badcolors if {[llength $badcolors] < $ncolors - 1} { foreach child $kids { if {[info exists colormap($child)] @@ -1659,55 +1906,6 @@ proc drawtags {id x xt y1} { return $xt } -proc checkcrossings {row endrow} { - global displayorder parentlist rowidlist - - for {} {$row < $endrow} {incr row} { - set id [lindex $displayorder $row] - set i [lsearch -exact [lindex $rowidlist $row] $id] - if {$i < 0} continue - set idlist [lindex $rowidlist [expr {$row+1}]] - foreach p [lindex $parentlist $row] { - set j [lsearch -exact $idlist $p] - if {$j > 0} { - if {$j < $i - 1} { - notecrossings $row $p $j $i [expr {$j+1}] - } elseif {$j > $i + 1} { - notecrossings $row $p $i $j [expr {$j-1}] - } - } - } - } -} - -proc notecrossings {row id lo hi corner} { - global rowidlist crossings cornercrossings - - for {set i $lo} {[incr i] < $hi} {} { - set p [lindex [lindex $rowidlist $row] $i] - if {$p == {}} continue - if {$i == $corner} { - if {![info exists cornercrossings($id)] - || [lsearch -exact $cornercrossings($id) $p] < 0} { - lappend cornercrossings($id) $p - } - if {![info exists cornercrossings($p)] - || [lsearch -exact $cornercrossings($p) $id] < 0} { - lappend cornercrossings($p) $id - } - } else { - if {![info exists crossings($id)] - || [lsearch -exact $crossings($id) $p] < 0} { - lappend crossings($id) $p - } - if {![info exists crossings($p)] - || [lsearch -exact $crossings($p) $id] < 0} { - lappend crossings($p) $id - } - } - } -} - proc xcoord {i level ln} { global canvx0 xspc1 xspc2 @@ -1763,7 +1961,7 @@ proc drawrest {} { showstuff $commitidx set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}] - puts "overall $drawmsecs ms for $numcommits commits" + #puts "overall $drawmsecs ms for $numcommits commits" } proc findmatches {f} { @@ -2433,9 +2631,10 @@ proc selnextline {dir} { } proc unselectline {} { - global selectedline + global selectedline currentid catch {unset selectedline} + catch {unset currentid} allcanvs delete secsel } @@ -2948,12 +3147,13 @@ proc linehover {} { } proc clickisonarrow {id y} { - global lthickness idrowranges + global lthickness + set ranges [rowranges $id] set thresh [expr {2 * $lthickness + 6}] - set n [expr {[llength $idrowranges($id)] - 1}] + set n [expr {[llength $ranges] - 1}] for {set i 1} {$i < $n} {incr i} { - set row [lindex $idrowranges($id) $i] + set row [lindex $ranges $i] if {abs([yc $row] - $y) < $thresh} { return $i } @@ -2962,11 +3162,11 @@ proc clickisonarrow {id y} { } proc arrowjump {id n y} { - global idrowranges canv + global canv # 1 <-> 2, 3 <-> 4, etc... set n [expr {(($n - 1) ^ 1) + 1}] - set row [lindex $idrowranges($id) $n] + set row [lindex [rowranges $id] $n] set yt [yc $row] set ymax [lindex [$canv cget -scrollregion] 3] if {$ymax eq {} || $ymax <= 0} return @@ -3819,10 +4019,26 @@ set historyindex 0 set optim_delay 16 +set nextviewnum 1 +set curview 0 +set viewfiles(0) {} + set stopped 0 set stuffsaved 0 set patchnum 0 setcoords makewindow $revtreeargs readrefs -getcommits $revtreeargs +parse_args $revtreeargs +set args $parsed_args +if {$cmdline_files ne {}} { + # create a view for the files/dirs specified on the command line + set curview 1 + set nextviewnum 2 + set viewname(1) "Command line" + set viewfiles(1) $cmdline_files + .bar.view add command -label $viewname(1) -command {showview 1} + .bar.view entryconf 2 -state normal + set args [concat $args "--" $cmdline_files] +} +getcommits $args From d94f8cd6adc746b850aad421e30d5f90f7f11ee4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Apr 2006 10:18:23 +1000 Subject: [PATCH 2/8] gitk: Make File->Update work properly again If a view is selected it will now just update that view. Also fixed a few other things - if you switch away from a view while gitk is still reading it in, then switch back, gitk will re-read it from scratch. We now re-read the references when switching views. If something was selected before a view change, and we need to read in the new view, we now select the previously-selected commit when we come across it. Fixed a bug in setting of rowrangelist plus a couple of other minor things. Signed-off-by: Paul Mackerras --- gitk | 59 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/gitk b/gitk index 961b582a4..c6649a56d 100755 --- a/gitk +++ b/gitk @@ -22,8 +22,8 @@ proc parse_args {rargs} { set parsed_args {} set cmdline_files {} if {[catch { - set parse_args [concat --default HEAD $rargs] - set args [split [eval exec git-rev-parse $parse_args] "\n"] + set args [concat --default HEAD $rargs] + set args [split [eval exec git-rev-parse $args] "\n"] set i 0 foreach arg $args { if {![regexp {^[0-9a-f]{40}$} $arg]} { @@ -217,17 +217,13 @@ proc readcommit {id} { } proc updatecommits {} { - global parsed_args + global viewdata curview revtreeargs - unselectline - stopfindproc - foreach v {matchinglines treediffs currentid} { - global $v - catch {unset $v} - } - clear_display - readrefs - getcommits $parsed_args + set n $curview + set curview -1 + catch {unset viewdata($n)} + parse_args $revtreeargs + showview $n } proc parsecommit {id contents listed} { @@ -354,7 +350,7 @@ proc error_popup msg { tkwait window $w } -proc makewindow {rargs} { +proc makewindow {} { global canv canv2 canv3 linespc charspc ctext cflist textfont global findtype findtypemenu findloc findstring fstring geometry global entries sha1entry sha1string sha1but @@ -817,13 +813,6 @@ proc delview {} { showview 0 } -proc saveview {} { - global curview viewdata - global displayorder parentlist childlist rowidlist rowoffsets - global rowrangelist commitlisted - -} - proc showview {n} { global curview viewdata viewfiles global displayorder parentlist childlist rowidlist rowoffsets @@ -832,6 +821,7 @@ proc showview {n} { global selectedline currentid canv canvy0 global matchinglines treediffs global parsed_args + global pending_select phase if {$n == $curview} return set selid {} @@ -850,7 +840,7 @@ proc showview {n} { } unselectline stopfindproc - if {![info exists viewdata($curview)]} { + if {$curview >= 0 && $phase eq {} && ![info exists viewdata($curview)]} { set viewdata($curview) \ [list $displayorder $parentlist $childlist $rowidlist \ $rowoffsets $rowrangelist $commitlisted] @@ -858,6 +848,7 @@ proc showview {n} { catch {unset matchinglines} catch {unset treediffs} clear_display + readrefs set curview $n .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] @@ -867,6 +858,7 @@ proc showview {n} { if {$viewfiles($n) ne {}} { set args [concat $args "--" $viewfiles($n)] } + set pending_select $selid getcommits $args return } @@ -1036,7 +1028,7 @@ proc initlayout {} { set commitlisted {} set parentlist {} set childlist {} - set rowrangelist {{}} + set rowrangelist {} catch {unset children} set nextcolor 0 set rowidlist {{}} @@ -1099,7 +1091,7 @@ proc layoutmore {} { } proc showstuff {canshow} { - global numcommits + global numcommits commitrow pending_select global linesegends idrowranges idrangedrawn if {$numcommits == 0} { @@ -1113,6 +1105,7 @@ proc showstuff {canshow} { set rows [visiblerows] set r0 [lindex $rows 0] set r1 [lindex $rows 1] + set selrow -1 for {set r $row} {$r < $canshow} {incr r} { if {[info exists linesegends($r)]} { foreach id $linesegends($r) { @@ -1135,6 +1128,11 @@ proc showstuff {canshow} { drawcmitrow $row incr row } + if {[info exists pending_select] && + [info exists commitrow($pending_select)] && + $commitrow($pending_select) < $numcommits} { + selectline $commitrow($pending_select) 1 + } } proc layoutrows {row endrow last} { @@ -1202,10 +1200,12 @@ proc layoutrows {row endrow last} { } else { unset idinlist($id) } + set ranges {} if {[info exists idrowranges($id)]} { lappend idrowranges($id) $row - lappend rowrangelist $idrowranges($id) + set ranges $idrowranges($id) } + lappend rowrangelist $ranges incr row set offs [ntimes [llength $idlist] 0] set l [llength $newolds] @@ -1732,8 +1732,8 @@ proc findcrossings {id} { foreach {s e} [rowranges $id] { if {$e >= $numcommits} { set e [expr {$numcommits - 1}] - if {$e < $s} continue } + if {$e <= $s} continue set x [lsearch -exact [lindex $rowidlist $e] $id] if {$x < 0} { puts "findcrossings: oops, no [shortids $id] in row $e" @@ -2360,7 +2360,7 @@ proc donefilediff {} { } } -proc findcont {id} { +proc findcont {} { global findid treediffs parentlist global ffileline findstartline finddidsel global displayorder numcommits matchinglines findinprogress @@ -2493,8 +2493,9 @@ proc selectline {l isnew} { global canvy0 linespc parentlist childlist global cflist currentid sha1entry global commentend idtags linknum - global mergemax numcommits + global mergemax numcommits pending_select + catch {unset pending_select} $canv delete hover normalline if {$l < 0 || $l >= $numcommits} return @@ -2784,7 +2785,7 @@ proc getmergediffline {mdf id np} { incr nextupdate 100 fileevent $mdf readable {} update - fileevent $mdf readable [list getmergediffline $mdf $id] + fileevent $mdf readable [list getmergediffline $mdf $id $np] } } @@ -4027,7 +4028,7 @@ set stopped 0 set stuffsaved 0 set patchnum 0 setcoords -makewindow $revtreeargs +makewindow readrefs parse_args $revtreeargs set args $parsed_args From fdedbcfb0d71d99f96e08c1903ce8bd5a8f51a39 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Apr 2006 21:22:52 +1000 Subject: [PATCH 3/8] gitk: Fix various bugs in the view support - don't re-read refs when switching views, it's too slow; just do it if the user did File->Update - make the view menu use the uifont - if we have a graph line selected, unselect it before changing the view - if a row is selected and appears in the new view, but we have to read in the new view, select that row when we come across it - if no row was previously selected, or if we don't find the previously selected row in the new view, select the first row Signed-off-by: Paul Mackerras --- gitk | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gitk b/gitk index cfd0a3a69..093213f24 100755 --- a/gitk +++ b/gitk @@ -223,6 +223,7 @@ proc updatecommits {} { set curview -1 catch {unset viewdata($n)} parse_args $revtreeargs + readrefs showview $n } @@ -351,7 +352,8 @@ proc error_popup msg { } proc makewindow {} { - global canv canv2 canv3 linespc charspc ctext cflist textfont mainfont uifont + global canv canv2 canv3 linespc charspc ctext cflist + global textfont mainfont uifont global findtype findtypemenu findloc findstring fstring geometry global entries sha1entry sha1string sha1but global maincursor textcursor curtextcursor @@ -369,7 +371,7 @@ proc makewindow {} { .bar add cascade -label "Edit" -menu .bar.edit .bar.edit add command -label "Preferences" -command doprefs .bar.edit configure -font $uifont - menu .bar.view + menu .bar.view -font $uifont .bar add cascade -label "View" -menu .bar.view .bar.view add command -label "New view..." -command newview .bar.view add command -label "Delete view" -command delview -state disabled @@ -907,6 +909,7 @@ proc showview {n} { } } unselectline + normalline stopfindproc if {$curview >= 0 && $phase eq {} && ![info exists viewdata($curview)]} { set viewdata($curview) \ @@ -916,7 +919,6 @@ proc showview {n} { catch {unset matchinglines} catch {unset treediffs} clear_display - readrefs set curview $n .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] @@ -1159,7 +1161,7 @@ proc layoutmore {} { } proc showstuff {canshow} { - global numcommits commitrow pending_select + global numcommits commitrow pending_select selectedline global linesegends idrowranges idrangedrawn if {$numcommits == 0} { @@ -1201,6 +1203,9 @@ proc showstuff {canshow} { $commitrow($pending_select) < $numcommits} { selectline $commitrow($pending_select) 1 } + if {![info exists selectedline] && ![info exists pending_select]} { + selectline 0 1 + } } proc layoutrows {row endrow last} { @@ -1989,7 +1994,7 @@ proc xcoord {i level ln} { proc finishcommits {} { global commitidx phase global canv mainfont ctext maincursor textcursor - global findinprogress + global findinprogress pending_select if {$commitidx > 0} { drawrest @@ -2003,6 +2008,7 @@ proc finishcommits {} { settextcursor $textcursor } set phase {} + catch {unset pending_select} } # Don't change the text pane cursor if it is currently the hand cursor, @@ -2021,12 +2027,16 @@ proc drawrest {} { global startmsecs global canvy0 numcommits linespc global rowlaidout commitidx + global pending_select set row $rowlaidout layoutrows $rowlaidout $commitidx 1 layouttail optimize_rows $row 0 $commitidx showstuff $commitidx + if {[info exists pending_select]} { + selectline 0 1 + } set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}] #puts "overall $drawmsecs ms for $numcommits commits" From 22626ef4fd5a0b2cf1fc8e90bbb23f8ff0ed43ea Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 17 Apr 2006 09:56:02 +1000 Subject: [PATCH 4/8] gitk: Don't reread git-rev-list output from scratch on view switch Previously, if we switched away from a view before we had finished reading the git-rev-list output for it and laying out the graph, we would discard the partially-laid-out graph and reread it from scratch if we switched back to the view. With this, we preserve the state of the partially-laid-out graph in viewdata($view) and restore it if we switch back. The pipe to git-rev-list remains open but we just don't read from it any more until we switch back to that view. This also makes linesegends a list rather than an array, which turns out to be slightly faster, as well as being easier to save and restore. The `update' menu item now kills the git-rev-list process if there is one still running when we do the update. Signed-off-by: Paul Mackerras --- gitk | 157 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 116 insertions(+), 41 deletions(-) diff --git a/gitk b/gitk index 093213f24..85f426ab2 100755 --- a/gitk +++ b/gitk @@ -80,6 +80,18 @@ proc start_rev_list {rlargs} { settextcursor watch } +proc stop_rev_list {} { + global commfd + + if {![info exists commfd]} return + catch { + set pid [pid $commfd] + exec kill $pid + } + catch {close $commfd} + unset commfd +} + proc getcommits {rargs} { global phase canv mainfont @@ -173,6 +185,7 @@ proc getcommitlines {commfd} { lappend parentlist $olds if {[info exists children($id)]} { lappend childlist $children($id) + unset children($id) } else { lappend childlist {} } @@ -217,8 +230,12 @@ proc readcommit {id} { } proc updatecommits {} { - global viewdata curview revtreeargs + global viewdata curview revtreeargs phase + if {$phase ne {}} { + stop_rev_list + set phase {} + } set n $curview set curview -1 catch {unset viewdata($n)} @@ -883,6 +900,25 @@ proc delview {} { showview 0 } +proc flatten {var} { + global $var + + set ret {} + foreach i [array names $var] { + lappend ret $i [set $var\($i\)] + } + return $ret +} + +proc unflatten {var l} { + global $var + + catch {unset $var} + foreach {i v} $l { + set $var\($i\) $v + } +} + proc showview {n} { global curview viewdata viewfiles global displayorder parentlist childlist rowidlist rowoffsets @@ -892,6 +928,8 @@ proc showview {n} { global matchinglines treediffs global parsed_args global pending_select phase + global commitidx rowlaidout rowoptim linesegends leftover + global commfd nextupdate if {$n == $curview} return set selid {} @@ -911,10 +949,21 @@ proc showview {n} { unselectline normalline stopfindproc - if {$curview >= 0 && $phase eq {} && ![info exists viewdata($curview)]} { - set viewdata($curview) \ - [list $displayorder $parentlist $childlist $rowidlist \ - $rowoffsets $rowrangelist $commitlisted] + if {$curview >= 0} { + if {$phase ne {}} { + set viewdata($curview) \ + [list $phase $displayorder $parentlist $childlist $rowidlist \ + $rowoffsets $rowrangelist $commitlisted \ + [flatten children] [flatten idrowranges] \ + [flatten idinlist] \ + $commitidx $rowlaidout $rowoptim $numcommits \ + $linesegends $leftover $commfd] + fileevent $commfd readable {} + } elseif {![info exists viewdata($curview)]} { + set viewdata($curview) \ + [list {} $displayorder $parentlist $childlist $rowidlist \ + $rowoffsets $rowrangelist $commitlisted] + } } catch {unset matchinglines} catch {unset treediffs} @@ -933,18 +982,37 @@ proc showview {n} { return } - set displayorder [lindex $viewdata($n) 0] - set parentlist [lindex $viewdata($n) 1] - set childlist [lindex $viewdata($n) 2] - set rowidlist [lindex $viewdata($n) 3] - set rowoffsets [lindex $viewdata($n) 4] - set rowrangelist [lindex $viewdata($n) 5] - set commitlisted [lindex $viewdata($n) 6] - set numcommits [llength $displayorder] + set v $viewdata($n) + set phase [lindex $v 0] + set displayorder [lindex $v 1] + set parentlist [lindex $v 2] + set childlist [lindex $v 3] + set rowidlist [lindex $v 4] + set rowoffsets [lindex $v 5] + set rowrangelist [lindex $v 6] + set commitlisted [lindex $v 7] + if {$phase eq {}} { + set numcommits [llength $displayorder] + catch {unset idrowranges} + catch {unset children} + } else { + unflatten children [lindex $v 8] + unflatten idrowranges [lindex $v 9] + unflatten idinlist [lindex $v 10] + set commitidx [lindex $v 11] + set rowlaidout [lindex $v 12] + set rowoptim [lindex $v 13] + set numcommits [lindex $v 14] + set linesegends [lindex $v 15] + set leftover [lindex $v 16] + set commfd [lindex $v 17] + fileevent $commfd readable [list getcommitlines $commfd] + set nextupdate [expr {[clock clicks -milliseconds] + 100}] + } + catch {unset colormap} catch {unset rowtextx} catch {unset commitrow} - catch {unset idrowranges} set curview $n set row 0 foreach id $displayorder { @@ -1004,20 +1072,21 @@ proc ntimes {n o} { } proc usedinrange {id l1 l2} { - global children commitrow + global children commitrow childlist if {[info exists commitrow($id)]} { set r $commitrow($id) if {$l1 <= $r && $r <= $l2} { return [expr {$r - $l1 + 1}] } + set kids [lindex $childlist $r] + } else { + set kids $children($id) } - foreach c $children($id) { - if {[info exists commitrow($c)]} { - set r $commitrow($c) - if {$l1 <= $r && $r <= $l2} { - return [expr {$r - $l1 + 1}] - } + foreach c $kids { + set r $commitrow($c) + if {$l1 <= $r && $r <= $l2} { + return [expr {$r - $l1 + 1}] } } return 0 @@ -1112,7 +1181,7 @@ proc initlayout {} { catch {unset rowtextx} catch {unset commitrow} catch {unset idrowranges} - catch {unset linesegends} + set linesegends {} } proc setcanvscroll {} { @@ -1177,16 +1246,14 @@ proc showstuff {canshow} { set r1 [lindex $rows 1] set selrow -1 for {set r $row} {$r < $canshow} {incr r} { - if {[info exists linesegends($r)]} { - foreach id $linesegends($r) { - set i -1 - foreach {s e} $idrowranges($id) { - incr i - if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0 - && ![info exists idrangedrawn($id,$i)]} { - drawlineseg $id $i - set idrangedrawn($id,$i) 1 - } + foreach id [lindex $linesegends [expr {$r+1}]] { + set i -1 + foreach {s e} [rowranges $id] { + incr i + if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0 + && ![info exists idrangedrawn($id,$i)]} { + drawlineseg $id $i + set idrangedrawn($id,$i) 1 } } } @@ -1229,6 +1296,7 @@ proc layoutrows {row endrow last} { lappend oldolds $p } } + set lse {} set nev [expr {[llength $idlist] + [llength $newolds] + [llength $oldolds] - $maxwidth + 1}] if {$nev > 0} { @@ -1244,7 +1312,7 @@ proc layoutrows {row endrow last} { set offs [incrange $offs $x 1] set idinlist($i) 0 set rm1 [expr {$row - 1}] - lappend linesegends($rm1) $i + lappend lse $i lappend idrowranges($i) $rm1 if {[incr nev -1] <= 0} break continue @@ -1255,6 +1323,7 @@ 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] @@ -1275,8 +1344,9 @@ proc layoutrows {row endrow last} { } set ranges {} if {[info exists idrowranges($id)]} { - lappend idrowranges($id) $row set ranges $idrowranges($id) + lappend ranges $row + unset idrowranges($id) } lappend rowrangelist $ranges incr row @@ -1331,6 +1401,7 @@ proc addextraid {id row} { } if {[info exists children($id)]} { lappend childlist $children($id) + unset children($id) } else { lappend childlist {} } @@ -1349,6 +1420,7 @@ proc layouttail {} { unset idinlist($id) lappend idrowranges($id) $row lappend rowrangelist $idrowranges($id) + unset idrowranges($id) incr row set offs [ntimes $col 0] set idlist [lreplace $idlist $col $col] @@ -1363,6 +1435,7 @@ proc layouttail {} { makeuparrow $id 0 $row 0 lappend idrowranges($id) $row lappend rowrangelist $idrowranges($id) + unset idrowranges($id) incr row lappend rowidlist {} lappend rowoffsets {} @@ -1398,8 +1471,8 @@ proc optimize_rows {row col endrow} { set z0 [lindex $rowoffsets $y0 $x0] if {$z0 eq {}} { set id [lindex $idlist $col] - if {[info exists idrowranges($id)] && - $y0 > [lindex $idrowranges($id) 0]} { + set ranges [rowranges $id] + if {$ranges ne {} && $y0 > [lindex $ranges 0]} { set isarrow 1 } } @@ -1457,8 +1530,8 @@ proc optimize_rows {row col endrow} { if {$o eq {}} { # check if this is the link to the first child set id [lindex $idlist $col] - if {[info exists idrowranges($id)] && - $row == [lindex $idrowranges($id) 0]} { + set ranges [rowranges $id] + if {$ranges ne {} && $row == [lindex $ranges 0]} { # it is, work out offset to child set y0 [expr {$row - 1}] set id [lindex $displayorder $y0] @@ -1513,10 +1586,11 @@ proc linewidth {id} { } proc rowranges {id} { - global idrowranges commitrow numcommits rowrangelist + global phase idrowranges commitrow rowlaidout rowrangelist set ranges {} - if {[info exists commitrow($id)] && $commitrow($id) < $numcommits} { + if {$phase eq {} || + ([info exists commitrow($id)] && $commitrow($id) < $rowlaidout)} { set ranges [lindex $rowrangelist $commitrow($id)] } elseif {[info exists idrowranges($id)]} { set ranges $idrowranges($id) @@ -1727,6 +1801,7 @@ proc drawcmitrow {row} { if {$row >= $numcommits} return foreach id [lindex $rowidlist $row] { + if {$id eq {}} continue set i -1 foreach {s e} [rowranges $id] { incr i @@ -3142,7 +3217,7 @@ proc incrfont {inc} { foreach e $entries { $e conf -font $mainfont } - if {$phase == "getcommits"} { + if {$phase eq "getcommits"} { $canv itemconf textitems -font $mainfont } redisplay From 2516dae2f63b6e6c4f7dbe2eb1322ba32da092c5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 21 Apr 2006 10:35:31 +1000 Subject: [PATCH 5/8] gitk: Remember the view in the history list When moving backwards or forwards through the history list, this automatically switches the view so that each point that we jump to is shown in the same view that it was originally displayed in. Signed-off-by: Paul Mackerras --- gitk | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/gitk b/gitk index 85f426ab2..305aa2ef0 100755 --- a/gitk +++ b/gitk @@ -959,7 +959,8 @@ proc showview {n} { $commitidx $rowlaidout $rowoptim $numcommits \ $linesegends $leftover $commfd] fileevent $commfd readable {} - } elseif {![info exists viewdata($curview)]} { + } elseif {![info exists viewdata($curview)] + || [lindex $viewdata($curview) 0] ne {}} { set viewdata($curview) \ [list {} $displayorder $parentlist $childlist $rowidlist \ $rowoffsets $rowrangelist $commitlisted] @@ -1035,6 +1036,14 @@ proc showview {n} { allcanvs yview moveto $yf drawvisible selectline $row 0 + if {$phase eq {}} { + global maincursor textcursor + . config -cursor $maincursor + settextcursor $textcursor + } else { + . config -cursor watch + settextcursor watch + } } proc shortids {ids} { @@ -2301,7 +2310,7 @@ proc stopfindproc {{done 0}} { } if {[info exists findinprogress]} { unset findinprogress - if {$phase != "incrdraw"} { + if {$phase eq {}} { . config -cursor $maincursor settextcursor $textcursor } @@ -2840,17 +2849,18 @@ proc unselectline {} { } proc addtohistory {cmd} { - global history historyindex + global history historyindex curview + set elt [list $curview $cmd] if {$historyindex > 0 - && [lindex $history [expr {$historyindex - 1}]] == $cmd} { + && [lindex $history [expr {$historyindex - 1}]] == $elt} { return } if {$historyindex < [llength $history]} { - set history [lreplace $history $historyindex end $cmd] + set history [lreplace $history $historyindex end $elt] } else { - lappend history $cmd + lappend history $elt } incr historyindex if {$historyindex > 1} { @@ -2861,13 +2871,23 @@ proc addtohistory {cmd} { .ctop.top.bar.rightbut conf -state disabled } +proc godo {elt} { + global curview + + set view [lindex $elt 0] + set cmd [lindex $elt 1] + if {$curview != $view} { + showview $view + } + eval $cmd +} + proc goback {} { global history historyindex if {$historyindex > 1} { incr historyindex -1 - set cmd [lindex $history [expr {$historyindex - 1}]] - eval $cmd + godo [lindex $history [expr {$historyindex - 1}]] .ctop.top.bar.rightbut conf -state normal } if {$historyindex <= 1} { @@ -2881,7 +2901,7 @@ proc goforw {} { if {$historyindex < [llength $history]} { set cmd [lindex $history $historyindex] incr historyindex - eval $cmd + godo $cmd .ctop.top.bar.leftbut conf -state normal } if {$historyindex >= [llength $history]} { From a8aaf19c419a30d335f0640ab644112ecda6dd12 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 23 Apr 2006 22:45:55 +1000 Subject: [PATCH 6/8] gitk: Use git-rev-parse only to identify file/dir names on cmd line This uses git-rev-parse --no-revs --no-flags to give us just the file and directory names on the command line, so that we can create the "Command line" view if any were specified. All other arguments just get passed to git-rev-list (without a pass through git-rev-parse). Signed-off-by: Paul Mackerras --- gitk | 73 +++++++++++++++++++----------------------------------------- 1 file changed, 23 insertions(+), 50 deletions(-) diff --git a/gitk b/gitk index 305aa2ef0..6cefc8721 100755 --- a/gitk +++ b/gitk @@ -16,56 +16,26 @@ proc gitdir {} { } } -proc parse_args {rargs} { - global parsed_args cmdline_files - - set parsed_args {} - set cmdline_files {} - if {[catch { - set args [concat --default HEAD $rargs] - set args [split [eval exec git-rev-parse $args] "\n"] - set i 0 - foreach arg $args { - if {![regexp {^[0-9a-f]{40}$} $arg]} { - if {$arg eq "--"} { - incr i - } - set cmdline_files [lrange $args $i end] - break - } - lappend parsed_args $arg - incr i - } - }]} { - # if git-rev-parse failed for some reason... - set i [lsearch -exact $rargs "--"] - if {$i >= 0} { - set cmdline_files [lrange $rargs [expr {$i+1}] end] - set rargs [lrange $rargs 0 [expr {$i-1}]] - } - if {$rargs == {}} { - set parsed_args HEAD - } else { - set parsed_args $rargs - } - } -} - -proc start_rev_list {rlargs} { +proc start_rev_list {} { global startmsecs nextupdate ncmupdate global commfd leftover tclencoding datemode + global revtreeargs curview viewfiles set startmsecs [clock clicks -milliseconds] set nextupdate [expr {$startmsecs + 100}] set ncmupdate 1 initlayout + set args $revtreeargs + if {$viewfiles($curview) ne {}} { + set args [concat $args "--" $viewfiles($curview)] + } set order "--topo-order" if {$datemode} { set order "--date-order" } if {[catch { set commfd [open [concat | git-rev-list --header $order \ - --parents --boundary $rlargs] r] + --parents --boundary --default HEAD $args] r] } err]} { puts stderr "Error executing git-rev-list: $err" exit 1 @@ -92,11 +62,11 @@ proc stop_rev_list {} { unset commfd } -proc getcommits {rargs} { +proc getcommits {} { global phase canv mainfont set phase getcommits - start_rev_list $rargs + start_rev_list $canv delete all $canv create text 3 3 -anchor nw -text "Reading commits..." \ -font $mainfont -tags textitems @@ -239,7 +209,6 @@ proc updatecommits {} { set n $curview set curview -1 catch {unset viewdata($n)} - parse_args $revtreeargs readrefs showview $n } @@ -926,7 +895,6 @@ proc showview {n} { global numcommits rowrangelist commitlisted idrowranges global selectedline currentid canv canvy0 global matchinglines treediffs - global parsed_args global pending_select phase global commitidx rowlaidout rowoptim linesegends leftover global commfd nextupdate @@ -974,12 +942,8 @@ proc showview {n} { .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] if {![info exists viewdata($n)]} { - set args $parsed_args - if {$viewfiles($n) ne {}} { - set args [concat $args "--" $viewfiles($n)] - } set pending_select $selid - getcommits $args + getcommits return } @@ -4252,8 +4216,18 @@ set patchnum 0 setcoords makewindow readrefs -parse_args $revtreeargs -set args $parsed_args + +set cmdline_files {} +catch { + set fileargs [eval exec git-rev-parse --no-revs --no-flags $revtreeargs] + set cmdline_files [split $fileargs "\n"] + set n [llength $cmdline_files] + set revtreeargs [lrange $revtreeargs 0 end-$n] +} +if {[lindex $revtreeargs end] eq "--"} { + set revtreeargs [lrange $revtreeargs 0 end-1] +} + if {$cmdline_files ne {}} { # create a view for the files/dirs specified on the command line set curview 1 @@ -4262,6 +4236,5 @@ if {$cmdline_files ne {}} { set viewfiles(1) $cmdline_files .bar.view add command -label $viewname(1) -command {showview 1} .bar.view entryconf 2 -state normal - set args [concat $args "--" $cmdline_files] } -getcommits $args +getcommits From a90a6d249bc4fe29c11ce3291f9ec90d8e5e67f4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 25 Apr 2006 17:12:46 +1000 Subject: [PATCH 7/8] gitk: Implement "permanent" views (stored in ~/.gitk) With this the user can now mark a view as "permanent" and it will appear in the list every time gitk is started (until it is deleted). Also tidied up the view definition window, and changed the view menu to use radiobuttons for the view selections so there is some feedback as to which is the current view. Signed-off-by: Paul Mackerras --- gitk | 61 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/gitk b/gitk index 4ee51223b..6d6a2f32c 100755 --- a/gitk +++ b/gitk @@ -362,7 +362,8 @@ proc makewindow {} { .bar.view add command -label "New view..." -command newview .bar.view add command -label "Delete view" -command delview -state disabled .bar.view add separator - .bar.view add command -label "All files" -command {showview 0} + .bar.view add radiobutton -label "All files" -command {showview 0} \ + -variable selectedview -value 0 menu .bar.help .bar add cascade -label "Help" -menu .bar.help .bar.help add command -label "About gitk" -command about @@ -632,6 +633,7 @@ proc savestuff {w} { global canv canv2 canv3 ctext cflist mainfont textfont uifont global stuffsaved findmergefiles maxgraphpct global maxwidth + global viewname viewfiles viewperm nextviewnum if {$stuffsaved} return if {![winfo viewable .]} return @@ -655,6 +657,13 @@ proc savestuff {w} { set wid [expr {([winfo width $cflist] - 11) \ / [font measure [$cflist cget -font] "0"]}] puts $f "set geometry(cflistw) $wid" + puts -nonewline $f "set permviews {" + for {set v 0} {$v < $nextviewnum} {incr v} { + if {$viewperm($v)} { + puts $f "{[list $viewname($v) $viewfiles($v)]}" + } + } + puts $f "}" close $f file rename -force "~/.gitk-new" "~/.gitk" } @@ -797,7 +806,7 @@ f Scroll diff view to next file } proc newview {} { - global newviewname nextviewnum newviewtop + global newviewname nextviewnum newviewtop newviewperm uifont set top .gitkview if {[winfo exists $top]} { @@ -807,14 +816,18 @@ proc newview {} { set newviewtop $top toplevel $top wm title $top "Gitk view definition" - label $top.nl -text "Name" + label $top.nl -text "Name" -font $uifont entry $top.name -width 20 -textvariable newviewname set newviewname "View $nextviewnum" - grid $top.nl $top.name -sticky w - label $top.l -text "Files and directories to include:" - grid $top.l - -sticky w -pady 10 - text $top.t -width 30 -height 10 - grid $top.t - -sticky w + grid $top.nl $top.name -sticky w -pady 5 + set newviewperm 0 + checkbutton $top.perm -text "Remember this view" -variable newviewperm + grid $top.perm - -pady 5 -sticky w + message $top.l -aspect 500 -font $uifont \ + -text "Enter files and directories to include, one per line:" + grid $top.l - -sticky w + text $top.t -width 40 -height 10 -background white + grid $top.t - -sticky w -padx 5 frame $top.buts button $top.buts.ok -text "OK" -command newviewok button $top.buts.can -text "Cancel" -command newviewcan @@ -826,12 +839,13 @@ proc newview {} { } proc newviewok {} { - global newviewtop nextviewnum - global viewname viewfiles + global newviewtop nextviewnum newviewperm + global viewname viewfiles viewperm selectedview set n $nextviewnum incr nextviewnum set viewname($n) [$newviewtop.name get] + set viewperm($n) $newviewperm set files {} foreach f [split [$newviewtop.t get 0.0 end] "\n"] { set ft [string trim $f] @@ -842,7 +856,8 @@ proc newviewok {} { set viewfiles($n) $files catch {destroy $newviewtop} unset newviewtop - .bar.view add command -label $viewname($n) -command [list showview $n] + .bar.view add radiobutton -label $viewname($n) \ + -command [list showview $n] -variable selectedview -value $n after idle showview $n } @@ -854,7 +869,7 @@ proc newviewcan {} { } proc delview {} { - global curview viewdata + global curview viewdata viewperm if {$curview == 0} return set nmenu [.bar.view index end] @@ -866,6 +881,7 @@ proc delview {} { } } set viewdata($curview) {} + set viewperm($curview) 0 showview 0 } @@ -898,6 +914,7 @@ proc showview {n} { global pending_select phase global commitidx rowlaidout rowoptim linesegends leftover global commfd nextupdate + global selectedview if {$n == $curview} return set selid {} @@ -939,6 +956,7 @@ proc showview {n} { clear_display set curview $n + set selectedview $n .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] if {![info exists viewdata($n)]} { @@ -4209,7 +4227,9 @@ set optim_delay 16 set nextviewnum 1 set curview 0 +set selectedview 0 set viewfiles(0) {} +set viewperm(0) 0 set stopped 0 set stuffsaved 0 @@ -4232,10 +4252,25 @@ if {[lindex $revtreeargs end] eq "--"} { if {$cmdline_files ne {}} { # create a view for the files/dirs specified on the command line set curview 1 + set selectedview 1 set nextviewnum 2 set viewname(1) "Command line" set viewfiles(1) $cmdline_files - .bar.view add command -label $viewname(1) -command {showview 1} + set viewperm(1) 0 + .bar.view add radiobutton -label $viewname(1) -command {showview 1} \ + -variable selectedview -value 1 .bar.view entryconf 2 -state normal } + +if {[info exists permviews]} { + foreach v $permviews { + set n $nextviewnum + incr nextviewnum + set viewname($n) [lindex $v 0] + set viewfiles($n) [lindex $v 1] + set viewperm($n) 1 + .bar.view add radiobutton -label $viewname($n) \ + -command [list showview $n] -variable selectedview -value $n + } +} getcommits From d16c0812a9472794175b2543c2aa2df45a927202 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 25 Apr 2006 21:21:10 +1000 Subject: [PATCH 8/8] gitk: add menu item for editing the current view This allows the user to change the name of the view, whether it is permanent, and the list of files/directories for the view. Signed-off-by: Paul Mackerras --- gitk | 127 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 37 deletions(-) diff --git a/gitk b/gitk index 6d6a2f32c..a33a1e8a9 100755 --- a/gitk +++ b/gitk @@ -360,6 +360,7 @@ proc makewindow {} { menu .bar.view -font $uifont .bar add cascade -label "View" -menu .bar.view .bar.view add command -label "New view..." -command newview + .bar.view add command -label "Edit view..." -command editview .bar.view add command -label "Delete view" -command delview -state disabled .bar.view add separator .bar.view add radiobutton -label "All files" -command {showview 0} \ @@ -806,31 +807,59 @@ f Scroll diff view to next file } proc newview {} { - global newviewname nextviewnum newviewtop newviewperm uifont + global nextviewnum newviewname newviewperm uifont set top .gitkview if {[winfo exists $top]} { raise $top return } - set newviewtop $top + set newviewname($nextviewnum) "View $nextviewnum" + set newviewperm($nextviewnum) 0 + vieweditor $top $nextviewnum "Gitk view definition" +} + +proc editview {} { + global curview + global viewname viewperm newviewname newviewperm + + set top .gitkvedit-$curview + if {[winfo exists $top]} { + raise $top + return + } + set newviewname($curview) $viewname($curview) + set newviewperm($curview) $viewperm($curview) + vieweditor $top $curview "Gitk: edit view $viewname($curview)" +} + +proc vieweditor {top n title} { + global newviewname newviewperm viewfiles + global uifont + toplevel $top - wm title $top "Gitk view definition" + wm title $top $title label $top.nl -text "Name" -font $uifont - entry $top.name -width 20 -textvariable newviewname - set newviewname "View $nextviewnum" + entry $top.name -width 20 -textvariable newviewname($n) grid $top.nl $top.name -sticky w -pady 5 - set newviewperm 0 - checkbutton $top.perm -text "Remember this view" -variable newviewperm + checkbutton $top.perm -text "Remember this view" -variable newviewperm($n) grid $top.perm - -pady 5 -sticky w message $top.l -aspect 500 -font $uifont \ -text "Enter files and directories to include, one per line:" grid $top.l - -sticky w text $top.t -width 40 -height 10 -background white + if {[info exists viewfiles($n)]} { + foreach f $viewfiles($n) { + $top.t insert end $f + $top.t insert end "\n" + } + $top.t delete {end - 1c} end + $top.t mark set insert 0.0 + } grid $top.t - -sticky w -padx 5 frame $top.buts - button $top.buts.ok -text "OK" -command newviewok - button $top.buts.can -text "Cancel" -command newviewcan + button $top.buts.ok -text "OK" -command [list newviewok $top $n] + button $top.buts.can -text "Cancel" -command [list destroy $top] grid $top.buts.ok $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -838,47 +867,64 @@ proc newview {} { focus $top.t } -proc newviewok {} { - global newviewtop nextviewnum newviewperm - global viewname viewfiles viewperm selectedview +proc viewmenuitem {n} { + set nmenu [.bar.view index end] + set targetcmd [list showview $n] + for {set i 6} {$i <= $nmenu} {incr i} { + if {[.bar.view entrycget $i -command] eq $targetcmd} { + return $i + } + } + return {} +} + +proc newviewok {top n} { + global nextviewnum newviewperm newviewname + global viewname viewfiles viewperm selectedview curview - set n $nextviewnum - incr nextviewnum - set viewname($n) [$newviewtop.name get] - set viewperm($n) $newviewperm set files {} - foreach f [split [$newviewtop.t get 0.0 end] "\n"] { + foreach f [split [$top.t get 0.0 end] "\n"] { set ft [string trim $f] if {$ft ne {}} { lappend files $ft } } - set viewfiles($n) $files - catch {destroy $newviewtop} - unset newviewtop - .bar.view add radiobutton -label $viewname($n) \ - -command [list showview $n] -variable selectedview -value $n - after idle showview $n -} - -proc newviewcan {} { - global newviewtop - - catch {destroy $newviewtop} - unset newviewtop + if {![info exists viewfiles($n)]} { + # creating a new view + incr nextviewnum + set viewname($n) $newviewname($n) + set viewperm($n) $newviewperm($n) + set viewfiles($n) $files + .bar.view add radiobutton -label $viewname($n) \ + -command [list showview $n] -variable selectedview -value $n + after idle showview $n + } else { + # editing an existing view + set viewperm($n) $newviewperm($n) + if {$newviewname($n) ne $viewname($n)} { + set viewname($n) $newviewname($n) + set i [viewmenuitem $n] + if {$i ne {}} { + .bar.view entryconf $i -label $viewname($n) + } + } + if {$files ne $viewfiles($n)} { + set viewfiles($n) $files + if {$curview == $n} { + after idle updatecommits + } + } + } + catch {destroy $top} } proc delview {} { global curview viewdata viewperm if {$curview == 0} return - set nmenu [.bar.view index end] - set targetcmd [list showview $curview] - for {set i 5} {$i <= $nmenu} {incr i} { - if {[.bar.view entrycget $i -command] eq $targetcmd} { - .bar.view delete $i - break - } + set i [viewmenuitem $curview] + if {$i ne {}} { + .bar.view delete $i } set viewdata($curview) {} set viewperm($curview) 0 @@ -958,6 +1004,7 @@ proc showview {n} { set curview $n set selectedview $n .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] + .bar.view entryconf 3 -state [expr {$n == 0? "disabled": "normal"}] if {![info exists viewdata($n)]} { set pending_select $selid @@ -1025,6 +1072,11 @@ proc showview {n} { } else { . config -cursor watch settextcursor watch + if {$phase eq "getcommits"} { + global mainfont + $canv create text 3 3 -anchor nw -text "Reading commits..." \ + -font $mainfont -tags textitems + } } } @@ -4260,6 +4312,7 @@ if {$cmdline_files ne {}} { .bar.view add radiobutton -label $viewname(1) -command {showview 1} \ -variable selectedview -value 1 .bar.view entryconf 2 -state normal + .bar.view entryconf 3 -state normal } if {[info exists permviews]} {