On Sun, Nov 30 2025, Kristoffer Balintona wrote: > Hello, > > Attached is a proposed patch for allowing the `notmuch-show-mode' and > `notmuch-tree-mode' scrolling commands (six in total) to accept an > optional argument (interactively, the prefix argument). When the > argument is non-nil, instead of the usual behavior, that many lines will > be scrolled instead. > > This is the default prefix argument behavior of the built-in > `scroll-up-command' and `scroll-down-command', so I think it's > appropriate to implement them in notmuch's own scrolling commands.
Updated patch. There was a case in `notmuch-tree-scroll-message-window-back' and `notmuch-tree-scroll-message-window' that I had forgotten to address.
-- Kind regards, Kristoffer
From a7f0feb5fa85f8275d0d540a023cbcd40bff4d8a Mon Sep 17 00:00:00 2001 From: Kristoffer Balintona <[email protected]> Date: Tue, 18 Nov 2025 14:08:56 -0600 Subject: [PATCH 1/1] emacs: Message scrolling commands now accept a prefix argument There are several commands with special behavior used to scroll message buffers. In `notmuch-show-mode` buffers: - `notmuch-show-advance`, - `notmuch-show-advance-and-archive` - `notmuch-show-rewind` And in `notmuch-tree-mode' buffers: - `notmuch-tree-scroll-message-window` - `notmuch-tree-scroll-message-window-back` - `notmuch-tree-scroll-or-next` These commands now accept an optional argument, ARG (interactively, the prefix argument), such that their behavior aligns with the built-in Emacs scrolling commands: `scroll-up-command` and `scroll-down-command`. Specifically, when ARG is nil, the previous behavior of the given command is retained. However, when ARG is non-nil, it will cause that command to only scroll up or down (depending on the command) ARG number of lines in the message buffer (and nothing else). For example, `notmuch-show-advance-and-archive` is bound to SPC in `notmuch-show-mode` buffers. Now, when the user presses C-u 5 SPC, the screen will scroll 5 lines upward. Finally, I have updated these commands' docstrings to reflect their new behavior while enhancing the existing behavior they expressed. --- emacs/notmuch-show.el | 94 +++++++++++++++++++++++-------------------- emacs/notmuch-tree.el | 47 +++++++++++++++------- 2 files changed, 84 insertions(+), 57 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 14e3c698..04d2a57c 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1971,15 +1971,17 @@ Reshows the current thread with matches defined by the new query-string." ;;; Commands typically bound to keys. -(defun notmuch-show-advance () +(defun notmuch-show-advance (&optional arg) "Advance through thread. -If the current message in the thread is not yet fully visible, -scroll by a near screenful to read more of the message. +If ARG is non-nil (interactively, the prefix argument), scroll up that +many lines. If ARG is nil and 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), advance to the next open message." - (interactive) +Otherwise (when ARG is nil and the end of the current message is already +within the current window), advance to the next open message." + (interactive "P") (let* ((end-of-this-message (notmuch-show-message-bottom)) (visible-end-of-this-message (1- end-of-this-message)) (ret nil)) @@ -1992,10 +1994,11 @@ current window), advance to the next open message." ;; Ideally we would test `end-of-this-message' against the result ;; of `window-end', but that doesn't account for the fact that ;; the end of the message might be hidden. - ((and visible-end-of-this-message - (> visible-end-of-this-message (window-end))) - ;; The bottom of this message is not visible - scroll. - (scroll-up nil)) + ((or arg (and visible-end-of-this-message + (> visible-end-of-this-message (window-end)))) + ;; ARG is non-nil or the bottom of this message is not visible - + ;; scroll. + (scroll-up arg)) ((not (= end-of-this-message (point-max))) ;; This is not the last message - move to the next visible one. (notmuch-show-next-open-message)) @@ -2008,53 +2011,58 @@ current window), advance to the next open message." (setq ret t))) ret)) -(defun notmuch-show-advance-and-archive () +(defun notmuch-show-advance-and-archive (&optional arg) "Advance through thread and archive. -This command is intended to be one of the simplest ways to -process a thread of email. It works exactly like -notmuch-show-advance, in that it scrolls through messages in a -show buffer, except that when it gets to the end of the buffer it -archives the entire current thread, (apply changes in -`notmuch-archive-tags'), kills the buffer, and displays the next -thread from the search from which this thread was originally -shown." - (interactive) - (when (notmuch-show-advance) +This command is intended to be one of the simplest ways to process a +thread of email. + +It works exactly like `notmuch-show-advance' in that it scrolls through +messages in the current show buffer according to ARG (the prefix +argument when called interactively). However, when it gets to the end of +the buffer, it archives the entire current thread (apply changes in +`notmuch-archive-tags'), kills the buffer, and displays the next thread +from the search from which this thread was originally shown." + (interactive "P") + (when (notmuch-show-advance arg) (notmuch-show-archive-thread-then-next))) -(defun notmuch-show-rewind () +(defun notmuch-show-rewind (&optional arg) "Backup through the thread (reverse scrolling compared to \ \\[notmuch-show-advance-and-archive]). -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'. +Specifically, when ARG (interactively, the prefix argument) is non-nil, +scroll down that many lines. When ARG is nil, 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-and-archive'." - (interactive) +This command does not modify any message tags, (it does not undo any +effects from previous calls to `notmuch-show-advance-and-archive'." + (interactive "P") (let ((start-of-message (notmuch-show-message-top)) (start-of-window (window-start))) (cond - ;; Either this message is properly aligned with the start of the - ;; window or the start of this message is not visible on the - ;; screen - scroll. - ((or (= start-of-message start-of-window) + ;; Either (1) ARG is non-nil, (2) this message is properly + ;; aligned with the start of the window, or (3) the start of this + ;; message is not visible on the screen - scroll. + ((or arg + (= start-of-message start-of-window) (< start-of-message start-of-window)) - (scroll-down) - ;; If a small number of lines from the previous message are - ;; visible, realign so that the top of the current message is at - ;; the top of the screen. - (when (<= (count-screen-lines (window-start) start-of-message) - next-screen-context-lines) - (goto-char (notmuch-show-message-top)) - (notmuch-show-message-adjust)) - ;; Move to the top left of the window. - (goto-char (window-start))) + (scroll-down arg) + ;; Only move point when ARG is nil (i.e., when the user only + ;; wants to scroll) + (unless arg + ;; If a small number of lines from the previous message are + ;; visible, realign so that the top of the current message is + ;; at the top of the screen. + (when (<= (count-screen-lines (window-start) start-of-message) + next-screen-context-lines) + (goto-char (notmuch-show-message-top)) + (notmuch-show-message-adjust)) + ;; Move to the top left of the window. + (goto-char (window-start)))) (t ;; Move to the previous message. (notmuch-show-previous-message))))) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index faec89c4..5851d6a4 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -668,29 +668,48 @@ Shows in split pane or whole window according to value of (notmuch-tree-show-message-out) (notmuch-tree-show-message-in))) -(defun notmuch-tree-scroll-message-window () - "Scroll the message window (if it exists)." - (interactive) +(defun notmuch-tree-scroll-message-window (&optional arg) + "Scroll the message window (if it exists) ARG lines. + +If ARG is non-nil, scroll the screen that many lines upward. + +If ARG is nil, scroll upward by a near full screen. However, when ARG is +nil and the end of the message window is already visible, do nothing and +return non-nil instead of scrolling." + (interactive "P") (when (window-live-p notmuch-tree-message-window) (with-selected-window notmuch-tree-message-window - (if (pos-visible-in-window-p (point-max)) + (if (and (not arg) + (pos-visible-in-window-p (point-max))) t - (scroll-up))))) + (scroll-up arg))))) -(defun notmuch-tree-scroll-message-window-back () - "Scroll the message window back (if it exists)." - (interactive) +(defun notmuch-tree-scroll-message-window-back (&optional arg) + "Scroll the message window back (if it exists) ARG lines. + +If ARG is non-nil, scroll the screen that many lines down. + +If ARG is nil, scroll downward by a near full screen. However, when ARG +is nil and the beginning of the message window is already visible, do +nothing and return non-nil instead of scrolling." + (interactive "P") (when (window-live-p notmuch-tree-message-window) (with-selected-window notmuch-tree-message-window - (if (pos-visible-in-window-p (point-min)) + (if (and (not arg) + (pos-visible-in-window-p (point-min))) t - (scroll-down))))) + (scroll-down arg))))) -(defun notmuch-tree-scroll-or-next () +(defun notmuch-tree-scroll-or-next (&optional arg) "Scroll the message window. -If it at end go to next message." - (interactive) - (when (notmuch-tree-scroll-message-window) + +If ARG is non-nil, scroll the screen that many lines upward. + +If ARG is nil, scroll upward by a near full screen. However, when ARG is +nil and the end of the buffer is already visible, go to next message +instead." + (interactive "P") + (when (notmuch-tree-scroll-message-window arg) (notmuch-tree-next-matching-message))) (defun notmuch-tree-quit (&optional kill-both) -- 2.52.0
_______________________________________________ notmuch mailing list -- [email protected] To unsubscribe send an email to [email protected]
