[PATCH] emacs: Disambiguate point placement after hiding message

Subject: [PATCH] emacs: Disambiguate point placement after hiding message

Date: Mon, 7 Jan 2013 15:39:49 -0500

To: notmuch@notmuchmail.org


From: Austin Clements

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.
 emacs/notmuch-show.el |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5751d98..94b4178 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1363,7 +1363,23 @@ effects."
 ;; components.
 (defun notmuch-show-message-visible (props visible-p)
-  (overlay-put (plist-get props :message-overlay) 'invisible (not visible-p))
+  (let ((ov (plist-get props :message-overlay)))
+    (overlay-put ov 'invisible (not visible-p))
+    (when (not visible-p)
+      ;; 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)))))))
   (notmuch-show-set-prop :message-visible visible-p props))
 (defun notmuch-show-headers-visible (props visible-p)