(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)
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
(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."
(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))
(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.
; 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]).
(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 ()
(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")
(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)
(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))
"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"))
(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
(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)
(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
(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.