ACMEEVENT(1)                                         ACMEEVENT(1)

     NAME
          acmeevent, acme.rc - shell script support for acme clients

     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
          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

     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.

     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)

     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 /bin/adict for the full implementation.

     SOURCE
          /src/cmd/acmeevent.c
          /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.