2009-09-19

wanderlust tips and tricks

Earlier, I spoke of the wonderful Wanderlust e-mail client. After years of using mutt, I am a quite happy Wanderlust-user now. Now, it's few months since my conversion, time to discuss some of the customizations I did. Not all the defaults are so well-chosen (in my opinion), but fortunately, the package is very configurable.

If you are interested in Wanderlust, this entry might save you some time in figuring out such customizations and some other tricks. If you haven't done so before, I'd recommend you to read the older entry first. Also, the entry about BBDB may be useful.

Before going into the customizations, let me first answer a question I got asked a couple of times: why I am using Wanderlust and not, say, VM, gnus, Mew or even mutt or some other client?

To start with the last part, an emacs-based client fits in very well with my workflow, which is (duh) revolves around emacs. Doing my email there as well makes a lot of sense - a little return-on-investment for the time spent taming emacs and its bag of tricks.

The reason I particularly like Wanderlust, is that it works very well with mail stored in maildirs - as you may know, maildir is a one-file-per-message way of storing your mail on disk. That's great for backing up things, and sync'ing different machines.

Unlike VM and gnus, Wanderlust keeps the mail in the maildir as-is, and does not use a separate spoolfile – thus, all changes are reflected in the maildir itself, making it possible to use different clients (ie., use mutt when needed). Even more important, the wonderful tool offlineimap does two-way synchronization with IMAP-servers, and downloads everything into a maildir. So, I can download all the mail on my laptop machine, go offline and work on the messages (delete, move, reply etc.) during a flight, and when I'm back online, I can synchronize things. All this 'cloud'-stuff is nice, but I like to have my mails on my side of the intertubes.

Ok, now let's take a look at some of the customizations and tricks. All of these are little snippets to add to your ~/.wl-file.

Forwarded mails should use 'Fwd:', not 'Forward:'

I wonder why this is not the default.

(setq
  wl-forward-subject-prefix "Fwd: " )    ;; use "Fwd: " not "Forward: "

Reply-to-all should not be the default

By default, Wanderlust uses Reply-to-All; that is usually not what we (well, I) want. The code below makes Reply-to-Sender the default, with Reply-to-All behind C-u; ie. A or a will reply to sender, C-u A and C-u a reply to all.

(Note, the uppercase A is for replying with quoting the original message, while the lowercase version starts the reply with an empty message)

;; from a WL-mailinglist post by David Bremner

;; Invert behaviour of with and without argument replies.
;; just the author
(setq wl-draft-reply-without-argument-list
  '(("Reply-To" ("Reply-To") nil nil)
     ("Mail-Reply-To" ("Mail-Reply-To") nil nil)
     ("From" ("From") nil nil)))


;; bombard the world
(setq wl-draft-reply-with-argument-list
  '(("Followup-To" nil nil ("Followup-To"))
     ("Mail-Followup-To" ("Mail-Followup-To") nil ("Newsgroups"))
     ("Reply-To" ("Reply-To") ("To" "Cc" "From") ("Newsgroups"))
     ("From" ("From") ("To" "Cc") ("Newsgroups"))))

Setting up spam-handling

If you're using spamassassin for spamfiltering, you can quite easily integrate it with Wanderlust:

