ulis, 2004-01-20. FindWords is an editor utility that let you jump to another occurrence of the selected string. Designed for Textpad it can be used (modified) for other editors.
Modified 2004-01-25: Added quotes around the $Sel arg to deal with strings containing spaces.
Modified 2004-01-26: Added keyboard support.
A snapshot
The script
######################### # # FindWords: jump to a string (Textpad utility) # # (C) 2004, ulis; NOL # # ----------------------- # input: source file, selected string # output: exec of a script ######################### if 0 \ { # Abstract This script let you see a listbox with all the occurrences of the selected string, select one of them and have the text cursor positionned in front of the selected one. # Install For Textpad: - Optional: copy the DDEOPN32.EXE utility from the Textpad system directory to the Windows sytem32 or system directory - Put FindWords.tcl & FindWords.cfg in the TextPad system directory (or elsewhere) - With the /Configure/Preferences menu add a new tool with: - Commands = <the path of wish> - Parameters = <the path of this file> $File "$Sel" - Initial folder = $FileDir - Rename this tool: FindWords - Modify FindWords.cfg exec = <script to execute to go to the word> (where you can have to set the DDEOPN32.EXE path) inside this script: %FileName% will be replaced by the Tcl source file name %Line% will be replaced by the line where is the string. %Char% will be replaced by the number of the char where start the string. options = <space separated list of key/value pairs> -over <boolean> 0 : don't search for overlapping strings 1 : search for overlapping strings -thick <integer> thickness of the closeness (in chars) @exec, @options : Tcl script returning a value for exec or options - Optional: add a key accelerator with /Configure/Preferences/Keyboard/Categories/Utilities # Use From the Tcl/Tk text window select the /Tools/FindWords menu Click the right line inside the listbox } # ------------------ # GetWords # # ------------------ # returns a list of lines description # in the form of {line-# char-# closeness} # ------------------ proc GetWords {} \ { variable {} # get string set string $(string) # open Tcl source file set fn $(fn) if {![catch { open $fn } res]} { set fp $res } \ else { tk_messageBox -message $res; exit } # loop thru lines set l 1 if {$(-over)} { set l [string len $string] } set strs {} set lines {} set ln 0 while {![eof $fp]} \ { # get a line set line [string trimleft [gets $fp]] lappend lines $line # search for the string inside the line set cn 0 while {$cn > -1} \ { set cn [string first $string $line $cn] if {$cn > -1} \ { lappend strs [list $ln $cn]; incr cn $l } } # update current line number incr ln } close $fp set (strs) $strs set (lines) $lines } # ------------------ # GotoWord # # ------------------ # exec's the (script) to go to the string # ------------------ proc GotoWord {} \ { variable {} set index [.lb curselection] if {$index == ""} { return } foreach {ln cn} [lindex $(strs) $index] break set fn [string map {\\ /} $(fn)] set script [string map [list %FileName% $fn %Line% [incr ln] %Char% [incr cn]] $(exec)] catch { eval $script } msg if {$msg != ""} { tk_messageBox -message $msg } exit } # ------------------ # SetParms # # ------------------ # sets the (keys) & (script) parameters # ------------------ proc SetParms {} \ { variable {} set (exec) "exec DDEOPN32.EXE Textpad \"%FileName%(%Line%,%Char%)\"" set (opts) {-font {Courier 9} -over 0 -thick 10} set fn [file join [file dirname [info script]] FindWords.cfg] if {![catch { open $fn } res]} { set fp $res } \ else { tk_messageBox -message $res; exit } while {![eof $fp]} \ { set line [string trimleft [gets $fp]] switch -glob -- $line \ { "" - \;* - \[* - #* { set key "" } exe* { set key exec } opt* { set key opts } @exe* { set key @exec } @opt* { set key @opts } default \ { tk_messageBox -message "unknown key \"$line\" in config file"; exit } } if {$key == ""} { continue } set n [string first = $line] if {$n == -1} \ { tk_messageBox -message "wrong line \"$line\" in config file"; exit } set value [string trim [string range $line $n end] " ="] set ($key) $value if {[string match @* $key]} \ { set key [string range $key 1 end] set ($key) [$value] } } close $fp # get options foreach {option value} $(opts) \ { switch -glob -- $option \ { -f* { set key -font } -o* { set key -over } -t* { set key -thick } default \ { tk_messageBox -message "unknown option \"$option\" in config file"; exit } } set ($key) $value } } # ------------------ # ChooseWord # # ------------------ # presents the listbox with all strings occurrence # ------------------ proc ChooseWord {} \ { variable {} wm withdraw . set (fn) [lindex $::argv 0] set (string) [lindex $::argv 1] if {$(string) == ""} \ { tk_messageBox -message "word is empty"; exit } SetParms GetWords if {[llength $(strs)] == 0} \ { tk_messageBox -message "no word found"; exit } wm deiconify . wm title . "FindWord \"$(string)\"" listbox .lb -font $(-font) -yscrollc {.vs set} -activestyle none scrollbar .vs -command {.lb yview} grid .lb -row 0 -column 0 -sticky nsew grid .vs -row 0 -column 1 -sticky ns grid rowconfigure . 0 -weight 1 grid columnconfigure . 0 -weight 1 bind .lb <ButtonRelease-1> GotoWord bind .lb <KeyPress-Return> GotoWord set height 0 set width 0 set t $(-thick) set l [string length $(string)] set l [expr {$l + $t - 1}] foreach item $(strs) \ { foreach {ln cn} $item break set line [lindex $(lines) $ln] set n1 $cn; incr n1 -$t set n2 $cn; incr n2 $l set string [string range $line $n1 $n2] set item "$ln,$cn: $string" .lb insert end $item incr height set length [string length $item] if {$width < $length} { set width $length } } if {$height > 40} { set height 40 } if {$height < 10} { set height 10 } if {$width > 80} { set width 80 } if {$width < 20} { set width 20 } .lb config -width $width -height $height .lb selection set 0 focus -force .lb focus -force . raise . } # ======== # # let's go # # ======== package require Tk ChooseWord
The config file
# --------------------- # FindWords config file # --------------------- exec = exec DDEOPN32.EXE Textpad "%FileName%(%Line%,%Char%)" options = -font {Courier 9} -over 0 -thick 15
Peter Lewerin your introduction seems to imply that it's OK to modify and reuse this code. Maybe it would be a good idea to make an explicit statement to that effect next to the (c) notice (this being a Wiki, I could add such a statement, but somehow it doesn't seem right :-) ).
ulis In short: yes you can. See Who owns the content on this Wiki. The used licence, NOL, means: No Obligation Licence. For you, as for me.
(PL) : I know I can, but in many cases we shouldn't make modifications. For instance, editing the terms of use of someone else's source code qualifies as evil for me. Thanks for the clarification, I wasn't familiar with the acronym, NOL.
ulis Sorry for the misuse of the verb: I don't speak english and have to survive with that. Feel free to correct the offending word. And yes the ability(?) given to everybody to change the content of the Wiki has some moral limits (we are between gentlemen ;^)).