(define-key map "h" 'notmuch-show-toggle-headers-visible)
(define-key map "n" 'notmuch-show-next-message)
(define-key map "p" 'notmuch-show-previous-message)
+ (define-key map (kbd "C-n") 'notmuch-show-next-line)
+ (define-key map (kbd "C-p") 'notmuch-show-previous-line)
(define-key map "q" 'kill-this-buffer)
(define-key map "s" 'notmuch-show-toggle-signatures-visible)
(define-key map "x" 'kill-this-buffer)
(or (memq prop buffer-invisibility-spec)
(assq prop buffer-invisibility-spec)))))
+(defun notmuch-show-next-line ()
+ "Like builtin `next-line' but ensuring we end on a visible character.
+
+By advancing forward until reaching a visible character.
+
+Unlike builtin `next-line' this version accepts no arguments."
+ (interactive)
+ (set 'this-command 'next-line)
+ (call-interactively 'next-line)
+ (while (point-invisible-p)
+ (forward-char)))
+
+(defun notmuch-show-previous-line ()
+ "Like builtin `previous-line' but ensuring we end on a visible character.
+
+By advancing forward until reaching a visible character.
+
+Unlike builtin `next-line' this version accepts no arguments."
+ (interactive)
+ (set 'this-command 'previous-line)
+ (call-interactively 'previous-line)
+ (while (point-invisible-p)
+ (forward-char)))
+
(defun notmuch-show-get-message-id ()
(save-excursion
(beginning-of-line)
(let ((overlay (make-overlay beg-sub end)))
(overlay-put overlay 'invisible 'notmuch-show-signature)
(overlay-put overlay 'before-string
- (concat "[" (number-to-string (count-lines beg-sub (point)))
+ (concat "[" (number-to-string (count-lines beg-sub end))
"-line signature.]"))
(goto-char end)))
(next-line))))
(progn
(notmuch-show-next-unread-message)
; But if there are no unread messages, go back to the
- ; beginning of the buffer.
+ ; beginning of the buffer, and open up the bodies of all
+ ; read message.
(if (not (notmuch-show-message-unread-p))
- (goto-char (point-min)))))
+ (progn
+ (goto-char (point-min))
+ (notmuch-show-toggle-body-read-visible)))))
)))
(defvar notmuch-search-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "a" 'notmuch-search-archive-thread)
- (define-key map "b" 'scroll-down)
+ (define-key map "b" 'notmuch-search-scroll-down)
(define-key map "f" 'notmuch-search-filter)
(define-key map "n" 'next-line)
(define-key map "p" 'previous-line)
(define-key map ">" 'notmuch-search-goto-last-thread)
(define-key map "=" 'notmuch-search-refresh-view)
(define-key map "\M->" 'notmuch-search-goto-last-thread)
- (define-key map " " 'scroll-up)
- (define-key map (kbd "<DEL>") 'scroll-down)
+ (define-key map " " 'notmuch-search-scroll-up)
+ (define-key map (kbd "<DEL>") 'notmuch-search-scroll-down)
map)
"Keymap for \"notmuch search\" buffers.")
(fset 'notmuch-search-mode-map notmuch-search-mode-map)
+(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)))
+
(defun notmuch-search-goto-last-thread (&optional arg)
"Move point to the last thread in the buffer."
(interactive "^P")