In the design, the next question was what format mu should use for its
output for mu4e (Emacs) to process. Some other programs use JSON
here, but it seemed easier (and possibly, more efficient) just to talk to Emacs
in its native language: s-expressions, and interpret those using the
Emacs-function read-from-string. See The message s-expression for
details on the format.
So, now let’s look at how we process the data from mu server in Emacs. We’ll
leave out a lot of details, mu4e-specifics, and look at a bit more
generic approach.
The first thing to do is to create a process (for example, with
start-process), and then register a filter function for it, which is
invoked whenever the process has some data for us. Something like:
(let ((proc (start-process <arguments>)))
(set-process-filter proc 'my-process-filter)
(set-process-sentinel proc 'my-process-sentinel))
Note, the process sentinel is invoked when the process is terminated
— so there you can clean things up. The function
my-process-filter is a user-defined function that takes the
process and the chunk of output as arguments; in mu4e it looks
something like (pseudo-lisp):
(defun my-process-filter (proc str)
;; mu4e-buf: a global string variable to which data gets appended
;; as we receive it
(setq mu4e-buf (concat mu4e-buf str))
(when <we-have-received-a-full-expression>
<eat-expression-from mu4e-buf>
<evaluate-expression>))
<evaluate-expression> de-multiplexes the s-expression we got.
For example, if the s-expression looks like an e-mail message header,
it is processed by the header-handling function, which appends it to
the header list. If the s-expression looks like an error message, it
is reported to the user. And so on.
The language between frontend and backend is documented partly in the
mu-server man-page and more completely in the output of mu
server --commands.
mu4e can log these communications; you can use M-x
mu4e-toggle-logging to turn logging on and off, and you can view the
log using M-x mu4e-show-log ($).