}
}
-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
settextcursor watch
}
-proc getcommits {rargs} {
+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 {} {
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
lappend parentlist $olds
if {[info exists children($id)]} {
lappend childlist $children($id)
+ unset children($id)
} else {
lappend childlist {}
}
}
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)}
- parse_args $revtreeargs
readrefs
showview $n
}
.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
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
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"
}
}
proc newview {} {
- global newviewname nextviewnum newviewtop
+ global newviewname nextviewnum newviewtop newviewperm uifont
set top .gitkview
if {[winfo exists $top]} {
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
}
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]
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
}
}
proc delview {} {
- global curview viewdata
+ global curview viewdata viewperm
if {$curview == 0} return
set nmenu [.bar.view index end]
}
}
set viewdata($curview) {}
+ set viewperm($curview) 0
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
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
+ global selectedview
if {$n == $curview} return
set selid {}
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)]
+ || [lindex $viewdata($curview) 0] ne {}} {
+ set viewdata($curview) \
+ [list {} $displayorder $parentlist $childlist $rowidlist \
+ $rowoffsets $rowrangelist $commitlisted]
+ }
}
catch {unset matchinglines}
catch {unset treediffs}
clear_display
set curview $n
+ set selectedview $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
}
- 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 {
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} {
}
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
catch {unset rowtextx}
catch {unset commitrow}
catch {unset idrowranges}
- catch {unset linesegends}
+ set linesegends {}
}
proc setcanvscroll {} {
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
}
}
}
lappend oldolds $p
}
}
+ set lse {}
set nev [expr {[llength $idlist] + [llength $newolds]
+ [llength $oldolds] - $maxwidth + 1}]
if {$nev > 0} {
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
lset rowidlist $row $idlist
lset rowoffsets $row $offs
}
+ lappend linesegends $lse
set col [lsearch -exact $idlist $id]
if {$col < 0} {
set col [llength $idlist]
}
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
proc addextraid {id row} {
global displayorder commitrow commitinfo
- global commitidx
+ global commitidx commitlisted
global parentlist childlist children
incr commitidx
lappend displayorder $id
+ lappend commitlisted 0
lappend parentlist {}
set commitrow($id) $row
readcommit $id
}
if {[info exists children($id)]} {
lappend childlist $children($id)
+ unset children($id)
} else {
lappend childlist {}
}
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]
makeuparrow $id 0 $row 0
lappend idrowranges($id) $row
lappend rowrangelist $idrowranges($id)
+ unset idrowranges($id)
incr row
lappend rowidlist {}
lappend rowoffsets {}
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
}
}
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]
}
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)
proc drawcmitrow {row} {
global displayorder rowidlist
global idrangedrawn iddrawn
- global commitinfo commitlisted parentlist numcommits
+ global commitinfo parentlist numcommits
if {$row >= $numcommits} return
foreach id [lindex $rowidlist $row] {
+ if {$id eq {}} continue
set i -1
foreach {s e} [rowranges $id] {
incr i
}
if {[info exists findinprogress]} {
unset findinprogress
- if {$phase != "incrdraw"} {
+ if {$phase eq {}} {
. config -cursor $maincursor
settextcursor $textcursor
}
}
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} {
.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} {
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]} {
foreach e $entries {
$e conf -font $mainfont
}
- if {$phase == "getcommits"} {
+ if {$phase eq "getcommits"} {
$canv itemconf textitems -font $mainfont
}
redisplay
set nextviewnum 1
set curview 0
+set selectedview 0
set viewfiles(0) {}
+set viewperm(0) 0
set stopped 0
set stuffsaved 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
+ 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
- set args [concat $args "--" $cmdline_files]
}
-getcommits $args
+
+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