Integrating tools, especially shells, terminals and editors to achieve the common programmer’s tasks.
WIP this article needs to convey a better feeling of the acme experience and provide more links to interesting code
A programmer’s primary concern is to program computers and consequently:
- define or follow the program design, which can be materialized as PDF, github issues, photoshop mockups, UML diagrams …
- manage the project source code versionning, with a git client for instance
- alter the source code with a text editor
- make the program run, locally or remotely, with an appropiate buildchain and deployment tool
- monitor the programs logs, tests output, build, cpu/mem/io usage, …
- inspect the programs data, in/out, files, database, etc.
For every task, there’s a “interactive graphical representation” in the form of a “window” that is either visible or hidden to the programmer who has to switch between them, to re-arrange them or have them interacting.
acme, the User Interface for Programmers
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.
See acme, watch a tour of acme by Russ Cox and maybe read the original paper by Rob Pike. The paper and the great man pages covers a lot of what I will be writing about.
From the man page
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”.
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
- 2-middle click
pwdto get the output of the command in a new window named
- 3-right click
main.go:3to open the file at line 3 or
main.go:/Printlnto jump/open directly to the first occurence of
Printlnin 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
acmethen 3-right click one of the results to jump to the file
godocwith button 2-middle, then with 2-middle still down, click on
fmtto pass it as an argument and see the documentation open in a new window.
- 3-right click on
http://foo.barto 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.
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
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
- that knows the current working directory
cwdof 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
- that allows easy selection of patterns such as
- a text editor:
- an plumbing system, that should trigger actions based on the informations sent
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.
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
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 --remote or
terminals and tiling window managers
As the name implies, a tiling window manager just manages windows in a tiling fashion.
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.
vi, vim, neovim
The venerable vi has been my editor of choice for nearly 20 years. 20 YEARS.
vi comes it many flavours: [nvi], 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
winprogram (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
--remoteand 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