]> git.cworth.org Git - obsolete/notmuch-wiki/blobdiff - emacstips.mdwn
refer to the cli manpages from frontends
[obsolete/notmuch-wiki] / emacstips.mdwn
index ac59e1008ba1ebaaba19a7a45739c47e500826ee..820d181725c7b02b2a16f7a80fe467638a9a9aac 100644 (file)
-[[!img notmuch-logo.png alt="Notmuch logo" class="left"]]
-#Tips and Tricks for using notmuch with Emacs
-
-* How to do FCC/BCC...
-
-  Any notmuch reply will automatically include your primary email
-  address in a BCC so that any messages you send will (eventually) end
-  up in your mail store as well.
-
-  But this doesn't do anything for messages that you compose that are
-  not replies. So we need to get sane message-mode FCC figured
-  out. Some investigation is still needed here.
-
-* How to customize notmuch-folders
-
-  There's a "notmuch-folder" command available in the emacs client
-  that displays a list of "folders" and the number of messages in
-  each. Each folder is simply a named search specification. To
-  configure this mode, edit your ${HOME}/.emacs file and include text
-  something like the following:
-
-               (setq notmuch-folders '(("inbox" . "tag:inbox")
-                                       ("unread" . "tag:inbox AND tag:unread")
-                                       ("notmuch" . "tag:inbox AND to:notmuchmail.org")))
-
-  Of course, you can have any number of folders, each configured
-  with any supported search terms (see "notmuch help search-terms").
-
-* Viewing HTML messages with an external viewer
-
-  The emacs client can often display an HTML message inline, but it
-  sometimes fails for one reason or another, (or is perhaps inadequate
-  if you really need to see the graphical presentation of the HTML
-  message).
-
-  In this case, it can be useful to display the message in an external
-  viewer, such as a web browser. Here's a little script that Keith
-  Packard wrote, which he calls view-html:
-
-               #!/bin/sh
-               dir=3D`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
-  necessary. Then within the emacs client, press "|" to pipe the
-  current message, then type "view-html".
-
-  Keith mentions the following caveat, "Note that if iceweasel isn't
-  already running, it seems to shut down when the script exits. I
-  don't know why."
+# 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 (notmuch-emacs in Debian).  This page goes over some usage
+tips for using notmuch with Emacs.
+
+[[!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)
+
+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.  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
+represents a message thread.  Hitting the '?' key will show help for
+this mode.
+
+In general, the 'q' will kill the current notmuch buffer and return
+you to the previous buffer (sort of like a 'pop').
+
+In search mode, navigating to a thread and hitting return will then
+open a new buffer in `notmuch-show-mode`, which will show the actual
+message contents of the thread.
+
+## Sending mail
+
+In any notmuch mode, you can start a new message by hitting the 'm'
+key.  To reply to a message or thread, just hit the 'r' key.
+
+When composing new messages, you will be entered in emacs's
+`message-mode`, which is a powerful mode for composing and sending
+messages.  When in message mode, you can type `C-c ?` for help.
+
+If you would like to use address autocompletion when composing
+messages, see [address completion](#address_completion).
+
+When you are ready to send a message, type `C-c C-c`. By default
+message mode will use your sendmail command to send mail, so make sure
+that works. One annoying standard configuration of message mode is
+that it will hide the sent mail in your emacs frame stack, but it will
+not close it. If you type several mails in an emacs session they will
+accumulate and make switching between buffers more annoying. You can
+avoid that behavior by adding `(setq message-kill-buffer-on-exit t)`
+in your `.emacs` file (or doing `M-x
+customize-variable<RET>message-kill-buffer-on-exit<RET>`) which will
+really close the mail window after sending it.
+
+## Attaching files
+
+Using the `M-x mml-attach-file` command, you can attach any file to be
+sent with your mail. By default this command is bound to the menu item
+*Attachments--Attach File* with the key binding `C-c C-a`. The
+variable `mml-dnd-attach-options` (`M-x
+customize-variable<RET>mml-dnd-attach-options<RET>`) can be set to
+allow the prompting for various attachment options (such as
+inline/attachment) if you want to do that.
+
+For those who prefer a more graphical interface, you can also simply
+drag and drop files from a file manager into a mail composition window
+to have them attached. In Ubuntu this works without any modifications
+if files are dragged from the file manager.
+
+And for those who prefer working from command line, the following
+script opens new emacs window with empty message and attaches files
+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)"
+
+## 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)
+
+
+## Add a key binding to add/remove/toggle a tag
+
+The `notmuch-{search,show}-{add,remove}-tag` functions are very useful
+for making quick tag key bindings.  For instance, here's an example
+of how to make a key binding to add the "spam" tag and remove the
+"inbox" tag in notmuch-show-mode:
+
+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)
+
+(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"))))
+
+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 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.
+
+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`
+address. Please see the documentation for the variable
+`notmuch-fcc-dirs` in the customization window for how to arrange
+this.
+
+## How to customize `notmuch-saved-searches`
+
+When starting notmuch, a list of saved searches and message counts is
+displayed, replacing the older `notmuch-folders` command. The set of
+saved searches displayed can be modified directly from the notmuch
+interface (using the `[save]` button next to a previous search) or by
+customising the variable `notmuch-saved-searches`.
+
+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")))
+
+Of course, you can have any number of saved searches, each configured
+with any supported search terms (see "notmuch help search-terms").
+
+Some users find it useful to add `and not tag:delete` to those
+searches, as they use the `delete` tag to mark messages as
+deleted. This causes messages that are marked as deleted to be removed
+from the commonly used views of messages.  Use whatever seems most
+useful to you.
+
+## Viewing HTML messages with an external viewer
+
+The emacs client can display an HTML message inline using either the
+`html2text` library or some text browser, like w3m or lynx. This is
+controlled by the `mm-text-html-renderer` variable.
+
+The first option is theorically better, because it can generate
+strings formatted for emacs and do whatever you want, e.g., substitute
+text inside &lt;b&gt; tags for bold text in the buffer. The library, however
+is still in a very early development phase and cannot yet process
+properly many elements, like tables and <style> directives, and even
+the generated text is often poorly formatted.
+
+Among the available browsers, w3m seems to do a better job converting
+the html, and if you have the w3m emacs package, you can use it,
+instead of the w3m-standalone, and thus preserve the text formatting.
+
+But if the rendering fails for one reason or another, or if you really
+need to see the graphical presentation of the HTML message, it can be
+useful to display the message in an external viewer, such as a web
+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
+
+Save that script somewhere in your `${PATH}`, make it executable,
+and change the invocation of `iceweasel` to any other HTML viewer if
+necessary. Then within the emacs client, press '|' to pipe the
+current message, then type "view-html".
+
+Keith mentions the following caveat, "Note that if iceweasel isn't
+already running, it seems to shut down when the script exits. I
+don't know why."
+
+## msmtp, message mode and multiple accounts
+
+As an alternative to running a mail server such as sendmail or postfix
+just to send email, it is possible to use
+[msmtp](http://msmtp.sourceforge.net/). This small application will
+look like `/usr/bin/sendmail` to a MUA such as emacs message mode, but
+will just forward the email to an external SMTP server. It's fairly
+easy to set up and it supports several accounts for using different
+SMTP servers. The msmtp pages have several examples.
+
+A typical scenario is that you want to use the company SMTP server
+for email coming from your company email address, and your personal
+server for personal email.  If msmtp is passed the envelope address
+on the command line (the -f/--from option) it will automatically
+pick the matching account.  The only trick here seems to be getting
+emacs to actually pass the envelope from.  There are a number of
+overlapping configuration variables that control this, and it's a
+little confusion, but setting these three works for me:
+
+ - `mail-specify-envelope-from`: `t`
+
+ - `message-sendmail-envelope-from`: `header`
+
+ - `mail-envelope-from`: `header`
+
+With that in place, you need a `.msmtprc` with the accounts configured
+for the domains you want to send out using specific SMTP servers and
+the rest will go to the default account.
+
+If you have a hard time getting the above to work for you, as I did,
+it's also possible to add a message-send-mail-hook in your .emacs to
+send the from header explicitly as an argument to msmtp as described
+[here](http://www.emacswiki.org/cgi-bin/wiki/GnusMSMTP#toc2) on the
+emacswiki.
+
+
+## <span id="address_completion">Address completion when composing</span>
+
+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
+available:
+
+  * The python tool `notmuch_address.py` (`git clone
+    http://commonmeasure.org/~jkr/git/notmuch_addresses.git`) (slower, but
+    no compilation required so good for testing the setup)
+
+  * The vala-based
+    [addrlookup](http://github.com/spaetz/vala-notmuch) (faster, but
+    needs compiling).  The addrlookup binary needs to be compiled.
+    Grab
+    `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
+
+  * 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:
+
+        (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:
+
+        ;; 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
+when sending (so one can just manually delete that line if signing
+is not required).
+
+Alternatively, you may prefer to use `mml-secure-message-sign-pgpmime` instead
+of `mml-secure-sign-pgpmime` to sign the whole message instead of just one
+part.
+
+### Troubleshooting message-mode gpg support
+
+- 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.