2015-11-28 Fixing mml-attach-file using advice

I use mu4e as my MUA, and I’m quite happy with it. (I toyed with the idea of setting up Gnus, but I can’t afford quitting my job to find the time for that;-).) However, one thing with the message mode (which mu4e uses) did annoy me a lot: the attachments. I really didn’t like having my attachments after the signature, since I have a signature changing function which (as part of its operation) deletes everything from the sigdashes up to the end of buffer.

It turned out, I was wrong: having the attachments anywhere but at the end of buffer is asking for trouble. Read this thread for the explanation why. This means that I had to change my functions (which was not really that hard anyway). But now I had another problem: how to avoid putting the attachment in the message body? In message mode, when I press C-c C-a (mml-attach-file), the attachment is put at point (unless it’s in the header).

Advice to the rescue. Advising functions is quite a powerful concept. The idea is that you can take any Elisp function and “add” a piece of code to be executed before, or after, or instead of that function. Basically that means changing the functionality of a function without actually modifying it. And it especially nice that you can put a few pieces of advice on a single function, and turn them on or off independently.

Before you go and advise your functions like crazy, be warned that it is not always a good idea. The manual mentions a few situations when advising is dangerous. An extreme case is primitive functions: while you can advise them, you should never do it. Check the manual to learn why. Also, advising might lead to unexpected behavior simply because you may not know about it or expect it.

In this case, however, I do not expect any problems. The idea is to arrange so that the point is at the end of the buffer when mml-attach-file does its job, and restore the state afterwards. (Restoring the state is easy, you just use the save-... macros.) So, here’s the code.

(defun mml-attach-file--go-to-eob (orig-fun &rest args)
  "Go to the end of buffer before attaching files."
  (save-excursion
    (save-restriction
      (widen)
      (goto-char (point-max))
      (apply orig-fun args))))

(advice-add 'mml-attach-file :around #'mml-attach-file--go-to-eob)

And that’s pretty much it. The function mml-attach-file–go-to-eob is simple; the only point of interest is that it gets the original function as the first argument and its arguments as the rest, so (apply orig-fun args) does the bulk of the job; both save-... forms ensure that the point position and the narrowing will be restored. Look up the manual to check other possible arguments to advice-add (:around is the most general, there are more possibilities, like :before or :after, which are less powerful, but simpler to use).

Happy attaching;-)!

CategoryEnglish, CategoryBlog, CategoryEmacs