- (erase-buffer)
- (goto-char (point-min))
- (save-excursion
- (let* ((basic-args (list notmuch-show-thread-id))
- (args (if notmuch-show-query-context
- (append (list "\'") basic-args
- (list "and (" notmuch-show-query-context ")\'"))
- (append (list "\'") basic-args (list "\'"))))
- (cli-args (cons "--exclude=false"
- (when notmuch-show-elide-non-matching-messages
- (list "--entire-thread=false")))))
-
- (notmuch-show-insert-forest (notmuch-query-get-threads (append cli-args args)))
- ;; If the query context reduced the results to nothing, run
- ;; the basic query.
- (when (and (eq (buffer-size) 0)
- notmuch-show-query-context)
- (notmuch-show-insert-forest
- (notmuch-query-get-threads (append cli-args basic-args)))))
-
- (jit-lock-register #'notmuch-show-buttonise-links)
-
- (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags))))
-
- ;; Set the header line to the subject of the first message.
- (setq header-line-format
- (replace-regexp-in-string "%" "%%"
- (notmuch-sanitize
- (notmuch-show-strip-re
- (notmuch-show-get-subject)))))
-
- (run-hooks 'notmuch-show-hook))))
+ (let ((inhibit-read-only t))
+ (if (notmuch-show--build-buffer)
+ ;; Messages were inserted into the buffer.
+ (current-buffer)
+ ;; No messages were inserted - presumably none matched the
+ ;; query.
+ (kill-buffer (current-buffer))
+ (ding)
+ (message "No messages matched the query!")
+ nil))))
+
+(defun notmuch-show--build-queries (thread context)
+ "Return a list of queries to try for this search.
+
+THREAD and CONTEXT are both strings, though CONTEXT may be nil.
+When CONTEXT is not nil, the first query is the conjunction of it
+and THREAD. The next query is THREAD alone, and serves as a
+fallback if the prior matches no messages."
+ (let (queries)
+ (push (list thread) queries)
+ (when context
+ (push (list thread "and (" context ")") queries))
+ queries))
+
+(defun notmuch-show--header-line-format ()
+ "Compute the header line format of a notmuch-show buffer."
+ (when notmuch-show-header-line
+ (let* ((s (notmuch-sanitize
+ (notmuch-show-strip-re (notmuch-show-get-subject))))
+ (subject (replace-regexp-in-string "%" "%%" s)))
+ (cond ((stringp notmuch-show-header-line)
+ (format-spec notmuch-show-header-line `((?s . ,subject))))
+ ((functionp notmuch-show-header-line)
+ (funcall notmuch-show-header-line subject))
+ (notmuch-show-header-line subject)))))
+
+(defun notmuch-show--build-buffer (&optional state)
+ "Display messages matching the current buffer context.
+
+Apply the previously saved STATE if supplied, otherwise show the
+first relevant message.
+
+If no messages match the query return NIL."
+ (let* ((cli-args (list "--exclude=false"))
+ (cli-args (if notmuch-show-elide-non-matching-messages (cons "--entire-thread=false" cli-args) cli-args))
+ ;; "part 0 is the whole message (headers and body)" notmuch-show(1)
+ (cli-args (if notmuch-show-single-message (cons "--part=0" cli-args) cli-args))
+ (queries (notmuch-show--build-queries
+ notmuch-show-thread-id notmuch-show-query-context))
+ (forest nil)
+ ;; Must be reset every time we are going to start inserting
+ ;; messages into the buffer.
+ (notmuch-show-previous-subject ""))
+ ;; Use results from the first query that returns some.
+ (while (and (not forest) queries)
+ (setq forest (notmuch--run-show
+ (append cli-args (list "'") (car queries) (list "'"))))
+ (when (and forest notmuch-show-single-message)
+ (setq forest (list (list (list forest)))))
+ (setq queries (cdr queries)))
+ (when forest
+ (notmuch-show-insert-forest forest)
+ ;; Store the original tags for each message so that we can
+ ;; display changes.
+ (notmuch-show-mapc
+ (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags))))
+ (setq header-line-format (notmuch-show--header-line-format))
+ (run-hooks 'notmuch-show-hook)
+ (if state
+ (notmuch-show-apply-state state)
+ ;; With no state to apply, just go to the first message.
+ (notmuch-show-goto-first-wanted-message)))
+ ;; Report back to the caller whether any messages matched.
+ forest))
+
+;;; Refresh command