X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=gitk;h=c90ef993c518e7079cbda3f11df258c1d7f0a28b;hb=60f7a7dc4904ba4baab44b70e2675a01e6172f54;hp=4aa57c01ce56e505aba5384f716376a68a7fdc7a;hpb=098dd8a34b43ea1317527ca1a3354aae9f3704b5;p=git.git diff --git a/gitk b/gitk index 4aa57c01..c90ef993 100755 --- a/gitk +++ b/gitk @@ -187,7 +187,7 @@ proc getcommitlines {fd view} { if {$view == $curview} { layoutmore } elseif {[info exists hlview] && $view == $hlview} { - highlightmore + vhighlightmore } } if {[clock clicks -milliseconds] >= $nextupdate} { @@ -223,7 +223,7 @@ proc readcommit {id} { proc updatecommits {} { global viewdata curview phase displayorder - global children commitrow + global children commitrow selectedline thickerline if {$phase ne {}} { stop_rev_list @@ -235,6 +235,8 @@ proc updatecommits {} { catch {unset commitrow($n,$id)} } set curview -1 + catch {unset selectedline} + catch {unset thickerline} catch {unset viewdata($n)} readrefs showview $n @@ -381,6 +383,8 @@ proc makewindow {} { global entries sha1entry sha1string sha1but global maincursor textcursor curtextcursor global rowctxmenu mergemax + global highlight_files gdttype + global searchstring sstring menu .bar .bar add cascade -label "File" -menu .bar.file @@ -396,20 +400,14 @@ proc makewindow {} { .bar.edit configure -font $uifont menu .bar.view -font $uifont - menu .bar.view.hl -font $uifont -tearoff 0 .bar add cascade -label "View" -menu .bar.view .bar.view add command -label "New view..." -command {newview 0} .bar.view add command -label "Edit view..." -command editview \ -state disabled .bar.view add command -label "Delete view" -command delview -state disabled - .bar.view add cascade -label "Highlight" -menu .bar.view.hl .bar.view add separator .bar.view add radiobutton -label "All files" -command {showview 0} \ -variable selectedview -value 0 - .bar.view.hl add command -label "New view..." -command {newview 1} - .bar.view.hl add command -label "Remove" -command delhighlight \ - -state disabled - .bar.view.hl add separator menu .bar.help .bar add cascade -label "Help" -menu .bar.help @@ -436,6 +434,8 @@ proc makewindow {} { } frame .ctop.top frame .ctop.top.bar + frame .ctop.top.lbar + pack .ctop.top.lbar -side bottom -fill x pack .ctop.top.bar -side bottom -fill x set cscroll .ctop.top.csb scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0 @@ -497,31 +497,65 @@ proc makewindow {} { set findstring {} set fstring .ctop.top.bar.findstring lappend entries $fstring - entry $fstring -width 30 -font $textfont -textvariable findstring -font $textfont + entry $fstring -width 30 -font $textfont -textvariable findstring + trace add variable findstring write find_change pack $fstring -side left -expand 1 -fill x set findtype Exact set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \ findtype Exact IgnCase Regexp] + trace add variable findtype write find_change .ctop.top.bar.findtype configure -font $uifont .ctop.top.bar.findtype.menu configure -font $uifont set findloc "All fields" tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \ - Comments Author Committer Files Pickaxe + Comments Author Committer + trace add variable findloc write find_change .ctop.top.bar.findloc configure -font $uifont .ctop.top.bar.findloc.menu configure -font $uifont - pack .ctop.top.bar.findloc -side right pack .ctop.top.bar.findtype -side right - # for making sure type==Exact whenever loc==Pickaxe - trace add variable findloc write findlocchange + + label .ctop.top.lbar.flabel -text "Highlight: Commits " \ + -font $uifont + pack .ctop.top.lbar.flabel -side left -fill y + set gdttype "touching paths:" + set gm [tk_optionMenu .ctop.top.lbar.gdttype gdttype "touching paths:" \ + "adding/removing string:"] + trace add variable gdttype write hfiles_change + $gm conf -font $uifont + .ctop.top.lbar.gdttype conf -font $uifont + pack .ctop.top.lbar.gdttype -side left -fill y + entry .ctop.top.lbar.fent -width 25 -font $textfont \ + -textvariable highlight_files + trace add variable highlight_files write hfiles_change + lappend entries .ctop.top.lbar.fent + pack .ctop.top.lbar.fent -side left -fill x -expand 1 + label .ctop.top.lbar.vlabel -text " OR in view" -font $uifont + pack .ctop.top.lbar.vlabel -side left -fill y + global viewhlmenu selectedhlview + set viewhlmenu [tk_optionMenu .ctop.top.lbar.vhl selectedhlview None] + $viewhlmenu entryconf 0 -command delvhighlight + $viewhlmenu conf -font $uifont + .ctop.top.lbar.vhl conf -font $uifont + pack .ctop.top.lbar.vhl -side left -fill y panedwindow .ctop.cdet -orient horizontal .ctop add .ctop.cdet frame .ctop.cdet.left + frame .ctop.cdet.left.bot + pack .ctop.cdet.left.bot -side bottom -fill x + button .ctop.cdet.left.bot.search -text "Search" -command dosearch \ + -font $uifont + pack .ctop.cdet.left.bot.search -side left -padx 5 + set sstring .ctop.cdet.left.bot.sstring + entry $sstring -width 20 -font $textfont -textvariable searchstring + lappend entries $sstring + trace add variable searchstring write incrsearch + pack $sstring -side left -expand 1 -fill x set ctext .ctop.cdet.left.ctext text $ctext -bg white -state disabled -font $textfont \ -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" pack .ctop.cdet.left.sb -side right -fill y pack $ctext -side left -fill both -expand 1 @@ -573,6 +607,7 @@ proc makewindow {} { pack $cflist -side left -fill both -expand 1 $cflist tag configure highlight \ -background [$cflist cget -selectbackground] + $cflist tag configure bold -font [concat $mainfont bold] .ctop.cdet add .ctop.cdet.right bind .ctop.cdet {resizecdetpanes %W %w} @@ -619,7 +654,8 @@ proc makewindow {} { bind . doquit bind . dofind bind . {findnext 0} - bind . findprev + bind . dosearchback + bind . dosearch bind . {incrfont 1} bind . {incrfont 1} bind . {incrfont -1} @@ -664,6 +700,7 @@ proc canvscan {op w x y} { proc scrollcanv {cscroll f0 f1} { $cscroll set $f0 $f1 drawfrac $f0 $f1 + flushhighlights } # when we make a key binding for the toplevel, make sure @@ -924,7 +961,7 @@ proc treeview {w l openlevs} { $w insert end $str $w image create end -align center -image $bm -padx 1 \ -name a:$ix - $w insert end $d + $w insert end $d [highlight_tag $prefix] $w mark set s:$ix "end -1c" $w mark gravity s:$ix left } @@ -936,7 +973,7 @@ proc treeview {w l openlevs} { set str "\n" for {set i 0} {$i < $lev} {incr i} {append str "\t"} $w insert end $str - $w insert end $tail + $w insert end $tail [highlight_tag $f] } lappend treecontents($prefix) $tail } @@ -973,6 +1010,22 @@ proc linetoelt {l} { } } +proc highlight_tree {y prefix} { + global treeheight treecontents cflist + + foreach e $treecontents($prefix) { + set path $prefix$e + if {[highlight_tag $path] ne {}} { + $cflist tag add bold $y.0 "$y.0 lineend" + } + incr y + if {[string index $e end] eq "/" && $treeheight($path) > 1} { + set y [highlight_tree $y $path] + } + } + return $y +} + proc treeclosedir {w dir} { global treediropen treeheight treeparent treeindex @@ -1006,8 +1059,8 @@ proc treeopendir {w dir} { incr treeheight($x) $n } foreach e $treecontents($dir) { + set de $dir$e if {[string index $e end] eq "/"} { - set de $dir$e set iy $treeindex($de) $w mark set d:$iy e:$ix $w mark gravity d:$iy left @@ -1015,13 +1068,13 @@ proc treeopendir {w dir} { set treediropen($de) 0 $w image create e:$ix -align center -image tri-rt -padx 1 \ -name a:$iy - $w insert e:$ix $e + $w insert e:$ix $e [highlight_tag $de] $w mark set s:$iy e:$ix $w mark gravity s:$iy left set treeheight($de) 1 } else { $w insert e:$ix $str - $w insert e:$ix $e + $w insert e:$ix $e [highlight_tag $de] } } $w mark gravity e:$ix left @@ -1117,20 +1170,56 @@ proc init_flist {first} { set difffilestart {} } -proc add_flist {fl} { - global flistmode cflist +proc highlight_tag {f} { + global highlight_paths + + foreach p $highlight_paths { + if {[string match $p $f]} { + return "bold" + } + } + return {} +} + +proc highlight_filelist {} { + global cmitmode cflist $cflist conf -state normal - if {$flistmode eq "flat"} { - foreach f $fl { - $cflist insert end "\n$f" + if {$cmitmode ne "tree"} { + set end [lindex [split [$cflist index end] .] 0] + for {set l 2} {$l < $end} {incr l} { + set line [$cflist get $l.0 "$l.0 lineend"] + if {[highlight_tag $line] ne {}} { + $cflist tag add bold $l.0 "$l.0 lineend" + } } + } else { + highlight_tree 2 {} + } + $cflist conf -state disabled +} + +proc unhighlight_filelist {} { + global cflist + + $cflist conf -state normal + $cflist tag remove bold 1.0 end + $cflist conf -state disabled +} + +proc add_flist {fl} { + global cflist + + $cflist conf -state normal + foreach f $fl { + $cflist insert end "\n" + $cflist insert end $f [highlight_tag $f] } $cflist conf -state disabled } proc sel_flist {w x y} { - global flistmode ctext difffilestart cflist cflist_top cmitmode + global ctext difffilestart cflist cflist_top cmitmode if {$cmitmode eq "tree"} return if {![info exists cflist_top]} return @@ -1313,25 +1402,27 @@ proc vieweditor {top n title} { focus $top.t } -proc doviewmenu {m first cmd op args} { +proc doviewmenu {m first cmd op argv} { set nmenu [$m index end] for {set i $first} {$i <= $nmenu} {incr i} { if {[$m entrycget $i -command] eq $cmd} { - eval $m $op $i $args + eval $m $op $i $argv break } } } proc allviewmenus {n op args} { + global viewhlmenu + doviewmenu .bar.view 7 [list showview $n] $op $args - doviewmenu .bar.view.hl 3 [list addhighlight $n] $op $args + doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args } proc newviewok {top n} { global nextviewnum newviewperm newviewname newishighlight global viewname viewfiles viewperm selectedview curview - global viewargs newviewargs + global viewargs newviewargs viewhlmenu if {[catch { set newargs [shellsplit $newviewargs($n)] @@ -1359,14 +1450,17 @@ proc newviewok {top n} { if {!$newishighlight} { after idle showview $n } else { - after idle addhighlight $n + after idle addvhighlight $n } } else { # editing an existing view set viewperm($n) $newviewperm($n) if {$newviewname($n) ne $viewname($n)} { set viewname($n) $newviewname($n) - allviewmenus $n entryconf -label $viewname($n) + doviewmenu .bar.view 7 [list showview $n] \ + entryconf [list -label $viewname($n)] + doviewmenu $viewhlmenu 1 [list addvhighlight $n] \ + entryconf [list -label $viewname($n) -value $viewname($n)] } if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} { set viewfiles($n) $files @@ -1380,9 +1474,13 @@ proc newviewok {top n} { } proc delview {} { - global curview viewdata viewperm + global curview viewdata viewperm hlview selectedhlview if {$curview == 0} return + if {[info exists hlview] && $hlview == $curview} { + set selectedhlview None + unset hlview + } allviewmenus $curview delete set viewdata($curview) {} set viewperm($curview) 0 @@ -1390,12 +1488,12 @@ proc delview {} { } proc addviewmenu {n} { - global viewname + global viewname viewhlmenu .bar.view add radiobutton -label $viewname($n) \ -command [list showview $n] -variable selectedview -value $n - .bar.view.hl add radiobutton -label $viewname($n) \ - -command [list addhighlight $n] -variable selectedhlview -value $n + $viewhlmenu add radiobutton -label $viewname($n) \ + -command [list addvhighlight $n] -variable selectedhlview } proc flatten {var} { @@ -1427,8 +1525,9 @@ proc showview {n} { global pending_select phase global commitidx rowlaidout rowoptim linesegends global commfd nextupdate - global selectedview hlview selectedhlview + global selectedview global vparentlist vchildlist vdisporder vcmitlisted + global hlview selectedhlview if {$n == $curview} return set selid {} @@ -1467,14 +1566,15 @@ proc showview {n} { catch {unset matchinglines} catch {unset treediffs} clear_display + if {[info exists hlview] && $hlview == $n} { + unset hlview + set selectedhlview None + } set curview $n set selectedview $n - set selectedhlview -1 .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] .bar.view entryconf 3 -state [expr {$n == 0? "disabled": "normal"}] - catch {unset hlview} - .bar.view.hl entryconf 1 -state disabled if {![info exists viewdata($n)]} { set pending_select $selid @@ -1539,18 +1639,66 @@ proc showview {n} { } } -proc addhighlight {n} { - global hlview curview viewdata highlighted highlightedrows - global selectedhlview +# Stuff relating to the highlighting facility + +proc ishighlighted {row} { + global vhighlights fhighlights nhighlights + + if {[info exists nhighlights($row)] && $nhighlights($row) > 0} { + return $nhighlights($row) + } + if {[info exists vhighlights($row)] && $vhighlights($row) > 0} { + return $vhighlights($row) + } + if {[info exists fhighlights($row)] && $fhighlights($row) > 0} { + return $fhighlights($row) + } + return 0 +} + +proc bolden {row font} { + global canv linehtag selectedline + + $canv itemconf $linehtag($row) -font $font + if {$row == $selectedline} { + $canv delete secsel + set t [eval $canv create rect [$canv bbox $linehtag($row)] \ + -outline {{}} -tags secsel \ + -fill [$canv cget -selectbackground]] + $canv lower $t + } +} + +proc bolden_name {row font} { + global canv2 linentag selectedline + + $canv2 itemconf $linentag($row) -font $font + if {$row == $selectedline} { + $canv2 delete secsel + set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \ + -outline {{}} -tags secsel \ + -fill [$canv2 cget -selectbackground]] + $canv2 lower $t + } +} + +proc unbolden {rows} { + global mainfont + + foreach row $rows { + if {![ishighlighted $row]} { + bolden $row $mainfont + } + } +} + +proc addvhighlight {n} { + global hlview curview viewdata vhl_done vhighlights commitidx if {[info exists hlview]} { - delhighlight + delvhighlight } set hlview $n - set selectedhlview $n - .bar.view.hl entryconf 1 -state normal - set highlighted($n) 0 - set highlightedrows {} if {$n != $curview && ![info exists viewdata($n)]} { set viewdata($n) [list getcommits {{}} {{}} {} {} {} 0 0 0 {}] set vparentlist($n) {} @@ -1558,34 +1706,29 @@ proc addhighlight {n} { set vdisporder($n) {} set vcmitlisted($n) {} start_rev_list $n - } else { - highlightmore + } + set vhl_done $commitidx($hlview) + if {$vhl_done > 0} { + drawvisible } } -proc delhighlight {} { - global hlview highlightedrows canv linehtag mainfont - global selectedhlview selectedline +proc delvhighlight {} { + global hlview vhighlights + global selectedline if {![info exists hlview]} return unset hlview - set selectedhlview {} - .bar.view.hl entryconf 1 -state disabled - foreach l $highlightedrows { - $canv itemconf $linehtag($l) -font $mainfont - if {$l == $selectedline} { - $canv delete secsel - set t [eval $canv create rect [$canv bbox $linehtag($l)] \ - -outline {{}} -tags secsel \ - -fill [$canv cget -selectbackground]] - $canv lower $t - } + set rows [array names vhighlights] + if {$rows ne {}} { + unset vhighlights + unbolden $rows } } -proc highlightmore {} { - global hlview highlighted commitidx highlightedrows linehtag mainfont - global displayorder vdisporder curview canv commitrow selectedline +proc vhighlightmore {} { + global hlview vhl_done commitidx vhighlights + global displayorder vdisporder curview mainfont set font [concat $mainfont bold] set max $commitidx($hlview) @@ -1594,25 +1737,193 @@ proc highlightmore {} { } else { set disp $vdisporder($hlview) } - for {set i $highlighted($hlview)} {$i < $max} {incr i} { + set vr [visiblerows] + set r0 [lindex $vr 0] + set r1 [lindex $vr 1] + for {set i $vhl_done} {$i < $max} {incr i} { set id [lindex $disp $i] if {[info exists commitrow($curview,$id)]} { set row $commitrow($curview,$id) - if {[info exists linehtag($row)]} { - $canv itemconf $linehtag($row) -font $font - lappend highlightedrows $row - if {$row == $selectedline} { - $canv delete secsel - set t [eval $canv create rect \ - [$canv bbox $linehtag($row)] \ - -outline {{}} -tags secsel \ - -fill [$canv cget -selectbackground]] - $canv lower $t + if {$r0 <= $row && $row <= $r1} { + if {![highlighted $row]} { + bolden $row $font } + set vhighlights($row) 1 } } } - set highlighted($hlview) $max + set vhl_done $max +} + +proc askvhighlight {row id} { + global hlview vhighlights commitrow iddrawn mainfont + + if {[info exists commitrow($hlview,$id)]} { + if {[info exists iddrawn($id)] && ![ishighlighted $row]} { + bolden $row [concat $mainfont bold] + } + set vhighlights($row) 1 + } else { + set vhighlights($row) 0 + } +} + +proc hfiles_change {name ix op} { + global highlight_files filehighlight fhighlights fh_serial + global mainfont highlight_paths + + if {[info exists filehighlight]} { + # delete previous highlights + catch {close $filehighlight} + unset filehighlight + set rows [array names fhighlights] + if {$rows ne {}} { + unset fhighlights + unbolden $rows + } + unhighlight_filelist + } + set highlight_paths {} + after cancel do_file_hl $fh_serial + incr fh_serial + if {$highlight_files ne {}} { + after 300 do_file_hl $fh_serial + } +} + +proc makepatterns {l} { + set ret {} + foreach e $l { + set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e] + if {[string index $ee end] eq "/"} { + lappend ret "$ee*" + } else { + lappend ret $ee + lappend ret "$ee/*" + } + } + return $ret +} + +proc do_file_hl {serial} { + global highlight_files filehighlight highlight_paths gdttype + + if {$gdttype eq "touching paths:"} { + if {[catch {set paths [shellsplit $highlight_files]}]} return + set highlight_paths [makepatterns $paths] + highlight_filelist + set gdtargs [concat -- $paths] + } else { + set gdtargs [list "-S$highlight_files"] + } + set cmd [concat | git-diff-tree -r -s --stdin $gdtargs] + set filehighlight [open $cmd r+] + fconfigure $filehighlight -blocking 0 + fileevent $filehighlight readable readfhighlight + drawvisible + flushhighlights +} + +proc flushhighlights {} { + global filehighlight + + if {[info exists filehighlight]} { + puts $filehighlight "" + flush $filehighlight + } +} + +proc askfilehighlight {row id} { + global filehighlight fhighlights + + set fhighlights($row) 0 + puts $filehighlight $id +} + +proc readfhighlight {} { + global filehighlight fhighlights commitrow curview mainfont iddrawn + + set n [gets $filehighlight line] + if {$n < 0} { + if {[eof $filehighlight]} { + # strange... + puts "oops, git-diff-tree died" + catch {close $filehighlight} + unset filehighlight + } + return + } + set line [string trim $line] + if {$line eq {}} return + if {![info exists commitrow($curview,$line)]} return + set row $commitrow($curview,$line) + if {[info exists iddrawn($line)] && ![ishighlighted $row]} { + bolden $row [concat $mainfont bold] + } + set fhighlights($row) 1 +} + +proc find_change {name ix op} { + global nhighlights mainfont + global findstring findpattern findtype + + # delete previous highlights, if any + set rows [array names nhighlights] + if {$rows ne {}} { + foreach row $rows { + if {$nhighlights($row) >= 2} { + bolden_name $row $mainfont + } + } + unset nhighlights + unbolden $rows + } + if {$findtype ne "Regexp"} { + set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \ + $findstring] + set findpattern "*$e*" + } + drawvisible +} + +proc askfindhighlight {row id} { + global nhighlights commitinfo iddrawn mainfont + global findstring findtype findloc findpattern + + if {![info exists commitinfo($id)]} { + getcommit $id + } + set info $commitinfo($id) + set isbold 0 + set fldtypes {Headline Author Date Committer CDate Comments} + foreach f $info ty $fldtypes { + if {$findloc ne "All fields" && $findloc ne $ty} { + continue + } + if {$findtype eq "Regexp"} { + set doesmatch [regexp $findstring $f] + } elseif {$findtype eq "IgnCase"} { + set doesmatch [string match -nocase $findpattern $f] + } else { + set doesmatch [string match $findpattern $f] + } + if {$doesmatch} { + if {$ty eq "Author"} { + set isbold 2 + } else { + set isbold 1 + } + } + } + if {[info exists iddrawn($id)]} { + if {$isbold && ![ishighlighted $row]} { + bolden $row [concat $mainfont bold] + } + if {$isbold >= 2} { + bolden_name $row [concat $mainfont bold] + } + } + set nhighlights($row) $isbold } # Graph layout functions @@ -2335,7 +2646,6 @@ proc drawcmittext {id row col rmx} { global rowtextx idpos idtags idheads idotherrefs global linehtag linentag linedtag global mainfont canvxmax - global hlview commitrow highlightedrows set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}] set x [xc $row $col] @@ -2361,15 +2671,19 @@ proc drawcmittext {id row col rmx} { set date [lindex $commitinfo($id) 2] set date [formatdate $date] set font $mainfont - if {[info exists hlview] && [info exists commitrow($hlview,$id)]} { + set nfont $mainfont + set isbold [ishighlighted $row] + if {$isbold > 0} { lappend font bold - lappend highlightedrows $row + if {$isbold > 1} { + lappend nfont bold + } } set linehtag($row) [$canv create text $xt $y -anchor w \ -text $headline -font $font] $canv bind $linehtag($row) "rowmenu %X %Y $id" set linentag($row) [$canv2 create text 3 $y -anchor w \ - -text $name -font $mainfont] + -text $name -font $nfont] set linedtag($row) [$canv3 create text 3 $y -anchor w \ -text $date -font $mainfont] set xr [expr {$xt + [font measure $mainfont $headline]}] @@ -2383,6 +2697,8 @@ proc drawcmitrow {row} { global displayorder rowidlist global idrangedrawn iddrawn global commitinfo parentlist numcommits + global filehighlight fhighlights findstring nhighlights + global hlview vhighlights if {$row >= $numcommits} return foreach id [lindex $rowidlist $row] { @@ -2403,6 +2719,15 @@ proc drawcmitrow {row} { } set id [lindex $displayorder $row] + if {[info exists hlview] && ![info exists vhighlights($row)]} { + askvhighlight $row $id + } + if {[info exists filehighlight] && ![info exists fhighlights($row)]} { + askfilehighlight $row $id + } + if {$findstring ne {} && ![info exists nhighlights($row)]} { + askfindhighlight $row $id + } if {[info exists iddrawn($id)]} return set col [lsearch -exact [lindex $rowidlist $row] $id] if {$col < 0} { @@ -2451,10 +2776,14 @@ proc drawvisible {} { proc clear_display {} { global iddrawn idrangedrawn + global vhighlights fhighlights nhighlights allcanvs delete all catch {unset iddrawn} catch {unset idrangedrawn} + catch {unset vhighlights} + catch {unset fhighlights} + catch {unset nhighlights} } proc findcrossings {id} { @@ -2760,10 +3089,6 @@ proc dofind {} { unmarkmatches focus . set matchinglines {} - if {$findloc == "Pickaxe"} { - findpatches - return - } if {$findtype == "IgnCase"} { set foundstring [string tolower $findstring] } else { @@ -2773,17 +3098,13 @@ proc dofind {} { if {$foundstrlen == 0} return regsub -all {[*?\[\\]} $foundstring {\\&} matchstring set matchstring "*$matchstring*" - if {$findloc == "Files"} { - findfiles - return - } if {![info exists selectedline]} { set oldsel -1 } else { set oldsel $selectedline } set didsel 0 - set fldtypes {Headline Author Date Committer CDate Comment} + set fldtypes {Headline Author Date Committer CDate Comments} set l -1 foreach id $displayorder { set d $commitdata($id) @@ -2886,18 +3207,6 @@ proc findprev {} { } } -proc findlocchange {name ix op} { - global findloc findtype findtypemenu - if {$findloc == "Pickaxe"} { - set findtype Exact - set state disabled - } else { - set state normal - } - $findtypemenu entryconf 1 -state $state - $findtypemenu entryconf 2 -state $state -} - proc stopfindproc {{done 0}} { global findprocpid findprocfile findids global ctext findoldcursor phase maincursor textcursor @@ -2915,247 +3224,6 @@ proc stopfindproc {{done 0}} { notbusy find } -proc findpatches {} { - global findstring selectedline numcommits - global findprocpid findprocfile - global finddidsel ctext displayorder findinprogress - global findinsertpos - - if {$numcommits == 0} return - - # make a list of all the ids to search, starting at the one - # after the selected line (if any) - if {[info exists selectedline]} { - set l $selectedline - } else { - set l -1 - } - set inputids {} - for {set i 0} {$i < $numcommits} {incr i} { - if {[incr l] >= $numcommits} { - set l 0 - } - append inputids [lindex $displayorder $l] "\n" - } - - if {[catch { - set f [open [list | git-diff-tree --stdin -s -r -S$findstring \ - << $inputids] r] - } err]} { - error_popup "Error starting search process: $err" - return - } - - set findinsertpos end - set findprocfile $f - set findprocpid [pid $f] - fconfigure $f -blocking 0 - fileevent $f readable readfindproc - set finddidsel 0 - nowbusy find - set findinprogress 1 -} - -proc readfindproc {} { - global findprocfile finddidsel - global commitrow matchinglines findinsertpos curview - - set n [gets $findprocfile line] - if {$n < 0} { - if {[eof $findprocfile]} { - stopfindproc 1 - if {!$finddidsel} { - bell - } - } - return - } - if {![regexp {^[0-9a-f]{40}} $line id]} { - error_popup "Can't parse git-diff-tree output: $line" - stopfindproc - return - } - if {![info exists commitrow($curview,$id)]} { - puts stderr "spurious id: $id" - return - } - set l $commitrow($curview,$id) - insertmatch $l $id -} - -proc insertmatch {l id} { - global matchinglines findinsertpos finddidsel - - if {$findinsertpos == "end"} { - if {$matchinglines != {} && $l < [lindex $matchinglines 0]} { - set matchinglines [linsert $matchinglines 0 $l] - set findinsertpos 1 - } else { - lappend matchinglines $l - } - } else { - set matchinglines [linsert $matchinglines $findinsertpos $l] - incr findinsertpos - } - markheadline $l $id - if {!$finddidsel} { - findselectline $l - set finddidsel 1 - } -} - -proc findfiles {} { - global selectedline numcommits displayorder ctext - global ffileline finddidsel parentlist - global findinprogress findstartline findinsertpos - global treediffs fdiffid fdiffsneeded fdiffpos - global findmergefiles - - if {$numcommits == 0} return - - if {[info exists selectedline]} { - set l [expr {$selectedline + 1}] - } else { - set l 0 - } - set ffileline $l - set findstartline $l - set diffsneeded {} - set fdiffsneeded {} - while 1 { - set id [lindex $displayorder $l] - if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} { - if {![info exists treediffs($id)]} { - append diffsneeded "$id\n" - lappend fdiffsneeded $id - } - } - if {[incr l] >= $numcommits} { - set l 0 - } - if {$l == $findstartline} break - } - - # start off a git-diff-tree process if needed - if {$diffsneeded ne {}} { - if {[catch { - set df [open [list | git-diff-tree -r --stdin << $diffsneeded] r] - } err ]} { - error_popup "Error starting search process: $err" - return - } - catch {unset fdiffid} - set fdiffpos 0 - fconfigure $df -blocking 0 - fileevent $df readable [list readfilediffs $df] - } - - set finddidsel 0 - set findinsertpos end - set id [lindex $displayorder $l] - nowbusy find - set findinprogress 1 - findcont - update -} - -proc readfilediffs {df} { - global findid fdiffid fdiffs - - set n [gets $df line] - if {$n < 0} { - if {[eof $df]} { - donefilediff - if {[catch {close $df} err]} { - stopfindproc - bell - error_popup "Error in git-diff-tree: $err" - } elseif {[info exists findid]} { - set id $findid - stopfindproc - bell - error_popup "Couldn't find diffs for $id" - } - } - return - } - if {[regexp {^([0-9a-f]{40})$} $line match id]} { - # start of a new string of diffs - donefilediff - set fdiffid $id - set fdiffs {} - } elseif {[string match ":*" $line]} { - lappend fdiffs [lindex $line 5] - } -} - -proc donefilediff {} { - global fdiffid fdiffs treediffs findid - global fdiffsneeded fdiffpos - - if {[info exists fdiffid]} { - while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffid - && $fdiffpos < [llength $fdiffsneeded]} { - # git-diff-tree doesn't output anything for a commit - # which doesn't change anything - set nullid [lindex $fdiffsneeded $fdiffpos] - set treediffs($nullid) {} - if {[info exists findid] && $nullid eq $findid} { - unset findid - findcont - } - incr fdiffpos - } - incr fdiffpos - - if {![info exists treediffs($fdiffid)]} { - set treediffs($fdiffid) $fdiffs - } - if {[info exists findid] && $fdiffid eq $findid} { - unset findid - findcont - } - } -} - -proc findcont {} { - global findid treediffs parentlist - global ffileline findstartline finddidsel - global displayorder numcommits matchinglines findinprogress - global findmergefiles - - set l $ffileline - while {1} { - set id [lindex $displayorder $l] - if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} { - if {![info exists treediffs($id)]} { - set findid $id - set ffileline $l - return - } - set doesmatch 0 - foreach f $treediffs($id) { - set x [findmatches $f] - if {$x != {}} { - set doesmatch 1 - break - } - } - if {$doesmatch} { - insertmatch $l $id - } - } - if {[incr l] >= $numcommits} { - set l 0 - } - if {$l == $findstartline} break - } - stopfindproc - if {!$finddidsel} { - bell - } -} - # mark a commit as matching by putting a yellow background # behind the headline proc markheadline {l id} { @@ -3213,8 +3281,11 @@ proc selcanvline {w x y} { proc commit_descriptor {p} { global commitinfo + if {![info exists commitinfo($p)]} { + getcommit $p + } set l "..." - if {[info exists commitinfo($p)]} { + if {[llength $commitinfo($p)] > 1} { set l [lindex $commitinfo($p) 0] } return "$p ($l)" @@ -3339,7 +3410,7 @@ proc selectline {l isnew} { $sha1entry selection to end $ctext conf -state normal - $ctext delete 0.0 end + clear_ctext set linknum 0 set info $commitinfo($id) set date [formatdate [lindex $info 2]] @@ -3426,6 +3497,7 @@ proc selnextpage {dir} { set lpp 1 } allcanvs yview scroll [expr {$dir * $lpp}] units + drawvisible if {![info exists selectedline]} return set l [expr {$selectedline + $dir * $lpp}] if {$l < 0} { @@ -3576,7 +3648,7 @@ proc showfile {f} { fconfigure $bf -blocking 0 fileevent $bf readable [list getblobline $bf $diffids] $ctext config -state normal - $ctext delete $commentend end + clear_ctext $commentend $ctext insert end "\n" $ctext insert end "$f\n" filesep $ctext config -state disabled @@ -3876,6 +3948,138 @@ proc nextfile {} { } } +proc clear_ctext {{first 1.0}} { + global ctext smarktop smarkbot + + set l [lindex [split $first .] 0] + if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} { + set smarktop $l + } + if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} { + set smarkbot $l + } + $ctext delete $first end +} + +proc incrsearch {name ix op} { + global ctext searchstring searchdirn + + $ctext tag remove found 1.0 end + if {[catch {$ctext index anchor}]} { + # no anchor set, use start of selection, or of visible area + set sel [$ctext tag ranges sel] + if {$sel ne {}} { + $ctext mark set anchor [lindex $sel 0] + } elseif {$searchdirn eq "-forwards"} { + $ctext mark set anchor @0,0 + } else { + $ctext mark set anchor @0,[winfo height $ctext] + } + } + if {$searchstring ne {}} { + set here [$ctext search $searchdirn -- $searchstring anchor] + if {$here ne {}} { + $ctext see $here + } + searchmarkvisible 1 + } +} + +proc dosearch {} { + global sstring ctext searchstring searchdirn + + focus $sstring + $sstring icursor end + set searchdirn -forwards + if {$searchstring ne {}} { + set sel [$ctext tag ranges sel] + if {$sel ne {}} { + set start "[lindex $sel 0] + 1c" + } elseif {[catch {set start [$ctext index anchor]}]} { + set start "@0,0" + } + set match [$ctext search -count mlen -- $searchstring $start] + $ctext tag remove sel 1.0 end + if {$match eq {}} { + bell + return + } + $ctext see $match + set mend "$match + $mlen c" + $ctext tag add sel $match $mend + $ctext mark unset anchor + } +} + +proc dosearchback {} { + global sstring ctext searchstring searchdirn + + focus $sstring + $sstring icursor end + set searchdirn -backwards + if {$searchstring ne {}} { + set sel [$ctext tag ranges sel] + if {$sel ne {}} { + set start [lindex $sel 0] + } elseif {[catch {set start [$ctext index anchor]}]} { + set start @0,[winfo height $ctext] + } + set match [$ctext search -backwards -count ml -- $searchstring $start] + $ctext tag remove sel 1.0 end + if {$match eq {}} { + bell + return + } + $ctext see $match + set mend "$match + $ml c" + $ctext tag add sel $match $mend + $ctext mark unset anchor + } +} + +proc searchmark {first last} { + global ctext searchstring + + set mend $first.0 + while {1} { + set match [$ctext search -count mlen -- $searchstring $mend $last.end] + if {$match eq {}} break + set mend "$match + $mlen c" + $ctext tag add found $match $mend + } +} + +proc searchmarkvisible {doall} { + global ctext smarktop smarkbot + + set topline [lindex [split [$ctext index @0,0] .] 0] + set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0] + if {$doall || $botline < $smarktop || $topline > $smarkbot} { + # no overlap with previous + searchmark $topline $botline + set smarktop $topline + set smarkbot $botline + } else { + if {$topline < $smarktop} { + searchmark $topline [expr {$smarktop-1}] + set smarktop $topline + } + if {$botline > $smarkbot} { + searchmark [expr {$smarkbot+1}] $botline + set smarkbot $botline + } + } +} + +proc scrolltext {f0 f1} { + global searchstring + + .ctop.cdet.left.sb set $f0 $f1 + if {$searchstring ne {}} { + searchmarkvisible 0 + } +} + proc setcoords {} { global linespc charspc canvx0 canvy0 mainfont global xspc1 xspc2 lthickness @@ -4110,7 +4314,7 @@ proc lineclick {x y id isnew} { } # fill the details pane with info about this line $ctext conf -state normal - $ctext delete 0.0 end + clear_ctext $ctext tag conf link -foreground blue -underline 1 $ctext tag bind link { %W configure -cursor hand2 } $ctext tag bind link { %W configure -cursor $curtextcursor } @@ -4203,7 +4407,7 @@ proc doseldiff {oldid newid} { global commitinfo $ctext conf -state normal - $ctext delete 0.0 end + clear_ctext init_flist "Top" $ctext insert end "From " $ctext tag conf link -foreground blue -underline 1 @@ -4497,7 +4701,7 @@ proc showtag {tag isnew} { addtohistory [list showtag $tag 0] } $ctext conf -state normal - $ctext delete 0.0 end + clear_ctext set linknum 0 if {[info exists tagcontents($tag)]} { set text $tagcontents($tag) @@ -4516,7 +4720,7 @@ proc doquit {} { } proc doprefs {} { - global maxwidth maxgraphpct diffopts findmergefiles + global maxwidth maxgraphpct diffopts global oldprefs prefstop set top .gitkprefs @@ -4525,7 +4729,7 @@ proc doprefs {} { raise $top return } - foreach v {maxwidth maxgraphpct diffopts findmergefiles} { + foreach v {maxwidth maxgraphpct diffopts} { set oldprefs($v) [set $v] } toplevel $top @@ -4541,10 +4745,6 @@ proc doprefs {} { -font optionfont spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct grid x $top.maxpctl $top.maxpct -sticky w - checkbutton $top.findm -variable findmergefiles - label $top.findml -text "Include merges for \"Find\" in \"Files\"" \ - -font optionfont - grid $top.findm $top.findml - -sticky w label $top.ddisp -text "Diff display options" grid $top.ddisp - -sticky w -pady 10 label $top.diffoptl -text "Options for diff program" \ @@ -4561,10 +4761,10 @@ proc doprefs {} { } proc prefscan {} { - global maxwidth maxgraphpct diffopts findmergefiles + global maxwidth maxgraphpct diffopts global oldprefs prefstop - foreach v {maxwidth maxgraphpct diffopts findmergefiles} { + foreach v {maxwidth maxgraphpct diffopts} { set $v $oldprefs($v) } catch {destroy $prefstop} @@ -4888,7 +5088,6 @@ set fastdate 0 set uparrowlen 7 set downarrowlen 7 set mingaplen 30 -set flistmode "flat" set cmitmode "patch" set colors {green red blue magenta darkgrey brown orange} @@ -4940,13 +5139,17 @@ if {$i >= 0} { set history {} set historyindex 0 +set fh_serial 0 +set nhl_names {} +set highlight_paths {} +set searchdirn -forwards set optim_delay 16 set nextviewnum 1 set curview 0 set selectedview 0 -set selectedhlview {} +set selectedhlview None set viewfiles(0) {} set viewperm(0) 0 set viewargs(0) {}