+(defun notmuch-search-scroll-up ()
+ "Scroll up, moving point to last message in thread if at end."
+ (interactive)
+ (condition-case nil
+ (scroll-up nil)
+ ((end-of-buffer) (notmuch-search-goto-last-thread))))
+
+(defun notmuch-search-scroll-down ()
+ "Scroll down, moving point to first message in thread if at beginning."
+ (interactive)
+ ; I don't know why scroll-down doesn't signal beginning-of-buffer
+ ; the way that scroll-up signals end-of-buffer, but c'est la vie.
+ ;
+ ; So instead of trapping a signal we instead check whether the
+ ; window begins on the first line of the buffer and if so, move
+ ; directly to that position. (We have to count lines since the
+ ; window-start position is not the same as point-min due to the
+ ; invisible thread-ID characters on the first line.
+ (if (equal (count-lines (point-min) (window-start)) 1)
+ (goto-char (window-start))
+ (scroll-down nil)))
+