(require 'wl-spam)
(wl-spam-setup)
(setq elmo-spam-scheme 'sa)   ;; sa for spamassassin, see the elmo-spam-scheme
                              ;; docs for alternatives
(setq wl-spam-folder ".spam") ;; maildir to store spam

After this, you quite easily handle spam in the 'Summary' with some keybindings:

  • k C : check whether spamassassin considers this message 'spam'
  • k m : mark message(s) as spam (move to spam folder)
  • k n : learn this message is 'ham'
  • k s : learn this message is 'spam'

Note, there are some hooks for other spamfiltering solutions as well.

How to easily refile messages

I receive all my messages in only two mailboxes: one for personal mail, and one for mailing lists. If, after reading, I want to keep the message, I'll refile it to some other folder (after all, it's good to empty your mailboxes quite often. Wanderlust makes this refiling quite easy; the first way is to do it semi-automatic, i.e., let Wanderlust 'guess' the folder for you, based on the contents of the message. Then, when pressing 'o' in the summary, it will suggest this folder, and you can refile (move) the message. You can set up this 'guessing' something like this:

(setq
  ;; refile rules determine the default where mails are put

  ;; when you mark them for refiling ('o'); cfg. save-hooks in mutt
   wl-refile-rule-alist  
  '(
     ("Subject" ;; put more specific rules before more general ones.
       ("emacs"   . ".emacs")   ;; emacs-related mail

       ("running" . ".running") ;; running-related mail
       )
     
     (("To" "Cc" "Delivered-To") 
       ("myself@company.com"      . ".workmail") 
       ("myself@home.com"         . ".privatemail"))
     
     (("Precedence" "Priority")
       ("bulk\|1\|2\|list"       . ".bulkmail"))))

Explicit refiling

Semi-automatic refiling works fairly well, but you might also want to have some explicit shortcuts to move messages to specific folders. For example, to move message from your inbox to your Project X-folder, or your Project Y-folder.

(defun djcb-wl-summary-refile (&optional folder)
  "refile the current message to FOLDER; if FOLDER is nil, use the default"
  (interactive)
  (wl-summary-refile (wl-summary-message-number) folder)
  (wl-summary-next)
  (message (concat "refiled to " folder)))

(define-key wl-summary-mode-map (kbd "b x") ;; => Project X

  '(lambda()(interactive)(djcb-wl-summary-refile ".project-x"))) 
(define-key wl-summary-mode-map (kbd "b y") ;; => Project Y
  '(lambda()(interactive)(djcb-wl-summary-refile ".project-y")))

Assuming you have (Maildir) folders project-x and project-y.

Check outgoing mail

It's not uncommon to forget to add a subject or an attachment when you send a mail (or at least, when I send a mail…). However, using wl-mail-send-pre-hook we can let Wanderlust warn us when something like that happens.

;; suggested by Masaru Nomiya on the WL mailing list

(defun djcb-wl-draft-subject-check ()
  "check whether the message has a subject before sending"
  (if (and (< (length (std11-field-body "Subject")) 1)
        (null (y-or-n-p "No subject! Send current draft?")))
      (error "Abort.")))


;; note, this check could cause some false positives; anyway, better
;; safe than sorry...
(defun djcb-wl-draft-attachment-check ()
  "if attachment is mention but none included, warn the the user"
  (save-excursion
    (goto-char 0)
    (unless ;; don't we have an attachment?

      (re-search-forward "^Content-Disposition: attachment" nil t) 
     (when ;; no attachment; did we mention an attachment?
        (re-search-forward "attach" nil t)
        (unless (y-or-n-p "Possibly missing an attachment. Send current draft?")
          (error "Abort."))))))

(add-hook 'wl-mail-send-pre-hook 'djcb-wl-draft-subject-check)
(add-hook 'wl-mail-send-pre-hook 'djcb-wl-draft-attachment-check)

Ok, that's all for now… I'll get back to Wanderlust in the future; of course, feel free to add your own tricks in the comments-section.

19 comments:

Jeff Kowalczyk said...

Thanks for these wanderlust tips. I'm interested in it over GNUS for the same reasons (maildir). Would be interested in hearing about org-mode integrations if you have any.

Do you happen to know how to set the wanderlust init file location? I want to keep it in my git repository .emacs.d.

djcb said...

@Jeff:

org-mode does support Wanderlust (see the org-mode manual) -- you can have links to folders / mails etc.

about the init file:
(setq wl-init-file "~/.emacs.d/wl.el")

good luck with setting things up :)

tom said...

Thanks for the info, the wanderlust looks very interesting. Do you know how to get it for mac os? The ftp site needs password. Any (other) hind or help appreciated!

Ashish SHUKLA said...

It it still not clear to my why use WL over Gnus ? I'm using Gnus with Maildirs since 2 years using fetchmail for fetching mails and postfix (in smarthost mode) for sending mails via a SMTP relay. I don't use any mbox mailspool file. It works awesome, I use mutt and kmail also with the same mailboxen. Although read/unread/flags on mails aren't preserved.

djcb said...

@tom: some of the mirrors work, and you can get the latest (beta) version:
http://www.jpl.org/elips/wl/snapshots/; you'll also need the dependencies (apel, flim and semi). Carbon-emacs might even ship Wanderlust. Good luck!

@Wah Java: well, it never worked well for me -- and you basically answer your own question in the last sentence :-)

Matt said...

@Wah Java

Compared to mutt and wanderlust, Gnus maildir implementation is notoriously bad. Nnmaildir creates two files for each mail --- which IMO is quite wasteful. And, as you mentioned, it uses unconventional marks.

Gnus works best if you're willing to take the plunge and use its modified mh (nnml) or mbox (nnfolder) formats. For synchronized/easily shared formats, it is subpar IMO.

Tracy Reed said...

I have been wanting something better than mutt for a while but it always seemed to me that wanderlust was no longer being developed/maintained. Is this not the case? The wanderlust website says:

Last modified: Sat, 26 Mar 2005 00:13:47 JST

djcb said...

@Tracy Reed: there is in fact some effort underway to update the website, and there are snapshots available of fairly recent date. Wanderlust could use some fresh energy (and hopefully my postings are part of that), but the project is alive.

Tracy Reed said...

Ok, I am going to give wanderlust a try. I am also in #wanderlust on freenode if anyone would like to join in. #mutt has 94 people in it. Hopefully wanderlust can develop such a large community.

Anonymous said...

Nice post I must try wanderlust. I use offlineimap to synchronize my local maildirs with several remote imap accounts. As mailreader I use mutt, I try gnus via local imapserver (dovecot) but that config not satisfy me. I like mutt, slrn and newsbeuter but when I start they via ansi-term from emacs dont work very well (my subjective opinion). I search native emacs replacements for that applications and I think wanderlust maybe this one for mutt.

Greg B said...

I've been using Wanderlust for quite some time now, and it is great. But there are two things I could never figure out, perhaps you have:

- When you send an email, it shows up as unread mail in the Sent folder; similarly, when I delete an email from the Inbox, it shows up as unread in Trash. But a message I just wrote/deleted should not be set to unread.

- I could never figure out attachments. If you send a large file, wanderlust (or whatever it hands it over to) cuts it into many messages and sends it in pieces. Standard mailreaders at the other end, however, don't merge these messages. Well, perhaps this is not wanderlust's fault, but I have to drop into Evolution to send attachments.

djcb said...

@Greg B: (setq wl-fcc-force-as-read t) may help for the first problem; I never
had issues with the second

Greg B said...

(setq wl-fcc-force-as-read t) never worked for me, and I haven't been able to figure out why.

Erik Hetzner said...

Hi Greg B - If you're still listening, check this snippet for fixing your attachment problem:

;; don't ****ing split large messages
(setq mime-edit-split-message nil)

Greg B said...

Yes, I am listening -- this is one of the blogs I often return to. Thanks for the trip, I've found it meanwhile... but still no solution to the other problem.

Anonymous said...

Seems like pretty awesome client.

However it doesn't display attached images correctly for some reason.

Could you post your entire wl.el somewhere - to make sure that it's bug not in my conf but somewhere else.

djcb said...

@Anonymous: will do that at some point, but it will need some cleanup first..

chandan said...

I tried to use GNUS. But it failed miserably when handling large Maildirs (consider 37000 mails for the linux-kernel mailing list). Does Wanderlust perform any better? If yes, I would want to move to it.

just-tim said...

Thank you very much for your posts on wl. I have never liked my gnus workflow, and wl solves all of those problems.
I have installed offlineimap, wl and have done the customizations you proposed.

My question is; do you have an automated process to sync wl and offlineimap at the same time ? possibly using the offlineimap.el package ?