diff options
Diffstat (limited to 'git-gui/lib/search.tcl')
-rw-r--r-- | git-gui/lib/search.tcl | 123 |
1 files changed, 111 insertions, 12 deletions
diff --git a/git-gui/lib/search.tcl b/git-gui/lib/search.tcl index ef3486f083..ef1e55521d 100644 --- a/git-gui/lib/search.tcl +++ b/git-gui/lib/search.tcl @@ -7,9 +7,16 @@ field w field ctext field searchstring {} -field casesensitive 1 +field regexpsearch +field default_regexpsearch +field casesensitive +field default_casesensitive +field smartcase field searchdirn -forwards +field history +field history_index + field smarktop field smarkbot @@ -18,15 +25,37 @@ constructor new {i_w i_text args} { set w $i_w set ctext $i_text + set default_regexpsearch [is_config_true gui.search.regexp] + switch -- [get_config gui.search.case] { + no { + set default_casesensitive 0 + set smartcase 0 + } + smart { + set default_casesensitive 0 + set smartcase 1 + } + yes - + default { + set default_casesensitive 1 + set smartcase 0 + } + } + + set history [list] + ${NS}::frame $w ${NS}::label $w.l -text [mc Find:] - entry $w.ent -textvariable ${__this}::searchstring -background lightgreen + tentry $w.ent -textvariable ${__this}::searchstring -background lightgreen ${NS}::button $w.bn -text [mc Next] -command [cb find_next] ${NS}::button $w.bp -text [mc Prev] -command [cb find_prev] - ${NS}::checkbutton $w.cs -text [mc Case-Sensitive] \ + ${NS}::checkbutton $w.re -text [mc RegExp] \ + -variable ${__this}::regexpsearch -command [cb _incrsearch] + ${NS}::checkbutton $w.cs -text [mc Case] \ -variable ${__this}::casesensitive -command [cb _incrsearch] pack $w.l -side left pack $w.cs -side right + pack $w.re -side right pack $w.bp -side right pack $w.bn -side right pack $w.ent -side left -expand 1 -fill x @@ -37,6 +66,8 @@ constructor new {i_w i_text args} { trace add variable searchstring write [cb _incrsearch_cb] bind $w.ent <Return> [cb find_next] bind $w.ent <Shift-Return> [cb find_prev] + bind $w.ent <Key-Up> [cb _prev_search] + bind $w.ent <Key-Down> [cb _next_search] bind $w <Destroy> [list delete_this $this] return $this @@ -45,6 +76,10 @@ constructor new {i_w i_text args} { method show {} { if {![visible $this]} { grid $w + $w.ent delete 0 end + set regexpsearch $default_regexpsearch + set casesensitive $default_casesensitive + set history_index [llength $history] } focus -force $w.ent } @@ -53,6 +88,7 @@ method hide {} { if {[visible $this]} { focus $ctext grid remove $w + _save_search $this } } @@ -98,6 +134,9 @@ method _do_search {start {mlenvar {}} {dir {}} {endbound {}}} { upvar $mlenvar mlen lappend cmd -count mlen } + if {$regexpsearch} { + lappend cmd -regexp + } if {!$casesensitive} { lappend cmd -nocase } @@ -105,14 +144,16 @@ method _do_search {start {mlenvar {}} {dir {}} {endbound {}}} { set dir $searchdirn } lappend cmd $dir -- $searchstring - if {$endbound ne {}} { - set here [eval $cmd [list $start] [list $endbound]] - } else { - set here [eval $cmd [list $start]] - if {$here eq {}} { - set here [eval $cmd [_get_wrap_anchor $this $dir]] + if {[catch { + if {$endbound ne {}} { + set here [eval $cmd [list $start] [list $endbound]] + } else { + set here [eval $cmd [list $start]] + if {$here eq {}} { + set here [eval $cmd [_get_wrap_anchor $this $dir]] + } } - } + } err]} { set here {} } return $here } @@ -126,17 +167,74 @@ method _incrsearch {} { $ctext mark set anchor [_get_new_anchor $this] } if {$searchstring ne {}} { + if {$smartcase && [regexp {[[:upper:]]} $searchstring]} { + set casesensitive 1 + } set here [_do_search $this anchor mlen] if {$here ne {}} { $ctext see $here $ctext tag remove sel 1.0 end $ctext tag add sel $here "$here + $mlen c" - $w.ent configure -background lightgreen + #$w.ent configure -background lightgreen + $w.ent state !pressed _set_marks $this 1 } else { - $w.ent configure -background lightpink + #$w.ent configure -background lightpink + $w.ent state pressed } + } elseif {$smartcase} { + # clearing the field resets the smart case detection + set casesensitive 0 + } +} + +method _save_search {} { + if {$searchstring eq {}} { + return + } + if {[llength $history] > 0} { + foreach {s_regexp s_case s_expr} [lindex $history end] break + } else { + set s_regexp $regexpsearch + set s_case $casesensitive + set s_expr "" + } + if {$searchstring eq $s_expr} { + # update modes + set history [lreplace $history end end \ + [list $regexpsearch $casesensitive $searchstring]] + } else { + lappend history [list $regexpsearch $casesensitive $searchstring] + } + set history_index [llength $history] +} + +method _prev_search {} { + if {$history_index > 0} { + incr history_index -1 + foreach {s_regexp s_case s_expr} [lindex $history $history_index] break + $w.ent delete 0 end + $w.ent insert 0 $s_expr + set regexpsearch $s_regexp + set casesensitive $s_case + } +} + +method _next_search {} { + if {$history_index < [llength $history]} { + incr history_index + } + if {$history_index < [llength $history]} { + foreach {s_regexp s_case s_expr} [lindex $history $history_index] break + } else { + set s_regexp $default_regexpsearch + set s_case $default_casesensitive + set s_expr "" } + $w.ent delete 0 end + $w.ent insert 0 $s_expr + set regexpsearch $s_regexp + set casesensitive $s_case } method find_prev {} { @@ -149,6 +247,7 @@ method find_next {{dir -forwards}} { set searchdirn $dir $ctext mark unset anchor if {$searchstring ne {}} { + _save_search $this set start [_get_new_anchor $this] if {$dir eq "-forwards"} { set start "$start + 1c" |