X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch.el;h=f9454d8bd260ca575e82e8bd34b1e1b77eaac4aa;hp=f79d0047f66499b3c93e314839d6f03569d190e1;hb=42391b405610f48d81a369e899d0be9c9b0ee969;hpb=7ba5c86399f8c479442938dd2cc7ad07edd4d985 diff --git a/emacs/notmuch.el b/emacs/notmuch.el index f79d0047..f9454d8b 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -293,18 +293,25 @@ For a mouse binding, return nil." (defun notmuch-search-next-thread () "Select the next thread in the search results." (interactive) - (forward-line 1)) + (when (notmuch-search-get-result) + (goto-char (notmuch-search-result-end)))) (defun notmuch-search-previous-thread () "Select the previous thread in the search results." (interactive) - (forward-line -1)) + (if (notmuch-search-get-result) + (unless (bobp) + (goto-char (notmuch-search-result-beginning (- (point) 1)))) + ;; We must be past the end; jump to the last result + (notmuch-search-last-thread))) (defun notmuch-search-last-thread () "Select the last thread in the search results." (interactive) (goto-char (point-max)) - (forward-line -2)) + (forward-line -2) + (let ((beg (notmuch-search-result-beginning))) + (when beg (goto-char beg)))) (defun notmuch-search-first-thread () "Select the first thread in the search results." @@ -381,8 +388,9 @@ any tags). Pressing \\[notmuch-search-show-thread] on any line displays that thread. The '\\[notmuch-search-add-tag]' and '\\[notmuch-search-remove-tag]' keys can be used to add or remove tags from a thread. The '\\[notmuch-search-archive-thread]' key is a convenience for archiving a thread (removing the \"inbox\" -tag). The '\\[notmuch-search-tag-all]' key can be used to add or remove a tag from all -threads in the current buffer. +tag). The '\\[notmuch-search-tag-all]' key can be used to add and/or remove tags from all +messages (as opposed to threads) that match the current query. Use with caution, as this +will also tag matching messages that arrived *after* constructing the buffer. Other useful commands are '\\[notmuch-search-filter]' for filtering the current search based on an additional query string, '\\[notmuch-search-filter-by-tag]' for filtering to include @@ -465,16 +473,20 @@ BEG." (let (output) (notmuch-search-foreach-result beg end (lambda (pos) - (push (get-text-property pos property) output))) + (push (plist-get (notmuch-search-get-result pos) property) output))) output)) -(defun notmuch-search-find-thread-id () - "Return the thread for the current thread" - (get-text-property (point) 'notmuch-search-thread-id)) +(defun notmuch-search-find-thread-id (&optional bare) + "Return the thread for the current thread + +If BARE is set then do not prefix with \"thread:\"" + (let ((thread (plist-get (notmuch-search-get-result) :thread))) + (when thread (concat (unless bare "thread:") thread)))) (defun notmuch-search-find-thread-id-region (beg end) "Return a list of threads for the current region" - (notmuch-search-properties-in-region 'notmuch-search-thread-id beg end)) + (mapcar (lambda (thread) (concat "thread:" thread)) + (notmuch-search-properties-in-region :thread beg end))) (defun notmuch-search-find-thread-id-region-search (beg end) "Return a search string for threads for the current region" @@ -482,19 +494,19 @@ BEG." (defun notmuch-search-find-authors () "Return the authors for the current thread" - (get-text-property (point) 'notmuch-search-authors)) + (plist-get (notmuch-search-get-result) :authors)) (defun notmuch-search-find-authors-region (beg end) "Return a list of authors for the current region" - (notmuch-search-properties-in-region 'notmuch-search-authors beg end)) + (notmuch-search-properties-in-region :authors beg end)) (defun notmuch-search-find-subject () "Return the subject for the current thread" - (get-text-property (point) 'notmuch-search-subject)) + (plist-get (notmuch-search-get-result) :subject)) (defun notmuch-search-find-subject-region (beg end) "Return a list of authors for the current region" - (notmuch-search-properties-in-region 'notmuch-search-subject beg end)) + (notmuch-search-properties-in-region :subject beg end)) (defun notmuch-search-show-thread () "Display the currently selected thread." @@ -581,12 +593,20 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (interactive) (notmuch-search-tag "-")) -(defun notmuch-search-archive-thread () - "Archive the currently selected thread (remove its \"inbox\" tag). +(defun notmuch-search-archive-thread (&optional unarchive) + "Archive the currently selected thread. + +Archive each message in the currently selected thread by applying +the tag changes in `notmuch-archive-tags' to each (remove the +\"inbox\" tag by default). If a prefix argument is given, the +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) - (notmuch-search-tag '("-inbox")) + (interactive "P") + (when notmuch-archive-tags + (notmuch-search-tag + (notmuch-tag-change-list notmuch-archive-tags unarchive))) (notmuch-search-next-thread)) (defun notmuch-search-update-result (result &optional pos) @@ -773,11 +793,9 @@ non-authors is found, assume that all of the authors match." (notmuch-search-insert-authors format-string (plist-get result :authors))) ((string-equal field "tags") - ;; Ignore format-string here because notmuch-search-set-tags - ;; depends on the format of this - (insert (concat "(" (propertize - (mapconcat 'identity (plist-get result :tags) " ") - 'font-lock-face 'notmuch-tag-face) ")"))))) + (let ((tags-str (mapconcat 'identity (plist-get result :tags) " "))) + (insert (propertize (format format-string tags-str) + 'face 'notmuch-tag-face)))))) (defun notmuch-search-show-result (result &optional pos) "Insert RESULT at POS or the end of the buffer if POS is null." @@ -790,13 +808,7 @@ non-authors is found, assume that all of the authors match." (notmuch-search-insert-field (car spec) (cdr spec) result)) (insert "\n") (notmuch-search-color-line beg (point) (plist-get result :tags)) - (put-text-property beg (point) 'notmuch-search-result result) - (put-text-property beg (point) 'notmuch-search-thread-id - (concat "thread:" (plist-get result :thread))) - (put-text-property beg (point) 'notmuch-search-authors - (plist-get result :authors)) - (put-text-property beg (point) 'notmuch-search-subject - (plist-get result :subject))) + (put-text-property beg (point) 'notmuch-search-result result)) (when (string= (plist-get result :thread) notmuch-search-target-thread) (setq notmuch-search-target-thread "found") (goto-char beg))))) @@ -808,12 +820,6 @@ non-authors is found, assume that all of the authors match." (insert (apply #'format string objects)) (insert "\n"))) -(defvar notmuch-search-process-state nil - "Parsing state of the search process filter.") - -(defvar notmuch-search-json-parser nil - "Incremental JSON parser for the search process filter.") - (defun notmuch-search-process-filter (proc string) "Process and filter the output of \"notmuch search\"" (let ((results-buf (process-buffer proc)) @@ -826,41 +832,10 @@ non-authors is found, assume that all of the authors match." ;; Insert new data (save-excursion (goto-char (point-max)) - (insert string))) - (with-current-buffer results-buf - (while (not done) - (condition-case nil - (case notmuch-search-process-state - ((begin) - ;; Enter the results list - (if (eq (notmuch-json-begin-compound - notmuch-search-json-parser) 'retry) - (setq done t) - (setq notmuch-search-process-state 'result))) - ((result) - ;; Parse a result - (let ((result (notmuch-json-read notmuch-search-json-parser))) - (case result - ((retry) (setq done t)) - ((end) (setq notmuch-search-process-state 'end)) - (otherwise (notmuch-search-show-result result))))) - ((end) - ;; Any trailing data is unexpected - (notmuch-json-eof notmuch-search-json-parser) - (setq done t))) - (json-error - ;; Do our best to resynchronize and ensure forward - ;; progress - (notmuch-search-show-error - "%s" - (with-current-buffer parse-buf - (let ((bad (buffer-substring (line-beginning-position) - (line-end-position)))) - (forward-line) - bad)))))) - ;; Clear out what we've parsed - (with-current-buffer parse-buf - (delete-region (point-min) (point))))))) + (insert string)) + (notmuch-json-parse-partial-list 'notmuch-search-show-result + 'notmuch-search-show-error + results-buf))))) (defun notmuch-search-tag-all (&optional tag-changes) "Add/remove tags from all messages in current search buffer. @@ -905,7 +880,7 @@ PROMPT is the string to prompt with." (append (list "folder:" "thread:" "id:" "date:" "from:" "to:" "subject:" "attachment:") (mapcar (lambda (tag) - (concat "tag:" tag)) + (concat "tag:" (notmuch-escape-boolean-term tag))) (process-lines notmuch-command "search" "--output=tags" "*"))))) (let ((keymap (copy-keymap minibuffer-local-map)) (minibuffer-completion-table @@ -935,7 +910,7 @@ If `query' is nil, it is read interactively from the minibuffer. Other optional parameters are used as follows: oldest-first: A Boolean controlling the sort order of returned threads - target-thread: A thread ID (with the thread: prefix) that will be made + target-thread: A thread ID (without the thread: prefix) that will be made current if it appears in the search results. target-line: The line number to move to if the target thread does not appear in the search results." @@ -972,9 +947,6 @@ Other optional parameters are used as follows: ;; 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*"))) - (set (make-local-variable 'notmuch-search-process-state) 'begin) - (set (make-local-variable 'notmuch-search-json-parser) - (notmuch-json-create-parser parse-buf)) (process-put proc 'parse-buf parse-buf) (set-process-sentinel proc 'notmuch-search-process-sentinel) (set-process-filter proc 'notmuch-search-process-filter) @@ -992,7 +964,7 @@ same relative position within the new buffer." (interactive) (let ((target-line (line-number-at-pos)) (oldest-first notmuch-search-oldest-first) - (target-thread (notmuch-search-find-thread-id)) + (target-thread (notmuch-search-find-thread-id 'bare)) (query notmuch-search-query-string) (continuation notmuch-search-continuation)) (notmuch-kill-this-buffer)