[PATCH WIP] emacs: show: redesign unread/read logic
The decisions of when to mark messages read in notmuch-show has caused confusion/irritation (several discussions on irc and the mailing list eg the thread starting at id:87hadi0xse.fsf at boo.workgroup). This is an attempt to get some logic that people are happier with. Some examples of the current problems are: notmuch marks sometimes closed messages read, notmuch does not mark messages read if you page down through them, and notmuch removes the unread tag too soon: when you first see the message you do not if you have read it before. The patch separates out two things "seeing" a message and "marking it read". A message is deemed seen if both the top and bottom of the message have both been visible in the buffer's window. This is chosen so that just seeing 1 or 2 lines of a message at the bottom of the window does not mark it seen. A closed message is never marked seen. The seen status is updated via a command-hook (run on every command/key-press) so essentially any change which sees a message should mark it as seen. By default the unread status of seen messages is not updated until the user quits the show buffer, and the user has the option of prefix-arg quit to exit the show buffer without updating the unread status. However, if the user sets the custom variable notmuch-show-update-unread-on-seen then the unread status is updated (ie unread tag is removed) as soon as a message is seen (in the above sense). --- This patch brings the unread handling roughly in line with what I would expect, and is reasonably close to the suggestions from Austin id:20131005162202.GJ21611 at mit.edu and Jani id:87vc1aho64.fsf at nikula.org. It was also clear from the discussion that different people want different things so we will need some customisation possibilities. It is a large patch: I am afraid I don't see a way round that. At the moment there are two things that need fixing: first tree-view assumes the old behaviour so its displayed tags get out of sync with the actual tags. Secondly, a lot of tests fail for the obvious reason that the unread tag is not removed at the same time as before. It would be very helpful if people could test and see whether it works as they would like, and if not say why/when it is doing the wrong thing and what it should do in those cases. Best wishes Mark emacs/notmuch-show.el | 151 - emacs/notmuch-tree.el | 20 +-- 2 files changed, 151 insertions(+), 20 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 784644c..1081eb0 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -168,6 +168,10 @@ each attachment handler is logged in buffers with names beginning \" *notmuch-part*\". This option requires emacs version at least 24.3 to work.") +(defvar notmuch-show-seen-plist nil) +(make-variable-buffer-local 'notmuch-show-seen-plist) +(put 'notmuch-show-seen-plist 'permanent-local t) + (defcustom notmuch-show-stash-mlarchive-link-alist '(("Gmane" . "http://mid.gmane.org/;) ("MARC" . "http://marc.info/?i=;) @@ -211,6 +215,15 @@ For example, if you wanted to remove an \"unread\" tag and add a :type '(repeat string) :group 'notmuch-show) +(defcustom notmuch-show-update-unread-on-seen nil + "Update unread tags when seen rathe than when exiting show buffer. + +A message is seen if the top and bottom of the message have both +been visible in the buffer. When this is nil the unread status is +updated on exiting the show buffer. When this is t the unread +status is updated as soon as the message is seen." + :type 'boolean + :group 'notmuch-show) (defmacro with-current-notmuch-show-message ( body) "Evaluate body with current buffer set to the text of current message" @@ -1142,6 +1155,8 @@ function is used." (let ((inhibit-read-only t)) (notmuch-show-mode) +(add-hook 'post-command-hook #'notmuch-show-command-hook nil t) + ;; Don't track undo information for this buffer (set 'buffer-undo-list t) @@ -1213,6 +1228,12 @@ preferences. If invoked with a prefix argument (or RESET-STATE is non-nil) then the state of the buffer (open/closed messages) is reset based on the original query." (interactive "P") + ;; Do not mark seen messages read if we are resetting state. The + ;; idea is that resetting state is asking for the view to be reset + ;; to the current state of the database. + (unless notmuch-show-update-unread-on-seen +(notmuch-show-mark-all-seen-read reset-state)) + (let ((inhibit-read-only t) (state (unless reset-state (notmuch-show-capture-state @@ -1258,6 +1279,8 @@ reset based on the original query." (defvar notmuch-show-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map notmuch-common-keymap) + ;; the following overrides the common-keymap quit + (define-key map [remap notmuch-kill-this-buffer] 'notmuch-show-quit-and-mark-read) (define-key
[PATCH WIP] emacs: show: redesign unread/read logic
The decisions of when to mark messages read in notmuch-show has caused confusion/irritation (several discussions on irc and the mailing list eg the thread starting at id:87hadi0xse.fsf@boo.workgroup). This is an attempt to get some logic that people are happier with. Some examples of the current problems are: notmuch marks sometimes closed messages read, notmuch does not mark messages read if you page down through them, and notmuch removes the unread tag too soon: when you first see the message you do not if you have read it before. The patch separates out two things seeing a message and marking it read. A message is deemed seen if both the top and bottom of the message have both been visible in the buffer's window. This is chosen so that just seeing 1 or 2 lines of a message at the bottom of the window does not mark it seen. A closed message is never marked seen. The seen status is updated via a command-hook (run on every command/key-press) so essentially any change which sees a message should mark it as seen. By default the unread status of seen messages is not updated until the user quits the show buffer, and the user has the option of prefix-arg quit to exit the show buffer without updating the unread status. However, if the user sets the custom variable notmuch-show-update-unread-on-seen then the unread status is updated (ie unread tag is removed) as soon as a message is seen (in the above sense). --- This patch brings the unread handling roughly in line with what I would expect, and is reasonably close to the suggestions from Austin id:20131005162202.gj21...@mit.edu and Jani id:87vc1aho64@nikula.org. It was also clear from the discussion that different people want different things so we will need some customisation possibilities. It is a large patch: I am afraid I don't see a way round that. At the moment there are two things that need fixing: first tree-view assumes the old behaviour so its displayed tags get out of sync with the actual tags. Secondly, a lot of tests fail for the obvious reason that the unread tag is not removed at the same time as before. It would be very helpful if people could test and see whether it works as they would like, and if not say why/when it is doing the wrong thing and what it should do in those cases. Best wishes Mark emacs/notmuch-show.el | 151 - emacs/notmuch-tree.el | 20 +-- 2 files changed, 151 insertions(+), 20 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 784644c..1081eb0 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -168,6 +168,10 @@ each attachment handler is logged in buffers with names beginning \ *notmuch-part*\. This option requires emacs version at least 24.3 to work.) +(defvar notmuch-show-seen-plist nil) +(make-variable-buffer-local 'notmuch-show-seen-plist) +(put 'notmuch-show-seen-plist 'permanent-local t) + (defcustom notmuch-show-stash-mlarchive-link-alist '((Gmane . http://mid.gmane.org/;) (MARC . http://marc.info/?i=;) @@ -211,6 +215,15 @@ For example, if you wanted to remove an \unread\ tag and add a :type '(repeat string) :group 'notmuch-show) +(defcustom notmuch-show-update-unread-on-seen nil + Update unread tags when seen rathe than when exiting show buffer. + +A message is seen if the top and bottom of the message have both +been visible in the buffer. When this is nil the unread status is +updated on exiting the show buffer. When this is t the unread +status is updated as soon as the message is seen. + :type 'boolean + :group 'notmuch-show) (defmacro with-current-notmuch-show-message (rest body) Evaluate body with current buffer set to the text of current message @@ -1142,6 +1155,8 @@ function is used. (let ((inhibit-read-only t)) (notmuch-show-mode) +(add-hook 'post-command-hook #'notmuch-show-command-hook nil t) + ;; Don't track undo information for this buffer (set 'buffer-undo-list t) @@ -1213,6 +1228,12 @@ preferences. If invoked with a prefix argument (or RESET-STATE is non-nil) then the state of the buffer (open/closed messages) is reset based on the original query. (interactive P) + ;; Do not mark seen messages read if we are resetting state. The + ;; idea is that resetting state is asking for the view to be reset + ;; to the current state of the database. + (unless notmuch-show-update-unread-on-seen +(notmuch-show-mark-all-seen-read reset-state)) + (let ((inhibit-read-only t) (state (unless reset-state (notmuch-show-capture-state @@ -1258,6 +1279,8 @@ reset based on the original query. (defvar notmuch-show-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map notmuch-common-keymap) + ;; the following overrides the common-keymap quit + (define-key map [remap notmuch-kill-this-buffer] 'notmuch-show-quit-and-mark-read) (define-key map Z