# Wily

Gary Capell

### This document

Appearance, Unicode - Mouse Actions - Example - Extensions - Implementation - Availability - History -

### Other documents

- Preview of new Wily homepage
- One Page Users Manual
- Users Manual
- Wily + Python > Emacs + Lisp?
- Programmers Manual
- Differences between Acme and Wily

## Note for Sydney-ites

I'd be keen to demonstrate/explain Wily for interested folks in Sydney

## Abstract:

Wily is an emulation for the Unix/X environment of Acme [Pike95] from Plan 9. It combines most of the features of text editor, window manager, file manager and general user interface. It exploits a three-button mouse and bitmapped display to provide a smooth, simple and powerful environment for interacting with text of all kinds.

Wily differs from most other editors in a number of areas. Nearly all operations are through mouse actions on text on the screen: there are no menus, few "key bindings" and no "function keys". Text is usually displayed in a proportionally-spaced font, and is interpreted as UTF8-encoded Unicode. Mouse "chords" (combinations of mouse buttons) are used extensively. Wily's core functionality is almost totally unconfigurable. However, it is quite simple to extend Wily using other programs, written in any language, both for simple text-manipulation tasks, and to use Wily as a front-end for other programs such as mail or news readers, or terminals.

It is possible (and intended) to "live" in wily as with other, more complicated editors.

The learning curve is steep, but short. Once learnt, the interface is sufficiently addictive that the author re-implemented Acme to work under Unix, rather than coping with other editors. Wily and Acme have a small but growing number of addicts.

## Appearance

Wily appears as one or more vertical columns, divided into windows of scrolling text. Each column or window is headed by a thin horizontal tag. The leftmost text of the tag is the name of the file or directory the window represents. Other text in the tag are some words useful as commands.

The small square-ish box to the left of the tag is called the resize box. If the resize box is filled, this indicates that the text in the associated window has been modified since it was last read from or written to disk.

The text in the body of the window may represent a directory, a file, the interface to some program like a news reader, or the output from some program like `make`.

### Proportionally spaced, Unicode text

Text is displayed in a propotionally spaced font by default. There is a built in function to toggle with a monospace font (seen in the bottom-left window in the example pictured), but there are very few occasions when this is necessary or desirable. In most cases limiting a text editor to monospace fonts is blindly following the hardware limitations of the 1960s.

Text is read and written as UTF8-encoded Unicode, providing some support for editing multi-lingual and scientific text, but remaining backwardly compatible with plain 7-bit ASCII text. See 9term for an example of another program with Unicode support, with some screen shots.

## Basic Mouse Actions

Any text on the screen can be selected by dragging with a mouse button. Briefly, the left, middle and right mouse buttons are used to select, execute or goto text. In more detail:

Left button
  highlights the text for later actions
Middle button
  executes the text as a command, e.g. selecting the word '`make`' will run the `make` command as if it were typed to the shell. There is a small set of built-in functions (e.g. `Undo`, `Redo`, ) that are searched for first. Wily arranges for text representing these functions to be on the screen when and where appropriate, although they can always be typed anywhere anytime. Output from programs is captured and displayed in windows in Wily.
Right button
  attempts to goto the selected text. What this means depends on the text selected, but may involve opening a file or directory, or searching for a line number, regular expression or literal text.

  Wily tries to parse the selected text as `filename:address`, where `address` may be a line number or `/regexp`.

  Either or both of the filename and the `:address` may be recognized.

  If Wily cannot recognise any of these forms, it searches for the next occurrence of the selected text in the current window.

Panes and columns can be moved and reshaped by clicking or dragging in the resize box to the left of their tags.

There are no menus, and few special keys (page up, page down, arrow keys, Home, End, kill word, kill line, select recently typed text). All functions are accessed through mouse actions on text.

## A short example

Sally has been using wily to develop a program called wily.

- She clicks the middle mouse button in the word `make` somewhere in the tag of the window for her source directory, `/src/wily/`. Clicking the middle mouse button in some text tells wily to execute that text. In this case wily runs `make` in another process. The output and errors from this process will appear in a window labelled `/src/wily/+Errors`. (The window will be created if necessary). Unfortunately there is an error: the output includes the line `builtins.c:78: parse error before `)'`.
- She clicks the right mouse button anywhere in the text `builtins.c:78:`. Clicking in some text with the rightmost mouse button tells wily to goto that text. A new window labelled `/src/wily/builtins.c` is created if necessary, with line 78 centred and highlighted, and the cursor warps to this line. Sally sees that the last `)` on that line is unnecessary.
- She selects it with the left mouse button, and while holding this button down, also clicks the middle mouse button to cut out the offending parenthesis. Cutting and pasting text in wily can be done with combinations of mouse keys. This is very quick and easy. The resize box of the window is filled in, to indicate that the file has been modified.
- She clicks the middle mouse button in the word "Put" in the window's tag. Wily recognizes this as the name of the builtin function to write the file to disk, and does so. The resize box is cleared, to indicate that the file is "clean".
- She clicks the middle mouse button in the word `make`, and the cycle begins again.

This whole interaction requires six mouse clicks and much less time than the time to read about it.

### Combinations of mouse buttons

The system does some things so that the user doesn't need to place the mouse accurately. Double-clicking with the left mouse button selects a word, a line or a piece of text delimited by quotes, braces or brackets. With the middle or right button, a click inside a selection will be expanded to that selection, or a click inside a word that can be recognised as a command or address will be expanded to that word.

Simultaneous combinations of mouse buttons (Mouse chords) are used for cutting and pasting. To move some text from one place to another, it first is selected by dragging with the left mouse button. While holding this button down, if the middle button is also pressed, the text is cut. The text can later be pasted into place by holding the left button and then clicking the right button. This action is easier done than said, and is much quicker than searching for a menu entry.

A mouse chord is also used as a short-hand for the idiom of executing a command with some argument. While clicking with the middle button in the command, if the leftbutton is then pressed, the most recently selected text is given as an argument to the command. For example, one could point to a program variable, click the middle and left buttons on the name of some simple program, and get a list showing all the places that variable occurs. Clicking with the right button on any of the occurrences on that list will open the relevant file at the correct line.

The mouse cursor is often warped to where the program predicts the next action is likely to take place. For example, after opening a file at a particular address, the cursor is warped to that position of that file.

The escape key selects any text typed since the last cursor movement, making it easier to select with the mouse.

## Undo/Redo

Wily provides a full Undo/Redo history for each window.

## Window Positioning

Newly created windows are placed by the program, not the user. While it is possible for the user to reposition or resize the window after it is created, window-positioning heuristics generally make such positioning unnecessary.

## Extensions

Wily has no extension language, but is easy to connect to other UNIX programs.

### Program output is useful

The output (both `stdout` and `stderr`) of any commands run from wily will appear in a wily window, where it may be useful. For example, the author uses the shell functions `sg` and `def`. `sg` (short for source grep) is defined as `fn sg {agrep -w -n $* *.[ch]}`, `def` as `fn def {grep -n '^'^$1 *.c /dev/null}`. To find the definition of some C function, the author clicks with the left button in the name of the function, and does a middle-left button combination on the word `def`. The output from `def` will appear in a wily window, and be something like `/usr/gary/src/dir/file.c:243 function(int arg, char* otherarg)`. Clicking here with the right mouse button will then open the file if necessary, and move to and highlight the correct line. The function `sg` operates similarly, listing all occurrences of some identifier. Note that it would be simple to modify these functions to operate with other languages (HTML, Java, ...) and that they could be written in any language the user chooses.

### Filter programs

Commands beginning with |, > or < operate on the most recent selection. They either pipe it through a command, send it to a command, or replace it with the output of a command. For example, to reformat a paragraph, select it (using the left button), then click anywhere in the text `|fmt`. `fmt` will be executed, with its input taken from the current selection, and its output replacing the current selection.

Programs may also be used to filter text in wily windows. If a command starts with the pipe symbol `|`, it uses the most recently selected wily text as input and output. Indenting, formatting, html tagging can all be done using standard Unix tools, or tools written by the user in any language. Simply select some text, and click with the middle mouse button in `|cmd`. For example, here is the author's file `lib/html/guide`:

    |title |h1 |h2 |h3 |h4
    |italic |emph |strong |bold |code |href prog.html |name remote
    |fmt >spell |blanks2P

### Wily as a front-end

Longer-running processes may instead open a socket to wily, which can be used to send requests or receive events. One example of this is the program `win`, which provides a simple terminal within Wily. (For details refer to [Cap95a])

Python and Perl bindings for this message interface are available.

Mail and news readers or code browsers should be fairly simple to write using Wily as their front end. All of these programs would operate in a familiar fashion (left mouse button selects, middle button executes, right button does a "goto").

## No confirmations

When you close a file that wily knows contains changes, it doesn't bother you with a confirmation dialog, but does a backup of the file and prints a warning message in case you've made a mistake. This is quicker in the common case that you do want to discard the changes, is simple to recover from if you have made a mistake, and eliminates the mistake of confirming a deletion that shouldn't have been confirmed.

## The Implementation

