-[[!img notmuch-logo.png alt="Notmuch logo" class="left"]]
-#Tips and Tricks for using notmuch with Emacs
+# Tips and Tricks for using notmuch with Emacs
-[[!toc levels=2]]
+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 (notmuch-emacs in Debian). This page goes over some usage
+tips for using notmuch with Emacs.
-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.
+[[!toc levels=2]]
## Setup
+Have a look at the [Howto](http://notmuchmail.org/howto/) for
+prerequisites. Be sure you have done the general setup using the
+notmuch cli command!
+
To use the Notmuch emacs mode, first add the following line to your
`.emacs` rc file:
- (require 'notmuch)
+ (require 'notmuch)
+
+or you can load the package via autoload:
+
+ (autoload 'notmuch "notmuch" "notmuch mail" t)
Then, either run "emacs -f notmuch", or execute the command `M-x
notmuch` from within a running emacs.
## Navigating & reading mails
When first starting notmuch in emacs, you will be presented with the
-notmuch "hello" page. From here you can do searches, see lists of
-recent searches, saved searches, message tags, help information, etc.
+notmuch "hello" page. If it exits with an error after writing
+"Welcome to notmutch. You have" you need to do the basic notmuch setup
+first (see above).
+From here you can do searches, see lists of recent
+searches, saved searches, message tags, help information, etc.
Executing a search will open a new buffer in `notmuch-search-mode`
displaying the search results. Each line in the search results
mentioned as script arguments. (Note: The script expects that you have
`(server-start)` in your `.emacs` file.)
- #!/bin/sh
- attach_cmds=""
- while [ "$1" ]; do
- fullpath=$(readlink --canonicalize $1)
- attach_cmds="$attach_cmds (mml-attach-file \"$fullpath\")"
- shift
- done
- emacsclient -a '' -c -e "(progn (compose-mail) $attach_cmds)"
+ #!/bin/sh
+ attach_cmds=""
+ while [ "$1" ]; do
+ fullpath=$(readlink --canonicalize "$1")
+ attach_cmds="$attach_cmds (mml-attach-file \"$fullpath\")"
+ shift
+ done
+ emacsclient -a '' -c -e "(progn (compose-mail) $attach_cmds)"
+
+## Issues with Emacs 24
+
+If notmuch-show-mode behaves badly for you in emacs 24.x try adding one of
+
+ (setq gnus-inhibit-images nil)
+
+or
+
+ (require 'gnus-art)
+to your .emacs file.
-----
# Advanced tips and tweaks
+## Use separate emacs lisp file for notmuch configuration
+
+Instead of adding notmuch configuration code to `.emacs`, there
+is an option to collect those to a separate file (which is only
+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
+ ;;;
+
+ ;;; 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")
+
+ ;;; load notmuch
+ (require 'notmuch)
+
+ ;;; 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 to debug smtp sending problems
+ ;; (setq smtpmail-debug-info t)
+
+Then, add to `.emacs`:
+
+ (autoload 'notmuch "~/.emacs.d/my-notmuch" "notmuch mail" t)
+
+## Initial cursor position in notmuch 0.15 hello window
+
+In notmuch version 0.15 emacs client the handling of cursor position in
+notmuch hello window has been simplified to a version which suits best
+most cases.
+
+Initially the cursor is positioned at the beginning of buffer.
+
+Some users liked the "ancient" version where cursor was moved to the
+first `Saved searches` button.
+
+Add the following code to your notmuch emacs configuration file in
+case you want this behaviour:
+
+ (add-hook 'notmuch-hello-refresh-hook
+ (lambda ()
+ (if (and (eq (point) (point-min))
+ (search-forward "Saved searches:" nil t))
+ (progn
+ (forward-line)
+ (widget-forward 1))
+ (if (eq (widget-type (widget-at)) 'editable-field)
+ (beginning-of-line)))))
+
## Add a key binding to add/remove/toggle a tag
The `notmuch-{search,show}-{add,remove}-tag` functions are very useful
of how to make a key binding to add the "spam" tag and remove the
"inbox" tag in notmuch-show-mode:
- (define-key notmuch-show-mode-map "S"
- (lambda ()
- "mark message as spam"
- (interactive)
- (notmuch-show-add-tag "spam")
- (notmuch-show-remove-tag "inbox")))
+In notmuch versions up to 0.11.x
+
+ (define-key notmuch-show-mode-map "S"
+ (lambda ()
+ "mark message as spam"
+ (interactive)
+ (notmuch-show-add-tag "spam")
+ (notmuch-show-remove-tag "inbox")))
+
+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 ()
+ "mark message as spam"
+ (interactive)
+ (notmuch-show-tag-message "+spam" "-inbox")))
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:
+
+ (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()
- "mark message as spam"
- (interactive)
- (notmuch-show-add-tag "spam")
- (notmuch-show-remove-tag "inbox")))
- (define-key notmuch-show-mode-map "S" 'notmuch-show-tag-spam)
+ (defun notmuch-show-tag-spam ()
+ "mark message as spam"
+ (interactive)
+ (notmuch-show-add-tag "spam")
+ (notmuch-show-remove-tag "inbox")))
+ (define-key notmuch-show-mode-map "S" 'notmuch-show-tag-spam)
+
+(See above for analogy how to apply this for notmuch 0.12 and later)
Here's a more complicated example of how to add a toggle "deleted"
key:
- (define-key notmuch-show-mode-map "d"
- (lambda ()
- "toggle deleted tag for message"
- (interactive)
- (if (member "deleted" (notmuch-show-get-tags))
- (notmuch-show-remove-tag "deleted")
- (notmuch-show-add-tag "deleted"))))
+ (define-key notmuch-show-mode-map "d"
+ (lambda ()
+ "toggle deleted tag for message"
+ (interactive)
+ (if (member "deleted" (notmuch-show-get-tags))
+ (notmuch-show-remove-tag "deleted")
+ (notmuch-show-add-tag "deleted"))))
+
+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"))))
+
+## 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'
+
+Starting from notmuch 0.12 the 'r' key is bound to reply-to-sender instead of
+reply-to-all. Here's how to swap the reply to sender/all bindings in show mode:
+
+ (define-key notmuch-show-mode-map "r" 'notmuch-show-reply)
+ (define-key notmuch-show-mode-map "R" 'notmuch-show-reply-sender)
+
+And in search mode:
+
+ (define-key notmuch-search-mode-map "r" 'notmuch-search-reply-to-thread)
+ (define-key notmuch-search-mode-map "R" 'notmuch-search-reply-to-thread-sender)
+
## How to do FCC/BCC...
The Emacs interface to notmuch will automatically add an `Fcc`
header to your outgoing mail so that any messages you send will also
be saved in your mail store. You can control where this copy of the
-message is saved by setting the variables `message-directory` (which
-defines a base directory) and `notmuch-fcc-dirs` which defines the
-subdirectory relative to `message-directory` in which to save the
-mail. Enter a directory (without the maildir `/cur` ending which
-will be appended automatically). To customize both variables at the
-same time, use the fancy command:
+message is saved by setting the variable `notmuch-fcc-dirs` which defines the
+subdirectory relative to the `database.path` setting from your
+notmuch configuration in which to save the mail. Enter a directory
+(without the maildir `/cur` ending which will be appended
+automatically). Additional information can be found as usual using:
+
+ M-x describe-variable notmuch-fcc-dirs
+
+An additional variable that can affect FCC settings in some cases is
+`message-directory`. Emacs message-mode uses this variable for
+postponed messages.
- M-x customize-apropos<RET>\(notmuch-fcc-dirs\)\|\(message-directory\)
+To customize both variables at the same time, use the fancy command:
+
+ M-x customize-apropos<RET>\(notmuch-fcc-dirs\)\|\(message-directory\)
This mechanism also allows you to select different folders to be
used for the outgoing mail depending on your selected `From`
An example setting might be:
- (setq notmuch-saved-searches '(("inbox" . "tag:inbox")
- ("unread" . "tag:inbox AND tag:unread")
- ("notmuch" . "tag:inbox AND to:notmuchmail.org")))
+ (setq notmuch-saved-searches '(("inbox" . "tag:inbox")
+ ("unread" . "tag:inbox AND tag:unread")
+ ("notmuch" . "tag:inbox AND to:notmuchmail.org")))
Of course, you can have any number of saved searches, each configured
with any supported search terms (see "notmuch help search-terms").
browser. Here's a little script that Keith Packard wrote, which he
calls `view-html`:
- #!/bin/sh
- dir=`mktemp -d`
- trap "rm -r $dir" 0
- cat "$@" > "$dir"/msg
- if munpack -C "$dir" -t < "$dir"/msg 2>&1 | grep 'Did not find'; then
- sed -n '/[Hh][Tt][Mm][Ll]/,$p' "$dir"/msg > $dir/part1.html
- rm "$dir"/msg
- fi
- for i in "$dir"/part*; do
- if grep -q -i -e '<html>' -e 'text/html' "$i"; then
- iceweasel "$i" &
- sleep 3
- exit 0
- fi
- done
+ #!/bin/sh
+ dir=`mktemp -d`
+ trap "rm -r $dir" 0
+ cat "$@" > "$dir"/msg
+ if munpack -C "$dir" -t < "$dir"/msg 2>&1 | grep 'Did not find'; then
+ sed -n '/[Hh][Tt][Mm][Ll]/,$p' "$dir"/msg > $dir/part1.html
+ rm "$dir"/msg
+ fi
+ for i in "$dir"/part*; do
+ if grep -q -i -e '<html>' -e 'text/html' "$i"; then
+ iceweasel "$i" &
+ sleep 3
+ exit 0
+ fi
+ done
Save that script somewhere in your `${PATH}`, make it executable,
and change the invocation of `iceweasel` to any other HTML viewer if
## <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 two
+candidates based on a search string. There are currently three
available:
* The python tool `notmuch_address.py` (`git clone
`http://github.com/spaetz/vala-notmuch/raw/static-sources/src/addrlookup.c`
and build it with:
- cc -o addrlookup addrlookup.c `pkg-config --cflags --libs gobject-2.0` -lnotmuch
+ cc -o addrlookup addrlookup.c `pkg-config --cflags --libs gobject-2.0` -lnotmuch
+
+ * 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)`.
+
+You can perform tab-completion using any of these programs.
+Just add the following to your .emacs:
-You can perform tab-completion using either 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)
- (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)
+ ;; Sign messages by default.
+ (add-hook 'message-setup-hook 'mml-secure-sign-pgpmime)
This inserts the required `<#part sign=pgpmime>` into the beginning
of the mail text body and will be converted into a pgp signature
### 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`.
+
+## Resending (or bouncing) messages
+
+Add the following to your `.emacs` to be able to resend the current message in
+show mode.
+
+ (define-key notmuch-show-mode-map "b"
+ (lambda (&optional address)
+ "Bounce the current message."
+ (interactive "sBounce To: ")
+ (notmuch-show-view-raw-message)
+ (message-resend address)))
+
+## `notmuch-hello` refresh status message
+
+Add the following to your `.emacs` to get a status message about the change in
+the number of messages in the mail store when refreshing the `notmuch-hello`
+buffer.
+
+ (defvar notmuch-hello-refresh-count 0)
+
+ (defun notmuch-hello-refresh-status-message ()
+ (unless no-display
+ (let* ((new-count
+ (string-to-number
+ (car (process-lines notmuch-command "count"))))
+ (diff-count (- new-count notmuch-hello-refresh-count)))
+ (cond
+ ((= notmuch-hello-refresh-count 0)
+ (message "You have %s messages."
+ (notmuch-hello-nice-number new-count)))
+ ((> diff-count 0)
+ (message "You have %s more messages since last refresh."
+ (notmuch-hello-nice-number diff-count)))
+ ((< diff-count 0)
+ (message "You have %s fewer messages since last refresh."
+ (notmuch-hello-nice-number (- diff-count)))))
+ (setq notmuch-hello-refresh-count new-count))))
+
+ (add-hook 'notmuch-hello-refresh-hook 'notmuch-hello-refresh-status-message)
+
+## Replacing tabs with spaces in subject and header
+
+Mailman mailing list software rewrites and rewraps long message subjects in
+a way that causes TABs to appear in the middle of the subject and header
+lines. Add this to your `.emacs` to replace tabs with spaces in subject
+lines:
+
+ (defun notmuch-show-subject-tabs-to-spaces ()
+ "Replace tabs with spaces in subject line."
+ (goto-char (point-min))
+ (when (re-search-forward "^Subject:" nil t)
+ (while (re-search-forward "\t" (line-end-position) t)
+ (replace-match " " nil nil))))
+
+ (add-hook 'notmuch-show-markup-headers-hook 'notmuch-show-subject-tabs-to-spaces)
+
+And in header lines (this will only work with the yet to be released
+notmuch version 0.15):
+
+ (defun notmuch-show-header-tabs-to-spaces ()
+ "Replace tabs with spaces in header line."
+ (setq header-line-format
+ (notmuch-show-strip-re
+ (replace-regexp-in-string "\t" " " (notmuch-show-get-subject)))))
+
+ (add-hook 'notmuch-show-hook 'notmuch-show-header-tabs-to-spaces)
+
+## Hiding unread messages in notmuch-show
+
+I like to have an inbox saved search, but only show unread messages when they
+view a thread. This takes two steps:
+
+1. Apply
+[this patch from Mark Walters](http://notmuchmail.org/pipermail/notmuch/2012/010817.html)
+to add the `notmuch-show-filter-thread` function.
+1. Add the following hook to your emacs configuration:
+
+ (defun expand-only-unread-hook () (interactive)
+ (let ((unread nil)
+ (open (notmuch-show-get-message-ids-for-open-messages)))
+ (notmuch-show-mapc (lambda ()
+ (when (member "unread" (notmuch-show-get-tags))
+ (setq unread t))))
+ (when unread
+ (let ((notmuch-show-hook (remove 'expand-only-unread-hook notmuch-show-hook)))
+ (notmuch-show-filter-thread "tag:unread")))))
+
+ (add-hook 'notmuch-show-hook 'expand-only-unread-hook)
+
+## Changing the color of a saved search based on some other search
+
+I like to have a saved search for my inbox, but have it change color when there
+are thread with unread messages in the inbox. I accomplish this with the
+following code in my emacs config:
+
+ (defun color-inbox-if-unread () (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((cnt (car (process-lines "notmuch" "count" "tag:inbox and tag:unread"))))
+ (when (> (string-to-number cnt) 0)
+ (save-excursion
+ (when (search-forward "inbox" (point-max) t)
+ (let* ((overlays (overlays-in (match-beginning 0) (match-end 0)))
+ (overlay (car overlays)))
+ (when overlay
+ (overlay-put overlay 'face '((:inherit bold) (:foreground "green")))))))))))
+ (add-hook 'notmuch-hello-refresh-hook 'color-inbox-if-unread)
+
+## Linking to notmuch messages and threads from the Circe IRC client
+
+[Circe](https://github.com/jorgenschaefer/circe/wiki) is an IRC client for emacs.
+To have clickable buttons for notmuch messages and threads, add the following to
+`lui-buttons-list` (using, e.g. M-x customize-variable)
+
+ ("\\(?:id\\|mid\\|thread\\):[0-9A-Za-z][0-9A-Za-z.@-]*" 0 notmuch-show 0)
+
+If you have notmuch-pick installed, it works fine for this as well.
+
+## Linking to notmuch messages from org-mode
+
+Support for linking to notmuch messages is distributed with org-mode,
+but as a contrib file, so you might have to work a bit to load it.
+
+In Debian and derivatives,
+
+ (add-to-list 'load-path "/usr/share/org-mode/lisp")
+
+Then
+
+ (require 'org-notmuch)
+
+In general it is nice to have a key for org-links (not just for notmuch). For example
+
+ (define-key global-map "\C-cl" 'org-store-link)