Currently, if point is in the middle of a message when the user collapses it, Emacs then displays the cursor on the header line of the next message, even though point is still on the collapsed message and even though, if you explicitly move point to the same visual location, it will be on the next message. As a result, following actions like re-expanding the message or modifying tags apply to the collapsed message, even though, visually, it looks like they will apply to the message following the collapsed message. This patch addresses this by explicitly moving point when a message is collapsed so it is visually unambiguous that the point is still on the collapsed message. --- v2 should fix the strange behavior observed in v1. The added code is essentially identical to v1, but v2 adds it to notmuch-show-toggle-message---which is only used interactively---rather than the core notmuch-show-message-visible function. emacs/notmuch-show.el | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 5751d98..6ab926c 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1789,12 +1789,30 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (force-window-update)) (defun notmuch-show-toggle-message () - "Toggle the visibility of the current message." + "Toggle the visibility of the current message. + +If this hides the current message, it will also move point to +make it obvious it's still on the current message." (interactive) - (let ((props (notmuch-show-get-message-properties))) - (notmuch-show-message-visible - props - (not (plist-get props :message-visible)))) + (let* ((props (notmuch-show-get-message-properties)) + (visible-p (not (plist-get props :message-visible)))) + (notmuch-show-message-visible props visible-p) + (when (not visible-p) + (let ((ov (plist-get props :message-overlay))) + ;; If point was contained in the overlay, move it to a + ;; sensible spot that is visible and still on the same + ;; message. Strangely, the Emacs event loop doesn't move the + ;; point out of the invisible region for us like it normally + ;; does (perhaps because it doesn't know which way to go), so + ;; if we don't do this, it's visually ambiguous which message + ;; an action will apply to. + (let ((start (overlay-start ov)) + (end (overlay-end ov))) + (dolist (win (get-buffer-window-list nil nil t)) + (with-selected-window win + (when (and (<= start (point)) (< (point) end)) + (goto-char (1- start)) + (beginning-of-visual-line)))))))) (force-window-update)) (defun notmuch-show-open-or-close-all () -- 1.7.10.4