gitk: Move "pickaxe" find function to highlight facility

This removes the "Files" and "Pickaxe" parts of the "Find" function,
so Find is now just about searching the commit data.  We now highlight
the commits that match the Find string (without having to press Find),
and have a drop-down menu for selecting whether the git-diff-tree based
highlighting is done on paths or on adding/removing a given string.

Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Paul Mackerras 2006-05-26 10:43:47 +10:00
parent 1902c2705e
commit 60f7a7dc49

360
gitk
View File

@ -383,7 +383,7 @@ proc makewindow {} {
global entries sha1entry sha1string sha1but global entries sha1entry sha1string sha1but
global maincursor textcursor curtextcursor global maincursor textcursor curtextcursor
global rowctxmenu mergemax global rowctxmenu mergemax
global highlight_files highlight_names global highlight_files gdttype
global searchstring sstring global searchstring sstring
menu .bar menu .bar
@ -498,26 +498,33 @@ proc makewindow {} {
set fstring .ctop.top.bar.findstring set fstring .ctop.top.bar.findstring
lappend entries $fstring lappend entries $fstring
entry $fstring -width 30 -font $textfont -textvariable findstring entry $fstring -width 30 -font $textfont -textvariable findstring
trace add variable findstring write find_change
pack $fstring -side left -expand 1 -fill x pack $fstring -side left -expand 1 -fill x
set findtype Exact set findtype Exact
set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \ set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
findtype Exact IgnCase Regexp] findtype Exact IgnCase Regexp]
trace add variable findtype write find_change
.ctop.top.bar.findtype configure -font $uifont .ctop.top.bar.findtype configure -font $uifont
.ctop.top.bar.findtype.menu configure -font $uifont .ctop.top.bar.findtype.menu configure -font $uifont
set findloc "All fields" set findloc "All fields"
tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \ 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 configure -font $uifont
.ctop.top.bar.findloc.menu configure -font $uifont .ctop.top.bar.findloc.menu configure -font $uifont
pack .ctop.top.bar.findloc -side right pack .ctop.top.bar.findloc -side right
pack .ctop.top.bar.findtype -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 touching paths:" \ label .ctop.top.lbar.flabel -text "Highlight: Commits " \
-font $uifont -font $uifont
pack .ctop.top.lbar.flabel -side left -fill y 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 \ entry .ctop.top.lbar.fent -width 25 -font $textfont \
-textvariable highlight_files -textvariable highlight_files
trace add variable highlight_files write hfiles_change trace add variable highlight_files write hfiles_change
@ -531,14 +538,6 @@ proc makewindow {} {
$viewhlmenu conf -font $uifont $viewhlmenu conf -font $uifont
.ctop.top.lbar.vhl conf -font $uifont .ctop.top.lbar.vhl conf -font $uifont
pack .ctop.top.lbar.vhl -side left -fill y pack .ctop.top.lbar.vhl -side left -fill y
label .ctop.top.lbar.alabel -text " OR author/committer:" \
-font $uifont
pack .ctop.top.lbar.alabel -side left -fill y
entry .ctop.top.lbar.aent -width 20 -font $textfont \
-textvariable highlight_names
trace add variable highlight_names write hnames_change
lappend entries .ctop.top.lbar.aent
pack .ctop.top.lbar.aent -side right -fill x -expand 1
panedwindow .ctop.cdet -orient horizontal panedwindow .ctop.cdet -orient horizontal
.ctop add .ctop.cdet .ctop add .ctop.cdet
@ -1807,12 +1806,17 @@ proc makepatterns {l} {
} }
proc do_file_hl {serial} { proc do_file_hl {serial} {
global highlight_files filehighlight highlight_paths global highlight_files filehighlight highlight_paths gdttype
if {$gdttype eq "touching paths:"} {
if {[catch {set paths [shellsplit $highlight_files]}]} return if {[catch {set paths [shellsplit $highlight_files]}]} return
set highlight_paths [makepatterns $paths] set highlight_paths [makepatterns $paths]
highlight_filelist highlight_filelist
set cmd [concat | git-diff-tree -r -s --stdin -- $paths] 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+] set filehighlight [open $cmd r+]
fconfigure $filehighlight -blocking 0 fconfigure $filehighlight -blocking 0
fileevent $filehighlight readable readfhighlight fileevent $filehighlight readable readfhighlight
@ -1859,8 +1863,9 @@ proc readfhighlight {} {
set fhighlights($row) 1 set fhighlights($row) 1
} }
proc hnames_change {name ix op} { proc find_change {name ix op} {
global highlight_names nhighlights nhl_names mainfont global nhighlights mainfont
global findstring findpattern findtype
# delete previous highlights, if any # delete previous highlights, if any
set rows [array names nhighlights] set rows [array names nhighlights]
@ -1873,32 +1878,43 @@ proc hnames_change {name ix op} {
unset nhighlights unset nhighlights
unbolden $rows unbolden $rows
} }
if {[catch {set nhl_names [shellsplit $highlight_names]}]} { if {$findtype ne "Regexp"} {
set nhl_names {} set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
return $findstring]
set findpattern "*$e*"
} }
drawvisible drawvisible
} }
proc asknamehighlight {row id} { proc askfindhighlight {row id} {
global nhl_names nhighlights commitinfo iddrawn mainfont global nhighlights commitinfo iddrawn mainfont
global findstring findtype findloc findpattern
if {![info exists commitinfo($id)]} { if {![info exists commitinfo($id)]} {
getcommit $id getcommit $id
} }
set info $commitinfo($id)
set isbold 0 set isbold 0
set author [lindex $commitinfo($id) 1] set fldtypes {Headline Author Date Committer CDate Comments}
set committer [lindex $commitinfo($id) 3] foreach f $info ty $fldtypes {
foreach name $nhl_names { if {$findloc ne "All fields" && $findloc ne $ty} {
set pattern "*$name*" continue
if {[string match -nocase $pattern $author]} {
set isbold 2
break
} }
if {!$isbold && [string match -nocase $pattern $committer]} { 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 set isbold 1
} }
} }
}
if {[info exists iddrawn($id)]} { if {[info exists iddrawn($id)]} {
if {$isbold && ![ishighlighted $row]} { if {$isbold && ![ishighlighted $row]} {
bolden $row [concat $mainfont bold] bolden $row [concat $mainfont bold]
@ -2681,7 +2697,7 @@ proc drawcmitrow {row} {
global displayorder rowidlist global displayorder rowidlist
global idrangedrawn iddrawn global idrangedrawn iddrawn
global commitinfo parentlist numcommits global commitinfo parentlist numcommits
global filehighlight fhighlights nhl_names nhighlights global filehighlight fhighlights findstring nhighlights
global hlview vhighlights global hlview vhighlights
if {$row >= $numcommits} return if {$row >= $numcommits} return
@ -2709,8 +2725,8 @@ proc drawcmitrow {row} {
if {[info exists filehighlight] && ![info exists fhighlights($row)]} { if {[info exists filehighlight] && ![info exists fhighlights($row)]} {
askfilehighlight $row $id askfilehighlight $row $id
} }
if {$nhl_names ne {} && ![info exists nhighlights($row)]} { if {$findstring ne {} && ![info exists nhighlights($row)]} {
asknamehighlight $row $id askfindhighlight $row $id
} }
if {[info exists iddrawn($id)]} return if {[info exists iddrawn($id)]} return
set col [lsearch -exact [lindex $rowidlist $row] $id] set col [lsearch -exact [lindex $rowidlist $row] $id]
@ -3073,10 +3089,6 @@ proc dofind {} {
unmarkmatches unmarkmatches
focus . focus .
set matchinglines {} set matchinglines {}
if {$findloc == "Pickaxe"} {
findpatches
return
}
if {$findtype == "IgnCase"} { if {$findtype == "IgnCase"} {
set foundstring [string tolower $findstring] set foundstring [string tolower $findstring]
} else { } else {
@ -3086,17 +3098,13 @@ proc dofind {} {
if {$foundstrlen == 0} return if {$foundstrlen == 0} return
regsub -all {[*?\[\\]} $foundstring {\\&} matchstring regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
set matchstring "*$matchstring*" set matchstring "*$matchstring*"
if {$findloc == "Files"} {
findfiles
return
}
if {![info exists selectedline]} { if {![info exists selectedline]} {
set oldsel -1 set oldsel -1
} else { } else {
set oldsel $selectedline set oldsel $selectedline
} }
set didsel 0 set didsel 0
set fldtypes {Headline Author Date Committer CDate Comment} set fldtypes {Headline Author Date Committer CDate Comments}
set l -1 set l -1
foreach id $displayorder { foreach id $displayorder {
set d $commitdata($id) set d $commitdata($id)
@ -3199,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}} { proc stopfindproc {{done 0}} {
global findprocpid findprocfile findids global findprocpid findprocfile findids
global ctext findoldcursor phase maincursor textcursor global ctext findoldcursor phase maincursor textcursor
@ -3228,247 +3224,6 @@ proc stopfindproc {{done 0}} {
notbusy find 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 # mark a commit as matching by putting a yellow background
# behind the headline # behind the headline
proc markheadline {l id} { proc markheadline {l id} {
@ -4965,7 +4720,7 @@ proc doquit {} {
} }
proc doprefs {} { proc doprefs {} {
global maxwidth maxgraphpct diffopts findmergefiles global maxwidth maxgraphpct diffopts
global oldprefs prefstop global oldprefs prefstop
set top .gitkprefs set top .gitkprefs
@ -4974,7 +4729,7 @@ proc doprefs {} {
raise $top raise $top
return return
} }
foreach v {maxwidth maxgraphpct diffopts findmergefiles} { foreach v {maxwidth maxgraphpct diffopts} {
set oldprefs($v) [set $v] set oldprefs($v) [set $v]
} }
toplevel $top toplevel $top
@ -4990,10 +4745,6 @@ proc doprefs {} {
-font optionfont -font optionfont
spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
grid x $top.maxpctl $top.maxpct -sticky w 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" label $top.ddisp -text "Diff display options"
grid $top.ddisp - -sticky w -pady 10 grid $top.ddisp - -sticky w -pady 10
label $top.diffoptl -text "Options for diff program" \ label $top.diffoptl -text "Options for diff program" \
@ -5010,10 +4761,10 @@ proc doprefs {} {
} }
proc prefscan {} { proc prefscan {} {
global maxwidth maxgraphpct diffopts findmergefiles global maxwidth maxgraphpct diffopts
global oldprefs prefstop global oldprefs prefstop
foreach v {maxwidth maxgraphpct diffopts findmergefiles} { foreach v {maxwidth maxgraphpct diffopts} {
set $v $oldprefs($v) set $v $oldprefs($v)
} }
catch {destroy $prefstop} catch {destroy $prefstop}
@ -5389,7 +5140,6 @@ if {$i >= 0} {
set history {} set history {}
set historyindex 0 set historyindex 0
set fh_serial 0 set fh_serial 0
set highlight_names {}
set nhl_names {} set nhl_names {}
set highlight_paths {} set highlight_paths {}
set searchdirn -forwards set searchdirn -forwards