@@ -533,6 +533,7 @@ proc makewindow {} {
533533 menu .bar.file
534534 .bar.file add command -label " Update" -command updatecommits
535535 .bar.file add command -label " Reread references" -command rereadrefs
536+ .bar.file add command -label " List references" -command showrefs
536537 .bar.file add command -label " Quit" -command doquit
537538 .bar.file configure -font $uifont
538539 menu .bar.edit
@@ -1466,6 +1467,38 @@ image create bitmap tri-dn -background black -foreground blue -data {
14661467 0x00, 0x00};
14671468}
14681469
1470+ image create bitmap reficon-T -background black -foreground yellow -data {
1471+ # define tagicon_width 13
1472+ # define tagicon_height 9
1473+ static unsigned char tagicon_bits[] = {
1474+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf8, 0x07,
1475+ 0xfc, 0x07, 0xf8, 0x07, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00};
1476+ } -maskdata {
1477+ # define tagicon-mask_width 13
1478+ # define tagicon-mask_height 9
1479+ static unsigned char tagicon-mask_bits[] = {
1480+ 0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x0f, 0xfc, 0x0f,
1481+ 0xfe, 0x0f, 0xfc, 0x0f, 0xf8, 0x0f, 0xf0, 0x0f, 0x00, 0x00};
1482+ }
1483+ set rectdata {
1484+ # define headicon_width 13
1485+ # define headicon_height 9
1486+ static unsigned char headicon_bits[] = {
1487+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xf8, 0x07,
1488+ 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00};
1489+ }
1490+ set rectmask {
1491+ # define headicon-mask_width 13
1492+ # define headicon-mask_height 9
1493+ static unsigned char headicon-mask_bits[] = {
1494+ 0x00, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
1495+ 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0x00, 0x00};
1496+ }
1497+ image create bitmap reficon-H -background black -foreground green \
1498+ -data $rectdata -maskdata $rectmask
1499+ image create bitmap reficon-o -background black -foreground " #ddddff" \
1500+ -data $rectdata -maskdata $rectmask
1501+
14691502proc init_flist {first} {
14701503 global cflist cflist_top selectedline difffilestart
14711504
@@ -1988,6 +2021,7 @@ proc showview {n} {
19882021 } elseif {$numcommits == 0} {
19892022 show_status " No commits selected"
19902023 }
2024+ run refill_reflist
19912025}
19922026
19932027# Stuff relating to the highlighting facility
@@ -2751,13 +2785,22 @@ proc layoutmore {tmax allread} {
27512785proc showstuff {canshow last} {
27522786 global numcommits commitrow pending_select selectedline curview
27532787 global lookingforhead mainheadid displayorder selectfirst
2754- global lastscrollset
2788+ global lastscrollset commitinterest
27552789
27562790 if {$numcommits == 0} {
27572791 global phase
27582792 set phase " incrdraw"
27592793 allcanvs delete all
27602794 }
2795+ for {set l $numcommits } {$l < $canshow } {incr l} {
2796+ set id [lindex $displayorder $l ]
2797+ if {[info exists commitinterest($id )]} {
2798+ foreach script $commitinterest($id) {
2799+ eval [string map [list " %I" $id ] $script ]
2800+ }
2801+ unset commitinterest($id )
2802+ }
2803+ }
27612804 set r0 $numcommits
27622805 set prev $numcommits
27632806 set numcommits $canshow
@@ -4484,6 +4527,7 @@ proc selectline {l isnew} {
44844527 $canv delete hover
44854528 normalline
44864529 cancel_next_highlight
4530+ unsel_reflist
44874531 if {$l < 0 || $l >= $numcommits } return
44884532 set y [expr {$canvy0 + $l * $linespc }]
44894533 set ymax [lindex [$canv cget -scrollregion] 3]
@@ -5146,8 +5190,8 @@ proc getblobdiffline {bdf ids} {
51465190 # the middle char will be a space, and the two bits either
51475191 # side will be a/name and b/name, or "a/name" and "b/name".
51485192 # If the name has changed we'll get "rename from" and
5149- # "rename to" lines following this, and we'll use them
5150- # to get the filenames.
5193+ # "rename to" or "copy from" and "copy to" lines following this,
5194+ # and we'll use them to get the filenames.
51515195 # This complexity is necessary because spaces in the filename(s)
51525196 # don't get escaped.
51535197 set l [string length $line ]
@@ -5171,17 +5215,19 @@ proc getblobdiffline {bdf ids} {
51715215 set diffinhdr 0
51725216
51735217 } elseif {$diffinhdr } {
5174- if {![string compare -length 12 " rename from " $line ]} {
5175- set fname [string range $line 12 end]
5218+ if {![string compare -length 12 " rename from " $line ] ||
5219+ ![string compare -length 10 " copy from " $line ]} {
5220+ set fname [string range $line [expr 6 + [string first " from " $line ] ] end]
51765221 if {[string index $fname 0] eq " \" " } {
51775222 set fname [lindex $fname 0]
51785223 }
51795224 set i [lsearch -exact $treediffs($ids) $fname ]
51805225 if {$i >= 0} {
51815226 setinlist difffilestart $i $curdiffstart
51825227 }
5183- } elseif {![string compare -length 10 $line " rename to " ]} {
5184- set fname [string range $line 10 end]
5228+ } elseif {![string compare -length 10 $line " rename to " ] ||
5229+ ![string compare -length 8 $line " copy to " ]} {
5230+ set fname [string range $line [expr 4 + [string first " to " $line ] ] end]
51855231 if {[string index $fname 0] eq " \" " } {
51865232 set fname [lindex $fname 0]
51875233 }
@@ -5412,7 +5458,7 @@ proc redisplay {} {
54125458}
54135459
54145460proc incrfont {inc} {
5415- global mainfont textfont ctext canv phase cflist
5461+ global mainfont textfont ctext canv phase cflist showrefstop
54165462 global charspc tabstop
54175463 global stopped entries
54185464 unmarkmatches
@@ -5428,6 +5474,9 @@ proc incrfont {inc} {
54285474 if {$phase eq " getcommits" } {
54295475 $canv itemconf textitems -font $mainfont
54305476 }
5477+ if {[info exists showrefstop] && [winfo exists $showrefstop ]} {
5478+ $showrefstop .list conf -font $mainfont
5479+ }
54315480 redisplay
54325481}
54335482
@@ -5886,6 +5935,8 @@ proc domktag {} {
58865935 lappend idtags($id ) $tag
58875936 redrawtags $id
58885937 addedtag $id
5938+ dispneartags 0
5939+ run refill_reflist
58895940}
58905941
58915942proc redrawtags {id} {
@@ -6027,6 +6078,7 @@ proc mkbrgo {top} {
60276078 notbusy newbranch
60286079 redrawtags $id
60296080 dispneartags 0
6081+ run refill_reflist
60306082 }
60316083}
60326084
@@ -6208,7 +6260,7 @@ proc rmbranch {} {
62086260 return
62096261 }
62106262 set dheads [descheads $id ]
6211- if {$idheads($dheads) eq $head } {
6263+ if {[ llength $dheads ] == 1 && $idheads($dheads) eq $head } {
62126264 # the stuff on this branch isn't on any other branch
62136265 if {![confirm_popup " The commits on branch $head aren't on any other\
62146266 branch.\n Really delete branch $head ?" ]} return
@@ -6225,6 +6277,163 @@ proc rmbranch {} {
62256277 redrawtags $id
62266278 notbusy rmbranch
62276279 dispneartags 0
6280+ run refill_reflist
6281+ }
6282+
6283+ # Display a list of tags and heads
6284+ proc showrefs {} {
6285+ global showrefstop bgcolor fgcolor selectbgcolor mainfont
6286+ global bglist fglist uifont reflistfilter reflist maincursor
6287+
6288+ set top .showrefs
6289+ set showrefstop $top
6290+ if {[winfo exists $top ]} {
6291+ raise $top
6292+ refill_reflist
6293+ return
6294+ }
6295+ toplevel $top
6296+ wm title $top " Tags and heads: [ file tail [pwd ] ]"
6297+ text $top .list -background $bgcolor -foreground $fgcolor \
6298+ -selectbackground $selectbgcolor -font $mainfont \
6299+ -xscrollcommand " $top .xsb set" -yscrollcommand " $top .ysb set" \
6300+ -width 30 -height 20 -cursor $maincursor \
6301+ -spacing1 1 -spacing3 1 -state disabled
6302+ $top .list tag configure highlight -background $selectbgcolor
6303+ lappend bglist $top .list
6304+ lappend fglist $top .list
6305+ scrollbar $top .ysb -command " $top .list yview" -orient vertical
6306+ scrollbar $top .xsb -command " $top .list xview" -orient horizontal
6307+ grid $top .list $top .ysb -sticky nsew
6308+ grid $top .xsb x -sticky ew
6309+ frame $top .f
6310+ label $top .f.l -text " Filter: " -font $uifont
6311+ entry $top .f.e -width 20 -textvariable reflistfilter -font $uifont
6312+ set reflistfilter " *"
6313+ trace add variable reflistfilter write reflistfilter_change
6314+ pack $top .f.e -side right -fill x -expand 1
6315+ pack $top .f.l -side left
6316+ grid $top .f - -sticky ew -pady 2
6317+ button $top .close -command [list destroy $top ] -text " Close" \
6318+ -font $uifont
6319+ grid $top .close -
6320+ grid columnconfigure $top 0 -weight 1
6321+ grid rowconfigure $top 0 -weight 1
6322+ bind $top .list <1> {break }
6323+ bind $top .list <B1-Motion> {break }
6324+ bind $top .list <ButtonRelease-1> {sel_reflist %W %x %y; break }
6325+ set reflist {}
6326+ refill_reflist
6327+ }
6328+
6329+ proc sel_reflist {w x y} {
6330+ global showrefstop reflist headids tagids otherrefids
6331+
6332+ if {![winfo exists $showrefstop ]} return
6333+ set l [lindex [split [$w index " @$x ,$y " ] " ." ] 0]
6334+ set ref [lindex $reflist [expr {$l -1}]]
6335+ set n [lindex $ref 0]
6336+ switch -- [lindex $ref 1] {
6337+ " H" {selbyid $headids($n) }
6338+ " T" {selbyid $tagids($n) }
6339+ " o" {selbyid $otherrefids($n) }
6340+ }
6341+ $showrefstop .list tag add highlight $l .0 " $l .0 lineend"
6342+ }
6343+
6344+ proc unsel_reflist {} {
6345+ global showrefstop
6346+
6347+ if {![info exists showrefstop] || ![winfo exists $showrefstop ]} return
6348+ $showrefstop .list tag remove highlight 0.0 end
6349+ }
6350+
6351+ proc reflistfilter_change {n1 n2 op} {
6352+ global reflistfilter
6353+
6354+ after cancel refill_reflist
6355+ after 200 refill_reflist
6356+ }
6357+
6358+ proc refill_reflist {} {
6359+ global reflist reflistfilter showrefstop headids tagids otherrefids
6360+ global commitrow curview commitinterest
6361+
6362+ if {![info exists showrefstop] || ![winfo exists $showrefstop ]} return
6363+ set refs {}
6364+ foreach n [array names headids] {
6365+ if {[string match $reflistfilter $n ]} {
6366+ if {[info exists commitrow($curview ,$headids($n) )]} {
6367+ lappend refs [list $n H]
6368+ } else {
6369+ set commitinterest($headids($n) ) {run refill_reflist}
6370+ }
6371+ }
6372+ }
6373+ foreach n [array names tagids] {
6374+ if {[string match $reflistfilter $n ]} {
6375+ if {[info exists commitrow($curview ,$tagids($n) )]} {
6376+ lappend refs [list $n T]
6377+ } else {
6378+ set commitinterest($tagids($n) ) {run refill_reflist}
6379+ }
6380+ }
6381+ }
6382+ foreach n [array names otherrefids] {
6383+ if {[string match $reflistfilter $n ]} {
6384+ if {[info exists commitrow($curview ,$otherrefids($n) )]} {
6385+ lappend refs [list $n o]
6386+ } else {
6387+ set commitinterest($otherrefids($n) ) {run refill_reflist}
6388+ }
6389+ }
6390+ }
6391+ set refs [lsort -index 0 $refs ]
6392+ if {$refs eq $reflist } return
6393+
6394+ # Update the contents of $showrefstop.list according to the
6395+ # differences between $reflist (old) and $refs (new)
6396+ $showrefstop .list conf -state normal
6397+ $showrefstop .list insert end " \n "
6398+ set i 0
6399+ set j 0
6400+ while {$i < [llength $reflist ] || $j < [llength $refs ]} {
6401+ if {$i < [llength $reflist ]} {
6402+ if {$j < [llength $refs ]} {
6403+ set cmp [string compare [lindex $reflist $i 0] \
6404+ [lindex $refs $j 0]]
6405+ if {$cmp == 0} {
6406+ set cmp [string compare [lindex $reflist $i 1] \
6407+ [lindex $refs $j 1]]
6408+ }
6409+ } else {
6410+ set cmp -1
6411+ }
6412+ } else {
6413+ set cmp 1
6414+ }
6415+ switch -- $cmp {
6416+ -1 {
6417+ $showrefstop .list delete " [ expr {$j +1}] .0" " [ expr {$j +2}] .0"
6418+ incr i
6419+ }
6420+ 0 {
6421+ incr i
6422+ incr j
6423+ }
6424+ 1 {
6425+ set l [expr {$j + 1}]
6426+ $showrefstop .list image create $l .0 -align baseline \
6427+ -image reficon-[lindex $refs $j 1] -padx 2
6428+ $showrefstop .list insert $l .1 " [ lindex $refs $j 0] \n "
6429+ incr j
6430+ }
6431+ }
6432+ }
6433+ set reflist $refs
6434+ # delete last newline
6435+ $showrefstop .list delete end-2c end-1c
6436+ $showrefstop .list conf -state disabled
62286437}
62296438
62306439# Stuff for finding nearby tags
@@ -7122,6 +7331,7 @@ proc rereadrefs {} {
71227331 redrawtags $id
71237332 }
71247333 }
7334+ run refill_reflist
71257335}
71267336
71277337proc listrefs {id} {
0 commit comments