"The User Interface for Programmers"

Inspiration from, for anyone really

acme is introduced by its author, Rob Pike, as:

A hybrid of window system, shell, and editor, Acme gives text-oriented applications a clean, expressive, and consistent style of interaction.

The description of acme, from Rob Pike publication1, gathers most of the interfaces I use mostly, with the notable exception of the web browser.

acme is not vim, emacs or vscode:

  1. mouse usage is mandatory, yet very powerful AND different from anything else, thanks also to the plumber.
  2. acme has no config file, VERY limited configuration options and no plugins.
  3. acme has 5 keyboards shortcuts:
    • ^U -> Delete from cursor to start of line.
    • ^W -> Delete word before the cursor.
    • ^H -> Delete character before the cursor.
    • ^A -> Move cursor to start of the line.
    • ^E -> Move cursor to end of the line.
  4. acme is a complete system, that integrates with the surrounding environment
  5. acme state is however entirely controllable from a 9p interface (akin to a filesystem API), by any script and program you want

Acme is then extensible "from the outside" with any languages.

On the other hand, emacs is more of a lisp machine to build applications than an editor and vim stands in between, with an highly efficient keyboard UX and a bad extension language.

1 Imitating acme with existing tools

NB: I use vi in st terminals in a tiling window manager on debian linux on a thinkpad, with or without external displays, with or without external mouse and keyboard.

To improve my non-acme setup with some of the acme goodness, I need:

  • a window system, capable of handling many windows easily: dwm, [i3], …
  • a terminal running a shell: st and [zsh]
    • that allows easy selection of patterns such as ^some/path/to/file:line:col. I find it convenient to only use ` =(space) as the word delimiter in=st`.
    • that knows the current working directory cwd of its running shell
    • and can send the current selection to the plumber, along with some additional informations, such as the cwd, its pid and window name, etc
  • a text editor:
    • that is either remotely controllable: vim or neovim
    • and/or that shares its state between multiple instances (clipboard, opened buffers, etc)
  • an plumbing system, that should trigger actions based on the informations sent

1.1 Keyboard usage

Key Location Usage
Shift Symetric, 2-4, thumb or pinky Caps, inverse command, alternative
Control Side, capslock, left pinky In app modifier, shell mod, etc
Alt Usually left next to space Usually global modifier, extra app
Meta Usually alt key Emacs specific, general in app modifier
Super Usually the OS key, left and right to space  
Compose    

1.2 tmux

tmux is a terminal multiplexer that allows to run shells within a session, with tabs, panes, searchable buffer, attach-detach, … just like [GNU screen], with a somehow more modern implementation.

vim.png
Figure 1: tmux

It is particularly interesting when working on a remote server via ssh/mosh, for pair programming for instance.

tmux has mouse support to select text, move the cursor around, resize panes and changes window. You can't move panes or frames around like you could with acme. The latest version to date (2.4) handles more events (click, double click, triple clicks, drag) which can be bound to user defined actions.

You can ask tmux to re-arrange the layout from vertical, to horizontal, to fair, etc. You can also zoom the currently selected pane to fill the whole window to focus on that one task, with a single MOD-z keystroke.

tmux offers a nice "tiled" terminal environment, with potentially more featureful shells and terminals, searchable scrollback.

To provide the "right click to plumb" feature, I use this:

# mouse support
set -g mouse on
bind -t vi-copy 'v' begin-selection
bind -t vi-copy 'y' copy-selection
bind-key    -T root   MouseDown2Pane select-pane -t = \; send-keys -M \; paste-buffer
unbind-key MouseDown3Pane
bind-key    -T root  MouseDown3Pane select-pane -t = \; send-keys -M \; copy-mode -M \; send-keys -M \; send-keys b v e y\; split-window zsh -c "plumb.sh `tmux showb`" \;

in conjunction with a plumb.sh script that either call vim or vim --remote or xdg-open.

1.3 terminals and tiling window managers

As the name implies, a tiling window manager just manages windows in a tiling fashion.

dwm.png
Figure 2: dwm

I use dwm but there is enough choice to accomodate anyone, on every platform, even on iPad™.

A tiling window manager arranges your application windows according to a dynamic or manual layout, allowing you to show different applications at the same time, with no ovelap. On the other hand, they provide actions to jump from one to another, change layout and so on.

In the context of multiple displays, window managers brings event more control over the actual layout of applications across your setup, where tmux, acme and other single window applications come short.

