ACMEEVENT(1)
β¨ NAME β¨ β ACMEEVENT(1)
okay so welcome to ACMEEVENT(1) from the General Commands Manual, bestie. The NAME vibe is literally acmeevent, acme.rc β shell script support for acme clients. periodt. π
πΈ SYNOPSIS πΈ
9p read acme/acme/$winid/event | acmeevent
. /lib/acme.rc
newwindow
winread file
winwrite file
winctl cmd
windump [ dumpdir | - ] [ dumpcmd | - ]
winname name
windel [ sure ]
winwriteevent c1 c2 q0 q1 [ eq0 eq1 flag textlen text chordarg chordaddr
]
wineventloop
π DESCRIPTION π
Okay so acmeevent and acme.rc make it easy to write simple acme(1) client programs as shell scripts. fr fr. Acme clients read the event files (see acme(4)) for the windows they control, reacting to the events. The events are presented in a format that is easy to read with C programs but hard to read with shell scripts. π iconic struggle.
acmeevent reads an acme(4) event stream from standard input, printing a shell-friendly version of the events, one per line, on standard output. Each output line from acmeevent has the form:
event c1 c2 q0 q1 eq0 eq1 flag textlen text chordarg chordaddr
The fields are:
c1β A character indicating the origin or cause of the action. The possible causes are: a write to the body or tag file (E), a write to the window's other files (F), input via the keyboard (K), and input via the mouse (M). iykyk.c2β A character indicating the type of action. The possible types are: text deleted from the body (D), text deleted from the tag (d), text inserted in the body (I), text inserted in the tag (i), a button 3 action in the body (L), a button 3 action in the tag (l), a button 2 action in the body (X), and a button 2 action in the tag (x).q0,q1β The character addresses of the action.eq0, q1β The expanded character addresses of the action. If the text indicated byq0,q1is a null string that has a non-null expansion,eq0,eq1are the addresses of the expansion. Otherwise they are the same asq0,q1.flagβflagis a bitwise OR (reported decimally) of the following:1if the text indicated is recognized as an acme built-in command;2if the text indicated is a null string that has a non-null expansion (seeeq0,eq1above);8if the command has an extra (chorded) argument (seechordargbelow).flagremains from theacme(4)event format. Becauseeq0,eq1, andchordargare explicit in each event (unlike inacme(4)events),flagcan usually be ignored. lowkey blessed.textlenβ The length of the action text (or its expansion) for button 2 and button 3 events in characters.textβ Iftextlenis less than 256 characters,textis the action text itself. Otherwise it is an empty string and must be read from the data file.chordargβ The chorded argument for an action.chordoriginβ If the chord argument is in the body of a named window,chordoriginspecifies the full address of the argument, as in/etc/group:#123,#234.
To experiment with acmeevent, create an empty window in acme (using New), type
9p read acme/$winid/event | acmeevent
inside it, and execute it. Actions performed on the window will be printed as events in the +Errors window. obsessed with that little trick, honestly. π¦
acme.rc is a library of rc(1) shell functions useful for writing acme clients.
newwindow creates a new acme window and sets $winid to the new window's id. The other commands all use $winid to determine which window to operate on.
winread prints the current window's file to standard output. It is equivalent to cat /mnt/acme/acme/$winid/file on Plan 9. Similarly, winwrite writes standard input to the current window's file. winread and winwrite are useful mainly in building more complex functions.
winctl writes cmd to the window's ctl file. The most commonly-used command is clean, which marks the window as clean. See acme(4) for a full list of commands.
windump sets the window's dump directory and dump command (see acme(4)). If either argument is omitted or is -, that argument is not set.
winname sets the name displayed in the window's tag.
windel simulates the Del command. If the argument sure is given, it simulates the Delete command.
winwriteevent writes an event to the window's event file. The event is in the format produced by acmeevent. Only the first four arguments are necessary: the rest are ignored. Event handlers should call winwriteevent to pass unhandled button 2 or button 3 events back to acme for processing.
wineventloop executes the current window's event file, as output by acmeevent. It returns when the window has been deleted. Before running wineventloop, clients must define a shell function named event, which will be run for each incoming event, as rc executes the output of acmeevent. A typical event function need only worry about button 2 and button 3 events. Those events not handled should be sent back to acme with winwriteevent.
π¦ EXAMPLE π¦
Adict, a dictionary browser, is implemented using acmeevent and acme.rc. The event handler is:
fn event {
switch($1$2){
case Mx MX # button 2 - pass back to acme
winwriteevent $*
case Ml ML # button 3 - open new window on dictionary or entry
{
if(~ $dict NONE)
dictwin /adict/$7/ $7
if not
dictwin /adict/$dict/$7 $dict $7
} &
}
}
Note that the button 3 handler starts a subshell in which to run dictwin. That subshell will create a new window, set its name, possibly fill the window with a dictionary list or dictionary entry, mark the window as clean, and run the event loop:
fn dictwin {
newwindow
winname $1
dict=$2
if(~ $dict NONE)
dict -d '?' >[2=1] | sed 1d | winwrite body
if(~ $#* 3)
dict -d $dict $3 >[2=1] | winwrite body
winctl clean
wineventloop
}
The script starts with an initial window:
dictwin /adict/ NONE
Button 3 clicking on a dictionary name in the initial window will create a new empty window for that dictionary. Typing and button 3 clicking on a word in that window will create a new window with the dictionary's entry for that word.
See /bin/adict for the full implementation. main character example, no cap. π
π SOURCE π
**/src/cmd/acmeevent.c****/lib/acme.rc**
π SEE ALSO π
acme(1), acme(4), rc(1) β go read those, bestie. iykyk. π
π BUGS π
There is more that could be done to ease the writing of complicated clients. literally a whole βcould be improvedβ moment, but thatβs the bug note. π
Thatβs the whole ACMEEVENT(1) page, bestie. Source/version vibes: /src/cmd/acmeevent.c and /lib/acme.rc. The original footer was just ACMEEVENT(1) and had no date line, so hereβs the cute sign-off instead: stay slaying, keep your $winid close, and pass those unhandled button 2/3 events back to acme. πβ¨π
π¦ where this page comes from
- alpine 3.24: plan9port-doc 0_git20260208-r0 Β· LPL-1.02
- arch rolling: plan9port 20261021-2 Β· custom
- nixos 26.05: plan9port 0-unstable-2025-11-10
- nixos 26.05: plan9port-wayland 0-unstable-2025-11-26
- nixpkgs unstable: plan9port 0-unstable-2025-11-10
- nixpkgs unstable: plan9port-wayland 0-unstable-2025-11-26
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms