提交 b74fd579 编写于 作者: P Paul Mackerras

Add "Files" and "Pickaxe" to the find menu.

"Files" matches the find string against each of the files modified
by each commit, and can do exact, case-ignoring or regexp matching.

"Pickaxe" uses git-diff-tree -S'string' and can only do exact
matching.  I called it "pickaxe" rather than "find within patch"
since it only finds commits where the string is present in the child
but not the parents or vice versa, and "pickaxe" is what the author
of that feature calls it.
上级 4a2139f5
...@@ -270,7 +270,7 @@ proc error_popup msg { ...@@ -270,7 +270,7 @@ proc error_popup msg {
proc makewindow {} { proc makewindow {} {
global canv canv2 canv3 linespc charspc ctext cflist textfont global canv canv2 canv3 linespc charspc ctext cflist textfont
global findtype findloc findstring fstring geometry global findtype findtypemenu findloc findstring fstring geometry
global entries sha1entry sha1string sha1but global entries sha1entry sha1string sha1but
global maincursor textcursor global maincursor textcursor
global rowctxmenu global rowctxmenu
...@@ -342,12 +342,15 @@ proc makewindow {} { ...@@ -342,12 +342,15 @@ proc makewindow {} {
entry $fstring -width 30 -font $textfont -textvariable findstring entry $fstring -width 30 -font $textfont -textvariable findstring
pack $fstring -side left -expand 1 -fill x pack $fstring -side left -expand 1 -fill x
set findtype Exact set findtype Exact
tk_optionMenu .ctop.top.bar.findtype findtype Exact IgnCase Regexp set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
findtype Exact IgnCase Regexp]
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 Comments Author Committer Files Pickaxe
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
panedwindow .ctop.cdet -orient horizontal panedwindow .ctop.cdet -orient horizontal
.ctop add .ctop.cdet .ctop add .ctop.cdet
...@@ -397,12 +400,13 @@ proc makewindow {} { ...@@ -397,12 +400,13 @@ proc makewindow {} {
bindkey b "$ctext yview scroll -1 pages" bindkey b "$ctext yview scroll -1 pages"
bindkey d "$ctext yview scroll 18 units" bindkey d "$ctext yview scroll 18 units"
bindkey u "$ctext yview scroll -18 units" bindkey u "$ctext yview scroll -18 units"
bindkey / findnext bindkey / {findnext 1}
bindkey <Key-Return> {findnext 0}
bindkey ? findprev bindkey ? findprev
bindkey f nextfile bindkey f nextfile
bind . <Control-q> doquit bind . <Control-q> doquit
bind . <Control-f> dofind bind . <Control-f> dofind
bind . <Control-g> findnext bind . <Control-g> {findnext 0}
bind . <Control-r> findprev bind . <Control-r> findprev
bind . <Control-equal> {incrfont 1} bind . <Control-equal> {incrfont 1}
bind . <Control-KP_Add> {incrfont 1} bind . <Control-KP_Add> {incrfont 1}
...@@ -1136,10 +1140,15 @@ proc dofind {} { ...@@ -1136,10 +1140,15 @@ proc dofind {} {
global numcommits lineid linehtag linentag linedtag global numcommits lineid linehtag linentag linedtag
global mainfont namefont canv canv2 canv3 selectedline global mainfont namefont canv canv2 canv3 selectedline
global matchinglines foundstring foundstrlen global matchinglines foundstring foundstrlen
stopfindproc
unmarkmatches unmarkmatches
focus . focus .
set matchinglines {} set matchinglines {}
set fldtypes {Headline Author Date Committer CDate Comment} if {$findloc == "Pickaxe"} {
findpatches
return
}
if {$findtype == "IgnCase"} { if {$findtype == "IgnCase"} {
set foundstring [string tolower $findstring] set foundstring [string tolower $findstring]
} else { } else {
...@@ -1147,12 +1156,17 @@ proc dofind {} { ...@@ -1147,12 +1156,17 @@ proc dofind {} {
} }
set foundstrlen [string length $findstring] set foundstrlen [string length $findstring]
if {$foundstrlen == 0} return if {$foundstrlen == 0} return
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}
for {set l 0} {$l < $numcommits} {incr l} { for {set l 0} {$l < $numcommits} {incr l} {
set id $lineid($l) set id $lineid($l)
set info $commitinfo($id) set info $commitinfo($id)
...@@ -1202,10 +1216,12 @@ proc findselectline {l} { ...@@ -1202,10 +1216,12 @@ proc findselectline {l} {
} }
} }
proc findnext {} { proc findnext {restart} {
global matchinglines selectedline global matchinglines selectedline
if {![info exists matchinglines]} { if {![info exists matchinglines]} {
dofind if {$restart} {
dofind
}
return return
} }
if {![info exists selectedline]} return if {![info exists selectedline]} return
...@@ -1237,6 +1253,203 @@ proc findprev {} { ...@@ -1237,6 +1253,203 @@ 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
global findinprogress
catch {unset findids}
if {[info exists findprocpid]} {
if {!$done} {
catch {exec kill $findprocpid}
}
catch {close $findprocfile}
unset findprocpid
}
if {[info exists findinprogress]} {
unset findinprogress
if {$phase != "incrdraw"} {
. config -cursor $maincursor
$ctext config -cursor $textcursor
}
}
}
proc findpatches {} {
global findstring selectedline numcommits
global findprocpid findprocfile
global finddidsel ctext lineid findinprogress
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 $lineid($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 findprocfile $f
set findprocpid [pid $f]
fconfigure $f -blocking 0
fileevent $f readable readfindproc
set finddidsel 0
. config -cursor watch
$ctext config -cursor watch
set findinprogress 1
}
proc readfindproc {} {
global findprocfile finddidsel
global idline matchinglines
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 idline($id)]} {
puts stderr "spurious id: $id"
return
}
set l $idline($id)
lappend matchinglines $l
if {!$finddidsel} {
findselectline $l
set finddidsel 1
}
}
proc findfiles {} {
global selectedline numcommits lineid
global ffileline finddidsel parents findstartline
global findinprogress ctext
if {$numcommits == 0} return
if {[info exists selectedline]} {
set l [expr {$selectedline + 1}]
} else {
set l 0
}
set ffileline $l
set finddidsel 0
set findstartline $l
set id $lineid($l)
set p [lindex $parents($id) 0]
. config -cursor watch
$ctext config -cursor watch
set findinprogress 1
update
findcont [list $id $p]
}
proc findcont {ids} {
global findids treediffs parents nparents treepending
global ffileline findstartline finddidsel
global lineid numcommits matchinglines findinprogress
global findmergefiles
set id [lindex $ids 0]
set p [lindex $ids 1]
set pi [lsearch -exact $parents($id) $p]
set l $ffileline
while 1 {
if {$findmergefiles || $nparents($id) == 1} {
if {![info exists treediffs($ids)]} {
set findids $ids
set ffileline $l
if {![info exists treepending]} {
gettreediffs $ids
}
return
}
set doesmatch 0
foreach f $treediffs($ids) {
set x [findmatches $f]
if {$x != {}} {
set doesmatch 1
break
}
}
if {$doesmatch} {
lappend matchinglines $l
markheadline $l $id
if {!$finddidsel} {
findselectline $l
set finddidsel 1
}
set pi $nparents($id)
}
} else {
set pi $nparents($id)
}
if {[incr pi] >= $nparents($id)} {
set pi 0
if {[incr l] >= $numcommits} {
set l 0
}
if {$l == $findstartline} break
set id $lineid($l)
}
set p [lindex $parents($id) $pi]
set ids [list $id $p]
}
stopfindproc
if {!$finddidsel} {
bell
}
}
# mark a commit as matching by putting a yellow background
# behind the headline
proc markheadline {l id} {
global canv mainfont linehtag commitinfo
set bbox [$canv bbox $linehtag($l)]
set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
$canv lower $t
}
# mark the bits of a headline, author or date that match a find string
proc markmatches {canv l str tag matches font} { proc markmatches {canv l str tag matches font} {
set bbox [$canv bbox $tag] set bbox [$canv bbox $tag]
set x0 [lindex $bbox 0] set x0 [lindex $bbox 0]
...@@ -1255,9 +1468,10 @@ proc markmatches {canv l str tag matches font} { ...@@ -1255,9 +1468,10 @@ proc markmatches {canv l str tag matches font} {
} }
proc unmarkmatches {} { proc unmarkmatches {} {
global matchinglines global matchinglines findids
allcanvs delete matches allcanvs delete matches
catch {unset matchinglines} catch {unset matchinglines}
catch {unset findids}
} }
proc selcanvline {w x y} { proc selcanvline {w x y} {
...@@ -1393,11 +1607,7 @@ proc selnextline {dir} { ...@@ -1393,11 +1607,7 @@ proc selnextline {dir} {
} }
proc addtocflist {ids} { proc addtocflist {ids} {
global diffids treediffs cflist global treediffs cflist
if {$ids != $diffids} {
gettreediffs $diffids
return
}
foreach f $treediffs($ids) { foreach f $treediffs($ids) {
$cflist insert end $f $cflist insert end $f
} }
...@@ -1416,13 +1626,28 @@ proc gettreediffs {ids} { ...@@ -1416,13 +1626,28 @@ proc gettreediffs {ids} {
} }
proc gettreediffline {gdtf ids} { proc gettreediffline {gdtf ids} {
global treediffs treepending global treediffs treepending diffids findids
set n [gets $gdtf line] set n [gets $gdtf line]
if {$n < 0} { if {$n < 0} {
if {![eof $gdtf]} return if {![eof $gdtf]} return
close $gdtf close $gdtf
unset treepending unset treepending
addtocflist $ids if {[info exists diffids]} {
if {$ids != $diffids} {
gettreediffs $diffids
} else {
addtocflist $ids
}
}
if {[info exists findids]} {
if {$ids != $findids} {
if {![info exists treepending]} {
gettreediffs $findids
}
} else {
findcont $ids
}
}
return return
} }
set file [lindex $line 5] set file [lindex $line 5]
...@@ -1459,14 +1684,17 @@ proc getblobdiffline {bdf ids} { ...@@ -1459,14 +1684,17 @@ proc getblobdiffline {bdf ids} {
if {$n < 0} { if {$n < 0} {
if {[eof $bdf]} { if {[eof $bdf]} {
close $bdf close $bdf
if {$ids == $diffids && $bdf == $blobdifffd($ids)} { if {[info exists diffids] && $ids == $diffids
&& $bdf == $blobdifffd($ids)} {
$ctext tag add $curdifftag $curtagstart end $ctext tag add $curdifftag $curtagstart end
set seenfile($curdifftag) 1 set seenfile($curdifftag) 1
unset diffids
} }
} }
return return
} }
if {$ids != $diffids || $bdf != $blobdifffd($ids)} { if {![info exists diffids] || $ids != $diffids
|| $bdf != $blobdifffd($ids)} {
return return
} }
$ctext conf -state normal $ctext conf -state normal
...@@ -2044,6 +2272,7 @@ set wrcomcmd "git-diff-tree --stdin -p --pretty" ...@@ -2044,6 +2272,7 @@ set wrcomcmd "git-diff-tree --stdin -p --pretty"
set mainfont {Helvetica 9} set mainfont {Helvetica 9}
set textfont {Courier 9} set textfont {Courier 9}
set findmergefiles 0
set colors {green red blue magenta darkgrey brown orange} set colors {green red blue magenta darkgrey brown orange}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册