riffing with acme


Programmers tend to argue about most things, tabs vs spaces, camel case vs snake case vs aaardvark case, plaintext vs html emails… you get the idea. Probably one of the most notorious debates, that just wont end, is about editors. Programmers care a lot about their editors and how they have it setup. You’ve probably heard of vi and emacs of the yesterdecade, the epicenter of the editor wars, and newer shinier electron based endavours like atom and vs code for the crowd with more physical memory than sense.

But for my1 money

No editor made, pretty much anywhere,
surpasses our Acme in shape, material or finish.

If you don’t know what acme is, start with the tour of acme

For those of you that are not familiar; plan9 and therefore acme rely heavily on mouse usage, most actions are preformed by mouse chords and there are a handful of keybaord shortcuts in acme that were mostly added by the community. There is a whole page dedicated to this issue in the plan9 wiki.


Acme is in a very stable state, why risk adding new things and risk introducing new bugs? why is the mouse not enough?

Consider this my experience report about how I use acme and what I’m finding useful for me.

And in that spirit;

The best experience reports tell:

  1. what you wanted to do,
  2. what you actually did, and
  3. why that wasn’t great, illustrating those by real concrete examples, ideally from production use.

I am a creature of habbit, expect for editing the ocasional config file in a machine that I’ve ssh’d into, I’ve been using acme for a while as my main editor for a while now. I don’t miss anything in emacs or vi. I don’t miss syntax highlighting. I don’t miss auto-complete and I don’t even miss C-x+M-c+M-butterfly.

What I do miss is being able to edit an entire file without having to use a mouse. And it’s not all the time I want to be able to edit a file all by keyboard but often enough that I’m embarking on this endavour.

Q: Does Acme depend on using a three button mouse?

A: Acme is as dependent on a three button mouse as Emacs is on finger gymnastics and vim is on the Esc key. But don’t let it discourage you, Acme’s user interface makes much better use of the mouse than any other text editor. (Paraphrased from an answer given by Jessta on golang-nuts.)

source: acme faq2

xp report #1: macs

It’s not that often but there are times when I’m teaching a class or pairing with someone that I may need to touch macs.

Installing a plan9port on a mac is easy enough;

brew install plan9port && acme

will launch acme (setting aside macfuse and all the other setups you’d need for the full experience) which would allow me to work the way I’m used to. And acme without fuse is perfectly fine for editing small files and configurations.

Alas fuse support is often the least of my worries as using the trackpad is for text selection is so horrible, I usually endup using emacs or nano for simple edits So forget finger gymnastics any text selection on a mac using the trackpad is like olympic finger skating. You literally have to keep one finger pressed while you pivot around that finger with another finger. And that’s just basic text selection.

Doing a right click on a macs is easy enough. Use two fingers as you would on a regular mouse and…. well that’s it.


source: apple support3

doing a middle click actualy requires you to either hold down the and single tap on the trackpad. Or installing something like magicperf

The problem with the secondary-click and middle-clicks on macs are as most of these peripherals are multi-touch. Which means using a finger or two registers a new gesture where as on traditional 3 button mice, you can do 3 clicks all at once. This is why acme allows you to chord clicks like so;

mouse chords
mouse chords

source: acme mouse4

Now if you’re using a mac try chording Cut just by using your trackpad. Go ahead, I’ll wait! you’d probably need multiple trackpads to do so right? Using a trackpad for text editing is the most finger gymnastics-iest thing I’ve ever done. Like I’ve said, I sometimes have to resign to using a mac, it’s not a choice it’s a necessity.

xp repoty #2: onMouseOver()

Acme is not like most of the most editors. Where your mouse’s pointer is, is your active buffer. So if your hand accidently hits your mouse and moves it over to a different tag or window you’ll start inserting text into where ever your pointer is.

This means that you should always have a mental note of where your pointer is. Compare this to vi, where you only need to know if you’re in normal mode, command-line mode or insert mode. The active buffer needs to be explicitly selected, and you can’t accidentally switch buffers whilst typing unless you have a cat walking over your keybard.

Consider this, when plan9 and acme were originally developed, 1024 × 768 and 800 × 600 were the most popular screen resolutions. And that’s on CRT screens.

Clearly as the years go by our screen resolutions are increasing, but I’ve never seen anyone, anywere I’ve worked get a larger desk. This is clearly because we are able to fit more dots per inch than we ever could.

Fast forward to 2019 I have 2 4k monitors both holding 4096 × 2304 pixels. That means my pointer can be in any of 4096 × 2304 × 2 = 18874368 pixels that are present on the screen. Compare that to the 786432 potential pixels that the pointer could be hiding in a 1024 × 768 resolution, there is a lot more surface area that your eyes need to scan to find the cursor.

If you’re like me and you find your self moving the pointer away hastily when it’s obstructing something else on the screen it becomes a bit cumbersome to track it down again.

This clearly isn’t a problem that is unique to me, osx even has a built in feature that allows you to shake the mouse to locate pointer.

Now this issue can also be resolved with adding some kind of indicator to acme to indicate the active buffer. Perhaps even by having a single blinker on the screen that actually blinks but we’ll get to that later.

Setting up a development environment

OK, let’s start with the basics. I want to use acme to do my development (obvy) but that presents a chicken and egg problem. Running 2 acme instances on the same machine is kinda tricky, not impossible but just tricky, and I don’t feel like shaving that particular yak today.

A VM it is!


One of the apps i find very useful is Watch. Watch watches a directory and runs a the command you’ve specified when a file is modified.

To be able to iterate on this quickly, When ever I change a file I want to recompile acme and have the VM reload the newly compiled binary.

Let’s begin Riffing

So now that I have alienated everyone, allow me to do perfrom the sacriligious act of adding “riffing” to acme and alienate it’s 7 active users. Riffs in acme “refers to a brief, relaxed phrase repeated over changing buffers”.

To get started the acme virtuoso would hit the Home key which will put acme in riff mode. After entering riff mode the player would then end up in an fsm where each consecutive key after home would put acme in a different mode. There are some universal key bindings in riff mode such as

key binding
Home riff
Esc pop
e execute
p pipe
t tag

Then there are contextual key bindings which allow the player to lay some sweet riffs like;

riff result
Home+s+l selects the line
Home+s+w selects the word
Home+s+l+e selects and executes the line
Home+s+w+e selects and executes the word
Home+s+l+Return selects and delete line

If we were to draw a graph of riff transitions it may look a bit like:


start by adding a new function definition;

typedef void (*rifffunc)(Text*, Rune);
Fun times with function pointers, Inc.
struct Text
    // ...
    char    dir;

+   rifffunc next;

    uint    iq1;    /* last input position */
    // ...

the keen eyed will notice this is the start of a state-machine.

  1. acme2k

  2. acme faq

  3. How to right-click on Mac

  4. acme mouse