ACMEEVENT(1) ACMEEVENT(1)
NAME
acmeevent, acme.rc - shell script support for acme clients
SYNOPSIS
9p read acme/acme/$winid/event | acmeevent
. /usr/local/plan9/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
Acmeevent and acme.rc make it easy to write simple acme(1)
client programs as shell scripts.
Acme clients read the event files (see acme(4)) for the win-
dows 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.
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
Page 1 Plan 9 (printed 11/3/25)
ACMEEVENT(1) ACMEEVENT(1)
mouse (M).
c2 A character indicating the type of action. The possi-
ble 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 but-
ton 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 by q0, q1 is a null string that has a
non-null expansion, eq0, eq1 are the addresses of the
expansion. Otherwise they are the same as q0, q1.
flag Flag is a bitwise OR (reported decimally) of the fol-
lowing: 1 if the text indicated is recognized as an
acme built-in command; 2 if the text indicated is a
null string that has a non-null expansion (see eq0, eq1
above); 8 if the command has an extra (chorded) argu-
ment (see chordarg below). Flag remains from the
acme(4) event format. Because eq0, eq1, and chordarg
are explicit in each event (unlike in acme(4) events),
flag can usually be ignored.
textlen
The length of the action text (or its expansion) for
button 2 and button 3 events in characters.
text If textlen is less than 256 chracters, text is 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,
chordorigin specifies 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.
Page 2 Plan 9 (printed 11/3/25)
ACMEEVENT(1) ACMEEVENT(1)
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)
Page 3 Plan 9 (printed 11/3/25)
ACMEEVENT(1) ACMEEVENT(1)
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 /usr/local/plan9/bin/adict for the full implementation.
SOURCE
/usr/local/plan9/src/cmd/acmeevent.c
/usr/local/plan9/lib/acme.rc
SEE ALSO
acme(1), acme(4), rc(1)
BUGS
There is more that could be done to ease the writing of com-
plicated clients.
Page 4 Plan 9 (printed 11/3/25)