1 # incremental search panel
2 # based on code from gitk, Copyright (C) Paul Mackerras
11 field searchdirn
-forwards
16 constructor new
{i_w i_text args
} {
21 label $w.l
-text [mc Find
:]
22 entry $w.ent
-textvariable ${__this
}::searchstring -background lightgreen
23 button $w.bn
-text [mc Next
] -command [cb find_next
]
24 button $w.bp
-text [mc Prev
] -command [cb find_prev
]
25 checkbutton $w.cs
-text [mc Case-Sensitive
] \
26 -variable ${__this
}::casesensitive -command [cb _incrsearch
]
28 pack $w.cs
-side right
29 pack $w.bp
-side right
30 pack $w.bn
-side right
31 pack $w.ent
-side left
-expand 1 -fill x
33 eval grid conf
$w -sticky we
$args
36 trace add
variable searchstring write
[cb _incrsearch_cb
]
38 bind $w <Destroy
> [list delete_this
$this]
43 if {![visible
$this]} {
50 if {[visible
$this]} {
57 return [winfo ismapped
$w]
64 method _get_new_anchor
{} {
65 # use start of selection if it is visible,
66 # or the bounds of the visible area
67 set top
[$ctext index
@0,0]
68 set bottom
[$ctext index
@0,[winfo height
$ctext]]
69 set sel
[$ctext tag ranges sel
]
71 set spos
[lindex $sel 0]
72 if {[lindex $spos 0] >= [lindex $top 0] &&
73 [lindex $spos 0] <= [lindex $bottom 0]} {
77 if {$searchdirn eq
"-forwards"} {
84 method _get_wrap_anchor
{dir
} {
85 if {$dir eq
"-forwards"} {
92 method _do_search
{start
{mlenvar
{}} {dir
{}} {endbound
{}}} {
93 set cmd
[list $ctext search
]
96 lappend cmd
-count mlen
98 if {!$casesensitive} {
104 lappend cmd
$dir -- $searchstring
105 if {$endbound ne
{}} {
106 set here
[eval $cmd [list $start] [list $endbound]]
108 set here
[eval $cmd [list $start]]
110 set here
[eval $cmd [_get_wrap_anchor
$this $dir]]
116 method _incrsearch_cb
{name ix op
} {
117 after idle
[cb _incrsearch
]
120 method _incrsearch
{} {
121 $ctext tag remove found
1.0 end
122 if {[catch {$ctext index anchor
}]} {
123 $ctext mark
set anchor
[_get_new_anchor
$this]
125 if {$searchstring ne
{}} {
126 set here
[_do_search
$this anchor mlen
]
129 $ctext tag remove sel
1.0 end
130 $ctext tag add sel
$here "$here + $mlen c"
131 $w.ent configure
-background lightgreen
134 $w.ent configure
-background lightpink
139 method find_prev
{} {
140 find_next
$this -backwards
143 method find_next
{{dir
-forwards}} {
147 $ctext mark
unset anchor
148 if {$searchstring ne
{}} {
149 set start
[_get_new_anchor
$this]
150 if {$dir eq
"-forwards"} {
151 set start
"$start + 1c"
153 set match
[_do_search
$this $start mlen
]
154 $ctext tag remove sel
1.0 end
157 $ctext tag add sel
$match "$match + $mlen c"
162 method _mark_range
{first last
} {
165 set match
[_do_search
$this $mend mlen
-forwards $last.end
]
166 if {$match eq
{}} break
167 set mend
"$match + $mlen c"
168 $ctext tag add found
$match $mend
172 method _set_marks
{doall
} {
173 set topline
[lindex [split [$ctext index
@0,0] .
] 0]
174 set botline
[lindex [split [$ctext index
@0,[winfo height
$ctext]] .
] 0]
175 if {$doall ||
$botline < $smarktop ||
$topline > $smarkbot} {
176 # no overlap with previous
177 _mark_range
$this $topline $botline
178 set smarktop
$topline
179 set smarkbot
$botline
181 if {$topline < $smarktop} {
182 _mark_range
$this $topline [expr {$smarktop-1}]
183 set smarktop
$topline
185 if {$botline > $smarkbot} {
186 _mark_range
$this [expr {$smarkbot+1}] $botline
187 set smarkbot
$botline
193 if {$searchstring ne
{}} {
194 after idle
[cb _set_marks
0]