- ; First, ensure we get off the current message marker
- (if (not (bobp))
- (previous-line))
- (re-search-backward notmuch-show-message-begin-regexp nil t)
- ; This dance might look pointless, but it's important. I originally
- ; just had (beginning-of-line) here which looked right on the
- ; display but actually put point all the way back to the first
- ; character of the first invisible line. That is, it put point into
- ; the closing markers of the previous message rather than at the
- ; beginning of the current message. And that in turn meant that
- ; looking up the current message-ID would actually return the
- ; previous message ID.
- ;
- ; So this dance ensures that we're actually on the current message
- ; when it looks like we are.
- (end-of-visible-line)
- (beginning-of-line)
- (recenter 0))
+ (let ((start (point)))
+ (notmuch-show-move-to-current-message-summary-line)
+ (if (not (< (point) start))
+ ; Go backward twice to skip the current message's marker
+ (progn
+ (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)))
+
+(defun notmuch-show-find-previous-message ()
+ "Returns the position of the previous message in the buffer.
+
+Or the position of the beginning of the current message if point
+is originally within the message rather than at the beginning of
+it."
+ ; save-excursion doesn't save our window position
+ ; save-window-excursion doesn't save point
+ ; Looks like we have to use both.
+ (save-excursion
+ (save-window-excursion
+ (notmuch-show-previous-message)
+ (point))))
+
+(defun notmuch-show-mark-read-then-next-open-message ()
+ "Remove unread tag from current message, then advance to next unread message."
+ (interactive)
+ (notmuch-show-remove-tag "unread")
+ (notmuch-show-next-open-message))
+
+(defun notmuch-show-rewind ()
+ "Do reverse scrolling compared to `notmuch-show-advance-marking-read-and-archiving'
+
+Specifically, if the beginning of the previous email is fewer
+than `window-height' lines from the current point, move to it
+just like `notmuch-show-previous-message'.
+
+Otherwise, just scroll down a screenful of the current message.
+
+This command does not modify any message tags, (it does not undo
+any effects from previous calls to
+`notmuch-show-advance-marking-read-and-archiving'."
+ (interactive)
+ (let ((previous (notmuch-show-find-previous-message)))
+ (if (> (count-lines previous (point)) (- (window-height) next-screen-context-lines))
+ (progn
+ (condition-case nil
+ (scroll-down nil)
+ ((beginning-of-buffer) nil))
+ (goto-char (window-start)))
+ (notmuch-show-previous-message))))
+
+(defun notmuch-show-advance-marking-read-and-archiving ()
+ "Advance through buffer, marking read and archiving.
+
+This command is intended to be one of the simplest ways to
+process a thread of email. It does the following:
+
+If the current message in the thread is not yet fully visible,
+scroll by a near screenful to read more of the message.
+
+Otherwise, (the end of the current message is already within the
+current window), remove the \"unread\" tag (if present) from the
+current message and advance to the next open message.
+
+Finally, if there is no further message to advance to, and this
+last message is already read, then archive the entire current
+thread, (remove the \"inbox\" tag from each message). Also kill
+this buffer, and display the next thread from the search from
+which this thread was originally shown."
+ (interactive)
+ (let ((next (notmuch-show-find-next-message))
+ (unread (notmuch-show-message-unread-p)))
+ (if (> next (window-end))
+ (scroll-up nil)
+ (let ((last (notmuch-show-last-message-p)))
+ (notmuch-show-mark-read-then-next-open-message)
+ (if last
+ (notmuch-show-archive-thread))))))