global displayorder commitidx commitrow commitdata
global parentlist children curview hlview
global vparentlist vdisporder vcmitlisted
- global ordertok vnextroot
+ global ordertok vnextroot idpending
set stuff [read $fd 500000]
# git log doesn't terminate the last commit with a null...
if {![eof $fd]} {
return 1
}
+ # Check if we have seen any ids listed as parents that haven't
+ # appeared in the list
+ foreach vid [array names idpending "$view,*"] {
+ # should only get here if git log is buggy
+ set id [lindex [split $vid ","] 1]
+ set commitrow($vid) $commitidx($view)
+ incr commitidx($view)
+ if {$view == $curview} {
+ lappend parentlist {}
+ lappend displayorder $id
+ lappend commitlisted 0
+ } else {
+ lappend vparentlist($view) {}
+ lappend vdisporder($view) $id
+ lappend vcmitlisted($view) 0
+ }
+ }
global viewname
unset commfd($view)
notbusy $view
set ordertok($view,$id) $otok
} else {
set otok $ordertok($view,$id)
+ unset idpending($view,$id)
}
if {$listed} {
set olds [lrange $ids 1 end]
lappend children($view,$p) $id
if {![info exists ordertok($view,$p)]} {
set ordertok($view,$p) $ordertok($view,$id)
+ set idpending($view,$p) 1
}
} else {
set i 0
}
if {![info exists ordertok($view,$p)]} {
set ordertok($view,$p) "$otok[strrep $i]]"
+ set idpending($view,$p) 1
}
incr i
}
}
proc updatecommits {} {
- global viewdata curview phase displayorder
+ global viewdata curview phase displayorder ordertok idpending
global children commitrow selectedline thickerline showneartags
if {$phase ne {}} {
foreach id $displayorder {
catch {unset children($n,$id)}
catch {unset commitrow($n,$id)}
+ catch {unset ordertok($n,$id)}
+ }
+ foreach vid [array names idpending "$n,*"] {
+ unset idpending($vid)
}
set curview -1
catch {unset selectedline}
global curview viewdata viewfiles
global displayorder parentlist rowidlist
global colormap rowtextx commitrow nextcolor canvxmax
- global numcommits rowrangelist commitlisted idrowranges rowchk
+ global numcommits commitlisted rowchk
global selectedline currentid canv canvy0
global treediffs
global pending_select phase
global commfd
global selectedview selectfirst
global vparentlist vdisporder vcmitlisted
- global hlview selectedhlview
+ global hlview selectedhlview commitinterest
if {$n == $curview} return
set selid {}
set vcmitlisted($curview) $commitlisted
if {$phase ne {}} {
set viewdata($curview) \
- [list $phase $rowidlist {} $rowrangelist \
- [flatten idrowranges] [flatten idinlist] \
- $rowlaidout $rowoptim $numcommits]
+ [list $phase $rowidlist $rowlaidout $rowoptim $numcommits]
} elseif {![info exists viewdata($curview)]
|| [lindex $viewdata($curview) 0] ne {}} {
set viewdata($curview) \
- [list {} $rowidlist {} $rowrangelist]
+ [list {} $rowidlist]
}
}
catch {unset treediffs}
unset hlview
set selectedhlview None
}
+ catch {unset commitinterest}
set curview $n
set selectedview $n
set parentlist $vparentlist($n)
set commitlisted $vcmitlisted($n)
set rowidlist [lindex $v 1]
- set rowrangelist [lindex $v 3]
if {$phase eq {}} {
set numcommits [llength $displayorder]
- catch {unset idrowranges}
} else {
- unflatten idrowranges [lindex $v 4]
- unflatten idinlist [lindex $v 5]
- set rowlaidout [lindex $v 6]
- set rowoptim [lindex $v 7]
- set numcommits [lindex $v 8]
+ set rowlaidout [lindex $v 2]
+ set rowoptim [lindex $v 3]
+ set numcommits [lindex $v 4]
catch {unset rowchk}
}
}
set hlview $n
if {$n != $curview && ![info exists viewdata($n)]} {
- set viewdata($n) [list getcommits {{}} {{}} {} {} {} 0 0 0 {}]
+ set viewdata($n) [list getcommits {{}} 0 0 0]
set vparentlist($n) {}
set vdisporder($n) {}
set vcmitlisted($n) {}
}
set kids $children($curview,$id)
foreach c $kids {
- set r $commitrow($curview,$c)
- if {$l1 <= $r && $r <= $l2} {
- return [expr {$r - $l1 + 1}]
+ if {[info exists commitrow($curview,$c)]} {
+ set r $commitrow($curview,$c)
+ if {$l1 <= $r && $r <= $l2} {
+ return [expr {$r - $l1 + 1}]
+ }
}
}
return 0
}
proc makeuparrow {oid y x} {
- global rowidlist uparrowlen idrowranges displayorder
+ global rowidlist uparrowlen displayorder
for {set i 0} {$i < $uparrowlen && $y > 1} {incr i} {
incr y -1
set x [idcol $idl $oid $x]
lset rowidlist $y [linsert $idl $x $oid]
}
- lappend idrowranges($oid) [lindex $displayorder $y]
}
proc initlayout {} {
global rowidlist displayorder commitlisted
global rowlaidout rowoptim
- global idinlist rowchk rowrangelist idrowranges
+ global rowchk
global numcommits canvxmax canv
global nextcolor
global parentlist
set displayorder {}
set commitlisted {}
set parentlist {}
- set rowrangelist {}
set nextcolor 0
set rowidlist {{}}
- catch {unset idinlist}
catch {unset rowchk}
set rowlaidout 0
set rowoptim 0
set canvxmax [$canv cget -width]
catch {unset colormap}
catch {unset rowtextx}
- catch {unset idrowranges}
set selectfirst 1
}
proc layoutmore {tmax allread} {
global rowlaidout rowoptim commitidx numcommits optim_delay
- global uparrowlen curview rowidlist idinlist
+ global uparrowlen curview rowidlist
set showlast 0
set showdelay $optim_delay
} elseif {$allread} {
set optdelay 0
set nrows $commitidx($curview)
- if {[lindex $rowidlist $nrows] ne {} ||
- [array names idinlist] ne {}} {
+ if {[lindex $rowidlist $nrows] ne {}} {
layouttail
set rowlaidout $commitidx($curview)
} elseif {$rowoptim == $nrows} {
global rowidlist displayorder
global uparrowlen downarrowlen maxwidth mingaplen
global children parentlist
- global idrowranges
global commitidx curview
- global idinlist rowchk rowrangelist
+ global rowchk
set idlist [lindex $rowidlist $row]
while {$row < $endrow} {
[expr {$row + $uparrowlen + $mingaplen}]]
if {$r == 0} {
set idlist [lreplace $idlist $x $x]
- set idinlist($i) 0
- set rm1 [expr {$row - 1}]
- lappend idrowranges($i) [lindex $displayorder $rm1]
continue
}
set rowchk($i) [expr {$row + $r}]
set oldolds {}
set newolds {}
foreach p [lindex $parentlist $row] {
- if {![info exists idinlist($p)]} {
+ # is id the first child of this parent?
+ if {$id eq [lindex $children($curview,$p) 0]} {
lappend newolds $p
- } elseif {!$idinlist($p)} {
+ } elseif {[lsearch -exact $idlist $p] < 0} {
lappend oldolds $p
}
- set idinlist($p) 1
}
set col [lsearch -exact $idlist $id]
if {$col < 0} {
set idlist [linsert $idlist $col $id]
lset rowidlist $row $idlist
if {$children($curview,$id) ne {}} {
- unset idinlist($id)
makeuparrow $id $row $col
}
- } else {
- unset idinlist($id)
- }
- set ranges {}
- if {[info exists idrowranges($id)]} {
- set ranges $idrowranges($id)
- lappend ranges $id
- unset idrowranges($id)
}
- lappend rowrangelist $ranges
incr row
set idlist [lreplace $idlist $col $col]
set x $col
foreach i $newolds {
set x [idcol $idlist $i $x]
set idlist [linsert $idlist $x $i]
- set idrowranges($i) $id
}
foreach oid $oldolds {
set x [idcol $idlist $oid $x]
}
proc layouttail {} {
- global rowidlist idinlist commitidx curview
- global idrowranges rowrangelist
+ global rowidlist commitidx curview
set row $commitidx($curview)
set idlist [lindex $rowidlist $row]
set col [expr {[llength $idlist] - 1}]
set id [lindex $idlist $col]
addextraid $id $row
- catch {unset idinlist($id)}
- lappend idrowranges($id) $id
- lappend rowrangelist $idrowranges($id)
- unset idrowranges($id)
incr row
set idlist [lreplace $idlist $col $col]
lappend rowidlist $idlist
}
-
- foreach id [array names idinlist] {
- unset idinlist($id)
- addextraid $id $row
- lset rowidlist $row [list $id]
- makeuparrow $id $row 0
- lappend idrowranges($id) $id
- lappend rowrangelist $idrowranges($id)
- unset idrowranges($id)
- incr row
- lappend rowidlist {}
- }
}
proc insert_pad {row col npad} {
}
proc optimize_rows {row col endrow} {
- global rowidlist displayorder
+ global rowidlist displayorder curview children
if {$row < 1} {
set row 1
}
}
if {$z0 eq {}} {
- set ranges [rowranges $id]
- if {$ranges ne {} && $y0 > [lindex $ranges 0]} {
+ # if row y0 is the first child of $id then it's not an arrow
+ if {[lindex $children($curview,$id) 0] ne
+ [lindex $displayorder $y0]} {
set isarrow 1
}
}
set x0 [lsearch -exact $previdlist $id]
if {$x0 < 0} {
# check if this is the link to the first child
- set ranges [rowranges $id]
- if {$ranges ne {} && $row == [lindex $ranges 0]} {
+ set kid [lindex $displayorder $y0]
+ if {[lindex $children($curview,$id) 0] eq $kid} {
# it is, work out offset to child
- set id [lindex $displayorder $y0]
- set x0 [lsearch -exact $previdlist $id]
+ set x0 [lsearch -exact $previdlist $kid]
}
}
if {$x0 <= $col} break
}
proc rowranges {id} {
- global phase idrowranges commitrow rowlaidout rowrangelist curview
+ global commitrow curview children uparrowlen downarrowlen
+ global rowidlist
- set ranges {}
- if {$phase eq {} ||
- ([info exists commitrow($curview,$id)]
- && $commitrow($curview,$id) < $rowlaidout)} {
- set ranges [lindex $rowrangelist $commitrow($curview,$id)]
- } elseif {[info exists idrowranges($id)]} {
- set ranges $idrowranges($id)
- }
- set linenos {}
- foreach rid $ranges {
- lappend linenos $commitrow($curview,$rid)
+ set kids $children($curview,$id)
+ if {$kids eq {}} {
+ return {}
}
- if {$linenos ne {}} {
- lset linenos 0 [expr {[lindex $linenos 0] + 1}]
+ set ret {}
+ lappend kids $id
+ foreach child $kids {
+ if {![info exists commitrow($curview,$child)]} break
+ set row $commitrow($curview,$child)
+ if {![info exists prev]} {
+ lappend ret [expr {$row + 1}]
+ } else {
+ if {$row <= $prevrow} {
+ puts "oops children out of order [shortids $id] $row < [shortids $prev] $prevrow"
+ }
+ # see if the line extends the whole way from prevrow to row
+ if {$row > $prevrow + $uparrowlen + $downarrowlen &&
+ [lsearch -exact [lindex $rowidlist \
+ [expr {int(($row + $prevrow) / 2)}]] $id] < 0} {
+ # it doesn't, see where it ends
+ set r [expr {$prevrow + $downarrowlen}]
+ if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
+ while {[incr r -1] > $prevrow &&
+ [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
+ } else {
+ while {[incr r] <= $row &&
+ [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
+ incr r -1
+ }
+ lappend ret $r
+ # see where it starts up again
+ set r [expr {$row - $uparrowlen}]
+ if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
+ while {[incr r] < $row &&
+ [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
+ } else {
+ while {[incr r -1] >= $prevrow &&
+ [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
+ incr r
+ }
+ lappend ret $r
+ }
+ }
+ if {$child eq $id} {
+ lappend ret $row
+ }
+ set prev $id
+ set prevrow $row
}
- return $linenos
+ return $ret
}
proc drawlineseg {id row endrow arrowlow} {
proc insertrow {row newcmit} {
global displayorder parentlist commitlisted children
global commitrow curview rowidlist numcommits
- global rowrangelist rowlaidout rowoptim numcommits
+ global rowlaidout rowoptim numcommits
global selectedline rowchk commitidx
if {$row >= $numcommits} {
}
set rowidlist [linsert $rowidlist $row $idlist]
- set rowrangelist [linsert $rowrangelist $row {}]
- if {[llength $kids] > 1} {
- set rp1 [expr {$row + 1}]
- set ranges [lindex $rowrangelist $rp1]
- if {$ranges eq {}} {
- set ranges [list $newcmit $p]
- } elseif {[lindex $ranges end-1] eq $p} {
- lset ranges end-1 $newcmit
- }
- lset rowrangelist $rp1 $ranges
- }
-
catch {unset rowchk}
incr rowlaidout
proc removerow {row} {
global displayorder parentlist commitlisted children
global commitrow curview rowidlist numcommits
- global rowrangelist idrowranges rowlaidout rowoptim numcommits
+ global rowlaidout rowoptim numcommits
global linesegends selectedline rowchk commitidx
if {$row >= $numcommits} {
set rowidlist [lreplace $rowidlist $row $row]
- set rowrangelist [lreplace $rowrangelist $row $row]
- if {[llength $kids] > 0} {
- set ranges [lindex $rowrangelist $row]
- if {[lindex $ranges end-1] eq $id} {
- set ranges [lreplace $ranges end-1 end]
- lset rowrangelist $row $ranges
- }
- }
-
catch {unset rowchk}
incr rowlaidout -1
set last 0
for {} {$l > $lim} {incr l -1} {
set id [lindex $displayorder $l]
+ if {![info exists commitdata($id)]} continue
if {![doesmatch $commitdata($id)]} continue
if {![info exists commitinfo($id)]} {
getcommit $id
# append some text to the ctext widget, and make any SHA1 ID
# that we know about be a clickable link.
proc appendwithlinks {text tags} {
- global ctext commitrow linknum curview
+ global ctext commitrow linknum curview pendinglinks
set start [$ctext index "end - 1c"]
$ctext insert end $text $tags
set s [lindex $l 0]
set e [lindex $l 1]
set linkid [string range $text $s $e]
- if {![info exists commitrow($curview,$linkid)]} continue
incr e
- $ctext tag add link "$start + $s c" "$start + $e c"
$ctext tag add link$linknum "$start + $s c" "$start + $e c"
- $ctext tag bind link$linknum <1> \
- [list selectline $commitrow($curview,$linkid) 1]
+ setlink $linkid link$linknum
incr linknum
}
- $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 }
+}
+
+proc setlink {id lk} {
+ global curview commitrow ctext pendinglinks commitinterest
+
+ if {[info exists commitrow($curview,$id)]} {
+ $ctext tag conf $lk -foreground blue -underline 1
+ $ctext tag bind $lk <1> [list selectline $commitrow($curview,$id) 1]
+ $ctext tag bind $lk <Enter> {linkcursor %W 1}
+ $ctext tag bind $lk <Leave> {linkcursor %W -1}
+ } else {
+ lappend pendinglinks($id) $lk
+ lappend commitinterest($id) {makelink %I}
+ }
+}
+
+proc makelink {id} {
+ global pendinglinks
+
+ if {![info exists pendinglinks($id)]} return
+ foreach lk $pendinglinks($id) {
+ setlink $id $lk
+ }
+ unset pendinglinks($id)
+}
+
+proc linkcursor {w inc} {
+ global linkentercount curtextcursor
+
+ if {[incr linkentercount $inc] > 0} {
+ $w configure -cursor hand2
+ } else {
+ $w configure -cursor $curtextcursor
+ if {$linkentercount < 0} {
+ set linkentercount 0
+ }
+ }
}
proc viewnextline {dir} {
$ctext tag delete $lk
$ctext insert $pos $sep
$ctext insert $pos [lindex $ti 0] $lk
- if {[info exists commitrow($curview,$id)]} {
- $ctext tag conf $lk -foreground blue
- $ctext tag bind $lk <1> \
- [list selectline $commitrow($curview,$id) 1]
- $ctext tag conf $lk -underline 1
- $ctext tag bind $lk <Enter> { %W configure -cursor hand2 }
- $ctext tag bind $lk <Leave> \
- { %W configure -cursor $curtextcursor }
- }
+ setlink $id $lk
set sep ", "
}
}
proc clear_ctext {{first 1.0}} {
global ctext smarktop smarkbot
+ global pendinglinks
set l [lindex [split $first .] 0]
if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
set smarkbot $l
}
$ctext delete $first end
+ if {$first eq "1.0"} {
+ catch {unset pendinglinks}
+ }
}
proc incrsearch {name ix op} {
# fill the details pane with info about this line
$ctext conf -state normal
clear_ctext
- $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]
+ $ctext insert end $id link0
+ setlink $id link0
set info $commitinfo($id)
$ctext insert end "\n\t[lindex $info 0]\n"
$ctext insert end "\tAuthor:\t[lindex $info 1]\n"
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]
- $ctext tag bind link$i <1> [list selbyid $child]
+ $ctext insert end $child link$i
+ setlink $child link$i
$ctext insert end "\n\t[lindex $info 0]"
$ctext insert end "\n\tAuthor:\t[lindex $info 1]"
set date [formatdate [lindex $info 2]]
clear_ctext
init_flist "Top"
$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 $oldid link0
+ setlink $oldid link0
$ctext insert end "\n "
$ctext insert end [lindex $commitinfo($oldid) 0]
$ctext insert end "\n\nTo "
- $ctext tag bind link1 <1> [list selbyid $newid]
- $ctext insert end $newid [list link link1]
+ $ctext insert end $newid link1
+ setlink $newid link1
$ctext insert end "\n "
$ctext insert end [lindex $commitinfo($newid) 0]
$ctext insert end "\n"
set boldnamerows {}
set diffelide {0 0}
set markingmatches 0
+set linkentercount 0
set optim_delay 16