Using Tcl to search a Text Widget in Gnocl versions 0.9.92 and earlier

WJG (03-03-09) In response to the question of how to perform a text search in these widgets the following code example shows how it can be done.

 # GnoclText-Search.tcl
 #!/bin/sh
 # the next line restarts using tclsh \
 exec tclsh "$0" "[email protected]"
 package require Gnocl

 # w (w)idget to search
 # s (s)tring to search for
 # h (h)ight all occuracnces (Boolean: default = 1)
 # e (e)xact match (Boolean: default = 1)
 # c (c)ase sensitive (Boolean: default = 0)
 # returns list of all occurances
 #
 proc gnocl::textFind { w s {h 1} {e 1} {c 0} {command {} } } {
   # create tag if not available already
   $w tag create _find_ -foreground red -onEvent {puts "HI %t %x %y"}

   # foreach line of the text buffer
   for {set i 0 }  {$i < [$w getLineCount ] }  {incr i} {
     # get the contexts
     set j [expr $i+1]
     set tmp [$w get "$i 0" "$j 0"]
     # make modifications for exact/partial match
     if {$e } {
       puts "not exact match"
       } else {
       puts "partial match"
      }
     # make modifications for case sensitivity
     if {$c } {
       puts "not case senstive"
       } else {
       puts "case sensitive"
       set s [string tolower $s]
       set tmp [string tolower $tmp]
       }
     # apply tag to each item,
     # maybe add bindings to the tag?
     set lst [gnocl::stringSearch $s $tmp]
     foreach col $lst {
      set colb [expr $col + [string length $s] ]
      $w tag apply "$i $col" "$i $colb" -tags _find_
      }
    }
   return $lst
 }

 # w (w)ord to search for
 # s (s)tring to search within
 # returns list of all occurances
 #
 proc gnocl::stringSearch {w s} {
   set list ""
   set i [string first $w $s 0]
   set j [string length $w]

    while { $i != -1  } {
     lappend list $i
     incr i $j
     set i [string first $w $s $i]
     }
   return $list
 }

 # insert the current entry value to the top of the list
 proc listUpdate {w} {
   # get existing values
   set items [$w cget -items]

   # get current value
   set value [$w cget -value]

   # is the current item in the list? if not, add it.
   if { [lsearch $items  $value] == -1} {
   # add to the front of the list
   set items [linsert $items 0 $value  ]
   #  update
   $w configure -items $items
   }
 }

  # The Ubiquitous Demo!
  if {1} {
    set text [gnocl::text -baseColor #F5F6BE -baseFont {Sans 15}]
    set win [gnocl::window -title "Text" -child $text -width 600 -height 480 -visible 0]
    $win configure -visible 1
    $win configure -title DEMONSTRATION
    $text tag create bold -fontWeight bold -foreground blue

   $text insert end "Apple Banana Cherry\n"

   for {set i 0 } {$i < 10} {incr i} {
    $text insert end "ABCD EFGH IJKL MNOP QRST UVWX YZ\n"
    $text insert end "123Hello\n" -tags bold
    $text insert end "ABCD EFGH IJKL MNOP QRST UVWX YZ\n"
    $text insert end "01234567Hello\n" -tags bold
    $text insert end "ABCD Hello IJKL Hello QRST Hello YZ\n"
   }

  $text setCursor "0 5"
   foreach i {4 5 6} {
    set len [$text getLineLength "$i 0"]
    puts "Line length of line $i = $len"
    }

  gnocl::textFind $text ABC
  gnocl::mainLoop
 }

The planned 0.9.93 release of Gnocl takes advantage of the Gtk library functions to handle text searching and word replacement.