]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch.el
emacs: various cosmetic improvements
[notmuch] / emacs / notmuch.el
index babddbb6fef87652ed7204fb4dc65351d12f72b1..c4ee9e6321a14cf640a822b629950d262d666c8d 100644 (file)
@@ -1,4 +1,4 @@
-;;; notmuch.el --- run notmuch within emacs
+;;; notmuch.el --- run notmuch within emacs  -*- lexical-binding: t -*-
 ;;
 ;; Copyright © Carl Worth
 ;;
 ;;
 ;; Copyright © Carl Worth
 ;;
@@ -80,6 +80,8 @@
 (require 'notmuch-message)
 (require 'notmuch-parser)
 
 (require 'notmuch-message)
 (require 'notmuch-parser)
 
+;;; Options
+
 (defcustom notmuch-search-result-format
   `(("date" . "%12s ")
     ("count" . "%-7s ")
 (defcustom notmuch-search-result-format
   `(("date" . "%12s ")
     ("count" . "%-7s ")
@@ -115,6 +117,8 @@ there will be called at other points of notmuch execution."
 (defvar notmuch-query-history nil
   "Variable to store minibuffer history for notmuch queries.")
 
 (defvar notmuch-query-history nil
   "Variable to store minibuffer history for notmuch queries.")
 
+;;; Mime Utilities
+
 (defun notmuch-foreach-mime-part (function mm-handle)
   (cond ((stringp (car mm-handle))
         (dolist (part (cdr mm-handle))
 (defun notmuch-foreach-mime-part (function mm-handle)
   (cond ((stringp (car mm-handle))
         (dolist (part (cdr mm-handle))
@@ -151,6 +155,8 @@ there will be called at other points of notmuch execution."
            (mm-save-part p))))
    mm-handle))
 
            (mm-save-part p))))
    mm-handle))
 
+;;; Integrations
+
 (require 'hl-line)
 
 (defun notmuch-hl-line-mode ()
 (require 'hl-line)
 
 (defun notmuch-hl-line-mode ()
@@ -158,6 +164,8 @@ there will be called at other points of notmuch execution."
     (when hl-line-overlay
       (overlay-put hl-line-overlay 'priority 1))))
 
     (when hl-line-overlay
       (overlay-put hl-line-overlay 'priority 1))))
 
+;;; Options
+
 (defcustom notmuch-search-hook '(notmuch-hl-line-mode)
   "List of functions to call when notmuch displays the search results."
   :type 'hook
 (defcustom notmuch-search-hook '(notmuch-hl-line-mode)
   "List of functions to call when notmuch displays the search results."
   :type 'hook
@@ -165,11 +173,13 @@ there will be called at other points of notmuch execution."
   :group 'notmuch-search
   :group 'notmuch-hooks)
 
   :group 'notmuch-search
   :group 'notmuch-hooks)
 
+;;; Keymap
+
 (defvar notmuch-search-mode-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map notmuch-common-keymap)
     (define-key map "x" 'notmuch-bury-or-kill-this-buffer)
 (defvar notmuch-search-mode-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map notmuch-common-keymap)
     (define-key map "x" 'notmuch-bury-or-kill-this-buffer)
-    (define-key map (kbd "<DEL>") 'notmuch-search-scroll-down)
+    (define-key map (kbd "DEL") 'notmuch-search-scroll-down)
     (define-key map "b" 'notmuch-search-scroll-down)
     (define-key map " " 'notmuch-search-scroll-up)
     (define-key map "<" 'notmuch-search-first-thread)
     (define-key map "b" 'notmuch-search-scroll-down)
     (define-key map " " 'notmuch-search-scroll-up)
     (define-key map "<" 'notmuch-search-first-thread)
@@ -194,7 +204,8 @@ there will be called at other points of notmuch execution."
     (define-key map "U" 'notmuch-unthreaded-from-search-current-query)
     map)
   "Keymap for \"notmuch search\" buffers.")
     (define-key map "U" 'notmuch-unthreaded-from-search-current-query)
     map)
   "Keymap for \"notmuch search\" buffers.")
-(fset 'notmuch-search-mode-map notmuch-search-mode-map)
+
+;;; Stashing
 
 (defvar notmuch-search-stash-map
   (let ((map (make-sparse-keymap)))
 
 (defvar notmuch-search-stash-map
   (let ((map (make-sparse-keymap)))
@@ -215,11 +226,15 @@ there will be called at other points of notmuch execution."
   (interactive)
   (notmuch-common-do-stash (notmuch-search-get-query)))
 
   (interactive)
   (notmuch-common-do-stash (notmuch-search-get-query)))
 
+;;; Variables
+
 (defvar notmuch-search-query-string)
 (defvar notmuch-search-target-thread)
 (defvar notmuch-search-target-line)
 
 (defvar notmuch-search-query-string)
 (defvar notmuch-search-target-thread)
 (defvar notmuch-search-target-line)
 
-(defvar notmuch-search-disjunctive-regexp      "\\<[oO][rR]\\>")
+(defvar notmuch-search-disjunctive-regexp "\\<[oO][rR]\\>")
+
+;;; Movement
 
 (defun notmuch-search-scroll-up ()
   "Move forward through search results by one window's worth."
 
 (defun notmuch-search-scroll-up ()
   "Move forward through search results by one window's worth."
@@ -272,13 +287,15 @@ there will be called at other points of notmuch execution."
   (interactive)
   (goto-char (point-min)))
 
   (interactive)
   (goto-char (point-min)))
 
+;;; Faces
+
 (defface notmuch-message-summary-face
   `((((class color) (background light))
      ,@(and (>= emacs-major-version 27) '(:extend t))
 (defface notmuch-message-summary-face
   `((((class color) (background light))
      ,@(and (>= emacs-major-version 27) '(:extend t))
-     (:background "#f0f0f0"))
+     :background "#f0f0f0")
     (((class color) (background dark))
      ,@(and (>= emacs-major-version 27) '(:extend t))
     (((class color) (background dark))
      ,@(and (>= emacs-major-version 27) '(:extend t))
-     (:background "#303030")))
+     :background "#303030"))
   "Face for the single-line message summary in notmuch-show-mode."
   :group 'notmuch-show
   :group 'notmuch-faces)
   "Face for the single-line message summary in notmuch-show-mode."
   :group 'notmuch-show
   :group 'notmuch-faces)
@@ -343,7 +360,7 @@ there will be called at other points of notmuch execution."
   "Face used in search mode face for flagged threads.
 
 This face is the default value for the \"flagged\" tag in
   "Face used in search mode face for flagged threads.
 
 This face is the default value for the \"flagged\" tag in
-`notmuch-search-line-faces`."
+`notmuch-search-line-faces'."
   :group 'notmuch-search
   :group 'notmuch-faces)
 
   :group 'notmuch-search
   :group 'notmuch-faces)
 
@@ -353,10 +370,12 @@ This face is the default value for the \"flagged\" tag in
   "Face used in search mode for unread threads.
 
 This face is the default value for the \"unread\" tag in
   "Face used in search mode for unread threads.
 
 This face is the default value for the \"unread\" tag in
-`notmuch-search-line-faces`."
+`notmuch-search-line-faces'."
   :group 'notmuch-search
   :group 'notmuch-faces)
 
   :group 'notmuch-search
   :group 'notmuch-faces)
 
+;;; Mode
+
 (define-derived-mode notmuch-search-mode fundamental-mode "notmuch-search"
   "Major mode displaying results of a notmuch search.
 
 (define-derived-mode notmuch-search-mode fundamental-mode "notmuch-search"
   "Major mode displaying results of a notmuch search.
 
@@ -392,7 +411,7 @@ Complete list of currently available key bindings:
   (make-local-variable 'notmuch-search-target-thread)
   (make-local-variable 'notmuch-search-target-line)
   (setq notmuch-buffer-refresh-function #'notmuch-search-refresh-view)
   (make-local-variable 'notmuch-search-target-thread)
   (make-local-variable 'notmuch-search-target-line)
   (setq notmuch-buffer-refresh-function #'notmuch-search-refresh-view)
-  (set (make-local-variable 'scroll-preserve-screen-position) t)
+  (setq-local scroll-preserve-screen-position t)
   (add-to-invisibility-spec (cons 'ellipsis t))
   (setq truncate-lines t)
   (setq buffer-read-only t)
   (add-to-invisibility-spec (cons 'ellipsis t))
   (setq truncate-lines t)
   (setq buffer-read-only t)
@@ -401,6 +420,8 @@ Complete list of currently available key bindings:
   (setq imenu-extract-index-name-function
        #'notmuch-search-imenu-extract-index-name-function))
 
   (setq imenu-extract-index-name-function
        #'notmuch-search-imenu-extract-index-name-function))
 
+;;; Search Results
+
 (defun notmuch-search-get-result (&optional pos)
   "Return the result object for the thread at POS (or point).
 
 (defun notmuch-search-get-result (&optional pos)
   "Return the result object for the thread at POS (or point).
 
@@ -545,7 +566,7 @@ thread."
                notmuch-search-query-string
                nil
                (notmuch-prettify-subject (notmuch-search-find-subject))
                notmuch-search-query-string
                nil
                (notmuch-prettify-subject (notmuch-search-find-subject))
-               t))
+               t nil (current-buffer)))
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
   "Begin composing a reply-all to the entire current thread in a new buffer."
 
 (defun notmuch-search-reply-to-thread (&optional prompt-for-sender)
   "Begin composing a reply-all to the entire current thread in a new buffer."
@@ -559,6 +580,8 @@ thread."
   (let ((message-id (notmuch-search-find-thread-id)))
     (notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
   (let ((message-id (notmuch-search-find-thread-id)))
     (notmuch-mua-new-reply message-id prompt-for-sender nil)))
 
+;;; Tags
+
 (defun notmuch-search-set-tags (tags &optional pos)
   (let ((new-result (plist-put (notmuch-search-get-result pos) :tags tags)))
     (notmuch-search-update-result new-result pos)))
 (defun notmuch-search-set-tags (tags &optional pos)
   (let ((new-result (plist-put (notmuch-search-get-result pos) :tags tags)))
     (notmuch-search-update-result new-result pos)))
@@ -640,6 +663,8 @@ This function advances the next thread when finished."
   (when (eq beg end)
     (notmuch-search-next-thread)))
 
   (when (eq beg end)
     (notmuch-search-next-thread)))
 
+;;; Search Results
+
 (defun notmuch-search-update-result (result &optional pos)
   "Replace the result object of the thread at POS (or point) by
 RESULT and redraw it.
 (defun notmuch-search-update-result (result &optional pos)
   "Replace the result object of the thread at POS (or point) by
 RESULT and redraw it.
@@ -668,7 +693,7 @@ of the result."
                          (min init-point (- new-end 1)))))
        (goto-char new-point)))))
 
                          (min init-point (- new-end 1)))))
        (goto-char new-point)))))
 
-(defun notmuch-search-process-sentinel (proc msg)
+(defun notmuch-search-process-sentinel (proc _msg)
   "Add a message to let user know when \"notmuch search\" exits."
   (let ((buffer (process-buffer proc))
        (status (process-status proc))
   "Add a message to let user know when \"notmuch search\" exits."
   (let ((buffer (process-buffer proc))
        (status (process-status proc))
@@ -694,7 +719,7 @@ of the result."
                    (throw 'return nil))
                  (when (and atbob
                             (not (string= notmuch-search-target-thread "found")))
                    (throw 'return nil))
                  (when (and atbob
                             (not (string= notmuch-search-target-thread "found")))
-                   (set 'never-found-target-thread t)))))
+                   (setnever-found-target-thread t)))))
            (when (and never-found-target-thread
                       notmuch-search-target-line)
              (goto-char (point-min))
            (when (and never-found-target-thread
                       notmuch-search-target-line)
              (goto-char (point-min))
@@ -871,8 +896,7 @@ sets the :orig-tag property."
   "Process and filter the output of \"notmuch search\"."
   (let ((results-buf (process-buffer proc))
        (parse-buf (process-get proc 'parse-buf))
   "Process and filter the output of \"notmuch search\"."
   (let ((results-buf (process-buffer proc))
        (parse-buf (process-get proc 'parse-buf))
-       (inhibit-read-only t)
-       done)
+       (inhibit-read-only t))
     (when (buffer-live-p results-buf)
       (with-current-buffer parse-buf
        ;; Insert new data
     (when (buffer-live-p results-buf)
       (with-current-buffer parse-buf
        ;; Insert new data
@@ -882,6 +906,8 @@ sets the :orig-tag property."
        (notmuch-sexp-parse-partial-list 'notmuch-search-append-result
                                         results-buf)))))
 
        (notmuch-sexp-parse-partial-list 'notmuch-search-append-result
                                         results-buf)))))
 
+;;; Commands (and some helper functions used by them)
+
 (defun notmuch-search-tag-all (tag-changes)
   "Add/remove tags from all messages in current search buffer.
 
 (defun notmuch-search-tag-all (tag-changes)
   "Add/remove tags from all messages in current search buffer.
 
@@ -924,40 +950,39 @@ See `notmuch-tag' for information on the format of TAG-CHANGES."
   "Read a notmuch-query from the minibuffer with completion.
 
 PROMPT is the string to prompt with."
   "Read a notmuch-query from the minibuffer with completion.
 
 PROMPT is the string to prompt with."
-  (let*
-      ((all-tags
-       (mapcar (lambda (tag) (notmuch-escape-boolean-term tag))
-               (process-lines notmuch-command "search" "--output=tags" "*")))
-       (completions
-       (append (list "folder:" "path:" "thread:" "id:" "date:" "from:" "to:"
-                     "subject:" "attachment:")
-               (mapcar (lambda (tag) (concat "tag:" tag)) all-tags)
-               (mapcar (lambda (tag) (concat "is:" tag)) all-tags)
-               (mapcar (lambda (mimetype) (concat "mimetype:" mimetype))
-                       (mailcap-mime-types)))))
-    (let ((keymap (copy-keymap minibuffer-local-map))
-         (current-query (cl-case major-mode
-                          (notmuch-search-mode (notmuch-search-get-query))
-                          (notmuch-show-mode (notmuch-show-get-query))
-                          (notmuch-tree-mode (notmuch-tree-get-query))))
-         (minibuffer-completion-table
-          (completion-table-dynamic
-           (lambda (string)
-             ;; generate a list of possible completions for the current input
-             (cond
-              ;; this ugly regexp is used to get the last word of the input
-              ;; possibly preceded by a '('
-              ((string-match "\\(^\\|.* (?\\)\\([^ ]*\\)$" string)
-               (mapcar (lambda (compl)
-                         (concat (match-string-no-properties 1 string) compl))
-                       (all-completions (match-string-no-properties 2 string)
-                                        completions)))
-              (t (list string)))))))
-      ;; this was simpler than convincing completing-read to accept spaces:
-      (define-key keymap (kbd "TAB") 'minibuffer-complete)
-      (let ((history-delete-duplicates t))
-       (read-from-minibuffer prompt nil keymap nil
-                             'notmuch-search-history current-query nil)))))
+  (let* ((all-tags
+         (mapcar (lambda (tag) (notmuch-escape-boolean-term tag))
+                 (process-lines notmuch-command "search" "--output=tags" "*")))
+        (completions
+         (append (list "folder:" "path:" "thread:" "id:" "date:" "from:" "to:"
+                       "subject:" "attachment:")
+                 (mapcar (lambda (tag) (concat "tag:" tag)) all-tags)
+                 (mapcar (lambda (tag) (concat "is:" tag)) all-tags)
+                 (mapcar (lambda (mimetype) (concat "mimetype:" mimetype))
+                         (mailcap-mime-types))))
+        (keymap (copy-keymap minibuffer-local-map))
+        (current-query (cl-case major-mode
+                         (notmuch-search-mode (notmuch-search-get-query))
+                         (notmuch-show-mode (notmuch-show-get-query))
+                         (notmuch-tree-mode (notmuch-tree-get-query))))
+        (minibuffer-completion-table
+         (completion-table-dynamic
+          (lambda (string)
+            ;; Generate a list of possible completions for the current input.
+            (cond
+             ;; This ugly regexp is used to get the last word of the input
+             ;; possibly preceded by a '('.
+             ((string-match "\\(^\\|.* (?\\)\\([^ ]*\\)$" string)
+              (mapcar (lambda (compl)
+                        (concat (match-string-no-properties 1 string) compl))
+                      (all-completions (match-string-no-properties 2 string)
+                                       completions)))
+             (t (list string)))))))
+    ;; This was simpler than convincing completing-read to accept spaces:
+    (define-key keymap (kbd "TAB") 'minibuffer-complete)
+    (let ((history-delete-duplicates t))
+      (read-from-minibuffer prompt nil keymap nil
+                           'notmuch-search-history current-query nil))))
 
 (defun notmuch-search-get-query ()
   "Return the current query in this search buffer."
 
 (defun notmuch-search-get-query ()
   "Return the current query in this search buffer."
@@ -994,18 +1019,14 @@ the configured default sort order."
         (buffer (get-buffer-create (notmuch-search-buffer-title query))))
     (if no-display
        (set-buffer buffer)
         (buffer (get-buffer-create (notmuch-search-buffer-title query))))
     (if no-display
        (set-buffer buffer)
-      (switch-to-buffer buffer))
-    ;; avoid wiping out third party buffer-local variables in the case
-    ;; where we're just refreshing or changing the sort order of an
-    ;; existing search results buffer
-    (unless (eq major-mode 'notmuch-search-mode)
-      (notmuch-search-mode))
+      (pop-to-buffer-same-window buffer))
+    (notmuch-search-mode)
     ;; Don't track undo information for this buffer
     ;; Don't track undo information for this buffer
-    (set 'buffer-undo-list t)
-    (set 'notmuch-search-query-string query)
-    (set 'notmuch-search-oldest-first oldest-first)
-    (set 'notmuch-search-target-thread target-thread)
-    (set 'notmuch-search-target-line target-line)
+    (setbuffer-undo-list t)
+    (setnotmuch-search-query-string query)
+    (setnotmuch-search-oldest-first oldest-first)
+    (setnotmuch-search-target-thread target-thread)
+    (setnotmuch-search-target-line target-line)
     (notmuch-tag-clear-cache)
     (let ((proc (get-buffer-process (current-buffer)))
          (inhibit-read-only t))
     (notmuch-tag-clear-cache)
     (let ((proc (get-buffer-process (current-buffer)))
          (inhibit-read-only t))
@@ -1020,12 +1041,12 @@ the configured default sort order."
                     (if oldest-first
                         "--sort=oldest-first"
                       "--sort=newest-first")
                     (if oldest-first
                         "--sort=oldest-first"
                       "--sort=newest-first")
-                    query))
-             ;; Use a scratch buffer to accumulate partial output.
-             ;; This buffer will be killed by the sentinel, which
-             ;; should be called no matter how the process dies.
-             (parse-buf (generate-new-buffer " *notmuch search parse*")))
-         (process-put proc 'parse-buf parse-buf)
+                    query)))
+         ;; Use a scratch buffer to accumulate partial output.
+         ;; This buffer will be killed by the sentinel, which
+         ;; should be called no matter how the process dies.
+         (process-put proc 'parse-buf
+                      (generate-new-buffer " *notmuch search parse*"))
          (set-process-filter proc 'notmuch-search-process-filter)
          (set-process-query-on-exit-flag proc nil))))
     (run-hooks 'notmuch-search-hook)))
          (set-process-filter proc 'notmuch-search-process-filter)
          (set-process-query-on-exit-flag proc nil))))
     (run-hooks 'notmuch-search-hook)))
@@ -1053,7 +1074,7 @@ same relative position within the new buffer."
 This command toggles the sort order for the current search. The
 default sort order is defined by `notmuch-search-oldest-first'."
   (interactive)
 This command toggles the sort order for the current search. The
 default sort order is defined by `notmuch-search-oldest-first'."
   (interactive)
-  (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
+  (setnotmuch-search-oldest-first (not notmuch-search-oldest-first))
   (notmuch-search-refresh-view))
 
 (defun notmuch-group-disjunctive-query-string (query-string)
   (notmuch-search-refresh-view))
 
 (defun notmuch-group-disjunctive-query-string (query-string)
@@ -1134,10 +1155,10 @@ notmuch buffers exist, run `notmuch'."
        ;; If the first one we found is any other than the starting
        ;; buffer, switch to it.
        (unless (eq first start)
        ;; If the first one we found is any other than the starting
        ;; buffer, switch to it.
        (unless (eq first start)
-         (switch-to-buffer first))
+         (pop-to-buffer-same-window first))
       (notmuch))))
 
       (notmuch))))
 
-;;;; Imenu Support
+;;; Imenu Support
 
 (defun notmuch-search-imenu-prev-index-position-function ()
   "Move point to previous message in notmuch-search buffer.
 
 (defun notmuch-search-imenu-prev-index-position-function ()
   "Move point to previous message in notmuch-search buffer.
@@ -1154,6 +1175,8 @@ beginning of the line."
        (author (notmuch-search-find-authors)))
     (format "%s (%s)" subject author)))
 
        (author (notmuch-search-find-authors)))
     (format "%s (%s)" subject author)))
 
+;;; _
+
 (setq mail-user-agent 'notmuch-user-agent)
 
 (provide 'notmuch)
 (setq mail-user-agent 'notmuch-user-agent)
 
 (provide 'notmuch)