-<!-- -*- mode: text; indent-tabs-mode: nil -*- -->
+# Tips and Tricks for using notmuch with Emacs
-[[!img notmuch-logo.png alt="Notmuch logo" class="left"]]
-#Tips and Tricks for using notmuch with Emacs
+One of the more popular notmuch message reading clients is
+**notmuch.el**, an [emacs](http://www.gnu.org/software/emacs/) major
+mode for interacting with notmuch. It is included in the notmuch
+package. This page goes over some usage tips for using notmuch with
+Emacs.
[[!toc levels=2]]
-The main Notmuch message reading client is **notmuch.el**, which is an
-[emacs](http://www.gnu.org/software/emacs/) major mode, and is
-included in the notmuch package.
-
## Setup
To use the Notmuch emacs mode, first add the following line to your
#!/bin/sh
attach_cmds=""
while [ "$1" ]; do
- fullpath=$(readlink --canonicalize $1)
+ fullpath=$(readlink --canonicalize "$1")
attach_cmds="$attach_cmds (mml-attach-file \"$fullpath\")"
shift
done
loaded when `notmuch` is invoked). To do this, write, for example
a file called `~/.emacs.d/my-notmuch.el`:
- ;; my-notmuch.el -- my notmuch mail configuration
- ;;
+ ;;; my-notmuch.el -- my notmuch mail configuration
+ ;;;
- ;; add here stuff required to be configured *before*
- ;; notmuch is loaded;
+ ;;; add here stuff required to be configured *before*
+ ;;; notmuch is loaded;
- ; uncomment and modify in case some elisp files are not found in load-path
- ; (add-to-list 'load-path "~/vc/ext/notmuch/emacs")
+ ;; uncomment and modify in case some elisp files are not found in load-path
+ ;; (add-to-list 'load-path "~/vc/ext/notmuch/emacs")
- ;; load notmuch
+ ;;; load notmuch
(require 'notmuch)
- ;; add here stuff required to be configured *after*
- ;; notmuch is loaded;
-
- ;(setq user-mail-address (notmuch-user-primary-email)
- ; user-full-name (notmuch-user-name))
+ ;;; add here stuff required to be configured *after*
+ ;;; notmuch is loaded;
- ; uncomment & modify if you want to use external smtp server to send mail
- ; (setq smtpmail-smtp-server "smtp.server.tld"
- ; message-send-mail-function 'message-smtpmail-send-it)
+ ;; uncomment & modify if you want to use external smtp server to send mail
+ ;; (setq smtpmail-smtp-server "smtp.server.tld"
+ ;; message-send-mail-function 'message-smtpmail-send-it)
+ ;; uncomment to debug smtp sending problems
+ ;; (setq smtpmail-debug-info t)
-Then, adto `.emacs`:
+Then, add to `.emacs`:
(autoload 'notmuch "~/.emacs.d/my-notmuch" "notmuch mail" t)
(notmuch-show-add-tag "spam")
(notmuch-show-remove-tag "inbox")))
-Starting from notmuch 0.12 (not released yet) the functions
-`notmuch-show-add-tag` and `notmuch-show-remove-tag` have changed to
-be more versatile and lost noninteractive use. When upgrading to 0.12
-the above needs to be changed to this:
+Starting from notmuch 0.12 the functions `notmuch-show-add-tag` and
+`notmuch-show-remove-tag` have changed to be more versatile and lost
+noninteractive use. When upgrading to 0.12 the above needs to be
+changed to this:
(define-key notmuch-show-mode-map "S"
(lambda ()
You can do the same for threads in `notmuch-search-mode` by just
replacing "show" with "search" in the called functions.
-(Starting from notmuch 0.12 use `notmuch-search-tag-thread` instead)
+Starting from notmuch 0.12 use `notmuch-search-tag-thread` instead:
+
+ (define-key notmuch-search-mode-map "S"
+ (lambda ()
+ "mark messages in thread as spam"
+ (interactive)
+ (notmuch-show-tag-thread "+spam" "-inbox")))
+
+Starting from notmuch 0.13 use `notmuch-search-tag` -- it has a little
+different usage syntax:
+
+ (define-key notmuch-search-mode-map "S"
+ (lambda ()
+ "mark messages in thread as spam"
+ (interactive)
+ (notmuch-search-tag '("+spam" "-inbox"))))
The definition above makes use of a lambda function, but you could
also define a separate function first:
- (defun notmuch-show-tag-spam()
+ (defun notmuch-show-tag-spam ()
"mark message as spam"
(interactive)
(notmuch-show-add-tag "spam")
(notmuch-show-remove-tag "deleted")
(notmuch-show-add-tag "deleted"))))
-And version for notmuch 0.12 (not released yet)
+And version for notmuch 0.12
(define-key notmuch-show-mode-map "d"
(lambda ()
"toggle deleted tag for message"
(interactive)
(notmuch-show-tag-message
- (if (member "deleted" (notmuch-show-get-tags)
- "+deleted" "-deleted")))))
+ (if (member "deleted" (notmuch-show-get-tags))
+ "-deleted" "+deleted"))))
+
+## Adding many tagging keybindings
+
+If you want to have have many tagging keybindings, you can save the typing
+the few lines of boilerplate for every binding (for versions before 0.12,
+you will need to change notmuch-show-apply-tag-macro).
+
+ (eval-after-load 'notmuch-show
+ '(define-key notmuch-show-mode-map "`" 'notmuch-show-apply-tag-macro))
+
+ (setq notmuch-show-tag-macro-alist
+ (list
+ '("m" "+notmuch::patch" "+notmuch::moreinfo" "-notmuch::needs-review")
+ '("n" "+notmuch::patch" "+notmuch::needs-review" "-notmuch::pushed")
+ '("o" "+notmuch::patch" "+notmuch::obsolete"
+ "-notmuch::needs-review" "-notmuch::moreinfo")
+ '("p" "-notmuch::pushed" "-notmuch::needs-review"
+ "-notmuch::moreinfo" "+pending")
+ '("P" "-pending" "-notmuch::needs-review" "-notmuch::moreinfo" "+notmuch::pushed")
+ '("r" "-notmuch::patch" "+notmuch::review")
+ '("s" "+notmuch::patch" "-notmuch::obsolete" "-notmuch::needs-review" "-notmuch::moreinfo" "+notmuch::stale")
+ '("t" "+notmuch::patch" "-notmuch::needs-review" "+notmuch::trivial")
+ '("w" "+notmuch::patch" "+notmuch::wip" "-notmuch::needs-review")))
+
+ (defun notmuch-show-apply-tag-macro (key)
+ (interactive "k")
+ (let ((macro (assoc key notmuch-show-tag-macro-alist)))
+ (apply 'notmuch-show-tag-message (cdr macro))))
## Restore reply-to-all key binding to 'r'
## <span id="address_completion">Address completion when composing</span>
-There are currently two solutions to this:
+There are currently three solutions to this:
+
+### bbdb
[bbdb](http://bbdb.sourceforge.net) is a contact database for emacs
that works quite nicely together with message mode, including
address autocompletion.
+### notmuch database as an address book
+
You can also use the notmuch database as a mail address book itself.
To do this you need a command line tool that outputs likely address
candidates based on a search string. There are currently three
* Shell/fgrep/perl combination [nottoomuch-addresses.sh](http://www.iki.fi/too/nottoomuch/nottoomuch-addresses/).
This tools maintains it's own address "database" gathered from email
- files notmuch knows and search from that "database" is done by fgrep(1).
+ files notmuch knows and search from that "database" is done by `fgrep(1)`.
-You can perform tab-completion using any of these programs. Just add the following to your .emacs:
+You can perform tab-completion using any of these programs.
+Just add the following to your .emacs:
(require 'notmuch-address)
(setq notmuch-address-command "/path/to/address_fetching_program")
(notmuch-address-message-insinuate)
+### Google Contacts
+
+[GooBook](http://code.google.com/p/goobook/) is a command-line tool for
+accessing Google Contacts. Install and set it up according to its documentation.
+
+To use GooBook with notmuch, use this wrapper script and set it up like the
+programs above.
+
+ #!/bin/sh
+ goobook query "$*" | sed 's/\(.*\)\t\(.*\)\t.*/\2 \<\1\>/' | sed '/^$/d'
+
+You can add the sender of a message to Google Contacts by piping the message
+(`notmuch-show-pipe-message`) to `goobook add`.
## How to sign/encrypt messages with gpg
-Messages can by signed using gpg by invoking `M-x
-mml-secure-sign-pgpmime` (or `M-x
-mml-secure-encrypt-pgpmime`). These functions are available via the
-standard `message-mode` keybindings `C-c C-m s p` and `C-c C-m c
-p`. To sign outgoing mail by default, use the `message-setup-hook`
-in your `.emacs` file:
+Messages can by signed using gpg by invoking
+`M-x mml-secure-sign-pgpmime` (or `M-x mml-secure-encrypt-pgpmime`).
+These functions are available via the standard `message-mode` keybindings
+`C-c C-m s p` and `C-c C-m c p`. To sign outgoing mail by default, use the
+`message-setup-hook` in your `.emacs` file:
;; Sign messages by default.
(add-hook 'message-setup-hook 'mml-secure-sign-pgpmime)
### Troubleshooting message-mode gpg support
-- If you have trouble with expired subkeys, you may have encounted
+- If you have trouble with expired subkeys, you may have encountered
emacs bug #7931. This is fixed in git commit 301ea744c on
2011-02-02. Note that if you have the Debian package easypg
installed, it will shadow the fixed version of easypg included with
emacs.
+
+## Multiple identities using gnus-alias
+
+[gnus-alias](http://www.emacswiki.org/emacs/GnusAlias) allows you to
+define multiple identities when using `message-mode`. You can specify
+the from address, organization, extra headers (including *Bcc*), extra
+body text, and signature for each identity. Identities are chosen
+based on a set of rules. When you are in message mode, you can switch
+identities using gnus-alias.
+
+### Installation
+
+- put `gnus-alias.el` on your load Emacs-Lisp load path (add new directory
+ to load path by writing `(add-to-list 'load-path "/some/load/path")` into
+ your `.emacs`.
+
+- Add the following to your `.emacs`
+
+ (autoload 'gnus-alias-determine-identity "gnus-alias" "" t)
+ (add-hook 'message-setup-hook 'gnus-alias-determine-identity)
+
+Looking into `gnus-alias.el` gives a bit more information...
+
+### Example Configuration
+
+Here is an example configuration.
+
+ ;; Define two identities, "home" and "work"
+ (setq gnus-alias-identity-alist
+ '(("home"
+ nil ;; Does not refer to any other identity
+ "John Doe <jdoe@example.net>" ;; Sender address
+ nil ;; No organization header
+ nil ;; No extra headers
+ nil ;; No extra body text
+ "~/.signature")
+ ("work"
+ nil
+ "John Doe <john.doe@example.com>"
+ "Example Corp."
+ (("Bcc" . "john.doe@example.com"))
+ nil
+ "~/.signature.work")))
+ ;; Use "home" identity by default
+ (setq gnus-alias-default-identity "home")
+ ;; Define rules to match work identity
+ (setq gnus-alias-identity-rules
+ '(("work" ("any" "john.doe@\\(example\\.com\\|help\\.example.com\\)" both) "work"))
+ ;; Determine identity when message-mode loads
+ (add-hook 'message-setup-hook 'gnus-alias-determine-identity)
+
+When `gnus-alias` has been loaded (using autoload, require, *M-x load-library*
+or *M-x load-file* (load-file takes file path -- therefore it can be used
+without any `.emacs` changes)) the following commands can be used to get(/set)
+more information (some of these have "extensive documentation"):
+
+ M-x describe-variable RET gnus-alias-identity-alist
+ M-x describe-variable RET gnus-alias-identity-rules
+ M-x describe-variable RET gnus-alias-default-identity
+
+ M-x customize-group RET gnus-alias RET
+ or
+ M-x gnus-alias-customize RET
+
+The last two do the same thing.
+
+See also the **Usage:** section in `gnus-alias.el`.