by Dan Shafer
One of the most powerful tools in the PythonCard scripter's arsenal is also one of the easiest to overlook. Its innocuous name gives the impression that findfiles is a utility similar to what one would expect in a file finding utility at the operating system level. And while it does bear some strong resemblance to such programs, findfiles in PythonCard is much more than a simple file locator utility.
Very often when you are programming in any programming or scripting language, you want to find out how a particular function works or whether a particular property is settable, or any of a number of other questions. In many cases, you can find the answers to your questions by looking at the source code of the application or tool you're using. This is sometimes referred to as "code shopping," particularly when what you really hope to find is a method that does exactly what you want to do.
The PythonCard findfiles tool is designed to support you in these efforts.
Type in a string for which to search, tell findfiles the directories (yes, you can have more than one) in which to search for files containing that string, and send findfiles off to locate Python files with that specific content. Scroll through the list of files, each with a line reproducing part of the located line for each occurrence in the file, find the one you think is what you are looking for, and double-click the line. Voila! Either codeEditor or textEditor -- two other useful PythonCard utilities -- opens and scrolls instantly to the line you've selected.
This document describes how to use findfiles and provides some getting-started tips as well as some ideas you'll find useful as you come to rely more and more on this handy little application, as we have.
Getting Started with findfiles
To start using findfiles, first launch the application (it's in the PythonCard/tools/findfiles directory). You'll be greeted with a window that looks something like Figure 1, though its size will probably be different.
Figure 1. Opening Default Window in findfiles
In the File types field, type *.py;*.pyw. The semicolon is important; it separates multiple file types (and search directories) in the application.
Now click on the "Add Dirs" button and navigate to your PythonCard directory. Figure 2 shows approximately what your findfiles window should look like after you've done these steps.
Figure 2. Initial Setup for findfiles Window
(Since we've left the "Search subdirectories" checkbox checked, this search will look in all of the directories inside the PythonCard directory, including, of course, the samples directory. If you wanted a search that would focus only on the samples directory, you could create another search pointing only at that directory.)
Now go to the File menu and select "Save As..." and save the search configuration you've just created as PythonCard.grep". You'll want to be sure this file is in the same directory as the findfiles.py file you launched.
OK, now you can type in any search term you'd like findfiles to locate in any of the files stored in the PythonCard directory or any of its sub-directories. Let's start with a simple example. Let's say you want to see how a "choice" component is used in PythonCard samples. Type the word "choice" into the "Search for" field and click on "Search." After a very brief pause (findfiles is quite fast), you should be looking at a window something like Figure 3.
Figure 3. findfiles Window After Searching for "choice"
Notice that the result is an indented list. At the left margin is the complete path to the file in which the "hit" is located. Indented under that file name is a set of one or more rows showing the line number in that file where the targeted string was found, and displaying the line in question.
Select any of these lines. We chose line 82 in the first file above, "SourceForgeTracker.py" but you can choose any line in any file you like. When you either click on the "Open Selected File" button or double-click on the line, the PythonCard codeEditor launches if it isn't running, opens the target file, and scrolls to the line number in question, as you can see in Figure 4.
Figure 4. PythonCard codeEditor Open to Selected Line
If you point findfiles at text files rather than Python or PythonCard code files, then double-clicking the line in the results list or selecting a line and clicking on the "Open Selected File" button will launch the PythonCard textEditor rather than codeEditor. Otherwise, the behavior is identical.
Essentially, this is all there is to using findfiles. You point it at one or more directories, tell it what types of files to search for, give it a string to look for in those files, and let it go off and find those files for you. When you identify a file and line that are promising prospects for telling you what you want to know, double-click on the line in findfiles or select the line and click on "Open Selected File" and codeEditor opens on that file, scrolling to the found line.
We have three remaining topics of potential interest to discuss: special character in search strings, saving and using GREP files and using more sophisticated search strings.
Special Character Usage in findfiles
As you've no doubt surmised by now, findfiles uses classic Unix grep (regular expression) searches. If you know grep, that's probably all we need to say here. If, however, you have no clue why you should care about grep, read on.
The grep utility uses a technique called regular expression matching to locate information. In regular expressions, some characters have a special meaning. If you want to search for any of these special characters in the strings you supply in findfiles, you'll have to escape them by preceding them with a backward slash (\) character.
While there are many such characters in regular expressions, the ones with which you will need to be most careful are: question mark (?), asterisk (*), addition/concatenation operator (+), pipe or vertical bar (|), caret (^) and dollar sign ($). To search for a dollar sign in the target directories, for example, put "\$" into the search field. (Putting in a $ by itself will crash findfiles fairly reliably.)
Saving and Using grep Files
As you saw earlier when we walked through how to set up findfiles the first time you use it, you can define search parameters and then save them in a file which you can later load to re-run the same search. These files end with the suffix ".grep" and are saved in the same directory as the findfiles.py file.
We have set up several commonly used search patterns that include various combinations of directories to search and terms for which to search. For example, we quite often want to find stuff in the wxPython files since PythonCard relies heavily on wxPython for its GUI components. So we have defined one file that has nothing in the search field but has a pointer to the wxPython directory in the directories list. Another common use for this capability is to create a directory entry that points to your own source code files for your project(s).
A slightly more complex example is shown in Figure 5. There, I've defined a search that looks only in the directory where I keep my personal projects, and the search term "def." This enables me to obtain quickly a list of all the functions I've defined in my projects.
Figure 5. Sample findfiles Search Through Personal Projects for Methods
I save this file as "myproject_methods.grep" and load it whenever I need to repeat the search. Using pre-stored search patterns like this, combined with the fast execution of the find process itself, makes using findfiles a very powerful addition to your PythonCard development tool arsenal.
$Revision: 1.5 $ : $Author: kasplat $ : Last updated $Date: 2004/07/26 15:35:31 $