gitk: Use a text widget for the file list

This lets us do things like highlighting all the entries for which
the corresponding part of the diff is at least partly visible in the
commit/patch display window, and in future it will let us display
the file list in a hierarchical form rather than as a flat file list.

Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Paul Mackerras 2006-04-27 19:21:49 +10:00
parent cb303a949f
commit 7fcceed7a0

190
gitk
View File

@ -481,7 +481,7 @@ proc makewindow {} {
set ctext .ctop.cdet.left.ctext set ctext .ctop.cdet.left.ctext
text $ctext -bg white -state disabled -font $textfont \ text $ctext -bg white -state disabled -font $textfont \
-width $geometry(ctextw) -height $geometry(ctexth) \ -width $geometry(ctextw) -height $geometry(ctexth) \
-yscrollcommand ".ctop.cdet.left.sb set" -wrap none -yscrollcommand scrolltext -wrap none
scrollbar .ctop.cdet.left.sb -command "$ctext yview" scrollbar .ctop.cdet.left.sb -command "$ctext yview"
pack .ctop.cdet.left.sb -side right -fill y pack .ctop.cdet.left.sb -side right -fill y
pack $ctext -side left -fill both -expand 1 pack $ctext -side left -fill both -expand 1
@ -515,11 +515,16 @@ proc makewindow {} {
frame .ctop.cdet.right frame .ctop.cdet.right
set cflist .ctop.cdet.right.cfiles set cflist .ctop.cdet.right.cfiles
listbox $cflist -bg white -selectmode extended -width $geometry(cflistw) \ set indent [font measure $mainfont "nn"]
-yscrollcommand ".ctop.cdet.right.sb set" -font $mainfont text $cflist -width $geometry(cflistw) -background white -font $mainfont \
-tabs [list $indent [expr {2 * $indent}]] \
-yscrollcommand ".ctop.cdet.right.sb set" \
-cursor [. cget -cursor] \
-spacing1 1 -spacing3 1
scrollbar .ctop.cdet.right.sb -command "$cflist yview" scrollbar .ctop.cdet.right.sb -command "$cflist yview"
pack .ctop.cdet.right.sb -side right -fill y pack .ctop.cdet.right.sb -side right -fill y
pack $cflist -side left -fill both -expand 1 pack $cflist -side left -fill both -expand 1
$cflist tag configure highlight -background yellow
.ctop.cdet add .ctop.cdet.right .ctop.cdet add .ctop.cdet.right
bind .ctop.cdet <Configure> {resizecdetpanes %W %w} bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
@ -571,12 +576,13 @@ proc makewindow {} {
bind . <Control-KP_Add> {incrfont 1} bind . <Control-KP_Add> {incrfont 1}
bind . <Control-minus> {incrfont -1} bind . <Control-minus> {incrfont -1}
bind . <Control-KP_Subtract> {incrfont -1} bind . <Control-KP_Subtract> {incrfont -1}
bind $cflist <<ListboxSelect>> listboxsel
bind . <Destroy> {savestuff %W} bind . <Destroy> {savestuff %W}
bind . <Button-1> "click %W" bind . <Button-1> "click %W"
bind $fstring <Key-Return> dofind bind $fstring <Key-Return> dofind
bind $sha1entry <Key-Return> gotocommit bind $sha1entry <Key-Return> gotocommit
bind $sha1entry <<PasteSelection>> clearsha1 bind $sha1entry <<PasteSelection>> clearsha1
bind $cflist <1> {sel_flist %W %x %y; break}
bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
set maincursor [. cget -cursor] set maincursor [. cget -cursor]
set textcursor [$ctext cget -cursor] set textcursor [$ctext cget -cursor]
@ -812,6 +818,101 @@ f Scroll diff view to next file
pack $w.ok -side bottom pack $w.ok -side bottom
} }
# Procedures for manipulating the file list window at the
# bottom right of the overall window.
proc init_flist {first} {
global cflist cflist_top cflist_bot selectedline difffilestart
$cflist conf -state normal
$cflist delete 0.0 end
if {$first ne {}} {
$cflist insert end $first
set cflist_top 1
set cflist_bot 1
$cflist tag add highlight 1.0 "1.0 lineend"
} else {
catch {unset cflist_top}
}
$cflist conf -state disabled
set difffilestart {}
}
proc add_flist {f} {
global flistmode cflist
$cflist conf -state normal
if {$flistmode eq "flat"} {
$cflist insert end "\n$f"
}
$cflist conf -state disabled
}
proc sel_flist {w x y} {
global flistmode ctext difffilestart cflist cflist_top
if {![info exists cflist_top]} return
set l [lindex [split [$w index "@$x,$y"] "."] 0]
if {$flistmode eq "flat"} {
if {$l == 1} {
$ctext yview 1.0
} else {
catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
}
highlight_flist $l
}
}
proc scrolltext {f0 f1} {
global cflist_top
.ctop.cdet.left.sb set $f0 $f1
if {[info exists cflist_top]} {
highlight_flist $cflist_top
}
}
# Given an index $tl in the $ctext window, this works out which line
# of the $cflist window displays the filename whose patch is shown
# at the given point in the $ctext window. $ll is a hint about which
# line it might be, and is used as the starting point of the search.
proc ctext_index {tl ll} {
global ctext difffilestart
while {$ll >= 2 && [$ctext compare $tl < \
[lindex $difffilestart [expr {$ll - 2}]]]} {
incr ll -1
}
set nfiles [llength $difffilestart]
while {$ll - 1 < $nfiles && [$ctext compare $tl >= \
[lindex $difffilestart [expr {$ll - 1}]]]} {
incr ll
}
return $ll
}
proc highlight_flist {ll} {
global ctext cflist cflist_top cflist_bot difffilestart
if {![info exists difffilestart] || [llength $difffilestart] == 0} return
set ll [ctext_index [$ctext index @0,1] $ll]
set lb $cflist_bot
if {$lb < $ll} {
set lb $ll
}
set y [expr {[winfo height $ctext] - 2}]
set lb [ctext_index [$ctext index @0,$y] $lb]
if {$ll != $cflist_top || $lb != $cflist_bot} {
$cflist tag remove highlight $cflist_top.0 "$cflist_bot.0 lineend"
for {set l $ll} {$l <= $lb} {incr l} {
$cflist tag add highlight $l.0 "$l.0 lineend"
}
set cflist_top $ll
set cflist_bot $lb
}
}
# Code to implement multiple views
proc newview {} { proc newview {} {
global nextviewnum newviewname newviewperm uifont global nextviewnum newviewname newviewperm uifont
@ -2718,7 +2819,7 @@ 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
global canvy0 linespc parentlist childlist global canvy0 linespc parentlist childlist
global cflist currentid sha1entry global currentid sha1entry
global commentend idtags linknum global commentend idtags linknum
global mergemax numcommits pending_select global mergemax numcommits pending_select
@ -2841,8 +2942,7 @@ proc selectline {l isnew} {
$ctext conf -state disabled $ctext conf -state disabled
set commentend [$ctext index "end - 1c"] set commentend [$ctext index "end - 1c"]
$cflist delete 0 end init_flist "Comments"
$cflist insert end "Comments"
if {[llength $olds] <= 1} { if {[llength $olds] <= 1} {
startdiff $id startdiff $id
} else { } else {
@ -2960,12 +3060,11 @@ proc goforw {} {
proc mergediff {id l} { proc mergediff {id l} {
global diffmergeid diffopts mdifffd global diffmergeid diffopts mdifffd
global difffilestart diffids global diffids
global parentlist global parentlist
set diffmergeid $id set diffmergeid $id
set diffids $id set diffids $id
catch {unset difffilestart}
# this doesn't seem to actually affect anything... # this doesn't seem to actually affect anything...
set env(GIT_DIFF_OPTS) $diffopts set env(GIT_DIFF_OPTS) $diffopts
set cmd [concat | git-diff-tree --no-commit-id --cc $id] set cmd [concat | git-diff-tree --no-commit-id --cc $id]
@ -3000,11 +3099,10 @@ proc getmergediffline {mdf id np} {
# start of a new file # start of a new file
$ctext insert end "\n" $ctext insert end "\n"
set here [$ctext index "end - 1c"] set here [$ctext index "end - 1c"]
set i [$cflist index end] $ctext mark set f:$fname $here
$ctext mark set fmark.$i $here $ctext mark gravity f:$fname left
$ctext mark gravity fmark.$i left lappend difffilestart $here
set difffilestart([expr {$i-1}]) $here add_flist $fname
$cflist insert end $fname
set l [expr {(78 - [string length $fname]) / 2}] set l [expr {(78 - [string length $fname]) / 2}]
set pad [string range "----------------------------------------" 1 $l] set pad [string range "----------------------------------------" 1 $l]
$ctext insert end "$pad $fname $pad\n" filesep $ctext insert end "$pad $fname $pad\n" filesep
@ -3075,7 +3173,7 @@ proc startdiff {ids} {
proc addtocflist {ids} { proc addtocflist {ids} {
global treediffs cflist global treediffs cflist
foreach f $treediffs($ids) { foreach f $treediffs($ids) {
$cflist insert end $f add_flist $f
} }
getblobdiffs $ids getblobdiffs $ids
} }
@ -3115,7 +3213,7 @@ proc gettreediffline {gdtf ids} {
proc getblobdiffs {ids} { proc getblobdiffs {ids} {
global diffopts blobdifffd diffids env curdifftag curtagstart global diffopts blobdifffd diffids env curdifftag curtagstart
global difffilestart nextupdate diffinhdr treediffs global nextupdate diffinhdr treediffs
set env(GIT_DIFF_OPTS) $diffopts set env(GIT_DIFF_OPTS) $diffopts
set cmd [concat | git-diff-tree --no-commit-id -r -p -C $ids] set cmd [concat | git-diff-tree --no-commit-id -r -p -C $ids]
@ -3128,7 +3226,6 @@ proc getblobdiffs {ids} {
set blobdifffd($ids) $bdf set blobdifffd($ids) $bdf
set curdifftag Comments set curdifftag Comments
set curtagstart 0.0 set curtagstart 0.0
catch {unset difffilestart}
fileevent $bdf readable [list getblobdiffline $bdf $diffids] fileevent $bdf readable [list getblobdiffline $bdf $diffids]
set nextupdate [expr {[clock clicks -milliseconds] + 100}] set nextupdate [expr {[clock clicks -milliseconds] + 100}]
} }
@ -3156,24 +3253,15 @@ proc getblobdiffline {bdf ids} {
# start of a new file # start of a new file
$ctext insert end "\n" $ctext insert end "\n"
$ctext tag add $curdifftag $curtagstart end $ctext tag add $curdifftag $curtagstart end
set curtagstart [$ctext index "end - 1c"]
set header $newname
set here [$ctext index "end - 1c"] set here [$ctext index "end - 1c"]
set i [lsearch -exact $treediffs($diffids) $fname] set curtagstart $here
if {$i >= 0} { set header $newname
set difffilestart($i) $here lappend difffilestart $here
incr i $ctext mark set f:$fname $here
$ctext mark set fmark.$i $here $ctext mark gravity f:$fname left
$ctext mark gravity fmark.$i left
}
if {$newname != $fname} { if {$newname != $fname} {
set i [lsearch -exact $treediffs($diffids) $newname] $ctext mark set f:$newfname $here
if {$i >= 0} { $ctext mark gravity f:$newfname left
set difffilestart($i) $here
incr i
$ctext mark set fmark.$i $here
$ctext mark gravity fmark.$i left
}
} }
set curdifftag "f:$fname" set curdifftag "f:$fname"
$ctext tag delete $curdifftag $ctext tag delete $curdifftag
@ -3222,27 +3310,12 @@ proc getblobdiffline {bdf ids} {
proc nextfile {} { proc nextfile {} {
global difffilestart ctext global difffilestart ctext
set here [$ctext index @0,0] set here [$ctext index @0,0]
for {set i 0} {[info exists difffilestart($i)]} {incr i} { foreach loc $difffilestart {
if {[$ctext compare $difffilestart($i) > $here]} { if {[$ctext compare $loc > $here]} {
if {![info exists pos] $ctext yview $loc
|| [$ctext compare $difffilestart($i) < $pos]} {
set pos $difffilestart($i)
} }
} }
} }
if {[info exists pos]} {
$ctext yview $pos
}
}
proc listboxsel {} {
global ctext cflist currentid
if {![info exists currentid]} return
set sel [lsort [$cflist curselection]]
if {$sel eq {}} return
set first [lindex $sel 0]
catch {$ctext yview fmark.$first}
}
proc setcoords {} { proc setcoords {} {
global linespc charspc canvx0 canvy0 mainfont global linespc charspc canvx0 canvy0 mainfont
@ -3452,7 +3525,7 @@ proc arrowjump {id n y} {
} }
proc lineclick {x y id isnew} { proc lineclick {x y id isnew} {
global ctext commitinfo childlist commitrow cflist canv thickerline global ctext commitinfo childlist commitrow canv thickerline
if {![info exists commitinfo($id)] && ![getcommit $id]} return if {![info exists commitinfo($id)] && ![getcommit $id]} return
unmarkmatches unmarkmatches
@ -3509,8 +3582,7 @@ proc lineclick {x y id isnew} {
} }
} }
$ctext conf -state disabled $ctext conf -state disabled
init_flist {}
$cflist delete 0 end
} }
proc normalline {} { proc normalline {} {
@ -3568,15 +3640,14 @@ proc diffvssel {dirn} {
} }
proc doseldiff {oldid newid} { proc doseldiff {oldid newid} {
global ctext cflist global ctext
global commitinfo global commitinfo
$ctext conf -state normal $ctext conf -state normal
$ctext delete 0.0 end $ctext delete 0.0 end
$ctext mark set fmark.0 0.0 $ctext mark set fmark.0 0.0
$ctext mark gravity fmark.0 left $ctext mark gravity fmark.0 left
$cflist delete 0 end init_flist "Top"
$cflist insert end "Top"
$ctext insert end "From " $ctext insert end "From "
$ctext tag conf link -foreground blue -underline 1 $ctext tag conf link -foreground blue -underline 1
$ctext tag bind link <Enter> { %W configure -cursor hand2 } $ctext tag bind link <Enter> { %W configure -cursor hand2 }
@ -3862,7 +3933,7 @@ proc rereadrefs {} {
} }
proc showtag {tag isnew} { proc showtag {tag isnew} {
global ctext cflist tagcontents tagids linknum global ctext tagcontents tagids linknum
if {$isnew} { if {$isnew} {
addtohistory [list showtag $tag 0] addtohistory [list showtag $tag 0]
@ -3877,7 +3948,7 @@ proc showtag {tag isnew} {
} }
appendwithlinks $text appendwithlinks $text
$ctext conf -state disabled $ctext conf -state disabled
$cflist delete 0 end init_flist {}
} }
proc doquit {} { proc doquit {} {
@ -4259,6 +4330,7 @@ set fastdate 0
set uparrowlen 7 set uparrowlen 7
set downarrowlen 7 set downarrowlen 7
set mingaplen 30 set mingaplen 30
set flistmode "flat"
set colors {green red blue magenta darkgrey brown orange} set colors {green red blue magenta darkgrey brown orange}