They are of course not limited to text applications and provide a good foundation for whatever you choose to run within, may it be acme and tmux.

Since I use the suckless simple terminal, I hacked a little patch that provides the "right click to plumb" feature I missed so much from acme. See the patch section of st.

1.4 vi, vim, neovim

The venerable vi has been my editor of choice for nearly 20 years. 20 YEARS.

vi comes it many flavours: vis, vim, neovim, etc. vi editing mode is available for other applications as an extension, emacs, atom, vscode, edit, …

Recent versions includes features that extends its strict editor focus:

mouse support
pretty good, to visually select, resize windows, open file under cursor…
set switchbuf=useopen
nnoremap <RightMouse> <C-W>sgF
vnoremap <RightMouse> <C-W>sgF
window management
with buffer ring, splits, tabs window management in vi clones is different from acme's
terminal / shell support
in neovim, via vte. Terms in neovim are quite close to acme's win program (which source is located in plan9's src/cmd/9term/win): editable, using the same keyboard features. using vte, the application support is pretty good, so you can have colors, tab completion, shell history…
remote control
vim has --remote and neovim has nvim-remote that allows to send commands to a running vim server.
" try not to open nem buffers if one exists
set switchbuf=useopen

multi-cursor

2 Context and old rant

See acme, watch a tour of acme by Russ Cox and maybe read the original paper by Rob Pike1. The paper and the great man pages covers a lot of what I will be writing about.

From the man page acme(1):

Acme manages windows of text that may be edited interactively or by external programs. The interactive interface uses the keyboard and mouse; external programs use a set of files served by acme; these are discussed in acme(4).

acme features a text user interface, an environment that allows to edit text, whether it's a file, a shell, a file listing, a live log output, the tags… The whole interface is textual, editable and "clickable".

acme.png
Figure 3: acme

Using acme is a refreshing and yet bitter sweet experience as it packs such goodness only to lack what seems so familiar to many.

To start with the obvious: mouse oriented, no keyboard shorcut. Plain text, no syntax highlighting. That being said, acme windows can be splitted in columns, and columns in windows. These windows are created and arranged in a smart way automatically and yet you can re-arrange them in different ways, to move them around, maximize them, etc. Windows can be files to edit, a scratchpad, a file browser, a shell, an email client … It is all just text that reacts to mouse clicks, anywhere:

  • 1-left click to select
  • 2-middle click to execute
  • 3-right click to open, or find the next occurence
  • and some more when chording 1-2, 1-3 to cut/paste, …

There are many built-in text patterns recognized that can be extended with [the plan9 plumber tool][plumber]:

  • 3-right click to open a new window showing the content of the . directory
  • 2-middle click pwd to get the output of the command in a new window named +errors by default
  • 3-right click main.go:3 to open the file at line 3 or main.go:/Println to jump/open directly to the first occurence of Println in the file named main.go, then 3-right click again to advance to the next occurence.
  • 2-middle click (ag acme) to show the result of the ag search for acme then 3-right click one of the results to jump to the file
  • select godoc with button 2-middle, then with 2-middle still down, click on fmt to pass it as an argument and see the documentation open in a new window.
  • 3-right click on http://foo.bar to open the URL in the browser

All this is just clicking on text, anywhere in the interface and acme responding to it according to the plumbing rules.

To "extend" acme, one would either hack its code, craft some nifty plumbing rules or use its 9p file API, which represents its whole state, with any language you like, may it javascript, lua, shell, golang… See Agofmt or agoc for examples in go.

acme shines as an environment for programmers, thanks to its unique set of features, its consistency, its easy integration to the surrounding system and its approach to interactions between tasks. Russ Cox coined the term "Integrating Developer Environment".

Its feature set hits a sweet spot in terms of usability and consistency, that grows to become so addictive that you could easily get frustated by its editor/shell when using it as you could get frustated by the lack of acme features in your preferred environment:

  • "I want text objects in acme!@#"
  • "I want to open a file by clicking on its name in my terminal!@#"
  • "I want color in acme!@#"
  • "I want sam expressions in vim!@#"
  • "I want command history, tab completion in acme's shell!@#"
  • "I want editable scrollback buffer in xterm!@#"

Out of this frustration, quite a few projects are born:

  • edit, a single window mix of acme and vi
  • editor, a very ressembling editor written in go
  • vis, a vim like editor, featuring sam expressions
  • de and dewm, an editor and a tiling window manager, inspired by acme

Footnotes:

1

the original paper by Rob Pike: PDF