This is the commented version of RS's Simple Search and replace.
proc searchrep {t {replace 1}} {
# The procedure is called searchrep. A value should be returned in the # end?
set w .sr
#
if ![winfo exists $w] {
#
toplevel $w wm title $w "Search"
# The title Search should appear ...
grid [label $w.1 -text Find:] [entry $w.f -textvar Find] \ [button $w.bn -text Next \ -command [list searchrep'next $t]] -sticky ew bind $w.f <Return> [list $w.bn invoke] if $replace { grid [label $w.2 -text Replace:] [entry $w.r -textvar Replace] \ [button $w.br -text Replace \ -command [list searchrep'rep1 $t]] -sticky ew bind $w.r <Return> [list $w.br invoke] grid x x [button $w.ba -text "Replace all" \ -command [list searchrep'all $t]] -sticky ew } grid x [checkbutton $w.i -text "Ignore case" -variable IgnoreCase] \ [button $w.c -text Cancel -command "destroy $w"] -sticky ew grid $w.i -sticky w grid columnconfigure $w 1 -weight 1 $t tag config hilite -background yellow } else {raise $w} }
#-- Find the next instance
proc searchrep'next w { foreach {from to} [$w tag ranges hilite] { $w tag remove hilite $from $to } set cmd [list $w search -count n -- $::Find insert+2c] if $::IgnoreCase {set cmd [linsert $cmd 2 -nocase]} set pos [eval $cmd] if {$pos ne ""} { $w mark set insert $pos $w see insert $w tag add hilite $pos $pos+${n}c } }
#-- Replace the current instance, and find the next
proc searchrep'rep1 w { if {[$w tag ranges hilite] ne ""} { $w delete insert insert+[string length $::Find]c $w insert insert $::Replace searchrep'next $w return 1 } else {return 0} }
#-- Replace all
proc searchrep'all w { set go 1 while {$go} {set go [searchrep'rep1 $w]} }
#---------------- Test and demo:
package require Tk pack [text .t] .t insert end "hello world, this is some text to test on" searchrep .t
Here's how to plug this functionality into e: a tiny editor plugin for eTcl:
m+ $m Edit Search {searchrep .t.t 0} m+ $m Edit Replace {searchrep .t.t}
For better looks, I changed the -sticky settings to "news" there (buttons come very low else). A deeper problem is that the dialog comes up at top left, and possibly covers the "hilited" search term. Other than reparenting it into a non-toplevel (like Pocket Word does), I have no good solution for that...
The solution is simple: don't use a dialog. Personally I like how Firefox does it, as a popup toolbar of sorts at the bottom of the window.
2006-03-18 HE Perfectly! I need an search dialog and the wiki has it just in time :-)
See also Searching in a text widget, Simple Search and Replace commented
Category Example | Arts and crafts of Tcl-Tk programming | Category Widget