X-Git-Url: https://git.cworth.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch.el;h=6abb17ffdc6d0b1b529ac0024bb08cff5a127b45;hp=6d37c623e6597cb4f43c0d6029b2f9502f93c89f;hb=15207652a1e52f995d08eb5645f28531b5e19d46;hpb=9d6f4641d17a6100cb8d96bc1e09d3d4999c34f3 diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 6d37c623..6abb17ff 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -88,18 +88,21 @@ ("authors" . "%-20s ") ("subject" . "%s ") ("tags" . "(%s)")) - "Search result formatting. Supported fields are: - date, count, authors, subject, tags + "Search result formatting. + +Supported fields are: date, count, authors, subject, tags. For example: - (setq notmuch-search-result-format \(\(\"authors\" . \"%-40s\"\) - \(\"subject\" . \"%s\"\)\)\) + (setq notmuch-search-result-format + '((\"authors\" . \"%-40s\") + (\"subject\" . \"%s\"))) + Line breaks are permitted in format strings (though this is currently experimental). Note that a line break at the end of an \"authors\" field will get elided if the authors list is long; place it instead at the beginning of the following field. To enter a line break when setting this variable with setq, use \\n. To enter a line break in customize, press \\[quoted-insert] C-j." - :type '(alist :key-type (string) :value-type (string)) + :type '(alist :key-type string :value-type string) :group 'notmuch-search) ;; The name of this variable `notmuch-init-file' is consistent with the @@ -532,12 +535,12 @@ thread." (message "End of search results.")))) (defun notmuch-tree-from-search-current-query () - "Call notmuch tree with the current query." + "Tree view of current query." (interactive) (notmuch-tree notmuch-search-query-string)) (defun notmuch-unthreaded-from-search-current-query () - "Call notmuch tree with the current query." + "Unthreaded view of current query." (interactive) (notmuch-unthreaded notmuch-search-query-string)) @@ -830,26 +833,28 @@ non-authors is found, assume that all of the authors match." (insert padding)))) (defun notmuch-search-insert-field (field format-string result) - (cond - ((string-equal field "date") - (insert (propertize (format format-string (plist-get result :date_relative)) - 'face 'notmuch-search-date))) - ((string-equal field "count") - (insert (propertize (format format-string - (format "[%s/%s]" (plist-get result :matched) - (plist-get result :total))) - 'face 'notmuch-search-count))) - ((string-equal field "subject") - (insert (propertize (format format-string - (notmuch-sanitize (plist-get result :subject))) - 'face 'notmuch-search-subject))) - ((string-equal field "authors") - (notmuch-search-insert-authors - format-string (notmuch-sanitize (plist-get result :authors)))) - ((string-equal field "tags") - (let ((tags (plist-get result :tags)) - (orig-tags (plist-get result :orig-tags))) - (insert (format format-string (notmuch-tag-format-tags tags orig-tags))))))) + (pcase field + ((pred functionp) + (insert (funcall field format-string result))) + ("date" + (insert (propertize (format format-string (plist-get result :date_relative)) + 'face 'notmuch-search-date))) + ("count" + (insert (propertize (format format-string + (format "[%s/%s]" (plist-get result :matched) + (plist-get result :total))) + 'face 'notmuch-search-count))) + ("subject" + (insert (propertize (format format-string + (notmuch-sanitize (plist-get result :subject))) + 'face 'notmuch-search-subject))) + ("authors" + (notmuch-search-insert-authors format-string + (notmuch-sanitize (plist-get result :authors)))) + ("tags" + (let ((tags (plist-get result :tags)) + (orig-tags (plist-get result :orig-tags))) + (insert (format format-string (notmuch-tag-format-tags tags orig-tags))))))) (defun notmuch-search-show-result (result pos) "Insert RESULT at POS." @@ -875,6 +880,14 @@ sets the :orig-tag property." (setq notmuch-search-target-thread "found") (goto-char pos)))) +(defvar-local notmuch--search-hook-run nil + "Flag used to ensure the notmuch-search-hook is only run once per buffer") + +(defun notmuch--search-hook-wrapper () + (unless notmuch--search-hook-run + (setq notmuch--search-hook-run t) + (run-hooks 'notmuch-search-hook))) + (defun notmuch-search-process-filter (proc string) "Process and filter the output of \"notmuch search\"." (let ((results-buf (process-buffer proc)) @@ -887,7 +900,9 @@ sets the :orig-tag property." (goto-char (point-max)) (insert string)) (notmuch-sexp-parse-partial-list 'notmuch-search-append-result - results-buf))))) + results-buf)) + (with-current-buffer results-buf + (notmuch--search-hook-wrapper))))) ;;; Commands (and some helper functions used by them) @@ -900,7 +915,39 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). The +buffer name is formatted using `format-spec': see its docstring +for additional parameters for the s and t format specifiers. + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers for saved searches. + +In this spec, %s will be replaced by the saved search name and %t +by its type (search, tree or unthreaded). The buffer name is +formatted using `format-spec': see its docstring for additional +parameters for the s and t format specifiers. + +See also `notmuch-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defun notmuch-search-format-buffer-name (query type saved) + "Compose a buffer name for the given QUERY, TYPE (search, tree, +unthreaded) and whether it's SAVED (t or nil)." + (let ((fmt (if saved + notmuch-saved-search-buffer-name-format + notmuch-search-buffer-name-format))) + (format-spec fmt `((?t . ,(or type "search")) (?s . ,query))))) + +(defun notmuch-search-buffer-title (query &optional type) "Returns the title for a buffer with notmuch search results." (let* ((saved-search (let (longest @@ -915,19 +962,20 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." do (setq longest tuple)) longest)) (saved-search-name (notmuch-saved-search-get saved-search :name)) + (saved-search-type (notmuch-saved-search-get saved-search :search-type)) (saved-search-query (notmuch-saved-search-get saved-search :query))) (cond ((and saved-search (equal saved-search-query query)) ;; Query is the same as saved search (ignoring case) - (concat "*notmuch-saved-search-" saved-search-name "*")) + (notmuch-search-format-buffer-name saved-search-name + saved-search-type + t)) (saved-search - (concat "*notmuch-search-" - (replace-regexp-in-string - (concat "^" (regexp-quote saved-search-query)) - (concat "[ " saved-search-name " ]") - query) - "*")) - (t - (concat "*notmuch-search-" query "*"))))) + (let ((query (replace-regexp-in-string + (concat "^" (regexp-quote saved-search-query)) + (concat "[ " saved-search-name " ]") + query))) + (notmuch-search-format-buffer-name query saved-search-type t))) + (t (notmuch-search-format-buffer-name query type nil))))) (defun notmuch-read-query (prompt) "Read a notmuch-query from the minibuffer with completion. @@ -935,7 +983,7 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." 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" "*"))) + (notmuch--process-lines notmuch-command "search" "--output=tags" "*"))) (completions (append (list "folder:" "path:" "thread:" "id:" "date:" "from:" "to:" "subject:" "attachment:") @@ -973,7 +1021,8 @@ PROMPT is the string to prompt with." (put 'notmuch-search 'notmuch-doc "Search for messages.") ;;;###autoload -(defun notmuch-search (&optional query oldest-first target-thread target-line no-display) +(defun notmuch-search (&optional query oldest-first target-thread target-line + no-display) "Display threads matching QUERY in a notmuch-search buffer. If QUERY is nil, it is read interactively from the minibuffer. @@ -1019,7 +1068,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=4" + "search" "--format=sexp" "--format-version=5" (if oldest-first "--sort=oldest-first" "--sort=newest-first") @@ -1030,8 +1079,7 @@ the configured default sort order." (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-query-on-exit-flag proc nil)))))) (defun notmuch-search-refresh-view () "Refresh the current view. @@ -1162,8 +1210,6 @@ Point should be at the beginning of the line." ;;; _ -(setq mail-user-agent 'notmuch-user-agent) - (provide 'notmuch) ;; After provide to avoid loops if notmuch was require'd via notmuch-init-file.