E.3 Reading from the server

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> 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 ($).