Searching in a text widget

Richard Suchenwirth 2006-11-28 - Here is example code for searching substrings in a text widget. When an instance is found, it is highlighted with the given tag. At end of the text content, the search wraps around. A global variable reports the position of a found substring.

 proc find {w what tag _status} {
    upvar #0 $_status status
    foreach {from to} [$w tag ranges $tag] {
        $w tag remove $tag $from $to
    }
    set pos [$w search -count n -- $what insert+2c]
    if {$pos eq ""} {
        set status "not found: $what"
    } else {
        set status "found at $pos: $what"
        $w mark set insert $pos
        $w see $pos
        $w tag add $tag $pos $pos+${n}c
    }
 }

JOB - 2018-03-05

The following procedure searches for all instances of a given search string all in one go. Note: the function was copied over from the tk widget demo and slightly adopted to have the same interface as the above function.

proc findall {w what tag _status} {
        upvar #0 $_status status

        $w tag remove $tag 0.0 end

        if {$what == ""} {
                set status ""
                return
        }
        set cnt 0
        set cur 0.0
        while 1 {
                set cur [$w search -count length -- $what $cur end]
                if {$cur == ""} {
                        break
                }
                $w tag add $tag $cur "$cur + $length char"
                set cur [$w index "$cur + $length char"]
                incr cnt
        }
        
        if {$cnt == 0} {
                set status "no search result for: $what"
        } else {
                set status "search result: $cnt item(s) selected"
        }
}

Demo with an entry for the search term, a text, and a label for the status string:

package require Tk

pack [entry .e -textvariable Find] -fill x
bind .e <Return> {find .t $Find hilite state}

pack [text .t -wrap word] -fill both -expand true
.t tag configure hilite -background orange

pack [label .l -textvariable state] -anchor w


# fill text widget with some content

set fp [open [info script] "r"]
.t insert 0.0 [read $fp]
close $fp

# run the search..

set Find "proc"
findall .t $Find hilite state


WJG(05/03/18) The Gnocl text widget has search command. e.g.

gnocl::window -child [gnocl::text -name TEXT -wrapMode word]

TEXT verse ;# insert some default text
TEXT tag create found -background yellow

set ranges [TEXT search remember -tags found]

Apart from the words being tagged in the buffer, the command returns a list of the ranges occupied by the search string.


See also Simple search and replace

See also Incremental GUI text search