What would wickel do ?
Imagine, you want to use 'enscript' to produce PostScript output
for some files. And you want that output to be set in two columns
as landscape with the heading "This is my printout" in Helvetica on
the printer "local-printer", suppressing a burst-page.
Wouldn't it be nice if one could pop up a GUI, fill in the
relevant fields and either send the resulting command to the
clipboard or run it directly ?
Clearly, writing a GUI from scratch for every CLI program that it
might be useful for is very tedious and won't get very far. Hence
the need for a tool that uses a high-level description of a command
to produce the GUI.
The reason why it is possible to automatically generate the GUI
is that the semantics of the GUI will be extremely simple: accept
some values and assemble them into one string which can be run on
the command line. Note that tools like find are way out of
reach for this approach, since find's command line
switches are effectively a small language and should be dealt with
differently. But the vast majority of UNIX tools adheres to a very
simple semantic model: a command is parametrized by certain
variables, whose values can be set either through switches or
environment variables. Since the command line is only used for
passing individual, independent values, it is very easy to capture
a command line with an automatically generated GUI.
To make the generated GUI a helpful tool, it has to perform
error-checks on the values the user inputs. Many of these checks
can be automated: once it has been indicated that a certain
argument is an output file, wickel can automatically output checks
to ensure that a file isn't overwritten by mistake. The checks that
can not be automated have to be coded by hand and included in the
GUI. At this point it becomes important, that the GUI description
language makes it easy to add user-code; at the very least, the GUI
has to expose all the values entered for switches so far to the
user-code.
Why would one want to do this ?
- 'Active Manpages': even for an experienced user, there are
always some programs that one uses very infrequently, so that
it's hard to remember which command-line options are used for
what. Ususally, this means that you have to look in the
man-page, even though you're very familiar with the command in
question, except you don't remember whether the printername has
to be given after '-d' or '-P' ... and do you put a space
between the switch and the printer name or not ?
- Not-so-experienced users: wickel could serve as a good way to
bridge the gap between the total newbie, who knows hardly any
commands well and is therefore frightened of all shells and the
seasoned user.
The way it does this is by using a formalized description of the
options a command takes, e.g.
(switch switch1 r "Landscape")
declares that switch1 corresponds to the option "-r". This
declaration will produce a toggle button labeled "Landscape" in the
GUI
(switch switch2 header b string "Custom header:")
declares that switch2 corresponds to the option "-bSTRING" where
STRING will be read from an entry-field in the GUI labeled "Custom
header:"
On top of the description and type-declaration of the switches,
one also needs a very high-level description of the layout that
arranges all the elements defined with a 'switch' statement into
pages in a notebook.
Some issues/enhancements:
A complete implementation of wickel should at least contain the
features listed below. I am very interested to hear more
suggestions for enhancements. Please mail them to me.
- A sophisticated help system: (1) add tooltips to all
entries, (2) let the user pop up a more extensive explanation for
each switch and (3) offer showing the complete man-page as a last
resort.
- Chaining of commands: add an easy way to do all the
redirection/piping that one does on the command line from the
GUI. This would probably need some repository of GUI-descriptions
and a good manager for it.
- Simple user-defined add-ins: open the entries of the GUI
to user-supplied routines to allow for more flexible
customization.
In the simplest case, this could just be a
let style macro.
- Create aliases: let the user choose some settings with
the GUI and the store it in some repository and have menu-based
access to the repository.
- Add more primitive types to the declaration of
switches. In particular, a more finely grained approach to
file/directory names. It should be specified whether a file is
for input or output, so that wickel can check for overwriting
exisiting files or non-exisiting input and warn the user.
- Validation of input entries. Add routines to the entry
fields that check that an entry that has type file really
contains a valid filename etc.
- In the very far future, it should be possible to add the
interface description to the SGML documentation with additional
tags, so that everything can be generated from one file.
- A better way to express dependencies/mutual
exclusiveness among switches. Surprisingly, ls is a very good
case to see where my current system is too limited. (I have no
way to say that -c and -u only make sense when -t is given)
This could go all the way to a full-fledged constraint system.
- Syntax: the interface description syntax is a bit
adhoc. It definitely needs to be cleaned up. Maybe use a real
parser.
- Layout of the GUI: too cruddy right now, needs cleaning
up desperately.
- Compiler or Interpreter: at the moment, wickel is an
interpreter. But a compiler (especially to C) might be much more
useful.
Notes on the current implementation:
- Builtin-types:
bool : switch there/not there
integer : enter a numeric value
string : enter any string (integer and string behave
identically at the moment)
file : popos up a file-selection dialog
enum : for arguments that can only come from a finite
set, like LETTER, LEGAL, A4, A5
- Execution of the command is not very sophisticated: Well, it
doesn't do very much yet. You can generate nice GUI's and when
you press 'Execute' the command is run using system(), but the
output isn't sent anywhere. Better use 'Clipboard', which only
prints the command assembled so far on stdout. (Eventually, it
should send that string to the X-Clipboard)