@ -743,7 +743,7 @@ proc click {w} {
proc savestuff {w} {
proc savestuff {w} {
global canv canv2 canv3 ctext cflist mainfont textfont uifont
global canv canv2 canv3 ctext cflist mainfont textfont uifont
global stuffsaved findmergefiles maxgraphpct
global stuffsaved findmergefiles maxgraphpct
global maxwidth
global maxwidth showneartags
global viewname viewfiles viewargs viewperm nextviewnum
global viewname viewfiles viewargs viewperm nextviewnum
global cmitmode wrapcomment
global cmitmode wrapcomment
@ -759,6 +759,7 @@ proc savestuff {w} {
puts $f [list set maxwidth $maxwidth]
puts $f [list set maxwidth $maxwidth]
puts $f [list set cmitmode $cmitmode]
puts $f [list set cmitmode $cmitmode]
puts $f [list set wrapcomment $wrapcomment]
puts $f [list set wrapcomment $wrapcomment]
puts $f [list set showneartags $showneartags]
puts $f "set geometry(width) [winfo width .ctop]"
puts $f "set geometry(width) [winfo width .ctop]"
puts $f "set geometry(height) [winfo height .ctop]"
puts $f "set geometry(height) [winfo height .ctop]"
puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
@ -3523,7 +3524,7 @@ proc commit_descriptor {p} {
if {[llength $commitinfo($p)] > 1} {
if {[llength $commitinfo($p)] > 1} {
set l [lindex $commitinfo($p) 0]
set l [lindex $commitinfo($p) 0]
}
}
return "$p ($l)"
return "$p ($l)\n"
}
}
# append some text to the ctext widget, and make any SHA1 ID
# append some text to the ctext widget, and make any SHA1 ID
@ -3533,7 +3534,6 @@ proc appendwithlinks {text tags} {
set start [$ctext index "end - 1c"]
set start [$ctext index "end - 1c"]
$ctext insert end $text $tags
$ctext insert end $text $tags
$ctext insert end "\n"
set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
foreach l $links {
foreach l $links {
set s [lindex $l 0]
set s [lindex $l 0]
@ -3568,6 +3568,54 @@ proc viewnextline {dir} {
allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
}
}
# add a list of tag names at position pos
proc appendrefs {pos l} {
global ctext commitrow linknum curview idtags
if {[catch {$ctext index $pos}]} return
set tags {}
foreach id $l {
foreach tag $idtags($id) {
lappend tags [concat $tag $id]
}
}
set tags [lsort -index 1 $tags]
set sep {}
foreach tag $tags {
set name [lindex $tag 0]
set id [lindex $tag 1]
set lk link$linknum
incr linknum
$ctext insert $pos $sep
$ctext insert $pos $name $lk
$ctext tag conf $lk -foreground blue
if {[info exists commitrow($curview,$id)]} {
$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 }
}
set sep ", "
}
}
# called when we have finished computing the nearby tags
proc dispneartags {} {
global selectedline currentid ctext anc_tags desc_tags showneartags
if {![info exists selectedline] || !$showneartags} return
set id $currentid
$ctext conf -state normal
if {[info exists anc_tags($id)]} {
appendrefs follows $anc_tags($id)
}
if {[info exists desc_tags($id)]} {
appendrefs precedes $desc_tags($id)
}
$ctext conf -state disabled
}
proc selectline {l isnew} {
proc selectline {l isnew} {
global canv canv2 canv3 ctext commitinfo selectedline
global canv canv2 canv3 ctext commitinfo selectedline
global displayorder linehtag linentag linedtag
global displayorder linehtag linentag linedtag
@ -3575,7 +3623,7 @@ proc selectline {l isnew} {
global currentid sha1entry
global currentid sha1entry
global commentend idtags linknum
global commentend idtags linknum
global mergemax numcommits pending_select
global mergemax numcommits pending_select
global cmitmode
global cmitmode desc_tags anc_tags showneartags allcommits
catch {unset pending_select}
catch {unset pending_select}
$canv delete hover
$canv delete hover
@ -3678,16 +3726,35 @@ proc selectline {l isnew} {
}
}
} else {
} else {
foreach p $olds {
foreach p $olds {
append headers "Parent: [commit_descriptor $p]\n"
append headers "Parent: [commit_descriptor $p]"
}
}
}
}
foreach c [lindex $childlist $l] {
foreach c [lindex $childlist $l] {
append headers "Child: [commit_descriptor $c]\n"
append headers "Child: [commit_descriptor $c]"
}
}
# make anything that looks like a SHA1 ID be a clickable link
# make anything that looks like a SHA1 ID be a clickable link
appendwithlinks $headers {}
appendwithlinks $headers {}
if {$showneartags} {
if {![info exists allcommits]} {
getallcommits
}
$ctext insert end "Follows: "
$ctext mark set follows "end -1c"
$ctext mark gravity follows left
if {[info exists anc_tags($id)]} {
appendrefs follows $anc_tags($id)
}
$ctext insert end "\nPrecedes: "
$ctext mark set precedes "end -1c"
$ctext mark gravity precedes left
if {[info exists desc_tags($id)]} {
appendrefs precedes $desc_tags($id)
}
$ctext insert end "\n"
}
$ctext insert end "\n"
appendwithlinks [lindex $info 5] {comment}
appendwithlinks [lindex $info 5] {comment}
$ctext tag delete Comments
$ctext tag delete Comments
@ -4814,12 +4881,19 @@ proc domktag {} {
proc redrawtags {id} {
proc redrawtags {id} {
global canv linehtag commitrow idpos selectedline curview
global canv linehtag commitrow idpos selectedline curview
global mainfont
if {![info exists commitrow($curview,$id)]} return
if {![info exists commitrow($curview,$id)]} return
drawcmitrow $commitrow($curview,$id)
drawcmitrow $commitrow($curview,$id)
$canv delete tag.$id
$canv delete tag.$id
set xt [eval drawtags $id $idpos($id)]
set xt [eval drawtags $id $idpos($id)]
$canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2]
$canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2]
set text [$canv itemcget $linehtag($commitrow($curview,$id)) -text]
set xr [expr {$xt + [font measure $mainfont $text]}]
if {$xr > $canvxmax} {
set canvxmax $xr
setcanvscroll
}
if {[info exists selectedline]
if {[info exists selectedline]
&& $selectedline == $commitrow($curview,$id)} {
&& $selectedline == $commitrow($curview,$id)} {
selectline $selectedline 0
selectline $selectedline 0
@ -4893,22 +4967,164 @@ proc wrcomcan {} {
unset wrcomtop
unset wrcomtop
}
}
proc listrefs {id} {
# Stuff for finding nearby tags
global idtags idheads idotherrefs
proc getallcommits {} {
global allcstart allcommits
set fd [open [concat | git rev-list --all --topo-order --parents] r]
fconfigure $fd -blocking 0
set allcommits "reading"
nowbusy allcommits
restartgetall $fd
}
proc restartgetall {fd} {
global allcstart
set x {}
fileevent $fd readable [list getallclines $fd]
set allcstart [clock clicks -milliseconds]
}
proc combine_dtags {l1 l2} {
global tagisdesc notfirstd
set res [lsort -unique [concat $l1 $l2]]
for {set i 0} {$i < [llength $res]} {incr i} {
set x [lindex $res $i]
for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
set y [lindex $res $j]
if {[info exists tagisdesc($x,$y)]} {
if {$tagisdesc($x,$y) > 0} {
# x is a descendent of y, exclude x
set res [lreplace $res $i $i]
incr i -1
break
} else {
# y is a descendent of x, exclude y
set res [lreplace $res $j $j]
}
} else {
# no relation, keep going
incr j
}
}
}
return $res
}
proc combine_atags {l1 l2} {
global tagisdesc
set res [lsort -unique [concat $l1 $l2]]
for {set i 0} {$i < [llength $res]} {incr i} {
set x [lindex $res $i]
for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
set y [lindex $res $j]
if {[info exists tagisdesc($x,$y)]} {
if {$tagisdesc($x,$y) < 0} {
# x is an ancestor of y, exclude x
set res [lreplace $res $i $i]
incr i -1
break
} else {
# y is an ancestor of x, exclude y
set res [lreplace $res $j $j]
}
} else {
# no relation, keep going
incr j
}
}
}
return $res
}
proc getallclines {fd} {
global allparents allchildren allcommits allcstart
global desc_tags anc_tags idtags alldtags tagisdesc allids
while {[gets $fd line] >= 0} {
set id [lindex $line 0]
lappend allids $id
set olds [lrange $line 1 end]
set allparents($id) $olds
if {![info exists allchildren($id)]} {
set allchildren($id) {}
}
foreach p $olds {
lappend allchildren($p) $id
}
# compute nearest tagged descendents as we go
set dtags {}
foreach child $allchildren($id) {
if {[info exists idtags($child)]} {
set ctags [list $child]
} else {
set ctags $desc_tags($child)
}
if {$dtags eq {}} {
set dtags $ctags
} elseif {$ctags ne $dtags} {
set dtags [combine_dtags $dtags $ctags]
}
}
set desc_tags($id) $dtags
if {[info exists idtags($id)]} {
if {[info exists idtags($id)]} {
set x $idtags($id)
set adt $dtags
foreach tag $dtags {
set adt [concat $adt $alldtags($tag)]
}
}
set y {}
set adt [lsort -unique $adt]
if {[info exists idheads($id)]} {
set alldtags($id) $adt
set y $idheads($id)
foreach tag $adt {
set tagisdesc($id,$tag) -1
set tagisdesc($tag,$id) 1
}
}
if {[clock clicks -milliseconds] - $allcstart >= 50} {
fileevent $fd readable {}
after idle restartgetall $fd
return
}
}
if {[eof $fd]} {
after idle restartatags [llength $allids]
if {[catch {close $fd} err]} {
error_popup "Error reading full commit graph: $err.\n\
Results may be incomplete."
}
}
}
# walk backward through the tree and compute nearest tagged ancestors
proc restartatags {i} {
global allids allparents idtags anc_tags t0
set t0 [clock clicks -milliseconds]
while {[incr i -1] >= 0} {
set id [lindex $allids $i]
set atags {}
foreach p $allparents($id) {
if {[info exists idtags($p)]} {
set ptags [list $p]
} else {
set ptags $anc_tags($p)
}
if {$atags eq {}} {
set atags $ptags
} elseif {$ptags ne $atags} {
set atags [combine_atags $atags $ptags]
}
}
set anc_tags($id) $atags
if {[clock clicks -milliseconds] - $t0 >= 50} {
after idle restartatags $i
return
}
}
set z {}
if {[info exists idotherrefs($id)]} {
set z $idotherrefs($id)
}
}
return [list $x $y $z]
set allcommits "done"
notbusy allcommits
dispneartags
}
}
proc rereadrefs {} {
proc rereadrefs {} {
@ -4959,7 +5175,7 @@ proc doquit {} {
proc doprefs {} {
proc doprefs {} {
global maxwidth maxgraphpct diffopts
global maxwidth maxgraphpct diffopts
global oldprefs prefstop
global oldprefs prefstop showneartags
set top .gitkprefs
set top .gitkprefs
set prefstop $top
set prefstop $top
@ -4967,7 +5183,7 @@ proc doprefs {} {
raise $top
raise $top
return
return
}
}
foreach v {maxwidth maxgraphpct diffopts} {
foreach v {maxwidth maxgraphpct diffopts showneartags} {
set oldprefs($v) [set $v]
set oldprefs($v) [set $v]
}
}
toplevel $top
toplevel $top
@ -4989,6 +5205,11 @@ proc doprefs {} {
-font optionfont
-font optionfont
entry $top.diffopt -width 20 -textvariable diffopts
entry $top.diffopt -width 20 -textvariable diffopts
grid x $top.diffoptl $top.diffopt -sticky w
grid x $top.diffoptl $top.diffopt -sticky w
frame $top.ntag
label $top.ntag.l -text "Display nearby tags" -font optionfont
checkbutton $top.ntag.b -variable showneartags
pack $top.ntag.b $top.ntag.l -side left
grid x $top.ntag -sticky w
frame $top.buts
frame $top.buts
button $top.buts.ok -text "OK" -command prefsok
button $top.buts.ok -text "OK" -command prefsok
button $top.buts.can -text "Cancel" -command prefscan
button $top.buts.can -text "Cancel" -command prefscan
@ -5000,9 +5221,9 @@ proc doprefs {} {
proc prefscan {} {
proc prefscan {} {
global maxwidth maxgraphpct diffopts
global maxwidth maxgraphpct diffopts
global oldprefs prefstop
global oldprefs prefstop showneartags
foreach v {maxwidth maxgraphpct diffopts} {
foreach v {maxwidth maxgraphpct diffopts showneartags} {
set $v $oldprefs($v)
set $v $oldprefs($v)
}
}
catch {destroy $prefstop}
catch {destroy $prefstop}
@ -5011,13 +5232,15 @@ proc prefscan {} {
proc prefsok {} {
proc prefsok {} {
global maxwidth maxgraphpct
global maxwidth maxgraphpct
global oldprefs prefstop
global oldprefs prefstop showneartags
catch {destroy $prefstop}
catch {destroy $prefstop}
unset prefstop
unset prefstop
if {$maxwidth != $oldprefs(maxwidth)
if {$maxwidth != $oldprefs(maxwidth)
|| $maxgraphpct != $oldprefs(maxgraphpct)} {
|| $maxgraphpct != $oldprefs(maxgraphpct)} {
redisplay
redisplay
} elseif {$showneartags != $oldprefs(showneartags)} {
reselectline
}
}
}
}
@ -5328,6 +5551,7 @@ set downarrowlen 7
set mingaplen 30
set mingaplen 30
set cmitmode "patch"
set cmitmode "patch"
set wrapcomment "none"
set wrapcomment "none"
set showneartags 1
set colors {green red blue magenta darkgrey brown orange}
set colors {green red blue magenta darkgrey brown orange}