Wily is a single-threaded event-driven server process. The events it waits for are keyboard and mouse actions, and output arriving on sockets shared with child processes. Text display is handled by text widgets.

### Child Processes

To execute a command that isn't built in, the wily server forks a child, which modifies its execution environment, and `exec`s the required command.

The child sets its current directory to the directory the command was invoked from. The child's file descriptors are set so that `stdin` is redirected from `/dev/null`, and `stdout` and `stderr` are redirected to a file descriptor the server listens to for output.

The parent adds the file descriptors passed to the child to a list of file descriptors that it monitors for output, and remembers which directory that stream is associated with, so that output will appear in an appropriate window.

More sophisticated client processes can open a socket to wily and send (and receive messages). The idea here is that wily provides the "look and feel" of the user interface, with various client programs providing different data (mail, news, debugger...),

### Code bloat (not!)

Wily's source code (excluding some libraries from Bell Labs) takes 7600 lines of code, or 3100 counting only lines with semicolons. The binary (`ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped`) is 150k (c.f. 234k for vi, 2044k for xemacs). Wily typically takes less memory to run than Xterm.

## Strengths, Weaknesses and Further Work

The things the author misses most when using another editor are: mouse chording for cut and paste (alternatives seem very awkward), opening a file to a particular line with a single mouse click, and editing in a proportional font.

Some of wily's strengths may also be seen as weaknesses: heavy exploitation of bitmapped terminal and three button mouse mean wily is unusable on glass and paper teletypes. The terse mouse command language is opaque and even intimidating for new users.

The author is very interested in cooperating with any HCI researchers interested in comparing the usability and/or ease of learning of this editor with more traditional ones, or in comparing mouse-based and keyboard-based editors.

Wily is not as robust or efficient as the author would like.

## Availability

Wily source code and documentation (263k) and some binaries are available via FTP from sites in Australia, Israel, the UK and the US.

The author welcomes comments and suggestions.

There is a mailing list for discussion about wily and announcements of new releases. Mail wilyfans-request@jli.com to subscribe. The list is archived.

Wily runs on BSDi, AIX, OSF, HP-UX, IRIX, Linux, Solaris, SunOS4, (these are the OSs the author knows of to date). With any luck, `gunzip, tar, configure, make install` should get you going.

## History

Wily is a reimplementation of Acme [Pike95] for the Unix/X environment. Acme itself was heavily inspired by the Oberon [Wirt89] user interface. A port was not possible because the Acme implementation relies on Alef [Win95](a concurrent programming language not widely available) and non-portable features of Plan 9 [Pike95a].

The name "wily" derives from Wile E. Coyote, an avid user of Acme products.

## Acknowledgements

Many suggestions on wily and this paper, and much of the code were received from Bill Trost `<trost@cloud.rain.com>`. Libraries used include libXg and libframe, part of the Sam distribution by Rob Pike and Howard Trickey, and libtext by James Farrow.

This is an incomplete, alphabetical list of other people who have made significant contributions to wily: Assar, Davor Cubranic, Kyle Dean, Stephen Gallimore, Mark H. Wilkinson, Bjorn Helgaas, Steve Kilbane, Beirne Konarski, Bob Krzaczek, Alberto Nava, Arnold Robbins, Rich Salz, Scott Schwartz, Chris Siebenmann, and Richard Wolff.

## References

[Cap95]
  Gary Capell: Wily User's Guide
  `http://www.cs.su.oz.au/~gary/wily/user.html`
[Cap95a]
  Gary Capell: Wily Programmer's Guide
  `http://www.cs.su.oz.au/~gary/wily/msg.html`
[Pike95]
  Rob Pike: Acme: A User Interface for Programmers,
  Plan 9 Programmer's Manual, Volume Two, 2nd Ed.
  `http://plan9.bell-labs.com/plan9/doc/acme.html`
[Pike95a]
  Rob Pike et al.: Plan 9 from Bell Labs,
  Plan 9 Programmer's Manual, Volume Two, 2nd Ed.
  `http://plan9.bell-labs.com/plan9/doc/9.html`
[Win95]
  Phil Winterbottom: Alef language Reference Manual,
  Plan 9 Programmer's Manual, Volume Two, 2nd Ed.
  `http://plan9.bell-labs.com/plan9/doc/ref.html`
[vanRo95]
  Guido van Rossum: Python Tutorial,
  CWI Technical Report CS-R9526,
  1995
  `http://www.python.org/`
[Wirt89]
  N. Wirth and J. Gutknecht: The Oberon System,
  Software - Practice and Experience,
  Sep. 1989, Vol 19 #9, pp 857-894