X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=notmuch.el;h=5b553bbf55050be5b11a61221a28fb7c855e6ed7;hp=7723730f3e92f3da198df9353ea296c6298154aa;hb=07876ac135bbb3da264264ee5f7b83d36aad4290;hpb=3474263823d41b2a92942c5f66a87062757f1928 diff --git a/notmuch.el b/notmuch.el index 7723730f..5b553bbf 100644 --- a/notmuch.el +++ b/notmuch.el @@ -90,8 +90,10 @@ (define-key map "+" 'notmuch-show-add-tag) (define-key map "x" 'notmuch-show-archive-thread-then-exit) (define-key map "a" 'notmuch-show-archive-thread) - (define-key map "p" 'notmuch-show-previous-message) - (define-key map "n" 'notmuch-show-next-message) + (define-key map "P" 'notmuch-show-previous-message) + (define-key map "N" 'notmuch-show-next-message) + (define-key map "p" 'notmuch-show-previous-open-message) + (define-key map "n" 'notmuch-show-next-open-message) (define-key map (kbd "DEL") 'notmuch-show-rewind) (define-key map " " 'notmuch-show-advance-and-archive) map) @@ -523,7 +525,7 @@ Returns nil if already on the last message in the buffer." nil)) (defun notmuch-show-next-message () - "Advance to the beginning of the next message in the buffer. + "Advance to the next message (whether open or closed) and remove the unread tag from that message. Moves to the last visible character of the current message if @@ -548,7 +550,7 @@ message if already within the last message in the buffer." (point)))) (defun notmuch-show-next-unread-message () - "Advance to the beginning of the next unread message in the buffer. + "Advance to the next unread message. Moves to the last visible character of the current message if there are no more unread messages past the current point." @@ -561,17 +563,22 @@ there are no more unread messages past the current point." (notmuch-show-mark-read)) (defun notmuch-show-next-open-message () - "Advance to the next open message (that is, body is not invisible)." + "Advance to the next open message (that is, body is visible). + +Moves to the last visible character of the final message in the buffer +if there are no more open messages." + (interactive) (while (and (notmuch-show-next-message-without-marking-read) (not (notmuch-show-message-open-p)))) (notmuch-show-mark-read)) -(defun notmuch-show-previous-message () +(defun notmuch-show-previous-message-without-marking-read () "Backup to the beginning of the previous message in the buffer. If within a message rather than at the beginning of it, then -simply move to the beginning of the current message." - (interactive) +simply move to the beginning of the current message. + +Returns nil if already on the first message in the buffer." (let ((start (point))) (notmuch-show-move-to-current-message-summary-line) (if (not (< (point) start)) @@ -580,8 +587,22 @@ simply move to the beginning of the current message." (re-search-backward notmuch-show-message-begin-regexp nil t) (re-search-backward notmuch-show-message-begin-regexp nil t) (notmuch-show-move-to-current-message-summary-line) - )) - (recenter 0))) + (recenter 0) + (if (= (point) start) + nil + t)) + (recenter 0) + nil))) + +(defun notmuch-show-previous-message () + "Backup to the previous message (whether open or closed) +and remove the unread tag from that message. + +If within a message rather than at the beginning of it, then +simply move to the beginning of the current message." + (interactive) + (notmuch-show-previous-message-without-marking-read) + (notmuch-show-mark-read)) (defun notmuch-show-find-previous-message () "Returns the position of the previous message in the buffer. @@ -594,9 +615,19 @@ it." ; Looks like we have to use both. (save-excursion (save-window-excursion - (notmuch-show-previous-message) + (notmuch-show-previous-message-without-marking-read) (point)))) +(defun notmuch-show-previous-open-message () + "Backup to previous open message (that is, body is visible). + +Moves to the first message in the buffer if there are no previous +open messages." + (interactive) + (while (and (notmuch-show-previous-message-without-marking-read) + (not (notmuch-show-message-open-p)))) + (notmuch-show-mark-read)) + (defun notmuch-show-rewind () "Backup through the thread, (reverse scrolling compared to \\[notmuch-show-advance-and-archive]). @@ -616,7 +647,13 @@ any effects from previous calls to (condition-case nil (scroll-down nil) ((beginning-of-buffer) nil)) - (goto-char (window-start))) + (goto-char (window-start)) + ; Because count-lines counts invivisible lines, we may have + ; scrolled to far. If so., notice this and fix it up. + (if (< (point) previous) + (progn + (goto-char previous) + (recenter 0)))) (notmuch-show-previous-message)))) (defun notmuch-show-advance-and-archive () @@ -828,8 +865,8 @@ is what to put on the button." (defun notmuch-show-markup-body (depth match btn) "Markup a message body, (indenting, buttonizing citations, -etc.), and conditionally hiding the body itself if the message -has been read and does not match the current search. +etc.), and hiding the body itself if the message does not match +the current search. DEPTH specifies the depth at which this message appears in the tree of the current thread, (the top-level messages have depth 0 @@ -850,7 +887,7 @@ before the delimiter marking the beginning of the body." (overlay-put (make-overlay beg end) 'invisible invis-spec) (button-put btn 'invisibility-spec invis-spec) - (if (not (or (notmuch-show-message-unread-p) match)) + (if (not match) (add-to-invisibility-spec invis-spec))) (set-marker beg nil) (set-marker end nil) @@ -1209,6 +1246,8 @@ matching this search term are shown if non-nil. " (fset 'notmuch-search-mode-map notmuch-search-mode-map) (defvar notmuch-search-query-string) +(defvar notmuch-search-target-thread) +(defvar notmuch-search-target-position) (defvar notmuch-search-oldest-first t "Show the oldest mail first in the search-mode") @@ -1309,6 +1348,8 @@ Complete list of currently available key bindings: (kill-all-local-variables) (make-local-variable 'notmuch-search-query-string) (make-local-variable 'notmuch-search-oldest-first) + (make-local-variable 'notmuch-search-target-thread) + (make-local-variable 'notmuch-search-target-position) (set (make-local-variable 'scroll-preserve-screen-position) t) (add-to-invisibility-spec 'notmuch-search) (use-local-map notmuch-search-mode-map) @@ -1405,8 +1446,7 @@ which match the current search terms." (defun notmuch-search-remove-tag (tag) "Remove a tag from the currently selected thread. -The tag is removed from messages in the currently selected thread -which match the current search terms." +The tag is removed from all messages in the currently selected thread." (interactive (list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id)))) (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id)) @@ -1424,12 +1464,14 @@ This function advances the next thread when finished." "Add a message to let user know when \"notmuch search\" exits" (let ((buffer (process-buffer proc)) (status (process-status proc)) - (exit-status (process-exit-status proc))) + (exit-status (process-exit-status proc)) + (never-found-target-thread nil)) (if (memq status '(exit signal)) (if (buffer-live-p buffer) (with-current-buffer buffer (save-excursion - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) + (atbob (bobp))) (goto-char (point-max)) (if (eq status 'signal) (insert "Incomplete search results (search process was killed).\n")) @@ -1438,11 +1480,17 @@ This function advances the next thread when finished." (insert "End of search results.") (if (not (= exit-status 0)) (insert (format " (process returned %d)" exit-status))) - (insert "\n")))))))))) + (insert "\n") + (if (and atbob + notmuch-search-target-thread) + (set 'never-found-target-thread t)))))) + (if never-found-target-thread + (goto-char notmuch-search-target-position))))))) (defun notmuch-search-process-filter (proc string) "Process and filter the output of \"notmuch search\"" - (let ((buffer (process-buffer proc))) + (let ((buffer (process-buffer proc)) + (found-target nil)) (if (buffer-live-p buffer) (with-current-buffer buffer (save-excursion @@ -1465,9 +1513,16 @@ This function advances the next thread when finished." (insert (format "%s %-7s %-40s %s (%s)\n" date count authors subject tags)) (put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id) (put-text-property beg (point-marker) 'notmuch-search-authors authors) - (put-text-property beg (point-marker) 'notmuch-search-subject subject)) + (put-text-property beg (point-marker) 'notmuch-search-subject subject) + (if (and notmuch-search-target-thread + (string= thread-id notmuch-search-target-thread)) + (progn + (set 'found-target beg) + (set 'notmuch-search-target-thread nil)))) (set 'line (match-end 0))) - (set 'more nil)))))) + (set 'more nil))))) + (if found-target + (goto-char found-target))) (delete-process proc)))) (defun notmuch-search-operate-all (action) @@ -1494,14 +1549,27 @@ characters as well as `_.+-'. (append action-split (list notmuch-search-query-string) nil)))) ;;;###autoload -(defun notmuch-search (query &optional oldest-first) - "Run \"notmuch search\" with the given query string and display results." +(defun notmuch-search (query &optional oldest-first target-thread target-position) + "Run \"notmuch search\" with the given query string and display results. + +The 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 + current if it appears in the search results. + saved-position: If the search results complete, and the target thread is + not found in the results, and the point is still at the + beginning of the buffer, then the point will be moved to + the saved position. +" (interactive "sNotmuch search: ") (let ((buffer (get-buffer-create (concat "*notmuch-search-" query "*")))) (switch-to-buffer buffer) (notmuch-search-mode) (set 'notmuch-search-query-string query) (set 'notmuch-search-oldest-first oldest-first) + (set 'notmuch-search-target-thread target-thread) + (set 'notmuch-search-target-position target-position) (let ((proc (get-buffer-process (current-buffer))) (inhibit-read-only t)) (if proc @@ -1532,11 +1600,9 @@ same relative position within the new buffer." (thread (notmuch-search-find-thread-id)) (query notmuch-search-query-string)) (kill-this-buffer) - (notmuch-search query oldest-first) + (notmuch-search query oldest-first thread here) (goto-char (point-min)) - (if (re-search-forward (concat "^" thread) nil t) - (beginning-of-line) - (goto-char here)))) + )) (defun notmuch-search-toggle-order () "Toggle the current search order.