]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch.el
emacs: bind M-RET to notmuch-tree-from-search-thread
[notmuch] / emacs / notmuch.el
index d8d3afeb69b983312b637a20d05f145125c2f098..0d68d12361111a6e094bd23677e1d27c223ceba9 100644 (file)
 ;; Have fun, and let us know if you have any comment, questions, or
 ;; kudos: Notmuch list <notmuch@notmuchmail.org> (subscription is not
 ;; required, but is available from https://notmuchmail.org).
-
+;;
+;; Note for MELPA users (and others tracking the development version
+;; of notmuch-emacs):
+;;
+;; This emacs package needs a fairly closely matched version of the
+;; notmuch program. If you use the MELPA version of notmuch.el (as
+;; opposed to MELPA stable), you should be prepared to track the
+;; master development branch (i.e. build from git) for the notmuch
+;; program as well. Upgrading notmuch-emacs too far beyond the notmuch
+;; program can CAUSE YOUR EMAIL TO STOP WORKING.
+;;
+;; TL;DR: notmuch-emacs from MELPA and notmuch from distro packages is
+;; NOT SUPPORTED.
+;;
 ;;; Code:
 
 (eval-when-compile (require 'cl))
@@ -175,6 +188,7 @@ there will be called at other points of notmuch execution."
     (define-key map "-" 'notmuch-search-remove-tag)
     (define-key map "+" 'notmuch-search-add-tag)
     (define-key map (kbd "RET") 'notmuch-search-show-thread)
+    (define-key map (kbd "M-RET") 'notmuch-tree-from-search-thread)
     (define-key map "Z" 'notmuch-tree-from-search-current-query)
     map)
   "Keymap for \"notmuch search\" buffers.")
@@ -374,7 +388,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).
@@ -402,17 +420,17 @@ returns nil"
     (next-single-property-change (or pos (point)) 'notmuch-search-result
                                 nil (point-max))))
 
-(defun notmuch-search-foreach-result (beg end function)
-  "Invoke FUNCTION for each result between BEG and END.
+(defun notmuch-search-foreach-result (beg end fn)
+  "Invoke FN for each result between BEG and END.
 
-FUNCTION should take one argument.  It will be applied to the
+FN should take one argument.  It will be applied to the
 character position of the beginning of each result that overlaps
 the region between points BEG and END.  As a special case, if (=
-BEG END), FUNCTION will be applied to the result containing point
+BEG END), FN will be applied to the result containing point
 BEG."
 
   (lexical-let ((pos (notmuch-search-result-beginning beg))
-               ;; End must be a marker in case function changes the
+               ;; End must be a marker in case fn changes the
                ;; text.
                (end (copy-marker end))
                ;; Make sure we examine at least one result, even if
@@ -423,7 +441,7 @@ BEG."
     ;; pos.
     (while (and pos (or (< pos end) first))
       (when (notmuch-search-get-result pos)
-       (funcall function pos))
+       (funcall fn pos))
       (setq pos (notmuch-search-result-end pos)
            first nil))))
 ;; Unindent the function argument of notmuch-search-foreach-result so
@@ -540,20 +558,11 @@ thread."
        (setq output (append output (notmuch-search-get-tags pos)))))
     output))
 
-(defun notmuch-search-interactive-region ()
-  "Return the bounds of the current interactive region.
-
-This returns (BEG END), where BEG and END are the bounds of the
-region if the region is active, or both `point' otherwise."
-  (if (region-active-p)
-      (list (region-beginning) (region-end))
-    (list (point) (point))))
-
 (defun notmuch-search-interactive-tag-changes (&optional initial-input)
   "Prompt for tag changes for the current thread or region.
 
 Returns (TAG-CHANGES REGION-BEGIN REGION-END)."
-  (let* ((region (notmuch-search-interactive-region))
+  (let* ((region (notmuch-interactive-region))
         (beg (first region)) (end (second region))
         (prompt (if (= beg end) "Tag thread" "Tag region")))
     (cons (notmuch-read-tag-changes
@@ -573,8 +582,8 @@ is inactive this applies to the thread at point.
 If ONLY-MATCHED is non-nil, only tag matched messages."
   (interactive (notmuch-search-interactive-tag-changes))
   (unless (and beg end)
-    (setq beg (car (notmuch-search-interactive-region))
-         end (cadr (notmuch-search-interactive-region))))
+    (setq beg (car (notmuch-interactive-region))
+         end (cadr (notmuch-interactive-region))))
   (let ((search-string (notmuch-search-find-stable-query-region
                        beg end only-matched)))
     (notmuch-tag search-string tag-changes)
@@ -610,7 +619,7 @@ messages will be \"unarchived\" (i.e. the tag changes in
 `notmuch-archive-tags' will be reversed).
 
 This function advances the next thread when finished."
-  (interactive (cons current-prefix-arg (notmuch-search-interactive-region)))
+  (interactive (cons current-prefix-arg (notmuch-interactive-region)))
   (when notmuch-archive-tags
     (notmuch-search-tag
      (notmuch-tag-change-list notmuch-archive-tags unarchive) beg end))
@@ -694,7 +703,7 @@ A thread with TAG will have FACE applied.
 Here is an example of how to color search results based on tags.
  (the following text would be placed in your ~/.emacs file):
 
- (setq notmuch-search-line-faces '((\"unread\" . (:foreground \"green\"))
+ (setq notmuch-search-line-faces \\='((\"unread\" . (:foreground \"green\"))
                                    (\"deleted\" . (:foreground \"red\"
                                                  :background \"blue\"))))
 
@@ -990,7 +999,7 @@ the configured default sort order."
       (save-excursion
        (let ((proc (notmuch-start-notmuch
                     "notmuch-search" buffer #'notmuch-search-process-sentinel
-                    "search" "--format=sexp" "--format-version=2"
+                    "search" "--format=sexp" "--format-version=4"
                     (if oldest-first
                         "--sort=oldest-first"
                       "--sort=newest-first")
@@ -1059,7 +1068,7 @@ current search results AND the additional query string provided."
 Runs a new search matching only messages that match both the
 current search results AND that are tagged with the given tag."
   (interactive
-   (list (notmuch-select-tag-with-completion "Filter by tag: ")))
+   (list (notmuch-select-tag-with-completion "Filter by tag: " notmuch-search-query-string)))
   (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-oldest-first))
 
 ;;;###autoload
@@ -1094,8 +1103,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 +1113,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)