diff --git a/twander.1 b/twander.1 index bbb6861..b09ae72 100644 --- a/twander.1 +++ b/twander.1 @@ -6,12 +6,12 @@ selected files and directories. If you're new to \'twander\' and want to know why this program is better and different than whatever you're using at the moment, take a moment to read the section called -.B "DESIGN PHILOSOPHY" +.B DESIGN PHILOSOPHY toward the end of this document first. Similarly, if this is the first time you've worked with \'twander\', there is a section towards the end of this document entitled -.B "INSTALLING \'twander\'" +.B INSTALLING \'twander\' which describes how the program should be installed. .SH SYNOPSIS @@ -521,7 +521,6 @@ Here are several other subtleties regarding User-Defined Variables: -.PD 000 .IP \(bu 4 The Variable Name is case-sensitive - [EDITOR], [Editor], and [editor] all refer to different variables. @@ -547,7 +546,7 @@ Definition containing a string in the form [$something] is understood by \'twander\' to be a reference to an .B Environment Variable, -in this case, "$something". If you do something like: +named "$something". If you do something like: .nf $MYVAR = some-string @@ -566,9 +565,98 @@ which matches either one of the Builtin Variables (used in Command Definitions) or one of the Program Function Names (used for key bindings). -.PD -.P +.IP \(bu 4 +User-Defined Variables are replaced with simple string substitution +logic. Say you have: + +.n +VAR = something or other ... +.fi + +Anytime \'twander\' finds a reference later to [VAR] it replaces +it with everthing from "something..." to the end of the line including +spaces within the string. Only the leading and trailing spaces of +the right side of the variable are dropped. + +.IP \(bu 4 +User-Defined Variables may be +.B nested +up to 32 levels deep. You can have constructs like: + +.nf +Var1 = Foo +Var2 = Bar +FB = [Var1][Var2] +.fi + +Just make sure the variable +.B definitions +precede variable +.B references. +Later on (when defining some command) when \'twander\' runs into the +variable reference [FB], it will keep substituting variables until all +[...] references have been resolved or it hits the nesting limit (32). +This limit has to be imposed to catch silly things like this: + +.nf +Var = a[Var] +.fi + +This recursive definition is a no-no and will be cause \'twander\' +to generate an error while parsing the configuration file and then +terminate. + +Your variable definitions can also nest other kinds of variables +(Environment and Builtins). So, constructs like this are perfectly +OK: + +.nf +Var1 = [$PAGER] +Var2 = command-arguments +V = [Var1] [Var2] [DSELECTIONS] +.fi + +Notice that since the right-hand side of User-Defined Variables +is literally replaced later, we have to make sure there is +space between the various variable references. If we +used "[Var1][Var2][DSELECTIONS]" we would get one long string +back instead of a command with arguments and a list of selected +items. + +.IP \(bu 4 +While it is true that variables must be defined before they +are referenced, \'twander\' only checks this when a reference +to a variable actually appears - i.e., inside of some command +definition. Bear in mind that User-Defined Variables are simply +string replacement instructions and do not actually cause a +nested variable to be referenced. This creates an interesting +situtation. You edit your configuration file and add this: + +.nf +foo = [BAD-VBL] +bar = x[foo] +.fi + + +\'twander\' will run fine! Why? Because we are merely declaring +sting substitutions, we are not actually dereferencing any variables +that appear on the right-hand side of a definition. + +Say we add this to configuration file: + +.nf +c mycommand blah blah blah [bar] +.fi + + +Now we +.B do +get an error. Why? Because a [...] variable reference in a Command +Definition is always dereferenced, and in our example, the fact that +BAD-VBL is not defined anywhere is detected. + +.P .SS Key Binding Statements Key Binding Statements look just like Variable Definitions. The @@ -578,6 +666,230 @@ .SS Command Definitions +The heart of the \'twander\' configuration process is creating +of one or more "Command Definitions". These definitions are the +way user-defined commands are added to a given instance of \'twander\'. +A Command Definition consists of three fields separated by +whitespace: + +.nf +Command-Key Command-Name Command-String +.fi + +The "Command Key" +.B is any single character +which can be typed on the keyboard (except the "#" character). This is +the key that will be used to invoke the command from the keyboard. Command +Keys are case-sensitive. If "m" is used as a Command Key, "M" will not +invoke that command. Command Keys must be unique within a given +configuration file. \'twander\' will declare an error and refuse +to run if it sees two Command Definitions with the same Command Key +in a given configuration file. + +The "Command Name" is a string of any length containing any +character (except the "#" character). This is the name of the +command which is used to invoke the command from the Command Menu. +Command Names are case-sensitive ("command" and "Command" are different +names), but they are not required to be unique within a given configuration +file. That is, two different Command Definitions may have identical +Command Names associated with them, though this is not ordinarily +recommended. + +The "Command String" is any arbitarary string which is what \'twander\' +actually tries to execute when the command is invoked. + +In its simplest form, a Command Definition looks like this: + +.nf +# A simple Command Definition + +m MyMore more somefile +.fi + +This command can be invoked pressing the "m" key on the keyboard or +selecting the "MyMore" entry from the Command Menu. Either way, +\'twander\' will then execute the command, "more somefile". + +The problem is that this command as written actually will not give you +the result you'd like. (For more details on why, see the +.B GOTCHAS +section below.) It turns out that starting a non-gui program like +\'more\' in a new window needs some extra work. What we want to do +is run \'more\' inside a copy of \'xterm\'. Now our command looks like +this: + +.nf +# Our command setup to run as a GUI window + +m MyMore xterm -l -e more somefile +.fi + + +.SS User-Defined Variables In A Command String + +The last example works quite nicely. But, we're probably going to end up +using the string "xterm -l -e" over and over again for any +shell commands we'd like to see run in a new window. Why not create +a User-Defined Variable for this string so we can simplify its use +throughout the whole configuration file? Now, our command looks +like this: + +.nf +# Our command enhanced with a User-Defined Variable. +# Remember that the variable has to be defined *before* +# it is referenced. + +XTERM = xterm -l -e # This defines the variable +m MyMore [XTERM] more somefile # And the command then uses it +.fi + + +.SS Environment Variables In A Command String + +This is all very nice, but we'd really like a command to be generic +and be easily used by a variety of users. First of all, not everyone +likes the "more" program as a pager. In fact, on Unix-like systems, +especially, there is an environment variable ($PAGER) set by each user +which names the paging program that user prefers. We can refer to +environment variables just like any other variable as explained +previously. Now our command looks like this: + +.nf +# Our command using both a User-Defined Variable and +# an Environment Variable to make it more general + +XTERM = xterm -l -e +m MyMore [XTERM] [$PAGER] somefile +.fi + +.SS Builtin Variables In A Command String + +It would also be really nice if the command applied to more than just +a single file called "somefile". The whole point of \'twander\' +is to allow you to use the GUI to select one or more directories +and/or files and have your Command Definitions make use of those +selections. \'twander\' uses a set of +.B Builtin Variables +to communicate the current directory and user selections to the +any commands you've defined. Builtin Variables are referenced +just like User-Defined Variables and Environment Variables and +may be inserted any appropriate place in the Command String. +In our example, we probably want the command to pickup whatever +item the user has selected via the GUI and examine that item +with our paging program. Now our command becomes: + + +.nf +# Our command in its most generic form using +# User-Defined, Environment, and Builtin Variables + +XTERM = xterm -l -e +m MyMore [XTERM] [$PAGER] [DSELECTION] +.fi + +The "DSELECTION" builtin is what communicates the currently +selected item from the GUI to your command when the command +actually gets run. + +\'twander\' has a small, but rich set of Builtin Variables +for use in your command definitions: + +.IP \(bu 4 +.B [DIR] + +[DIR] is replaced with the current directory which \'twander\' +is viewing. + +.IP \(bu 4 +.B [DSELECTION] + +[DSELECTION] is replaced with the fully-qualified path name +of the item currently selected in the GUI. If more than +one item is selected, [DSELECTION] refers to the last item +in the group. + +.IP \(bu 4 +.B [DSELECTIONS] + +[DSELECTIONS] is replaced with the fully-qualified path +name of +.B all +items currently selected in the GUI. + +.IP \(bu 4 +.B [SELECTION] + +[SELECTION] is replaced with the name of the currently +selected item in the GUI. The path to that file is +.B not +included. As with [DSELECTION], if more than one item is selected in +the GUI, the name of the last item in the group is returned for this +variable. + +.IP \(bu 4 +.B [SELECTIONS] + +[SELECTIONS] is replaced with the names of +.B all +items currently selected in the GUI. The path to those names is +not included. + +.IP \(bu 4 +.B [PROMPT:Prompt-String] + +[PROMPT:...} allows you to insert an interactive prompt for the user +anywhere you'd like in a command definition. The user is prompted +with the "Prompt String" and this variable is replaced with their +response. If they respond with nothing, it is interpreted as an +abort, and the command execution is terminated. This makes commands +extremely powerful. For instance, say you want to create a group copy +command: + +.nf +# Copy a group of items to a location set by +# the user at runtime + +UnixCopy = cp -R +Win32Copy = copy + +# Unix Version + +c UnixCP [UnixCopy] [DSELECTIONS] [PROMPT:Please Enter Destination] + +# Win32 Version + +C Win32CP [UnixCopy] [DSELECTIONS] [PROMPT:Please Enter Destination] +.fi + + +.P +A few other points about Builtin Variables are worth noting: + +.IP \(bu 4 +Any of the builtins that return selections from the GUI will +always end a directory name with a path separator character +("/" or "\\"). + +.IP \(bu 4 +User-Defined and Environment Variables are resolved (substituted) +at the time the configuration file is read by \'twander\'. That +is, they are resolved +.B once +at load time. + +Builtin Variables are resolved +.B on each command invocation, +i.e - at runtime. + +.IP \(bu 4 +The results of all builtins are put inside double-quotes when they +are replaced in the command string. This default is recommended +so that any builtin substitions of, say, file names with spaces +in them, will be properly recognized by your commands. You can +suppress the addition of double-quotes by using the -t command line +option when starting \'twander\' + + .SH CHANGING KEYBOARD BINDINGS @@ -700,7 +1012,7 @@ a \'nohup\' ... & invocation, you will get .B no output. This is not a \'twander\' problem, it is innate to -how command line programs run under Unix shell control. To achieve +how command line programs run under Unix-like shell control. To achieve the desired results, you'll need something like this in your configuration file: @@ -740,7 +1052,7 @@ You must have Python 2.2 or later installed as well as Tkinter support installed for that release. In the case of Win32, Tkinter is bundled with the standard Windows Python distribution. In -the case of Unix, you may have to first install Python and +the case of Unix-like, you may have to first install Python and then the appropriate release of Tkinter. This is the case, for example, with FreeBSD. @@ -913,7 +1225,7 @@ .TP 4) Because \'twander\' is written in Python using Tkinter, the same -program runs essentially identically on many Unix-style and Win32 +program runs essentially identically on many Unix-like-style and Win32 systems. The only thing that may need to be changed across these various platforms are the command definitions in the configuration file. You only need to learn one interface (and the commands you've