[RFC PATCH] emacs: show: mark messages unread if seen in buffer

Subject: [RFC PATCH] emacs: show: mark messages unread if seen in buffer

Date: Fri, 9 May 2014 16:45:20 +0100

To: notmuch@notmuchmail.org

Cc:

From: Mark Walters


This adds a function that marks messages unread if they are "seen"
that is a user configurable amount of them has been visible in the
buffer.

To use set notmuch-show-mark-read-function to #'notmuch-show-do-seen
---

This adds the functionality to do my previous mark unread logic (see
id:1395777793-13297-1-git-send-email-markwalters1009@gmail.com) as an
option. It applies on top of the parent series.

This is not intended to be applied as is, but people can see whether
they prefer this or the logic introduced in patch 2. I think we might
as well include the patch 2 logic as an option regardless as some
people will prefer it, and it is very small.

This functionality could go in notmuch-show if many people prefer it,
it could go in contrib if a rather small number like it, or it could
just go on the wiki.

Indeed, a user can have this functionality by loading a file with this
diffs contents (doesn't need to be in the notmuch tree) and setting
notmuch-show-mark-function.

Best wishes

Mark



 emacs/notmuch-show.el |   67 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 2620f84..3f45830 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1550,6 +1550,73 @@ (defun notmuch-show-mark-read (&optional unread)
     (apply 'notmuch-show-tag-message
 	   (notmuch-tag-change-list notmuch-show-mark-read-tags unread))))
 
+(defcustom notmuch-show-seen-lines-needed 0.75
+  "Control which messages get marked seen.
+
+A message is marked seen if both the top of the message and a
+point far \"enough\" down in the message have each been visible
+in the buffer at some point. This parameter controls the
+definition of enough.  Seeing the bottom of message is always
+deemed enough. Additionally, it is deemed enough if a point n
+lines into the message has been visible in the window where n is
+this variable if this variable is an integer and n is this
+variable times the height of the window if this variable is a
+float."
+  :type 'number
+  :group 'notmuch-show)
+
+(defun notmuch-show-update-seen (top-or-bottom)
+  "Update seen status of current message
+
+Mark that we have seen the TOP-OR-BOTTOM of current message."
+  (let ((current (notmuch-show-get-prop :seen)))
+    (unless (or (eq current 'both) (eq current top-or-bottom))
+      (if (not current)
+	  (notmuch-show-set-prop :seen top-or-bottom)
+	(notmuch-show-set-prop :seen 'both)
+	(notmuch-show-mark-read)))))
+
+(defun notmuch-show-do-message-seen (start end)
+  "Update seen status for the current message.
+
+A message is seen if both the top and enough of the rest of the
+message have been visible in the buffer.  Enough means either the
+bottom of the message or a point in the message more than
+LINES-NEEDED lines into the message. LINES-NEEDED is
+`notmuch-show-seen-lines-needed` if that is an integer and that
+times the current window height if it is a float."
+  (let* ((lines-needed (if (integerp notmuch-show-seen-lines-needed)
+			   notmuch-show-seen-lines-needed
+			 (truncate (* notmuch-show-seen-lines-needed (window-body-height)))))
+	 (top (notmuch-show-message-top))
+	 (bottom (notmuch-show-message-bottom)))
+    (when (notmuch-show-message-visible-p)
+      (when (>= top start)
+	(notmuch-show-update-seen 'top))
+      (when (or (<= bottom end)
+		(> (count-screen-lines top end) lines-needed))
+	(notmuch-show-update-seen 'bottom)))))
+
+(defun notmuch-show-do-seen (start end)
+  "Update seen status for all messages between start and end.
+
+We mark the top (bottom) of a message seen if the top (enough of
+the rest of the message) respectively have been visible in the
+buffer. See `notmuch-show-do-message-seen` for the definition of
+enough. When both the top and bottom have been seen we mark the
+message read."
+  (save-excursion
+    (goto-char start)
+    (notmuch-show-do-message-seen start end)
+    (while (and (< (notmuch-show-message-bottom) end)
+		(notmuch-show-goto-message-next))
+      (notmuch-show-do-message-seen start end))
+    ;; This is a work around because emacs gives weird answers for
+    ;; window-end if the buffer ends with invisible text.
+    (when (and (pos-visible-in-window-p (point-max))
+	       (notmuch-show-message-visible-p))
+      (notmuch-show-update-seen 'bottom))))
+
 (defun notmuch-show-seen-current-message (start end)
   "Mark the current message read if it is open.
 
-- 
1.7.10.4


Thread: