Add Emacs' imenu support in notmuch-show and notmuch-search
authorDamien Cassou <damien@cassou.me>
Mon, 12 Jun 2017 13:30:10 +0000 (15:30 +0200)
committerDavid Bremner <david@tethera.net>
Wed, 14 Jun 2017 10:49:08 +0000 (07:49 -0300)
Emacs' major modes can facilitate navigation in their buffers by
supporting Imenu. In such major modes, launching Imenu (M-x imenu)
makes Emacs display a list of items (e.g., function definitions in a
code buffer). Selecting an item from this list moves point to this
item.

This patch adds Imenu support to both notmuch-show and notmuch-search
buffers:

* in notmuch-show, Imenu will present a list of all messages in the
  currently visible thread;

* in notmuch-search, Imenu will present a list of all messages in the
  search buffer.

emacs/notmuch-show.el
emacs/notmuch.el

index e7c22da0f54c35f128b70721128dbe6c87393b26..0f157ec56ffb1e1f506e7ba7425de8d1d884549c 100644 (file)
@@ -1516,7 +1516,11 @@ All currently available key bindings:
 \\{notmuch-show-mode-map}"
   (setq notmuch-buffer-refresh-function #'notmuch-show-refresh-view)
   (setq buffer-read-only t
-       truncate-lines t))
+       truncate-lines t)
+  (setq imenu-prev-index-position-function
+        #'notmuch-show-imenu-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        #'notmuch-show-imenu-extract-index-name-function))
 
 (defun notmuch-tree-from-show-current-query ()
   "Call notmuch tree with the current query"
@@ -2465,6 +2469,23 @@ the new buffer."
                          (mailcap-mime-types) nil nil nil nil "text/plain")))
   (notmuch-show-apply-to-current-part-handle #'notmuch-show--mm-display-part mime-type))
 
+(defun notmuch-show-imenu-prev-index-position-function ()
+  "Move point to previous message in notmuch-show buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (if (bobp)
+      nil
+    (notmuch-show-previous-message)
+    t))
+
+(defun notmuch-show-imenu-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (back-to-indentation)
+  (buffer-substring-no-properties (point) (line-end-position)))
+
 (provide 'notmuch-show)
 
 ;;; notmuch-show.el ends here
index 40b9fabdbc49c53a17720f1615a3984a8eb15558..90af68e399b966da5a97f1718b42e9ba1a0a849e 100644 (file)
@@ -374,7 +374,11 @@ Complete list of currently available key bindings:
   (set (make-local-variable 'scroll-preserve-screen-position) t)
   (add-to-invisibility-spec (cons 'ellipsis t))
   (setq truncate-lines t)
-  (setq buffer-read-only t))
+  (setq buffer-read-only t)
+  (setq imenu-prev-index-position-function
+        #'notmuch-search-imenu-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        #'notmuch-search-imenu-extract-index-name-function))
 
 (defun notmuch-search-get-result (&optional pos)
   "Return the result object for the thread at POS (or point).
@@ -1094,8 +1098,8 @@ notmuch buffers exist, run `notmuch'."
 
     ;; Find the first notmuch buffer.
     (setq first (loop for buffer in (buffer-list)
-                    if (notmuch-interesting-buffer buffer)
-                    return buffer))
+                     if (notmuch-interesting-buffer buffer)
+                     return buffer))
 
     (if first
        ;; If the first one we found is any other than the starting
@@ -1104,6 +1108,23 @@ notmuch buffers exist, run `notmuch'."
          (switch-to-buffer first))
       (notmuch))))
 
+;;;; Imenu Support
+
+(defun notmuch-search-imenu-prev-index-position-function ()
+  "Move point to previous message in notmuch-search buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (notmuch-search-previous-thread))
+
+(defun notmuch-search-imenu-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (let ((subject (notmuch-search-find-subject))
+       (author (notmuch-search-find-authors)))
+    (format "%s (%s)" subject author)))
+
 (setq mail-user-agent 'notmuch-user-agent)
 
 (provide 'notmuch)