{jfindpanel.tcl
Introduction
The jfindpanel.tcl library is distributed as part of the jstools package.  It consists of procedures to implement a search­and­replace dialogue box for text widgets.  The central procedure is ::jstools::find, which creates the dialogue box and calls the other procedures as necessary.

Currently, these procedures all communicate via global variables with the contents of the ::jstools::find fields and checkboxes.  I hope to change this in the future so that they will take arguments, to make them more useful independently of each other.  This means that you shouldn't count on the calling conventions for these procedures staying constant, except for ::jstools::find itself.

These procedures use the native find method of the Tk Text widget, which does searches line­by­line.  Therefore, search patterns can't cross lines.  I consider this a bug in the find panel, and I hope to work around it in the future.

This document describes jfindpanel.tcl version 2001.02.10.
Usage
Accessing the Library
In order to use the jfindpanel.tcl library, it (and any other libraries it depends on) must be in your Tcl auto_path, described in tclvars(n).  Information about how to arrange that, and other conventions common to the jstools libraries, is in the Usage section of The jstools Libraries.
Credits and Copyright
Author
Jay Sekora 
js@aq.org
http://www.aq.org/~js/
Copyright
The library is copyright © 1992-2001 by Jay Sekora, but may be freely redistributed under the conditions at the top of the file.
Overview
Procedures
::jstools::find - search­and­replace panel
::jstools::find_again - search again for same string
::jstools::find_pattern - find and select string in text widget
::jstools::find_replace - replace selection in text widget with string
::jstools::find_replace_regexp - replace regular expression in text with string
::jstools::find_replace_all - change all occurences of string in text widget
::jstools::find
Usage
	::jstools::find [options] w
Argument
	w is the text widget to search in
Option
	-replace bool  (default 1)
	-findhistory findhist  (default j_find)
	-replacehistory replhist  (default j_repl)
Description
This procedure brings up a find panel that allows the user to search for text (and, optionally, replace it) in a text widget, w.  By default, i.e. if bool is not false, the panel has two entry widgets labelled `Search for:' and `Replace with:', four checkbuttons labelled `Backwards', `Case­sensitive', `Regex', and `EOL', and four buttons labelled `Search', `Replace', `Replace All', and `Cancel'.  (The default button is `Search'.)

Complete usage documentation for the Find Panel itself (as opposed to the library) is available in The jstools Find Panel.

Unless -replace 0 has been specified, the user will be able to replace the found string by typing a replacement in the `Replace with:' field and clicking on the `Replace' or `Replace All' button.  You will want to specify -replace 0 when using the find panel with read­only (-state disabled) text widgets.  If you don't do this, the user will be able to hang your application by trying to replace text in a disabled widget.  (This should probably be considered a bug.)

If findhist or replhist is specified, they are used as the names of the history lists for the find and replace entries, respectively.  (History lists are implemented by jhistory.tcl.)  The defaults should be fine unless your users are editing special­purpose text.  (For instance, it might make sense to use different history lists for editing program code and email.)  However, I recommend leaving the defaults when your users are editing general­purpose natural­language text.  You can eliminate either history list (and the corresponding buttons) by specifying it as `{}'.

Note that although the find panel is non­modal, an application can only have one find panel displayed at a time.
::jstools::find_again
Usage
	::jstools::find_again w
Argument
	w is the text widget to search in
Description
This procedure is used to search for the next occurrence of a string previously entered into a find panel.  It has the same effect as clicking on the `Search' button in the find panel, but it doesn't require the find panel to be displayed.  It's convenient as a keyboard shortcut.

If no value has been entered into a find panel when this procedure is invoked, it will simply call ::jstools::find to display a find panel.
::jstools::find_pattern
::jstools::find_replace
::jstools::find_replace_all
These procedures are used by the Find Panel.  Their communication conventions are not very mature at this point, so you shouldn't rely on them yet.  They (or something like them) will become public procedures in a future version of the library.
Bugs and Limitations
· Under Tk4.0 and later, a search string can't contain a newline.  (Well, it can, but that guarantees that it won't be found, since the text widget does searches line­by­line.)
· The replacement string is always inserted literally; there should be a way to refer to submatches in a regular­expression search.
Future Directions
· The procedures that actually do the searches should be public, and they should take options rather than looking at global variables to decide what kind of search to perform
· You should be able to use more than one Find Panel in an application.
· You should be able to provide a window name for the find panel.  If the window doesn't exist, it should be created as a new toplevel; if it does exist, the new find panel should be packed into it (and the `Cancel' button shouldn't be displayed).  That would let people create find panels attached to text windows, which might be more intuitive for multi­window documents.
} {{{list:level:1 {61.0 63.0 64.0 67.0}} {jhtml:anchor:anchorname {28.0 29.0 47.0 48.0 56.0 59.0}} {jdoc:anchor:anchorname {2.0 3.0 10.0 11.0 13.0 14.0 20.0 21.0 28.0 29.0 47.0 48.0 56.0 59.0}} {jdoc:xref:link {3.57 3.64 3.192 3.207 5.90 5.105 5.368 5.383 12.215 12.236 12.244 12.261 12.265 12.286 22.0 22.15 23.0 23.21 24.0 24.23 25.0 25.23 26.0 26.30 27.0 27.27 40.99 40.121 44.169 44.181 55.99 55.114}} {jdoc:xref:manpage {12.131 12.138}} {richtext:font:roman {3.0 3.4 3.18 3.57 3.64 3.192 3.207 5.90 5.105 5.368 5.383 7.32 7.36 9.24 9.38 10.0 12.0 12.20 12.34 12.107 12.116 12.131 12.138 12.219 12.226 12.248 12.253 12.265 12.286 13.0 15.0 16.0 16.9 17.0 17.22 18.0 19.0 20.0 22.15 23.0 23.21 24.0 24.23 25.0 25.23 26.0 26.30 27.0 27.27 28.0 30.17 30.18 30.25 30.26 30.28 31.0 32.0 32.1 32.2 33.0 34.16 34.25 34.26 35.1 35.24 35.33 35.39 35.40 36.27 36.36 36.42 37.0 38.0 38.126 38.127 38.150 38.154 38.423 38.424 38.430 38.431 40.99 40.121 42.7 42.17 42.222 42.232 42.275 42.290 44.3 44.11 44.15 44.23 44.169 44.181 44.571 44.573 47.0 49.24 50.0 51.0 51.1 51.2 52.0 53.0 55.99 55.114 56.0 56.23 57.0 57.23 58.0 58.27 60.0 61.0 63.0 64.0 67.0}} {richtext:font:italic {30.18 30.25 30.27 30.28 32.1 32.2 34.10 34.14 35.14 35.22 36.17 36.25 38.126 38.127 38.150 38.154 38.423 38.424 38.430 38.431 44.3 44.11 44.15 44.23 49.23 49.24 51.1 51.2}} {richtext:font:bold {3.4 3.18 3.57 3.64 9.24 9.38 12.20 12.34 12.219 12.226 44.169 44.181}} {richtext:font:bolditalic {12.248 12.253 12.265 12.286 40.99 40.121}} {richtext:font:typewriter {3.192 3.207 5.90 5.105 5.368 5.383 7.32 7.36 12.107 12.116 12.131 12.138 16.0 16.9 17.0 17.22 22.0 22.15 23.0 23.21 24.0 24.23 25.0 25.23 26.0 26.30 27.0 27.27 30.0 30.17 30.26 30.27 34.0 34.10 34.14 34.16 34.25 34.26 35.1 35.14 35.22 35.24 35.33 35.39 36.1 36.17 36.25 36.27 36.36 36.42 42.7 42.17 42.222 42.232 42.275 42.290 44.571 44.573 49.0 49.23 55.99 55.114}} {richtext:font:heading0 {1.0 2.0}} {richtext:font:heading1 {2.0 3.0 10.0 11.0 13.0 14.0 20.0 21.0 28.0 29.0 47.0 48.0 56.0 56.23 57.0 57.23 58.0 58.27 60.0 61.0 63.0 64.0}} {richtext:font:heading2 {11.0 12.0 14.0 15.0 18.0 19.0 21.0 22.0 29.0 30.0 31.0 32.0 33.0 34.0 37.0 38.0 48.0 49.0 50.0 51.0 52.0 53.0}} {richtext:font:l_em {35.40 36.1}} {{} {13.0 19.0 21.0 21.10}} {jdoc:link:jstools.jdoc {3.57 3.64}} {jdoc:manpage:tclvars {12.131 12.138}} {jdoc:link:jslibraries.jdoc#Usage {12.244 12.261}} {jdoc:link:jslibraries.jdoc {12.265 12.286}} {jdoc:anchorname:Credits_and_Copyright {13.0 14.0}} {jdoc:anchorname:Introduction {2.0 3.0}} {jdoc:anchorname:Usage {10.0 11.0}} {jdoc:link:jslibraries.tcl {12.215 12.236}} {jdoc:anchorname:Overview {20.0 21.0}} {jdoc:link:jhistory.tcl.jdoc {44.169 44.181}} {list:1:ul {61.0 63.0 64.0 67.0}} {jdoc:anchorname:j:find {28.0 29.0}} {jdoc:anchorname:j:find:again {47.0 48.0}} {jdoc:anchorname:j:find:find_pattern {56.0 57.0}} {jdoc:anchorname:j:find:replace {57.0 58.0}} {jdoc:anchorname:j:find:replace_all {58.0 59.0}} {jdoc:link:#::jstools::find {3.192 3.207 5.90 5.105 5.368 5.383 22.0 22.15 55.99 55.114}} {jdoc:link:#::jstools::find_again {23.0 23.21}} {jdoc:link:#::jstools::find_pattern {24.0 24.23}} {jdoc:link:#::jstools::find_replace {25.0 25.23}} {jdoc:link:#::jstools::find_replace_regexp {26.0 26.30}} {jdoc:link:#::jstools::find_replace_all {27.0 27.27}} {jhtml:anchorname:::jstools::find {28.0 29.0}} {jhtml:anchorname:::jstools::find_again {47.0 48.0}} {jhtml:anchorname:::jstools::find_pattern {56.0 57.0}} {jhtml:anchorname:::jstools::find_replace {57.0 58.0}} {jhtml:anchorname:::jstools::find_replace_all {58.0 59.0}} {jdoc:link:findpanel.html {40.99 40.121}} {special:list_item:1 {61.0 61.1 62.0 62.1 64.0 64.1 65.0 65.1 66.0 66.1}}} {{convert:place:12.131 12.131} {del_from 67.0} {convert:place:62.0 62.0} {convert:place:42.290 42.290} {convert:place:36.17 36.17} {convert:place:62.1 62.1} {convert:place:27.27 27.27} {convert:place:28.0 28.0} {convert:place:12.0 12.0} {convert:place:12.215 12.215} {convert:place:12.286 12.286} {convert:place:66.0 66.0} {convert:place:42.222 42.222} {convert:place:38.423 38.423} {richptr 58.16} {convert:place:7.32 7.32} {convert:place:66.1 66.1} {convert:place:49.0 49.0} {convert:place:50.0 50.0} {convert:place:38.424 38.424} {convert:place:33.0 33.0} {convert:place:5.90 5.90} {convert:place:12.138 12.138} {convert:place:12.219 12.219} {convert:place:16.0 16.0} {convert:place:36.25 36.25} {convert:place:34.10 34.10} {convert:place:56.23 56.23} {convert:place:7.36 7.36} {convert:place:38.430 38.430} {convert:place:37.0 37.0} {convert:place:36.27 36.27} {current 61.130} {convert:place:21.0 21.0} {convert:place:38.431 38.431} {convert:place:5.383 5.383} {convert:place:34.14 34.14} {convert:place:25.23 25.23} {matchend 67.0} {convert:place:58.0 58.0} {convert:place:42.232 42.232} {convert:place:12.226 12.226} {convert:place:34.16 34.16} {convert:place:25.0 25.0} {convert:place:16.9 16.9} {convert:place:63.0 63.0} {convert:place:36.36 36.36} {convert:place:30.0 30.0} {convert:place:29.0 29.0} {convert:place:13.0 13.0} {convert:place:3.18 3.18} {convert:place:38.126 38.126} {convert:place:67.0 67.0} {convert:place:38.127 38.127} {convert:place:42.7 42.7} {convert:place:34.25 34.25} {convert:place:40.99 40.99} {convert:place:51.0 51.0} {convert:place:12.236 12.236} {convert:place:34.26 34.26} {convert:place:36.42 36.42} {convert:place:51.1 51.1} {convert:place:34.0 34.0} {convert:place:17.0 17.0} {convert:place:23.21 23.21} {convert:place:51.2 51.2} {convert:place:1.0 1.0} {convert:place:38.0 38.0} {convert:place:17.22 17.22} {convert:place:22.0 22.0} {convert:place:12.20 12.20} {convert:place:12.244 12.244} {convert:place:60.0 60.0} {convert:place:26.0 26.0} {convert:place:44.169 44.169} {convert:place:12.248 12.248} {convert:place:10.0 10.0} {convert:place:57.23 57.23} {convert:place:64.0 64.0} {convert:place:5.105 5.105} {anchor 19.36} {convert:place:47.0 47.0} {convert:place:64.1 64.1} {convert:place:31.0 31.0} {convert:place:12.253 12.253} {convert:place:44.571 44.571} {convert:place:35.14 35.14} {convert:place:14.0 14.0} {insert 19.36} {convert:place:68.0 68.0} {del_to 67.0} {convert:place:44.573 44.573} {convert:place:52.0 52.0} {convert:place:18.0 18.0} {convert:place:35.1 35.1} {convert:place:38.150 38.150} {convert:place:12.34 12.34} {convert:place:44.11 44.11} {convert:place:44.181 44.181} {convert:place:2.0 2.0} {convert:place:12.107 12.107} {convert:place:26.30 26.30} {convert:place:30.17 30.17} {convert:place:56.0 56.0} {convert:place:30.18 30.18} {convert:place:35.22 35.22} {convert:place:12.261 12.261} {convert:place:23.0 23.0} {convert:place:38.154 38.154} {convert:place:35.24 35.24} {convert:place:44.15 44.15} {convert:place:9.24 9.24} {convert:place:3.192 3.192} {convert:place:61.0 61.0} {convert:place:12.265 12.265} {abbrevstart 38.317} {convert:place:40.121 40.121} {convert:place:61.1 61.1} {convert:place:27.0 27.0} {convert:place:30.25 30.25} {convert:place:49.23 49.23} {convert:place:11.0 11.0} {convert:place:12.116 12.116} {emacs_mark 67.0} {matchstart 67.0} {convert:place:24.23 24.23} {convert:place:30.26 30.26} {convert:place:44.3 44.3} {convert:place:49.24 49.24} {convert:place:65.0 65.0} {convert:place:3.207 3.207} {convert:place:42.275 42.275} {convert:place:55.99 55.99} {convert:place:30.27 30.27} {convert:place:48.0 48.0} {convert:place:65.1 65.1} {convert:place:30.28 30.28} {convert:place:32.0 32.0} {convert:place:44.23 44.23} {convert:place:15.0 15.0} {convert:place:32.1 32.1} {convert:place:35.33 35.33} {convert:place:3.57 3.57} {convert:place:32.2 32.2} {convert:place:53.0 53.0} {convert:place:55.114 55.114} {abbrevend 38.322} {convert:place:19.0 19.0} {convert:place:20.0 20.0} {convert:place:22.15 22.15} {convert:place:36.1 36.1} {convert:place:3.0 3.0} {convert:place:9.38 9.38} {convert:place:35.39 35.39} {convert:place:35.40 35.40} {convert:place:57.0 57.0} {convert:place:3.64 3.64} {convert:place:5.368 5.368} {convert:place:24.0 24.0} {convert:place:42.17 42.17} {convert:place:58.27 58.27} {convert:place:3.4 3.4}}} {{body_alink #ff0000} {body_vlink #000080} {body_link #0000ff} {body_text #000000} {body_bgcolor #ffffff}}