]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch.el
Merge tag 0.28.4
[notmuch] / emacs / notmuch.el
index 079a3d1fdd1e9b7053d053f40b04e6607c4f335c..804e78ab8c53cf855cd9a5ea3713f19b40da4886 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))
@@ -313,8 +326,12 @@ there will be called at other points of notmuch execution."
   :group 'notmuch-faces)
 
 (defface notmuch-search-flagged-face
-  '((t
-     (:weight bold)))
+  '((((class color)
+      (background dark))
+     (:foreground "LightBlue1"))
+    (((class color)
+      (background light))
+     (:foreground "blue")))
   "Face used in search mode face for flagged threads.
 
 This face is the default value for the \"flagged\" tag in
@@ -324,7 +341,7 @@ This face is the default value for the \"flagged\" tag in
 
 (defface notmuch-search-unread-face
   '((t
-     (:foreground "blue")))
+     (:weight bold)))
   "Face used in search mode for unread threads.
 
 This face is the default value for the \"unread\" tag in
@@ -370,7 +387,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).
@@ -398,17 +419,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
@@ -419,7 +440,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
@@ -562,12 +583,15 @@ Returns (TAG-CHANGES REGION-BEGIN REGION-END)."
 See `notmuch-tag' for information on the format of TAG-CHANGES.
 When called interactively, this uses the region if the region is
 active.  When called directly, BEG and END provide the region.
-If these are nil or not provided, this applies to the thread at
-point.
+If these are nil or not provided, then, if the region is active
+this applied to all threads meeting the region, and if the region
+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 (point) end (point)))
+  (unless (and beg end)
+    (setq beg (car (notmuch-search-interactive-region))
+         end (cadr (notmuch-search-interactive-region))))
   (let ((search-string (notmuch-search-find-stable-query-region
                        beg end only-matched)))
     (notmuch-tag search-string tag-changes)
@@ -670,9 +694,16 @@ of the result."
                  (goto-char (point-min))
                  (forward-line (1- notmuch-search-target-line)))))))))
 
+(define-widget 'notmuch--custom-face-edit 'lazy
+  "Custom face edit with a tag Edit Face"
+  ;; I could not persuage custom-face-edit to respect the :tag
+  ;; property so create a widget specially
+  :tag "Manually specify face"
+  :type 'custom-face-edit)
+
 (defcustom notmuch-search-line-faces
-  '(("unread" 'notmuch-search-unread-face)
-    ("flagged" 'notmuch-search-flagged-face))
+  '(("unread" notmuch-search-unread-face)
+    ("flagged" notmuch-search-flagged-face))
   "Alist of tags to faces for line highlighting in notmuch-search.
 Each element looks like (TAG . FACE).
 A thread with TAG will have FACE applied.
@@ -680,7 +711,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\"))))
 
@@ -690,7 +721,9 @@ matching tags are merged, with earlier attributes overriding
 later. A message having both \"deleted\" and \"unread\" tags with
 the above settings would have a green foreground and blue
 background."
-  :type '(alist :key-type (string) :value-type (custom-face-edit))
+  :type '(alist :key-type (string)
+               :value-type (radio (face :tag "Face name")
+                                   (notmuch--custom-face-edit)))
   :group 'notmuch-search
   :group 'notmuch-faces)
 
@@ -924,8 +957,8 @@ PROMPT is the string to prompt with."
   "Return the current query in this search buffer"
   notmuch-search-query-string)
 
-;;;###autoload
 (put 'notmuch-search 'notmuch-doc "Search for messages.")
+;;;###autoload
 (defun notmuch-search (&optional query oldest-first target-thread target-line no-display)
   "Display threads matching QUERY in a notmuch-search buffer.
 
@@ -974,7 +1007,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")
@@ -1043,7 +1076,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
@@ -1057,8 +1090,9 @@ current search results AND that are tagged with the given tag."
   (with-current-buffer b
     (memq major-mode '(notmuch-show-mode
                       notmuch-search-mode
+                      notmuch-tree-mode
                       notmuch-hello-mode
-                      message-mode))))
+                      notmuch-message-mode))))
 
 ;;;###autoload
 (defun notmuch-cycle-notmuch-buffers ()
@@ -1077,8 +1111,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
@@ -1087,6 +1121,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)