[PATCH v8] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on registering a :level property in the messages p-list, that is then used by outline-minor-mode to to recognise headers. --- This patch overrides v7 and fixes some issues pointed out by David: - clarify the meaningo of :level with a comment - cl-case instead of cumbersome cond+eq - fix the check for the id of the shown message, since relying on the buffer name is fragile. - move hook code to notmuch-mode body Signed-off-by: jao --- doc/notmuch-emacs.rst | 23 ++ emacs/notmuch-tree.el | 183 +- 2 files changed, 204 insertions(+), 2 deletions(-) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..b5f88a98 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,29 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + +.. el:defcustom:: notmuch-tree-outline-open-on-next + + |docstring::notmuch-tree-outline-open-on-next| .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index b3c2c992..063d9a1d 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1014,7 +1014,10 @@ unchanged ADDRESS if parsing fails." A message tree is another name for a single sub-thread: i.e., a message together with all its descendents." (let ((msg (car tree)) - (replies (cadr tree))) + (replies (cadr tree)) + ;; outline level, computed from the message's depth and + ;; wether or not it's the first message in the tree. + (level (1+ (if (and (eq 0 depth) (not first)) 1 depth (cond ((and (< 0 depth) (not last)) (push (alist-get 'vertical-tee notmuch-tree-thread-symbols) tree-status)) @@ -1034,6 +1037,7 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg :level level)) (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1080,7 +1084,8 @@ Complete list of currently available key bindings: (setq notmuch-buffer-refresh-function #'notmuch-tree-refresh-view) (hl-line-mode 1) (setq buffer-read-only t) - (setq truncate-lines t)) + (setq truncate-lines t) + (when notmuch-tree-outline-enabled (notmuch-tree-outline-mode 1))) (defvar notmuch-tree-process-exit-functions nil "Functions called when the process inserting a tree of results finishes. @@ -1278,6 +1283,180 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. + +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + +(defcustom notmuch-tree-outline-open-on-next nil + "Open new messages under point if they are closed when moving to next one. + +When this flag is set, using the command +`notmuch-tree-outline-next' with point on a header for a new +message that is not shown will open its `notmuch-show' buffer +instead of moving point to next matching message." +
Re: [PATCH v7 1/1] emacs: notmuch-tree-outline-mode
Thanks for your comments, David. Unfortunately, i won't be able to work on this for quite a few months. I am hoping someone else might perhaps take the patch over and fix the issues you pinpoint below. I'm adding just a handful quick comments: On Sun, Dec 11 2022, David Bremner wrote: [...] >> +(defcustom notmuch-tree-outline-open-on-next nil >> + "Open new messages under point if they are closed when moving to next one. >> + >> +When this flag is set, using the command >> +`notmuch-tree-outline-next' with point on a header for a new >> +message that is not shown will open its `notmuch-show' buffer >> +instead of moving point to next matching message." >> + :type 'boolean) >> + > > I'm curious about your choice of defaults here. At least the second > seems like t might make more sense? principle of least surprise: next-message in "normal" tree mode always goes to the next message, regardless of whether the current one is on display or not. for personal use, i defined my own commands changing that behaviour a long time ago, and, in that regard, yes, i agree defaulting to t is more natural. but i wasn't sure other users would agree. >> +(defun notmuch-tree-outline--set-visibility () >> + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) >> +(cond ((eq notmuch-tree-outline-visibility 'hide-others) >> + (notmuch-tree-outline-hide-others)) >> + ((eq notmuch-tree-outline-visibility 'hide-all) >> + (outline-hide-body) > > I wouldn't insist, but cl-case (or even pcase) might be clearer here. no opinion here (personally, i feel exactly the opposite, but i think it's just a matter of taste or familiarity). >> +(add-hook 'notmuch-tree-process-exit-functions >> #'notmuch-tree-outline--on-exit) > > Although it is relatively common in emacs code, I'm a bit skeptical of > using hooks for things not intended to be customized by the user. Should > we just be calling this directly somewhere? i'm neutral on that. with a hook, this package can almost be an independent add-on (it would only need the :level property below). but it's true that doesn't matter if we merge in notmuch. >> +(defsubst notmuch-tree-outline--level ( props) >> + (or (plist-get (or props (notmuch-tree-get-message-properties)) :level) >> 0)) > > As mentioned in my previous reply, I'm still not 100% clear on why we > need both depth and level. i might be misremembering, but i think depth is just an auxiliarly argument taken by that function to know whether it's inserting the tip of a tree or not, not a real depth. level is. so a better way would be to make 'depth' take the values 'level' is currently taking, but i wasn't sure other code would be using depth with its old original meaning (e.g. via and advice; i did at some point). >> +(defsubst notmuch-tree-outline--message-open-p () >> + (and (buffer-live-p notmuch-tree-message-buffer) >> + (get-buffer-window notmuch-tree-message-buffer) >> + (string-match-p (regexp-quote (or (notmuch-tree-get-message-id) "")) > > What's going with the 'or' here? Are we hiding errors? just preventing errors if someone calls this function (via a user-level command) in the "End of search" line or the blank line at the end of the messages list. > >> + (buffer-name notmuch-tree-message-buffer > > At first glance, depending on the buffer name seems fragile? not sure why, or how to make it more robust... >> + Mode definition >> +(defvar notmuch-tree-outline-mode-lighter nil >> + "The lighter mark for notmuch-tree-outline mode. >> +Usually empty since outline-minor-mode's lighter will be active.") > > I feel like I should know what a "lighter" is in this context, but alas, > I don't the string in the mode line used to show a minor mode is active. aka "minor mode lighter" > Finally: > > According to a quick test, the folding does show up in > (visible-buffer-string) (from test/test-lib.el). So it seems feasible to > have a few tests with folded output? indeed. hope someone will find a bit of time for that! (fwiw, i've used variations of this code for almost a year, so it's relatively well field-tested; but of course that doesn't obviate proper tests) cheers, jao -- More people would learn from their mistakes if they weren't so busy denying them - Harlod J. Smith ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
Re: [PATCH v7 0/1] emacs: notmuch-tree-outline-mode
On Fri, Nov 04 2022, jao wrote: > This is essentiall the same as the previously sent v 6, rebased over > the current master branch. Since that previous version has not > elicited special enthusiasm, yet i use it all the time, so if you guys > think it's not worth integrating into notmuch-emacs upstream, please > just let me know and i'll create a separate ELPA package for it. i am actually going to take that back: my patch modifies only one line of existing code (notmuch-tree.el:1037), to set a new message property. tiny as the change is, it'd be quite complicated to do the same externally, from a package (barring very ugly hacks like an :override advice)... so i guess i'll keep using my private version of notmuch-tree.el if this patch cannot get in :) cheers, jao -- Lower your voice and strengthen your argument. -Lebanese proverb ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v7 1/1] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on registering a :level property in the messages p-list, that is then used by outline-minor-mode to to recognise headers. --- Leftover in verson 5 removed, sorry! This version supersedes v4 (id:20220923203449.3747562-1-...@gnu.org) by dispensing with the use of invisible text. Now, if desired, notmuch-tree-outline-mode could live in its own notmuch-tree-outline-mode.el without circular deps, but i don't see a pressing need given that notmuch-tree.el is nicely outlined. Signed-off-by: jao --- doc/notmuch-emacs.rst | 23 ++ emacs/notmuch-tree.el | 180 ++ 2 files changed, 203 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..b5f88a98 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,29 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + +.. el:defcustom:: notmuch-tree-outline-open-on-next + + |docstring::notmuch-tree-outline-open-on-next| .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index b3c2c992..47bd17bc 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1034,6 +1034,8 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg +:level (1+ (if (and (eq 0 depth) (not first)) 1 depth (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1278,6 +1280,184 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. + +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + +(defcustom notmuch-tree-outline-open-on-next nil + "Open new messages under point if they are closed when moving to next one. + +When this flag is set, using the command +`notmuch-tree-outline-next' with point on a header for a new +message that is not shown will open its `notmuch-show' buffer +instead of moving point to next matching message." + :type 'boolean) + + Helper functions +(defsubst notmuch-tree-outline--pop-at-end (pop-at-end) + (if notmuch-tree-outline-auto-close (not pop-at-end) pop-at-end)) + +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-status proc) 'exit) +(notmuch-tree-outline--set-visibility))) + +(add-hook 'notmuch-tree-process-exit-functions #'notmuch-tree-outline--on-exit) + +(defsubst notmuch-tree-outli
[PATCH v7 0/1] emacs: notmuch-tree-outline-mode
This is essentiall the same as the previously sent v 6, rebased over the current master branch. Since that previous version has not elicited special enthusiasm, yet i use it all the time, so if you guys think it's not worth integrating into notmuch-emacs upstream, please just let me know and i'll create a separate ELPA package for it. Thanks! jao jao (1): emacs: notmuch-tree-outline-mode doc/notmuch-emacs.rst | 23 ++ emacs/notmuch-tree.el | 180 ++ 2 files changed, 203 insertions(+) -- 2.38.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v6] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on registering a :level property in the messages p-list, that is then used by outline-minor-mode to to recognise headers. --- Leftover in verson 5 removed, sorry! This version supersedes v4 (id:20220923203449.3747562-1-...@gnu.org) by dispensing with the use of invisible text. Now, if desired, notmuch-tree-outline-mode could live in its own notmuch-tree-outline-mode.el without circular deps, but i don't see a pressing need given that notmuch-tree.el is nicely outlined. Signed-off-by: jao --- doc/notmuch-emacs.rst | 23 ++ emacs/notmuch-tree.el | 180 ++ 2 files changed, 203 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..b5f88a98 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,29 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + +.. el:defcustom:: notmuch-tree-outline-open-on-next + + |docstring::notmuch-tree-outline-open-on-next| .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index b3c2c992..47bd17bc 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1034,6 +1034,8 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg +:level (1+ (if (and (eq 0 depth) (not first)) 1 depth (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1278,6 +1280,184 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. + +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + +(defcustom notmuch-tree-outline-open-on-next nil + "Open new messages under point if they are closed when moving to next one. + +When this flag is set, using the command +`notmuch-tree-outline-next' with point on a header for a new +message that is not shown will open its `notmuch-show' buffer +instead of moving point to next matching message." + :type 'boolean) + + Helper functions +(defsubst notmuch-tree-outline--pop-at-end (pop-at-end) + (if notmuch-tree-outline-auto-close (not pop-at-end) pop-at-end)) + +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-status proc) 'exit) +(notmuch-tree-outline--set-visibility))) + +(add-hook 'notmuch-tree-process-exit-functions #'notmuch-tree-outline--on-exit) + +(defsubst notmuch-tree-outli
[PATCH v5] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on registering a :level property in the messages p-list, that is then used by outline-minor-mode to to recognise headers. --- This version supersedes v4 (id:20220923203449.3747562-1-...@gnu.org) by dispensing with the use of invisible text. Now, if desired, notmuch-tree-outline-mode could live in its own notmuch-tree-outline-mode.el without circular deps, but i don't see a pressing need given that notmuch-tree.el is nicely outlined. Signed-off-by: jao --- doc/notmuch-emacs.rst | 23 ++ emacs/notmuch-tree.el | 181 ++ 2 files changed, 204 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..b5f88a98 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,29 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + +.. el:defcustom:: notmuch-tree-outline-open-on-next + + |docstring::notmuch-tree-outline-open-on-next| .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index b3c2c992..3c92b839 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1034,6 +1034,8 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg +:level (1+ (if (and (eq 0 depth) (not first)) 1 depth (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1278,6 +1280,185 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. + +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + +(defcustom notmuch-tree-outline-open-on-next nil + "Open new messages under point if they are closed when moving to next one. + +When this flag is set, using the command +`notmuch-tree-outline-next' with point on a header for a new +message that is not shown will open its `notmuch-show' buffer +instead of moving point to next matching message." + :type 'boolean) + + Helper functions +(defsubst notmuch-tree-outline--pop-at-end (pop-at-end) + (if notmuch-tree-outline-auto-close (not pop-at-end) pop-at-end)) + +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-status proc) 'exit) +(notmuch-tree-outline--set-visibility))) + +(add-hook 'notmuch-tree-process-exit-functions #'notmuch-tree-outline--on-exit) + +(defsubst notmuch-tree-outline--level ( props) + (or (plist-get (or
[PATCH v4] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on the trick of inserting an invisible prefix before each thread head that is then used as the regexp used by outline-minor-mode to recognise headers. The message plist is also augmented with a :level property that provides a fast outline-level function. --- This version supesedes v3 (id:20220921225510.3159023-1-...@gnu.org) by allowing notmuch-tree-ouline-mode to be enabled manually, not only automatically via notmuch-tree-outline-enabled, which was misnamed in the defcustom, by the way: we use now that name, as documented). Signed-off-by: jao --- doc/notmuch-emacs.rst | 20 + emacs/notmuch-tree.el | 176 ++ 2 files changed, 196 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..53e68c4d 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,26 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 7ceddee2..bff29351 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -989,6 +989,7 @@ unchanged ADDRESS if parsing fails." ;; We need to save the previous subject as it will get overwritten ;; by the insert-field calls. (let ((previous-subject notmuch-tree-previous-subject)) +(notmuch-tree-outline--insert-prefix msg) (insert (notmuch-tree-format-field-list (notmuch-tree-result-format) msg)) (notmuch-tree-set-message-properties msg) (notmuch-tree-set-prop :previous-subject previous-subject) @@ -1036,6 +1037,8 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg +:level (1+ (if (and (eq 0 depth) (not first)) 1 depth (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1265,6 +1268,179 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + + Helper functions +(defsubst notmuch-tree-outline--pop-at-end (pop-at-end) + (if notmuch-tree-outline-auto-close (not pop-at-end) pop-at-end)) + +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-status proc) 'exit) +(notmuch-tree-outline--set-visibility))) + +(add-hook 'notmuch-tree-process-exit-functions #'notmuch-tree-outline--on-exit) + +(defs
[PATCH v3] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on the trick of inserting an invisible prefix before each thread head that is then used as the regexp used by outline-minor-mode to recognise headers. The message plist is also augmented with a :level property that provides a fast outline-level function. --- This version supesedes v2 (id:87v8ta60w4@mail.jao.io) with a small fix for one of the auxiliary functions (notmuch-tree-outline--message-open-p). This version supersedes id:20220918203658.1893065-1-...@gnu.org with: It improves on the above by allowing folding operations for nested subtrees, and fixing some glitches with (folded) thread navigation. Signed-off-by: jao --- doc/notmuch-emacs.rst | 20 + emacs/notmuch-tree.el | 176 ++ 2 files changed, 196 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..53e68c4d 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,26 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 7ceddee2..79de4c3d 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -989,6 +989,7 @@ unchanged ADDRESS if parsing fails." ;; We need to save the previous subject as it will get overwritten ;; by the insert-field calls. (let ((previous-subject notmuch-tree-previous-subject)) +(when notmuch-tree-outline-mode (notmuch-tree-outline--insert-prefix msg)) (insert (notmuch-tree-format-field-list (notmuch-tree-result-format) msg)) (notmuch-tree-set-message-properties msg) (notmuch-tree-set-prop :previous-subject previous-subject) @@ -1036,6 +1037,8 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg +:level (1+ (if (and (eq 0 depth) (not first)) 1 depth (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1265,6 +1268,179 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-mode-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + + Helper functions +(defsubst notmuch-tree-outline--pop-at-end (pop-at-end) + (if notmuch-tree-outline-auto-close (not pop-at-end) pop-at-end)) + +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-mode-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-status proc) 'exit) +(n
[PATCH v2] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on the trick of inserting an invisible prefix before each thread head that is then used as the regexp used by outline-minor-mode to recognise headers. The message plist is also augmented with a :level property that provides a fast outline-level function. --- This version supersedes id:20220918203658.1893065-1-...@gnu.org It improves on the above by allowing folding operations for nested subtrees, and fixing some glitches with (folded) thread navigation. Signed-off-by: jao --- doc/notmuch-emacs.rst | 20 + emacs/notmuch-tree.el | 174 ++ 2 files changed, 194 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..53e68c4d 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,26 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 7ceddee2..c2b5dbf2 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -989,6 +989,7 @@ unchanged ADDRESS if parsing fails." ;; We need to save the previous subject as it will get overwritten ;; by the insert-field calls. (let ((previous-subject notmuch-tree-previous-subject)) +(when notmuch-tree-outline-mode (notmuch-tree-outline--insert-prefix msg)) (insert (notmuch-tree-format-field-list (notmuch-tree-result-format) msg)) (notmuch-tree-set-message-properties msg) (notmuch-tree-set-prop :previous-subject previous-subject) @@ -1036,6 +1037,8 @@ message together with all its descendents." (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) +(setq msg (plist-put msg +:level (1+ (if (and (eq 0 depth) (not first)) 1 depth (notmuch-tree-goto-and-insert-msg msg) (pop tree-status) (pop tree-status) @@ -1265,6 +1268,177 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-mode-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close message and tree windows when moving past the last message." + :type 'boolean) + + Helper functions +(defsubst notmuch-tree-outline--pop-at-end (pop-at-end) + (if notmuch-tree-outline-auto-close (not pop-at-end) pop-at-end)) + +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-mode-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (> (point-max) (point-min))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-status proc) 'exit) +(notmuch-tree-outline--set-visibility))) + +(add-hook 'notmuch-tree-process-exit-functions #'notmuch-tree-outline--on-exit) + +(defsubst notmuch-tree-outline--l
[PATCH] emacs: notmuch-tree-outline-mode
With this mode, one can fold trees in the notmuch-tree buffer as if they were outlines, using all the commands provided by outline-minor-mode. We also define a couple of movement commands that, optional, will ensure that only the thread around point is unfolded. The implementation is based on the trick of inserting an invisible character before each thread head that is then used as the regexp used by outline-minor-mode to recognise headers. --- I've been using this mode for a while and seems to work well for my needs, although every now and then navigation with commands other than the ones it defines puts point in a bad place... usually it's very easy to go back to where you were (e.g., a simple C-a), but maybe i'm having stockholm syndrome :) I think the same trick i'm playing could be used to allow folding of subtrees at more than one level (just insert several hidden > instead of just one), but i'm not sure it would be of much use or introduce any problem, so i've not done it here. Perhaps we could add it under an opt-in option if people think it useful. Signed-off-by: jao --- doc/notmuch-emacs.rst | 20 ++ emacs/notmuch-tree.el | 157 ++ 2 files changed, 177 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 846f5e67..53e68c4d 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -606,6 +606,26 @@ can be controlled by the variable ``notmuch-search-oldest-first``. See also :el:defcustom:`notmuch-search-result-format` and :el:defcustom:`notmuch-unthreaded-result-format`. +It is also possible to enable outlines in notmuch tree buffers, via +``notmuch-tree-outline-mode``. + +|docstring::notmuch-tree-outline-mode| + +The behaviour of this minor mode is affected by the following +customizable variables: + +.. el:defcustom:: notmuch-tree-outline-enabled + + |docstring::notmuch-tree-outline-enabled| + +.. el:defcustom:: notmuch-tree-outline-visibility + + |docstring::notmuch-tree-outline-visibility| + +.. el:defcustom:: notmuch-tree-outline-auto-close + + |docstring::notmuch-tree-outline-auto-close| + .. _notmuch-unthreaded: diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 7ceddee2..50139589 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -984,11 +984,17 @@ unchanged ADDRESS if parsing fails." (setq result-string (concat result-string field-string (notmuch-apply-face result-string face t))) +(defvar notmuch-tree--insert-pre-fun nil + "Function called before every message header in the forest view. +Mainly for internal use (e.g. by outline mode).") + (defun notmuch-tree-insert-msg (msg) "Insert the message MSG according to notmuch-tree-result-format." ;; We need to save the previous subject as it will get overwritten ;; by the insert-field calls. (let ((previous-subject notmuch-tree-previous-subject)) +(when (functionp notmuch-tree--insert-pre-fun) + (funcall notmuch-tree--insert-pre-fun msg)) (insert (notmuch-tree-format-field-list (notmuch-tree-result-format) msg)) (notmuch-tree-set-message-properties msg) (notmuch-tree-set-prop :previous-subject previous-subject) @@ -1265,6 +1271,157 @@ search results and that are also tagged with the given TAG." nil notmuch-search-oldest-first))) +;;; Tree outline mode + Custom variables +(defcustom notmuch-tree-outline-mode-enabled nil + "Whether to automatically activate `notmuch-tree-outline-mode' in tree views." + :type 'boolean) + +(defcustom notmuch-tree-outline-visibility 'hide-others + "Default state of the forest outline for `notmuch-tree-outline-mode'. +This variable controls the state of a forest initially and after +a movement command. If set to nil, all trees are displayed while +the symbol hide-all indicates that all trees in the forest should +be folded and hide-other that only the first one should be +unfolded." + :type '(choice (const :tag "Show all" nil) +(const :tag "Hide others" hide-others) +(const :tag "Hide all" hide-all))) + +(defcustom notmuch-tree-outline-auto-close nil + "Close window when moving past the last message or before the first one." + :type 'boolean) + + Helper functions +(defun notmuch-tree-outline--enable-mode () + (when notmuch-tree-outline-mode-enabled (notmuch-tree-outline-mode 1))) + +(add-hook 'notmuch-tree-mode-hook #'notmuch-tree-outline--enable-mode) + +(defun notmuch-tree-outline--set-visibility () + (when (and notmuch-tree-outline-mode (not (looking-at-p "^$"))) +(cond ((eq notmuch-tree-outline-visibility 'hide-others) + (notmuch-tree-outline-hide-others)) + ((eq notmuch-tree-outline-visibility 'hide-all) + (outline-hide-body) + +(defun notmuch-tree-outline--on-exit (proc) + (when (eq (process-st
[PATCH] emacs: new notmuch-tree-process-exit-functions
Hook run when the tree insertion process finishes its job. -- This patch supersedes , but changing the new variable name. Right now, it can be used for silly things like removing or changing the the "End of search." hardcoded message in the tree buffer. But also for more sophisticated things like folding all threads in add-ons like my outline mode for tree buffers (to be submitted). Signed-off-by: jao --- emacs/notmuch-tree.el | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index f63ac9a5..7ceddee2 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1084,6 +1084,12 @@ Complete list of currently available key bindings: (setq buffer-read-only t) (setq truncate-lines t)) +(defvar notmuch-tree-process-exit-functions nil + "Functions called when the process inserting a tree of results finishes. + +Functions in this list are called with one argument, the process +object, and with the tree results buffer as the current buffer.") + (defun notmuch-tree-process-sentinel (proc _msg) "Add a message to let user know when \"notmuch tree\" exits." (let ((buffer (process-buffer proc)) @@ -1102,7 +1108,8 @@ Complete list of currently available key bindings: (insert "End of search results.") (unless (= exit-status 0) (insert (format " (process returned %d)" exit-status))) - (insert "\n") + (insert "\n" + (run-hook-with-args 'notmuch-tree-process-exit-functions proc)) (defun notmuch-tree-process-filter (proc string) "Process and filter the output of \"notmuch show\" for tree view." -- 2.37.2 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
Re: [PATCH] emacs: new notmuch-tree-process-hook
how about notmuch-tree-process-sentinel-functions, or perhaps, since it's only called on exit, notmuch-tree-process-exit-functions? jao ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: new notmuch-tree-process-hook
Hook run when the tree insertion process finishes its job. -- Right now, it can be used for silly things like removing or changing the the "End of search." hardcoded message in the tree buffer. But also for more sophisticated things like folding all threads in add-ons like my outline mode for tree buffers (to be submitted). Signed-off-by: jao --- emacs/notmuch-tree.el | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index f63ac9a5..265f7c1f 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1084,6 +1084,12 @@ Complete list of currently available key bindings: (setq buffer-read-only t) (setq truncate-lines t)) +(defvar notmuch-tree-process-hook nil + "Hook executed when the process inserting a tree of results finishes. + +Functions in this hook are called with one argument, the process +object, with the tree results buffer as the current buffer.") + (defun notmuch-tree-process-sentinel (proc _msg) "Add a message to let user know when \"notmuch tree\" exits." (let ((buffer (process-buffer proc)) @@ -1102,7 +1108,8 @@ Complete list of currently available key bindings: (insert "End of search results.") (unless (= exit-status 0) (insert (format " (process returned %d)" exit-status))) - (insert "\n") + (insert "\n" + (run-hook-with-args 'notmuch-tree-process-hook proc)) (defun notmuch-tree-process-filter (proc string) "Process and filter the output of \"notmuch show\" for tree view." -- 2.37.2 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v3] emacs: use message-dont-reply-to-names when composing replies
notmuch-mua functions for replies now use the built-in customizable variable message-dont-reply-to-names with the same semantics as message-mode. --- This version of the patch addresses stylistic issues according to review Signed-off-by: jao --- doc/notmuch-emacs.rst | 9 emacs/notmuch-mua.el| 19 test/T454-emacs-dont-reply-names.sh | 76 + 3 files changed, 104 insertions(+) create mode 100755 test/T454-emacs-dont-reply-names.sh diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 78528785..970cd7b7 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -493,6 +493,15 @@ Sending Mail :code:`compose-mail`. To use ``notmuch`` for this, customize this variable to the symbol :code:`notmuch-user-agent`. +:index:`message-dont-reply-to-names` + + When composing mail replies, Emacs's message mode uses the + variable :code:`message-dont-reply-to-names` to exclude + recipients matching a given collection of regular expressions + or satisfying an arbitrary predicate. Notmuch's MUA inherits + this standard mechanism and will honour your customization of + this variable. + Init File - diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 0ae33127..0f9ef3c2 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -21,7 +21,10 @@ ;;; Code: +(eval-when-compile (require 'subr-x)) + (require 'message) +(require 'gmm-utils) (require 'mm-view) (require 'format-spec) @@ -382,6 +385,21 @@ instead of `message-mode' and SWITCH-FUNCTION is mandatory." (erase-buffer) (notmuch-message-mode))) +(defun notmuch-mua--remove-dont-reply-to-names () + (when-let* ((nr (if (functionp message-dont-reply-to-names) + message-dont-reply-to-names + (gmm-regexp-concat message-dont-reply-to-names))) + (nr-filter + (if (functionp nr) + (lambda (mail) (and (not (funcall nr mail)) mail)) +(lambda (mail) (and (not (string-match-p nr mail)) mail) +(dolist (header '("To" "Cc")) + (when-let ((v (message-fetch-field header))) + (let* ((tokens (mapcar #'string-trim (message-tokenize-header v))) + (good-tokens (delq nil (mapcar nr-filter tokens))) + (addr (and good-tokens (mapconcat #'identity good-tokens ", " + (message-replace-header header addr)) + (defun notmuch-mua-mail ( to subject other-headers _continue switch-function yank-action send-actions return-action ignored) @@ -422,6 +440,7 @@ moved to the \"To:\" header." (message-this-is-mail t)) (message-setup-1 headers yank-action send-actions return-action)) (notmuch-fcc-header-setup) + (notmuch-mua--remove-dont-reply-to-names) (message-sort-headers) (message-hide-headers) (set-buffer-modified-p nil) diff --git a/test/T454-emacs-dont-reply-names.sh b/test/T454-emacs-dont-reply-names.sh new file mode 100755 index ..3a770177 --- /dev/null +++ b/test/T454-emacs-dont-reply-names.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +test_description="message-dont-reply-to-names in emacs replies" +. $(dirname "$0")/test-lib.sh || exit 1 +. $NOTMUCH_SRCDIR/test/test-lib-emacs.sh || exit 1 + +EXPECTED=$NOTMUCH_SRCDIR/test/emacs-show.expected-output + +test_require_emacs + +add_email_corpus default + +test_begin_subtest "regular expression" +test_emacs '(let ((message-dont-reply-to-names "notmuchmail\\|noreply\\|harvard")) + (notmuch-mua-new-reply + "id:20091117203301.gv3...@dottiness.seas.harvard.edu" nil t) + (test-visible-output "OUTPUT-FULL.raw"))' + +notmuch_dir_sanitize < OUTPUT-FULL.raw > OUTPUT-FULL +head -6 OUTPUT-FULL > OUTPUT + +cat < EXPECTED +From: Notmuch Test Suite +To: Mikhail Gusarov +Subject: Re: [notmuch] Working with Maildir storage? +In-Reply-To: <20091117203301.gv3...@dottiness.seas.harvard.edu> +Fcc: MAIL_DIR/sent +--text follows this line-- +EOF + +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "predicate" +test_emacs '(let ((message-dont-reply-to-names + (lambda (m) (string-prefix-p "Mikhail" m + (notmuch-mua-new-reply + "id:20091117203301.gv3...@dottiness.seas.harvard.edu" nil t) + (test-visible-output "OUTPUT-FULL-PRED.raw"))' + +notmuch_dir_sanitize < OUTPUT-FULL-PRED.raw > OUTPUT-FULL-PRED +head -7 OUTPUT-FULL-PRED > OUTPUT-PRED + +cat < EXPECTED-PRED +From: Notmuch Test Suite +To: Lars Kellogg-Stedman +Cc: notmuch@notmuchmail.org +Subject: Re: [notmuch] Working with Maildir storage? +In-Reply-To: <20091117203301.gv3...@dottiness.s
[PATCH v2] emacs: use message-dont-reply-to-names when composing replies
notmuch-mua functions for replies now use the built-in customizable variable message-dont-reply-to-names with the same semantics as message-mode. --- This version of the patch adds more testing and ensures predicate values work Signed-off-by: jao --- doc/notmuch-emacs.rst | 9 emacs/notmuch-mua.el| 13 + test/T454-emacs-dont-reply-names.sh | 76 + 3 files changed, 98 insertions(+) create mode 100755 test/T454-emacs-dont-reply-names.sh diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 78528785..970cd7b7 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -493,6 +493,15 @@ Sending Mail :code:`compose-mail`. To use ``notmuch`` for this, customize this variable to the symbol :code:`notmuch-user-agent`. +:index:`message-dont-reply-to-names` + + When composing mail replies, Emacs's message mode uses the + variable :code:`message-dont-reply-to-names` to exclude + recipients matching a given collection of regular expressions + or satisfying an arbitrary predicate. Notmuch's MUA inherits + this standard mechanism and will honour your customization of + this variable. + Init File - diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 0ae33127..865f4bb2 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -382,6 +382,18 @@ instead of `message-mode' and SWITCH-FUNCTION is mandatory." (erase-buffer) (notmuch-message-mode))) +(defun notmuch-mua--remove-dont-reply-to-names () + (when-let ((nr (message-dont-reply-to-names))) +(let ((nr-filter (if (functionp nr) +(lambda (mail) (unless (funcall nr mail) mail)) + (lambda (mail) (unless (string-match-p nr mail) mail) + (dolist (header '("To" "Cc")) + (when-let ((v (message-fetch-field header))) + (let* ((v (mapcar #'string-trim (message-tokenize-header v))) +(vs (delq nil (mapcar nr-filter v))) +(v (when vs (mapconcat #'identity vs ", " + (message-replace-header header v))) + (defun notmuch-mua-mail ( to subject other-headers _continue switch-function yank-action send-actions return-action ignored) @@ -422,6 +434,7 @@ moved to the \"To:\" header." (message-this-is-mail t)) (message-setup-1 headers yank-action send-actions return-action)) (notmuch-fcc-header-setup) + (notmuch-mua--remove-dont-reply-to-names) (message-sort-headers) (message-hide-headers) (set-buffer-modified-p nil) diff --git a/test/T454-emacs-dont-reply-names.sh b/test/T454-emacs-dont-reply-names.sh new file mode 100755 index ..e31141f9 --- /dev/null +++ b/test/T454-emacs-dont-reply-names.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +test_description="emacs reply" +. $(dirname "$0")/test-lib.sh || exit 1 +. $NOTMUCH_SRCDIR/test/test-lib-emacs.sh || exit 1 + +EXPECTED=$NOTMUCH_SRCDIR/test/emacs-show.expected-output + +test_require_emacs + +add_email_corpus default + +test_begin_subtest "regular expression" +test_emacs '(let ((message-dont-reply-to-names "notmuchmail\\|noreply\\|harvard")) + (notmuch-mua-new-reply + "id:20091117203301.gv3...@dottiness.seas.harvard.edu" nil t) + (test-visible-output "OUTPUT-FULL.raw"))' + +notmuch_dir_sanitize < OUTPUT-FULL.raw > OUTPUT-FULL +head -6 OUTPUT-FULL > OUTPUT + +cat < EXPECTED +From: Notmuch Test Suite +To: Mikhail Gusarov +Subject: Re: [notmuch] Working with Maildir storage? +In-Reply-To: <20091117203301.gv3...@dottiness.seas.harvard.edu> +Fcc: MAIL_DIR/sent +--text follows this line-- +EOF + +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "predicate" +test_emacs '(let ((message-dont-reply-to-names + (lambda (m) (string-prefix-p "Mikhail" m + (notmuch-mua-new-reply + "id:20091117203301.gv3...@dottiness.seas.harvard.edu" nil t) + (test-visible-output "OUTPUT-FULL-PRED.raw"))' + +notmuch_dir_sanitize < OUTPUT-FULL-PRED.raw > OUTPUT-FULL-PRED +head -7 OUTPUT-FULL-PRED > OUTPUT-PRED + +cat < EXPECTED-PRED +From: Notmuch Test Suite +To: Lars Kellogg-Stedman +Cc: notmuch@notmuchmail.org +Subject: Re: [notmuch] Working with Maildir storage? +In-Reply-To: <20091117203301.gv3...@dottiness.seas.harvard.edu> +Fcc: MAIL_DIR/sent +--text follows this line-- +EOF + +test_expect_equal_file EXPECTED-PRED OUTPUT-PRED + +test_begin_subtest "nil value" +test_emacs '(let ((message-dont-reply-to-names nil)) + (notmuch-mua-new-reply + "id:20091117203301.gv3...@dottiness.seas.harvard.edu" nil t) + (test-vi
[PATCH] emacs: use message-dont-reply-to-names when composing replies
notmuch-mua functions for replies now use the built-in customizable variable message-dont-reply-to-names with the same semantics as message-mode. Signed-off-by: jao --- doc/notmuch-emacs.rst | 9 emacs/notmuch-mua.el| 13 test/T454-emacs-dont-reply-names.sh | 33 + 3 files changed, 55 insertions(+) create mode 100755 test/T454-emacs-dont-reply-names.sh diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 78528785..970cd7b7 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -493,6 +493,15 @@ Sending Mail :code:`compose-mail`. To use ``notmuch`` for this, customize this variable to the symbol :code:`notmuch-user-agent`. +:index:`message-dont-reply-to-names` + + When composing mail replies, Emacs's message mode uses the + variable :code:`message-dont-reply-to-names` to exclude + recipients matching a given collection of regular expressions + or satisfying an arbitrary predicate. Notmuch's MUA inherits + this standard mechanism and will honour your customization of + this variable. + Init File - diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 0ae33127..6f2b9789 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -382,6 +382,18 @@ instead of `message-mode' and SWITCH-FUNCTION is mandatory." (erase-buffer) (notmuch-message-mode))) +(defun notmuch-mua--remove-dont-reply-to-names () + (when-let ((nr (message-dont-reply-to-names))) +(let ((nr-filter (if (functionp nr) +nr + (lambda (mail) (unless (string-match-p nr mail) mail) + (dolist (header '("To" "Cc")) + (when-let ((v (message-fetch-field header))) + (let* ((v (message-tokenize-header v)) +(vs (delq nil (mapcar nr-filter v))) +(v (when vs (mapconcat #'string-trim vs ", " + (message-replace-header header v))) + (defun notmuch-mua-mail ( to subject other-headers _continue switch-function yank-action send-actions return-action ignored) @@ -422,6 +434,7 @@ moved to the \"To:\" header." (message-this-is-mail t)) (message-setup-1 headers yank-action send-actions return-action)) (notmuch-fcc-header-setup) + (notmuch-mua--remove-dont-reply-to-names) (message-sort-headers) (message-hide-headers) (set-buffer-modified-p nil) diff --git a/test/T454-emacs-dont-reply-names.sh b/test/T454-emacs-dont-reply-names.sh new file mode 100755 index ..64ae74af --- /dev/null +++ b/test/T454-emacs-dont-reply-names.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +test_description="emacs reply" +. $(dirname "$0")/test-lib.sh || exit 1 +. $NOTMUCH_SRCDIR/test/test-lib-emacs.sh || exit 1 + +EXPECTED=$NOTMUCH_SRCDIR/test/emacs-show.expected-output + +test_require_emacs + +add_email_corpus default + +test_begin_subtest "not replying" +test_emacs '(let ((message-dont-reply-to-names "notmuchmail\\|noreply\\|harvard")) + (notmuch-mua-new-reply + "id:20091117203301.gv3...@dottiness.seas.harvard.edu" nil t) + (test-visible-output "OUTPUT-FULL.raw"))' + +notmuch_dir_sanitize < OUTPUT-FULL.raw > OUTPUT-FULL +head -6 OUTPUT-FULL > OUTPUT + +cat < EXPECTED +From: Notmuch Test Suite +To: Mikhail Gusarov +Subject: Re: [notmuch] Working with Maildir storage? +In-Reply-To: <20091117203301.gv3...@dottiness.seas.harvard.edu> +Fcc: MAIL_DIR/sent +--text follows this line-- +EOF + +test_expect_equal_file EXPECTED OUTPUT + +test_done -- 2.36.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v4 1/1] emacs: notmuch-show-header-line: allow format strings and functions
If a string value is assigned to notmuch-show-header-line, it's used as a format string to be passed passed to format-spec with `%s` substituted by the message's subject. If a function is given, it's called with the subject as argument, and its return value used as header line. As before, t means displaying the subject and nil not using any header line. Signed-off-by: jao --- emacs/notmuch-show.el | 46 ++- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 69f6c845..51b916ea 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -85,8 +85,30 @@ visible for any given message." :group 'notmuch-show) (defcustom notmuch-show-header-line t - "Show a header line with the current message's subject." - :type 'boolean + "Show a header line in notmuch show buffers. + +If t (the default), the header line will contain the current +message's subject. + +If a string, this value is interpreted as a format string to be +passed to `format-spec` with `%s` as the substitution variable +for the message's subject. E.g., to display the subject trimmed +to a maximum of 80 columns, you could use \"%>-80s\" as format. + +If you assign to this variable a function, it will be called with +the subject as argument, and the return value will be used as the +header line format. Since the function is called with the +message buffer as the current buffer, it is also possible to +access any other properties of the message, using for instance +notmuch-show functions such as +`notmuch-show-get-message-properties'. + +Finally, if this variabale is set to nil, no header is +displayed." + :type '(choice (const :tag "No header" ni) + (const :tag "Subject" t) + (string :tag "Format") +(function :tag "Function")) :group 'notmuch-show) (defcustom notmuch-show-relative-dates t @@ -1313,6 +1335,18 @@ fallback if the prior matches no messages." (push (list thread "and (" context ")") queries)) queries)) +(defun notmuch-show--header-line-format () + "Compute the header line format of a notmuch-show buffer." + (when notmuch-show-header-line +(let* ((s (notmuch-sanitize + (notmuch-show-strip-re (notmuch-show-get-subject + (subject (replace-regexp-in-string "%" "%%" s))) + (cond ((stringp notmuch-show-header-line) + (format-spec notmuch-show-header-line `((?s . ,subject + ((functionp notmuch-show-header-line) +(funcall notmuch-show-header-line subject)) + (notmuch-show-header-line subject) + (defun notmuch-show--build-buffer ( state) "Display messages matching the current buffer context. @@ -1343,13 +1377,7 @@ If no messages match the query return NIL." ;; display changes. (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags - ;; Set the header line to the subject of the first message. - (when notmuch-show-header-line - (setq header-line-format - (replace-regexp-in-string "%" "%%" - (notmuch-sanitize -(notmuch-show-strip-re - (notmuch-show-get-subject)) + (setq header-line-format (notmuch-show--header-line-format)) (run-hooks 'notmuch-show-hook) (if state (notmuch-show-apply-state state) -- 2.36.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v4 0/1] notmuch-show-header-line: allow format strings and functions
This one overrides id:20220518192956.1440103-1-...@gnu.org, by improving the docstring. jao (1): emacs: notmuch-show-header-line: allow format strings and functions emacs/notmuch-show.el | 46 ++- 1 file changed, 37 insertions(+), 9 deletions(-) -- 2.36.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
notmuch-show-header-line: allow format strings and functions
This one overrides id:20220516022039.551596-1-...@gnu.org, hopefully using proper indentation, and refactoring the new functionality in a separate function for clarity. ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: notmuch-show-header-line: allow format strings and functions
If a string value is assigned to notmuch-show-header-line, it's used as a format string to be passed passed to format-spec with `%s` substituted by the message's subject. If a function is given, it's called with the subject as argument, and its return value used as header line. As before, t means displaying the subject and nil not using any header line. Signed-off-by: jao --- emacs/notmuch-show.el | 42 +- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 69f6c845..266afbaa 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -85,8 +85,26 @@ visible for any given message." :group 'notmuch-show) (defcustom notmuch-show-header-line t - "Show a header line with the current message's subject." - :type 'boolean + "Show a header line in notmuch show buffers. + +If t (the default), the header line will contain the current +message's subject. + +If a string, this value is interpreted as a format string to be +passed to `format-spec` with `%s` as the substitution variable +for the message's subject. E.g., to display the subject trimmed +to a maximum of 80 columns, you could use \"%>-80s\" as format. + +If you assign to this variable a function, the function will be +called with the subject as argument and its return value used as +the header line. + +Finally, if this variabale is set to nil, no header is +displayed." + :type '(choice (const :tag "No header" ni) + (const :tag "Subject" t) + (string :tag "Format") +(function :tag "Function")) :group 'notmuch-show) (defcustom notmuch-show-relative-dates t @@ -1313,6 +1331,18 @@ fallback if the prior matches no messages." (push (list thread "and (" context ")") queries)) queries)) +(defun notmuch-show--header-line-format () + "Compute the header line format of a notmuch-show buffer." + (when notmuch-show-header-line +(let* ((s (notmuch-sanitize + (notmuch-show-strip-re (notmuch-show-get-subject + (subject (replace-regexp-in-string "%" "%%" s))) + (cond ((stringp notmuch-show-header-line) + (format-spec notmuch-show-header-line `((?s . ,subject + ((functionp notmuch-show-header-line) +(funcall notmuch-show-header-line subject)) + (notmuch-show-header-line subject) + (defun notmuch-show--build-buffer ( state) "Display messages matching the current buffer context. @@ -1343,13 +1373,7 @@ If no messages match the query return NIL." ;; display changes. (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags - ;; Set the header line to the subject of the first message. - (when notmuch-show-header-line - (setq header-line-format - (replace-regexp-in-string "%" "%%" - (notmuch-sanitize -(notmuch-show-strip-re - (notmuch-show-get-subject)) + (setq header-line-format (notmuch-show--header-line-format)) (run-hooks 'notmuch-show-hook) (if state (notmuch-show-apply-state state) -- 2.36.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v2 1/1] emacs: notmuch-show-header-line: allow format strings and functions
If a string value is assigned to notmuch-show-header-line, it's used as a format string to be passed passed to format-spec with `%s` substituted by the message's subject. If a function is given, it's called with the subject as argument, and its return value used as header line. As before, t means displaying the subject and nil not using any header line. Signed-off-by: jao --- emacs/notmuch-show.el | 37 ++--- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7c1f02c9..79599480 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -85,8 +85,26 @@ visible for any given message." :group 'notmuch-show) (defcustom notmuch-show-header-line t - "Show a header line with the current message's subject." - :type 'boolean + "Show a header line in notmuch show buffers. + +If t (the default), the header line will contain the current +message's subject. + +If a string, this value is interpreted as a format string to be +passed to `format-spec` with `%s` as the substitution variable +for the message's subject. E.g., to display the subject trimmed +to a maximum of 80 columns, you could use \"%>-80s\" as format. + +If you assign to this variable a function, the function will be +called with the subject as argument and its return value used as +the header line. + +Finally, if this variabale is set to nil, no header is +displayed." + :type '(choice (const :tag "No header" ni) + (const :tag "Subject" t) + (string :tag "Format") +(function :tag "Function")) :group 'notmuch-show) (defcustom notmuch-show-relative-dates t @@ -1351,11 +1369,16 @@ If no messages match the query return NIL." (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags ;; Set the header line to the subject of the first message. (when notmuch-show-header-line - (setq header-line-format - (replace-regexp-in-string "%" "%%" - (notmuch-sanitize -(notmuch-show-strip-re - (notmuch-show-get-subject)) +(let* ((s (replace-regexp-in-string "%" "%%" +(notmuch-sanitize + (notmuch-show-strip-re + (notmuch-show-get-subject) + (h (cond ((stringp notmuch-show-header-line) + (format-spec notmuch-show-header-line `((?s . ,s + ((functionp notmuch-show-header-line) +(funcall notmuch-show-header-line s)) + (notmuch-show-header-line s + (setq header-line-format h))) (run-hooks 'notmuch-show-hook) (if state (notmuch-show-apply-state state) -- 2.36.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v2 0/1] notmuch-show-header-line: allow format strings and functions
This one extends the previous version that accepted a format string by also accepting an arbitrary function. jao (1): emacs: notmuch-show-header-line: allow format strings and functions emacs/notmuch-show.el | 37 ++--- 1 file changed, 30 insertions(+), 7 deletions(-) -- 2.36.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: notmuch-show-header-line: allow format-spec format
If a string value is assigned to notmuch-show-header-line, it's used as a format string to be passed passed to format-spec with `%s` substituted by the message's subject. As before, t means displaying the subject and nil not using any header line. Signed-off-by: jao --- emacs/notmuch-show.el | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7c1f02c9..f31c15e6 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -85,8 +85,18 @@ visible for any given message." :group 'notmuch-show) (defcustom notmuch-show-header-line t - "Show a header line with the current message's subject." - :type 'boolean + "Show a header line in notmuch show buffers. + +If t (the default), the header line will contain the current +message's subject. If a string, this value is interpreted as a +format string to be passed to `format-spec` with `%s` as the +substitution variable for the message's subject. E.g., to +display the subject trimmed to a maximum of 80 columns, you could +use \"%>-80s\" as format. If this variabale is set to nil, no +header is displayed." + :type '(choice (const :tag "No header" ni) + (const :tag "Subject" t) + (string :tag "Format")) :group 'notmuch-show) (defcustom notmuch-show-relative-dates t @@ -1351,11 +1361,14 @@ If no messages match the query return NIL." (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags ;; Set the header line to the subject of the first message. (when notmuch-show-header-line - (setq header-line-format - (replace-regexp-in-string "%" "%%" - (notmuch-sanitize -(notmuch-show-strip-re - (notmuch-show-get-subject)) +(let* ((s (replace-regexp-in-string "%" "%%" +(notmuch-sanitize + (notmuch-show-strip-re + (notmuch-show-get-subject) + (h (cond ((stringp notmuch-show-header-line) + (format-spec notmuch-show-header-line `((?s . ,s + (notmuch-show-header-line s + (setq header-line-format h))) (run-hooks 'notmuch-show-hook) (if state (notmuch-show-apply-state state) -- 2.36.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v7] emacs: customizable names for search buffers
Customizable names for buffers presenting search results, via two custom variables (notmuch-search-buffer-name-format and notmuch-saved-search-buffer-name-format), defaulting to values currently used for plain searches and including too tree and unthreaded search buffers. --- This is a much improved version of the patch in id:20220108204121.1053932-1-...@gnu.org, according to discussion on that thread. This version includes documentation in notmuch-emacs.rst for the new customizable variables (id:87v8yafe1a@tethera.net). Signed-off-by: jao --- doc/notmuch-emacs.rst | 10 emacs/notmuch-hello.el | 11 + emacs/notmuch-tree.el | 10 emacs/notmuch.el | 53 ++ 4 files changed, 65 insertions(+), 19 deletions(-) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index fed619b7..049c7551 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -175,6 +175,16 @@ variables. :index:`notmuch-search-oldest-first` Display the oldest threads at the top of the buffer +It is also possible to costumize how the name of buffers containing +search results is formatted using the following variables: + +:index:`notmuch-search-buffer-name-format` + |docstring::notmuch-search-buffer-name-format| + +:index:`notmuch-saved-search-buffer-name-format` + |docstring::notmuch-saved-search-buffer-name-format| + + .. _notmuch-show: notmuch-show diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 581e7f3a..beb25382 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -486,11 +486,14 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil - (widget-get widget :notmuch-search-oldest-first))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) "tree" t))) + (notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil n nil nil nil + (widget-get widget :notmuch-search-oldest-first (unthreaded -(notmuch-unthreaded (widget-get widget :notmuch-search-terms))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) + "unthreaded" t))) + (notmuch-unthreaded (widget-get widget :notmuch-search-terms) nil nil n))) (t (notmuch-search (widget-get widget :notmuch-search-terms) (widget-get widget :notmuch-search-oldest-first) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index d7486904..303c6fad 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1191,11 +1191,11 @@ The arguments are: (setq query (notmuch-read-query (concat "Notmuch " (if unthreaded "unthreaded " "tree ") "view search: " - (let ((buffer (get-buffer-create (generate-new-buffer-name - (or buffer-name - (concat "*notmuch-" - (if unthreaded "unthreaded-" "tree-") - query "*") + (let* ((name + (or buffer-name + (notmuch-search-buffer-title query + (if unthreaded "unthreaded" "tree" +(buffer (get-buffer-create (generate-new-buffer-name name))) (inhibit-read-only t)) (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 85a54706..6abb17ff 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -915,7 +915,39 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). The +buffer name is formatted using `format-spec': see its docstring +for additional parameters for the s and t format specifiers. + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers for saved searches. + +In this spec, %s will be replaced by the saved search name and %t +by it
[PATCH v6] emacs: customizable names for search buffers
Customizable names for buffers presenting search results, via two custom variables (notmuch-search-buffer-name-format and notmuch-saved-search-buffer-name-format), defaulting to values currently used for plain searches and including too tree and unthreaded search buffers. --- This is a much improved version of the patch in id:20220108204121.1053932-1-...@gnu.org, according to discussion on that thread. This version always uses format-spec, since it's available since ancient times (see discussion in id:875yqjmgaq@kyleam.com). Signed-off-by: jao --- emacs/notmuch-hello.el | 11 + emacs/notmuch-tree.el | 10 emacs/notmuch.el | 53 ++ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index fc007c4c..44341dd6 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -486,11 +486,14 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil - (widget-get widget :notmuch-search-oldest-first))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) "tree" t))) + (notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil n nil nil nil + (widget-get widget :notmuch-search-oldest-first (unthreaded -(notmuch-unthreaded (widget-get widget :notmuch-search-terms))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) + "unthreaded" t))) + (notmuch-unthreaded (widget-get widget :notmuch-search-terms) nil nil n))) (t (notmuch-search (widget-get widget :notmuch-search-terms) (widget-get widget :notmuch-search-oldest-first) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index d7486904..303c6fad 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1191,11 +1191,11 @@ The arguments are: (setq query (notmuch-read-query (concat "Notmuch " (if unthreaded "unthreaded " "tree ") "view search: " - (let ((buffer (get-buffer-create (generate-new-buffer-name - (or buffer-name - (concat "*notmuch-" - (if unthreaded "unthreaded-" "tree-") - query "*") + (let* ((name + (or buffer-name + (notmuch-search-buffer-title query + (if unthreaded "unthreaded" "tree" +(buffer (get-buffer-create (generate-new-buffer-name name))) (inhibit-read-only t)) (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 85a54706..ef3af899 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -915,7 +915,39 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). The +buffer name is formatted using `format-spec': see its docstring +for additional parameters for the s and t format specifiers. + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by the saved search name and %t +by its type (search, tree or unthreaded). The buffer name is +formatted using `format-spec': see its docstring for additional +parameters for the s and t format specifiers. + +See also `notmuch-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defun notmuch-search-format-buffer-name (query type saved) + "Compose a buffer name for the given QUERY, TYPE (search, tree, +unthreaded) and whether it's SAVED (t or nil)." + (let ((fmt (if saved +notmuch-saved-search-buffer-name-format + notmuch-search-buffer-name-format))) +(format-spec fmt `((?t . ,(or type "search")) (?s . ,query) + +(defun notmuch-search-buffer-title (que
[PATCH v5] emacs: customizable names for search buffers
Customizable names for buffers presenting search results, via two custom variables (notmuch-search-buffer-name-format and notmuch-saved-search-buffer-name-format), defaulting to values currently used for plain searches and including too tree and unthreaded search buffers. --- This is a much improved version of the patch in id:20220108204121.1053932-1-...@gnu.org, according to discussion on that thread. This version fixes the regexp for detecting %t in emacs < 27, skipping word boundary checks. Signed-off-by: jao --- emacs/notmuch-hello.el | 11 + emacs/notmuch-tree.el | 10 - emacs/notmuch.el | 51 +- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index fc007c4c..44341dd6 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -486,11 +486,14 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil - (widget-get widget :notmuch-search-oldest-first))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) "tree" t))) + (notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil n nil nil nil + (widget-get widget :notmuch-search-oldest-first (unthreaded -(notmuch-unthreaded (widget-get widget :notmuch-search-terms))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) + "unthreaded" t))) + (notmuch-unthreaded (widget-get widget :notmuch-search-terms) nil nil n))) (t (notmuch-search (widget-get widget :notmuch-search-terms) (widget-get widget :notmuch-search-oldest-first) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index d7486904..303c6fad 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1191,11 +1191,11 @@ The arguments are: (setq query (notmuch-read-query (concat "Notmuch " (if unthreaded "unthreaded " "tree ") "view search: " - (let ((buffer (get-buffer-create (generate-new-buffer-name - (or buffer-name - (concat "*notmuch-" - (if unthreaded "unthreaded-" "tree-") - query "*") + (let* ((name + (or buffer-name + (notmuch-search-buffer-title query + (if unthreaded "unthreaded" "tree" +(buffer (get-buffer-create (generate-new-buffer-name name))) (inhibit-read-only t)) (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 85a54706..8c7eb519 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -915,7 +915,37 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by the saved search name and %t +by its type (search, tree or unthreaded). + +See also `notmuch-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defun notmuch-search-format-buffer-name (query type saved) + "Compose a buffer name for the given QUERY, TYPE (search, tree, +unthreaded) and whether it's SAVED (t or nil)." + (let ((fmt (if saved +notmuch-saved-search-buffer-name-format + notmuch-search-buffer-name-format))) +(if (fboundp 'format-spec) + (format-spec fmt `((?t . ,(or type "search")) (?s . ,query +(format (replace-regexp-in-string "%t" (or type "search") fmt) query))) + +(defun notmuch-search-buffer-title (query type) "Returns the title for a buffer with notmuch search results." (let* ((saved-search (let (longest @@ -930,19 +960,20 @@ See `notmuch
Re: FYI: emacs / notmuch-search-edit-search
hi, On Wed, Jan 12 2022, Tomi Ollila wrote: > Hi all > I've had this for a while in .emacs.d/notmuch-config.el > > --- > > (defun notmuch-search-edit-search () > "Edit current search" > (interactive) > (notmuch-search (read-from-minibuffer > "Edit search: " notmuch-search-query-string) > notmuch-search-oldest-first)) > > (define-key notmuch-search-mode-map "e" #'notmuch-search-edit-search) > > --- this looks useful indeed. if added, please consider adding also a notmuch-tree counterpart. in notmuch-tree-mode-map, "e" is taken for notmuch-tree-resume-message, so perhaps "E" could be used instead, possibly in both maps for consistency. untested: --8<---cut here---start->8--- (defun notmuch-tree-edit-search (query) "Edit the current search" (interactive (list (read-from-minibuffer "Edit search: " notmuch-search-query-string))) (let ((notmuch-show-process-crypto (notmuch-tree--message-process-crypto))) (notmuch-tree-close-message-window) (notmuch-tree query notmuch-tree-query-context nil nil nil notmuch-tree-unthreaded nil notmuch-search-oldest-first))) (define-key notmuch-tree-mode-map "E" #'notmuch-tree-edit-search) --8<---cut here---end--->8--- cheers, jao -- Configuring Emacs is more of a lifestyle choice than a task that one completes. – Stephen A. Ramsey ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v4] emacs: customizable names for search buffers
Customizable names for buffers presenting search results, via two custom variables (notmuch-search-buffer-name-format and notmuch-saved-search-buffer-name-format), defaulting to values currently used for plain searches and including too tree and unthreaded search buffers. --- This is a much improved version of the patch in id:20220108204121.1053932-1-...@gnu.org, according to discussion on that thread. This version fixes a doc string. Signed-off-by: jao --- emacs/notmuch-hello.el | 11 + emacs/notmuch-tree.el | 10 - emacs/notmuch.el | 51 +- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index fc007c4c..44341dd6 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -486,11 +486,14 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil - (widget-get widget :notmuch-search-oldest-first))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) "tree" t))) + (notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil n nil nil nil + (widget-get widget :notmuch-search-oldest-first (unthreaded -(notmuch-unthreaded (widget-get widget :notmuch-search-terms))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) + "unthreaded" t))) + (notmuch-unthreaded (widget-get widget :notmuch-search-terms) nil nil n))) (t (notmuch-search (widget-get widget :notmuch-search-terms) (widget-get widget :notmuch-search-oldest-first) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index d7486904..303c6fad 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1191,11 +1191,11 @@ The arguments are: (setq query (notmuch-read-query (concat "Notmuch " (if unthreaded "unthreaded " "tree ") "view search: " - (let ((buffer (get-buffer-create (generate-new-buffer-name - (or buffer-name - (concat "*notmuch-" - (if unthreaded "unthreaded-" "tree-") - query "*") + (let* ((name + (or buffer-name + (notmuch-search-buffer-title query + (if unthreaded "unthreaded" "tree" +(buffer (get-buffer-create (generate-new-buffer-name name))) (inhibit-read-only t)) (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 85a54706..afb0a115 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -915,7 +915,37 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by the saved search name and %t +by its type (search, tree or unthreaded). + +See also `notmuch-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defun notmuch-search-format-buffer-name (query type saved) + "Compose a buffer name for the given QUERY, TYPE (search, tree, +unthreaded) and whether it's SAVED (t or nil)." + (let ((fmt (if saved +notmuch-saved-search-buffer-name-format + notmuch-search-buffer-name-format))) +(if (fboundp 'format-spec) + (format-spec fmt `((?t . ,(or type "search")) (?s . ,query +(format (replace-regexp-in-string "\\b%t\\b" (or type "search") fmt) query))) + +(defun notmuch-search-buffer-title (query type) "Returns the title for a buffer with notmuch search results." (let* ((saved-search (let (longest @@ -930,19 +960,20 @@ See `notmuch-tag' for information on the format of TAG-CHA
[PATCH v3] emacs: customizable names for search buffers
Customizable names for buffers presenting search results, via two custom variables (notmuch-search-buffer-name-format and notmuch-saved-search-buffer-name-format), defaulting to values currently used for plain searches and including too tree and unthreaded search buffers. --- This is a much improved version of the patch in id:20220108204121.1053932-1-...@gnu.org, according to discussion on that thread. This version just squashes together the two patches in v2. Signed-off-by: jao --- emacs/notmuch-hello.el | 11 ++ emacs/notmuch-tree.el | 10 - emacs/notmuch.el | 50 +- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index fc007c4c..44341dd6 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -486,11 +486,14 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil - (widget-get widget :notmuch-search-oldest-first))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) "tree" t))) + (notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil n nil nil nil + (widget-get widget :notmuch-search-oldest-first (unthreaded -(notmuch-unthreaded (widget-get widget :notmuch-search-terms))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) + "unthreaded" t))) + (notmuch-unthreaded (widget-get widget :notmuch-search-terms) nil nil n))) (t (notmuch-search (widget-get widget :notmuch-search-terms) (widget-get widget :notmuch-search-oldest-first) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index d7486904..303c6fad 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1191,11 +1191,11 @@ The arguments are: (setq query (notmuch-read-query (concat "Notmuch " (if unthreaded "unthreaded " "tree ") "view search: " - (let ((buffer (get-buffer-create (generate-new-buffer-name - (or buffer-name - (concat "*notmuch-" - (if unthreaded "unthreaded-" "tree-") - query "*") + (let* ((name + (or buffer-name + (notmuch-search-buffer-title query + (if unthreaded "unthreaded" "tree" +(buffer (get-buffer-create (generate-new-buffer-name name))) (inhibit-read-only t)) (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 85a54706..a30e3334 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -915,7 +915,36 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by the saved search name and %t +by its type (search, tree or unthreaded). + +See also `notmuch-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defun notmuch-search-format-buffer-name (query type saved) + "Use the FMT spec to provide a query buffer name." + (let ((fmt (if saved +notmuch-saved-search-buffer-name-format + notmuch-search-buffer-name-format))) +(if (fboundp 'format-spec) + (format-spec fmt `((?t . ,(or type "search")) (?s . ,query +(format (replace-regexp-in-string "\\b%t\\b" (or type "search") fmt) query))) + +(defun notmuch-search-buffer-title (query type) "Returns the title for a buffer with notmuch search results." (let* ((saved-search (let (longest @@ -930,19 +959,20 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." do (setq long
[PATCH v2 2/2] emacs: customizable names for search buffers
Customizable names for buffers presenting search results, via two custom variables (notmuch-search-buffer-name-format and notmuch-saved-search-buffer-name-format), defaulting to values currently used for plain searches and including too tree and unthreaded search buffers. --- This is a much improved version of the patch in id:20220108204121.1053932-1-...@gnu.org, according to discussion on that thread. Signed-off-by: jao --- emacs/notmuch-hello.el | 11 ++ emacs/notmuch-tree.el | 10 - emacs/notmuch.el | 50 +- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 9f42a90b..44341dd6 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -486,11 +486,14 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil (widget-value widget) nil nil nil - (widget-get widget :notmuch-search-oldest-first))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) "tree" t))) + (notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil n nil nil nil + (widget-get widget :notmuch-search-oldest-first (unthreaded -(notmuch-unthreaded (widget-get widget :notmuch-search-terms))) +(let ((n (notmuch-search-format-buffer-name (widget-value widget) + "unthreaded" t))) + (notmuch-unthreaded (widget-get widget :notmuch-search-terms) nil nil n))) (t (notmuch-search (widget-get widget :notmuch-search-terms) (widget-get widget :notmuch-search-oldest-first) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index d7486904..303c6fad 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1191,11 +1191,11 @@ The arguments are: (setq query (notmuch-read-query (concat "Notmuch " (if unthreaded "unthreaded " "tree ") "view search: " - (let ((buffer (get-buffer-create (generate-new-buffer-name - (or buffer-name - (concat "*notmuch-" - (if unthreaded "unthreaded-" "tree-") - query "*") + (let* ((name + (or buffer-name + (notmuch-search-buffer-title query + (if unthreaded "unthreaded" "tree" +(buffer (get-buffer-create (generate-new-buffer-name name))) (inhibit-read-only t)) (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 85a54706..a30e3334 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -915,7 +915,36 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." (notmuch-search-get-tags-region (point-min) (point-max)) "Tag all"))) (notmuch-search-tag tag-changes (point-min) (point-max) t)) -(defun notmuch-search-buffer-title (query) +(defcustom notmuch-search-buffer-name-format "*notmuch-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by a description of the search +query and %t by its type (search, tree or unthreaded). + +See also `notmuch-saved-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defcustom notmuch-saved-search-buffer-name-format "*notmuch-saved-%t-%s*" + "Format for the name of search results buffers. + +In this spec, %s will be replaced by the saved search name and %t +by its type (search, tree or unthreaded). + +See also `notmuch-search-buffer-name-format'" + :type 'string + :group 'notmuch-search) + +(defun notmuch-search-format-buffer-name (query type saved) + "Use the FMT spec to provide a query buffer name." + (let ((fmt (if saved +notmuch-saved-search-buffer-name-format + notmuch-search-buffer-name-format))) +(if (fboundp 'format-spec) + (format-spec fmt `((?t . ,(or type "search")) (?s . ,query +(format (replace-regexp-in-string "\\b%t\\b" (or type "search") fmt) query))) + +(defun notmuch-search-buffer-title (query type) "Returns the title for a buffer with notmuch search results." (let* ((saved-search (let (longest @@ -930,19 +959,20 @@ See `notmuch-tag' for information on the format of TAG-CHANGES." do (setq longest tuple)) longest
[PATCH v2 1/2] emacs: use query name for tree saved-search buffer names
This simply mimics what we already do for non-tree searches, and makes up for nicer buffer names. Note that this patch only applies to queries not coming from a search widget in the hello buffer. Signed-off-by: jao --- emacs/notmuch-hello.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index fc007c4c..9f42a90b 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -487,7 +487,7 @@ diagonal." (cl-case (widget-get widget :notmuch-search-type) (tree (notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil + nil nil (widget-value widget) nil nil nil (widget-get widget :notmuch-search-oldest-first))) (unthreaded (notmuch-unthreaded (widget-get widget :notmuch-search-terms))) -- 2.34.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v2] emacs: make header line in notmuch-show buffers optional
New notmuch-show-header-line customizable boolean to allow inhibiting a header line in notmuch-show-mode buffers (for instance, because one prefers to just include Subject in notmuch-message-headers). --- Second version: includes a link to the new variable's docstring in notmuch-show section of notmuch-emacs.rst Signed-off-by: jao --- doc/notmuch-emacs.rst | 3 +++ emacs/notmuch-show.el | 16 +++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 22aee340..fed619b7 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -222,6 +222,9 @@ Display of messages can be controlled by the following variables :index:`notmuch-message-headers-visible` |docstring::notmuch-message-headers-visible| +:index:`notmuch-show-header-line` + |docstring::notmuch-show-header-line| + .. _show-copy: Copy to kill-ring diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 4de3e423..7c1f02c9 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -84,6 +84,11 @@ visible for any given message." :type 'boolean :group 'notmuch-show) +(defcustom notmuch-show-header-line t + "Show a header line with the current message's subject." + :type 'boolean + :group 'notmuch-show) + (defcustom notmuch-show-relative-dates t "Display relative dates in the message summary line." :type 'boolean @@ -1345,11 +1350,12 @@ If no messages match the query return NIL." (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags ;; Set the header line to the subject of the first message. - (setq header-line-format - (replace-regexp-in-string "%" "%%" - (notmuch-sanitize - (notmuch-show-strip-re - (notmuch-show-get-subject) + (when notmuch-show-header-line + (setq header-line-format + (replace-regexp-in-string "%" "%%" + (notmuch-sanitize +(notmuch-show-strip-re + (notmuch-show-get-subject)) (run-hooks 'notmuch-show-hook) (if state (notmuch-show-apply-state state) -- 2.34.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: use query name for tree saved-search buffer names
This simply mimics what we already do for non-tree searches, and makes up for nicer buffer names. Note that this patch only applies to queries not coming from a search widget in the hello buffer. Signed-off-by: jao --- emacs/notmuch-hello.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index fc007c4c..9f42a90b 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -487,7 +487,7 @@ diagonal." (cl-case (widget-get widget :notmuch-search-type) (tree (notmuch-tree (widget-get widget :notmuch-search-terms) - nil nil nil nil nil nil + nil nil (widget-value widget) nil nil nil (widget-get widget :notmuch-search-oldest-first))) (unthreaded (notmuch-unthreaded (widget-get widget :notmuch-search-terms))) -- 2.34.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: make header line in notmuch-show buffers optional
New notmuch-show-header-line customizable boolean to allow inhibiting a header line in notmuch-show-mode buffers (for instance, because one prefers to just include Subject in notmuch-message-headers). Signed-off-by: jao --- emacs/notmuch-show.el | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 4de3e423..7c1f02c9 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -84,6 +84,11 @@ visible for any given message." :type 'boolean :group 'notmuch-show) +(defcustom notmuch-show-header-line t + "Show a header line with the current message's subject." + :type 'boolean + :group 'notmuch-show) + (defcustom notmuch-show-relative-dates t "Display relative dates in the message summary line." :type 'boolean @@ -1345,11 +1350,12 @@ If no messages match the query return NIL." (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags ;; Set the header line to the subject of the first message. - (setq header-line-format - (replace-regexp-in-string "%" "%%" - (notmuch-sanitize - (notmuch-show-strip-re - (notmuch-show-get-subject) + (when notmuch-show-header-line + (setq header-line-format + (replace-regexp-in-string "%" "%%" + (notmuch-sanitize +(notmuch-show-strip-re + (notmuch-show-get-subject)) (run-hooks 'notmuch-show-hook) (if state (notmuch-show-apply-state state) -- 2.34.1 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v4] emacs: notmuch-tree: customizable strings for drawing trees
New customizable variable, notmuch-tree-thread-symbols, that allows tweaking of how trees in a forest are represented. For instance, one can now choose to use an hyphen rather than a white space as a prefix, or replace the character(s) used to draw arrows. --- emacs/notmuch-tree.el | 44 +-- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index b48a132d..485e89a8 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -74,6 +74,30 @@ notmuch-unthreaded-show-out notmuch-tree-show-out)) +(defcustom notmuch-tree-thread-symbols + '((prefix . " ") +(top . "─") +(top-tee . "┬") +(vertical . "│") +(vertical-tee . "├") +(bottom . "╰") +(arrow . "►")) + "Strings used to draw trees in notmuch tree results. +Symbol keys denote where the corresponding string value is used: +`prefix' is used at the top of the tree, followed by `top' if it +has no children or `top-tee' if it does; `vertical' is a bar +connecting with a response down the list skipping the current +one, while `vertical-tee' marks the current message as a reply to +the previous one; `bottom' is used at the bottom of threads. +Finally, the `arrrow' string in the list is used as a pointer to +every message. + +Common customizations include setting `prefix' to \"-\", to see +equal-length prefixes, and `arrow' to an empty string or to a +different kind of arrow point." + :type '(alist :key-type symbol :value-type string) + :group 'notmuch-tree) + (defcustom notmuch-tree-result-format `(("date" . "%12s ") ("authors" . "%-20s") @@ -980,20 +1004,20 @@ message together with all its descendents." (replies (cadr tree))) (cond ((and (< 0 depth) (not last)) - (push "├" tree-status)) + (push (alist-get 'vertical-tee notmuch-tree-thread-symbols) tree-status)) ((and (< 0 depth) last) - (push "╰" tree-status)) + (push (alist-get 'bottom notmuch-tree-thread-symbols) tree-status)) ((and (eq 0 depth) first last) - ;; Choice between these two variants is a matter of taste. - ;; (push "─" tree-status)) - (push " " tree-status)) + (push (alist-get 'prefix notmuch-tree-thread-symbols) tree-status)) ((and (eq 0 depth) first (not last)) - (push "┬" tree-status)) + (push (alist-get 'top-tee notmuch-tree-thread-symbols) tree-status)) ((and (eq 0 depth) (not first) last) - (push "╰" tree-status)) + (push (alist-get 'bottom notmuch-tree-thread-symbols) tree-status)) ((and (eq 0 depth) (not first) (not last)) - (push "├" tree-status))) -(push (concat (if replies "┬" "─") "►") tree-status) + (push (alist-get 'vertical-tee notmuch-tree-thread-symbols) tree-status))) +(push (concat (alist-get (if replies 'top-tee 'top) notmuch-tree-thread-symbols) + (alist-get 'arrow notmuch-tree-thread-symbols)) + tree-status) (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) @@ -1002,7 +1026,7 @@ message together with all its descendents." (pop tree-status) (if last (push " " tree-status) - (push "│" tree-status)) + (push (alist-get 'vertical notmuch-tree-thread-symbols 3) tree-status)) (notmuch-tree-insert-thread replies (1+ depth) tree-status))) (defun notmuch-tree-insert-thread (thread depth tree-status) -- 2.33.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: notmuch-tree: customizable strings for drawing trees
New customizable variable, notmuch-tree-thread-symbols, that allows tweaking of how trees in a forest are represented. For instance, one can now choose to use an hyphen rather than a white space as a prefix, or replace the character(s) used to draw arrows. --- emacs/notmuch-tree.el | 36 ++-- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 2f508128..a1dfa7b1 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -74,6 +74,22 @@ notmuch-unthreaded-show-out notmuch-tree-show-out)) +(defcustom notmuch-tree-thread-symbols '(" " "─" "┬" "│" "├" "╰" "►") + "List of strings used to draw trees in notmuch tree results. +The first element is used at the top of the tree, followed by the +second if it has no children or the third if it does. The fourth +is a bar connecting with a response down the list skipping the +current one, while the fifth marks the current message as a reply +to the previous. The sixth string is used at the bottom of +threads. Finally, the last string in the list is used as a +pointer to every message. + +Common customizations include setting the first element of the +list to \"-\", to see equal-length prefixes, or the last to an +empty string or to a different kind of arrow point." + :type '(list string) + :group 'notmuch-tree) + (defcustom notmuch-tree-result-format `(("date" . "%12s ") ("authors" . "%-20s") @@ -968,20 +984,20 @@ message together with all its descendents." (replies (cadr tree))) (cond ((and (< 0 depth) (not last)) - (push "├" tree-status)) + (push (elt notmuch-tree-thread-symbols 4) tree-status)) ((and (< 0 depth) last) - (push "╰" tree-status)) + (push (elt notmuch-tree-thread-symbols 5) tree-status)) ((and (eq 0 depth) first last) - ;; Choice between these two variants is a matter of taste. - ;; (push "─" tree-status)) - (push " " tree-status)) + (push (elt notmuch-tree-thread-symbols 0) tree-status)) ((and (eq 0 depth) first (not last)) - (push "┬" tree-status)) + (push (elt notmuch-tree-thread-symbols 2) tree-status)) ((and (eq 0 depth) (not first) last) - (push "╰" tree-status)) + (push (elt notmuch-tree-thread-symbols 5) tree-status)) ((and (eq 0 depth) (not first) (not last)) - (push "├" tree-status))) -(push (concat (if replies "┬" "─") "►") tree-status) + (push (elt notmuch-tree-thread-symbols 4) tree-status))) +(push (concat (elt notmuch-tree-thread-symbols (if replies 2 1)) + (elt notmuch-tree-thread-symbols 6)) + tree-status) (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) @@ -990,7 +1006,7 @@ message together with all its descendents." (pop tree-status) (if last (push " " tree-status) - (push "│" tree-status)) + (push (elt notmuch-tree-thread-symbols 3) tree-status)) (notmuch-tree-insert-thread replies (1+ depth) tree-status))) (defun notmuch-tree-insert-thread (thread depth tree-status) -- 2.33.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: notmuch-tree: customizable strings for drawing trees
New customizable variable, notmuch-tree-tread-symbols, that allows tweaking how trees in a forest are represented. For instance, one can now choose to use an hyphen rather than a white space as a prefix, or remove pointy arrows. --- emacs/notmuch-tree.el | 35 +-- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 01a77b71..27e5ac3a 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -74,6 +74,21 @@ notmuch-unthreaded-show-out notmuch-tree-show-out)) +(defcustom notmuch-tree-thread-symbols '(" " "─" "┬" "│" "├" "╰" "►") + "List of strings used to draw trees. +The first element is used at the top of the tree, followed by the +second if it has no direct children or the third if it does. The +fourth is a bar connecting with a response down the list skipping +the current one, while the fifth does not skip. The sixth and +the bottom of the thread. Finally, the last one is a pointer to +every messages. + +Common customizations include setting the first element of the +list to \"-\", to see equal-length prefixes, or the last and +empty string or a different kind of arrow point." + :type '(list string) + :group 'notmuch-tree) + (defcustom notmuch-tree-result-format `(("date" . "%12s ") ("authors" . "%-20s") @@ -968,20 +983,20 @@ message together with all its descendents." (replies (cadr tree))) (cond ((and (< 0 depth) (not last)) - (push "├" tree-status)) + (push (elt notmuch-tree-thread-symbols 4) tree-status)) ((and (< 0 depth) last) - (push "╰" tree-status)) + (push (elt notmuch-tree-thread-symbols 5) tree-status)) ((and (eq 0 depth) first last) - ;; Choice between these two variants is a matter of taste. - ;; (push "─" tree-status)) - (push " " tree-status)) + (push (elt notmuch-tree-thread-symbols 0) tree-status)) ((and (eq 0 depth) first (not last)) - (push "┬" tree-status)) + (push (elt notmuch-tree-thread-symbols 2) tree-status)) ((and (eq 0 depth) (not first) last) - (push "╰" tree-status)) + (push (elt notmuch-tree-thread-symbols 5) tree-status)) ((and (eq 0 depth) (not first) (not last)) - (push "├" tree-status))) -(push (concat (if replies "┬" "─") "►") tree-status) + (push (elt notmuch-tree-thread-symbols 4) tree-status))) +(push (concat (elt notmuch-tree-thread-symbols (if replies 2 1)) + (elt notmuch-tree-thread-symbols 6)) + tree-status) (setq msg (plist-put msg :first (and first (eq 0 depth (setq msg (plist-put msg :tree-status tree-status)) (setq msg (plist-put msg :orig-tags (plist-get msg :tags))) @@ -990,7 +1005,7 @@ message together with all its descendents." (pop tree-status) (if last (push " " tree-status) - (push "│" tree-status)) + (push (elt notmuch-tree-thread-symbols 3) tree-status)) (notmuch-tree-insert-thread replies (1+ depth) tree-status))) (defun notmuch-tree-insert-thread (thread depth tree-status) -- 2.33.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: honour notmuch-show-text/html-blocked-images in w3m messages
When mm-text-html-renderer is set to 'w3m, the variable playing the role of a regular expression for blocked images is w3m-ignored-image-url-regexp. We bind it when the renderer is not 'shr. --- emacs/notmuch-show.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 9a95eb34..0f96c4fe 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -59,6 +59,7 @@ (defvar shr-blocked-images) (defvar gnus-blocked-images) (defvar shr-content-function) +(defvar w3m-ignored-image-url-regexp) ;;; Options @@ -823,7 +824,8 @@ will return nil if the CID is unknown or cannot be retrieved." (let ((mm-inline-text-html-with-w3m-keymap nil) ;; FIXME: If we block an image, offer a button to load external ;; images. - (gnus-blocked-images notmuch-show-text/html-blocked-images)) + (gnus-blocked-images notmuch-show-text/html-blocked-images) + (w3m-ignored-image-url-regexp notmuch-show-text/html-blocked-images)) (notmuch-show-insert-part-*/* msg part content-type nth depth button ;;; Functions used by notmuch-show--insert-part-text/html-shr -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v2] emacs: new command notmuch-tree-filter
This command is analogous to notmuch-filter, but is defined on tree mode buffers. --- doc/notmuch-emacs.rst | 3 +++ emacs/notmuch-tree.el | 16 2 files changed, 19 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 952fe2a5..5accfa60 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -302,6 +302,9 @@ tags. ``o`` ``notmuch-tree-toggle-order`` |docstring::notmuch-tree-toggle-order| +``l`` ``notmuch-tree-filter`` + Filter or LIMIT the current search results based on an additional query string + ``g`` ``=`` Refresh the buffer diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index ef1ca4c5..f2938330 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -349,6 +349,7 @@ then NAME behaves like CMD." (define-key map "r" 'notmuch-tree-reply-sender) (define-key map "R" 'notmuch-tree-reply) (define-key map "V" 'notmuch-tree-view-raw-message) +(define-key map "l" 'notmuch-tree-filter) ;; The main tree view bindings (define-key map (kbd "RET") 'notmuch-tree-show-message) @@ -1168,6 +1169,21 @@ The arguments are: (interactive) (notmuch-tree query query-context target buffer-name open-target t)) +(defun notmuch-tree-filter (query) + "Filter or LIMIT the current search results based on an additional query string. + +Runs a new tree search matching only messages that match both the +current search results AND the additional query string provided." + (interactive (list (notmuch-read-query "Filter search: "))) + (let ((notmuch-show-process-crypto (notmuch-tree--message-process-crypto)) + (grouped-query (notmuch-group-disjunctive-query-string query)) + (grouped-original-query (notmuch-group-disjunctive-query-string +(notmuch-tree-get-query +(notmuch-tree-close-message-window) +(notmuch-tree (if (string= grouped-original-query "*") + grouped-query + (concat grouped-original-query " and " grouped-query) + ;;; _ (provide 'notmuch-tree) -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
emacs: new command notmuch-tree-filter (alternative)
The following patch is an alternative, shorter implementation of notmuch-tree-filter that doesn't try to use the notmuch-tree--define-close-message-window-and somewhat artificially. Either version works for me. ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH] emacs: new command notmuch-tree-filter
This command is analogous to notmuch-filter, but is defined on tree mode buffers. --- doc/notmuch-emacs.rst | 3 +++ emacs/notmuch-tree.el | 19 +++ 2 files changed, 22 insertions(+) diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 952fe2a5..5accfa60 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -302,6 +302,9 @@ tags. ``o`` ``notmuch-tree-toggle-order`` |docstring::notmuch-tree-toggle-order| +``l`` ``notmuch-tree-filter`` + Filter or LIMIT the current search results based on an additional query string + ``g`` ``=`` Refresh the buffer diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index ef1ca4c5..a18b47ff 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -349,6 +349,7 @@ then NAME behaves like CMD." (define-key map "r" 'notmuch-tree-reply-sender) (define-key map "R" 'notmuch-tree-reply) (define-key map "V" 'notmuch-tree-view-raw-message) +(define-key map "l" 'notmuch-tree-filter) ;; The main tree view bindings (define-key map (kbd "RET") 'notmuch-tree-show-message) @@ -1168,6 +1169,24 @@ The arguments are: (interactive) (notmuch-tree query query-context target buffer-name open-target t)) +(eval-when-compile + (defun notmuch-tree--filter (query) +"Filter or LIMIT the current search results based on an additional query string. + +Runs a new tree search matching only messages that match both the +current search results AND the additional query string provided." +(interactive (list (notmuch-read-query "Filter search: "))) +(let ((grouped-query (notmuch-group-disjunctive-query-string query)) + (grouped-original-query (notmuch-group-disjunctive-query-string + (notmuch-tree-get-query + (notmuch-tree (if (string= grouped-original-query "*") + grouped-query + (concat grouped-original-query " and " grouped-query)) + +(notmuch-tree--define-close-message-window-and + notmuch-tree-filter + notmuch-tree--filter) + ;;; _ (provide 'notmuch-tree) -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
Re: New --sort for notmuch show emacs notmuch-tree-mode (v3)
On Sat, Jul 03 2021, David Bremner wrote: > I have applied this version to master Thanks, David. Very much appreciated: i've been using it locally for weeks now and have experience no problems, so i hope other people will find it useful too. Cheers, jao -- Don't be yourself. Be someone a little nicer. -Mignon McLaughlin, journalist and author (1913-1983) ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v3 5/5] doc: new notmuch show --sort and related emacs commands
New --sort CLI option documented in notmuch-show's man page, and notmuch-search-toggle-order mentioned in doc/notmuch-emacs.rst and devel/emacs-keybindings.org (in the latter, there's also some whitespace changes in a table introduced by org-mode). --- devel/emacs-keybindings.org | 10 +- doc/man1/notmuch-show.rst | 13 + doc/notmuch-emacs.rst | 7 +++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/devel/emacs-keybindings.org b/devel/emacs-keybindings.org index 65dfe0eb..f7df3040 100644 --- a/devel/emacs-keybindings.org +++ b/devel/emacs-keybindings.org @@ -15,7 +15,7 @@ | l | notmuch-search-filter | notmuch-show-filter-thread| | | m | notmuch-mua-new-mail | notmuch-mua-new-mail | notmuch-mua-new-mail| | n | notmuch-search-next-thread | notmuch-show-next-open-message| notmuch-tree-next-matching-message | -| o | notmuch-search-toggle-order| | | +| o | notmuch-search-toggle-order| | notmuch-tree-toggle-order | | p | notmuch-search-previous-thread | notmuch-show-previous-open-message| notmuch-tree-prev-matching-message | | q | notmuch-bury-or-kill-this-buffer | notmuch-bury-or-kill-this-buffer | notmuch-bury-or-kill-this-buffer| | r | notmuch-search-reply-to-thread-sender | notmuch-show-reply-sender | notmuch-show-reply-sender | @@ -38,10 +38,10 @@ | V || notmuch-show-view-raw-message | notmuch-show-view-raw-message | | X || notmuch-show-archive-thread-then-exit | | | Z | notmuch-tree-from-search-current-query | notmuch-tree-from-show-current-query | | -| =!= || notmuch-show-toggle-elide-non-matching| | -| =#= || notmuch-show-print-message| | -| =$= || notmuch-show-toggle-process-crypto| | -| =*= | notmuch-search-tag-all | notmuch-show-tag-all | notmuch-tree-tag-thread | +| =!= || notmuch-show-toggle-elide-non-matching| | +| =#= || notmuch-show-print-message| | +| =$= || notmuch-show-toggle-process-crypto| | +| =*= | notmuch-search-tag-all | notmuch-show-tag-all | notmuch-tree-tag-thread | | + | notmuch-search-add-tag | notmuch-show-add-tag | notmuch-tree-add-tag| | - | notmuch-search-remove-tag | notmuch-show-remove-tag | notmuch-tree-remove-tag | | . || notmuch-show-part-map | | diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst index fc6bec62..64639174 100644 --- a/doc/man1/notmuch-show.rst +++ b/doc/man1/notmuch-show.rst @@ -111,6 +111,19 @@ Supported options for **show** include part still has two MIME parts: part 0 is the whole message (headers and body) and part 1 is just the body. +.. option:: --sort=(newest-first|oldest-first) + + This option can be used to present results in either chronological + order (**oldest-first**) or reverse chronological order + (**newest-first**). + + Only threads as a whole are reordered. Ordering of messages within + each thread will not be affected by this flag, since that order is + always determined by the thread's replies. + + By default, results will be displayed in reverse chronological + order, (that is, the newest results will be displayed first). + .. option:: --verify Compute and
[PATCH v3 4/5] emacs/tree: command to toggle search sort order in tree mode
New command notmuch-tree-toggle-order for switching the sort order (by reissuing the search with a different flag) in a notmuch-tree buffer. --- emacs/notmuch-tree.el | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 49d7659e..b288c05d 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -326,6 +326,7 @@ then NAME behaves like CMD." (define-key map [remap notmuch-mua-new-mail] 'notmuch-tree-new-mail) (define-key map [remap notmuch-jump-search] 'notmuch-tree-jump-search) +(define-key map "o" 'notmuch-tree-toggle-order) (define-key map "S" 'notmuch-search-from-tree-current-query) (define-key map "U" 'notmuch-unthreaded-from-tree-current-query) (define-key map "Z" 'notmuch-tree-from-unthreaded-current-query) @@ -751,7 +752,8 @@ nil otherwise." query-context target nil -unthreaded))) +unthreaded +notmuch-search-oldest-first))) (defun notmuch-tree-thread-top () (when (notmuch-tree-get-message-properties) @@ -1073,6 +1075,7 @@ the same as for the function notmuch-tree." (interactive) (notmuch-tree-mode) (add-hook 'post-command-hook #'notmuch-tree-command-hook t t) + (setq notmuch-search-oldest-first oldest-first) (setq notmuch-tree-unthreaded unthreaded) (setq notmuch-tree-basic-query basic-query) (setq notmuch-tree-query-context (if (or (string= query-context "") @@ -1117,6 +1120,15 @@ the same as for the function notmuch-tree." ")") notmuch-tree-basic-query)) +(defun notmuch-tree-toggle-order () + "Toggle the current search order. + +This command toggles the sort order for the current search. The +default sort order is defined by `notmuch-search-oldest-first'." + (interactive) + (setq notmuch-search-oldest-first (not notmuch-search-oldest-first)) + (notmuch-tree-refresh-view)) + (defun notmuch-tree ( query query-context target buffer-name open-target unthreaded parent-buffer oldest-first) "Display threads matching QUERY in tree view. -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v3 3/5] emacs/hello: honouring :sort-order in threaded queries
Now that notmuch show accepts --sort, we can, on the emacs side, use it according to the value of :sort-order in the definition of saved queries. --- emacs/notmuch-hello.el | 4 +++- emacs/notmuch-tree.el | 10 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 531f209d..5e1ff5fe 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -484,7 +484,9 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms))) +(notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil nil nil nil nil + (widget-get widget :notmuch-search-oldest-first))) (unthreaded (notmuch-unthreaded (widget-get widget :notmuch-search-terms))) (t diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 56863701..49d7659e 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1064,7 +1064,8 @@ Complete list of currently available key bindings: (notmuch-sexp-parse-partial-list 'notmuch-tree-insert-forest-thread results-buf) -(defun notmuch-tree-worker (basic-query query-context target open-target unthreaded) +(defun notmuch-tree-worker (basic-query query-context target + open-target unthreaded oldest-first) "Insert the tree view of the search in the current buffer. This is is a helper function for notmuch-tree. The arguments are @@ -1090,6 +1091,7 @@ the same as for the function notmuch-tree." (let* ((search-args (concat basic-query (and query-context (concat " and (" query-context ")" +(sort-arg (if oldest-first "--sort=oldest-first" "--sort=newest-first")) (message-arg (if unthreaded "--unthreaded" "--entire-thread"))) (when (equal (car (process-lines notmuch-command "count" search-args)) "0") (setq search-args basic-query)) @@ -1097,7 +1099,7 @@ the same as for the function notmuch-tree." (let ((proc (notmuch-start-notmuch "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel "show" "--body=false" "--format=sexp" "--format-version=4" -message-arg search-args)) +sort-arg message-arg search-args)) ;; Use a scratch buffer to accumulate partial output. ;; This buffer will be killed by the sentinel, which ;; should be called no matter how the process dies. @@ -1116,7 +1118,7 @@ the same as for the function notmuch-tree." notmuch-tree-basic-query)) (defun notmuch-tree ( query query-context target buffer-name - open-target unthreaded parent-buffer) + open-target unthreaded parent-buffer oldest-first) "Display threads matching QUERY in tree view. The arguments are: @@ -1145,7 +1147,7 @@ The arguments are: (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer (setq buffer-undo-list t) - (notmuch-tree-worker query query-context target open-target unthreaded) + (notmuch-tree-worker query query-context target open-target unthreaded oldest-first) (setq notmuch-tree-parent-buffer parent-buffer) (setq truncate-lines t)) -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v3 1/5] CLI/show: accept --sort
Add the command-line option --sort to the show command of the CLI notmuch interface, with the same possible values as the same option in notmuch search. --- notmuch-show.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/notmuch-show.c b/notmuch-show.c index 232557d5..852afc8d 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1249,8 +1249,13 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) bool single_message; bool unthreaded = FALSE; notmuch_status_t status; +int sort = NOTMUCH_SORT_NEWEST_FIRST; notmuch_opt_desc_t options[] = { + { .opt_keyword = , .name = "sort", .keywords = + (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST }, + { "newest-first", NOTMUCH_SORT_NEWEST_FIRST }, + { 0, 0 } } }, { .opt_keyword = , .name = "format", .keywords = (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON }, { "text", NOTMUCH_FORMAT_TEXT }, @@ -1367,6 +1372,8 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) return EXIT_FAILURE; } +notmuch_query_set_sort (query, sort); + /* Create structure printer. */ formatter = formatters[format]; sprinter = formatter->new_sprinter (notmuch, stdout); -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH v3 2/5] CLI/show: tests for the new --sort option
New unit tests for notmuch show --sort, covering the basic use cases. --- test/T520-show.sh | 17 + 1 file changed, 17 insertions(+) diff --git a/test/T520-show.sh b/test/T520-show.sh index 16222650..6f42ca12 100755 --- a/test/T520-show.sh +++ b/test/T520-show.sh @@ -10,4 +10,21 @@ notmuch show foo.. exit_code=$? test_expect_equal 1 $exit_code +test_begin_subtest "notmuch show --sort=newest-first" +notmuch show --entire-thread=true '*' > EXPECTED +notmuch show --entire-thread=true --sort=newest-first '*' > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "notmuch show --sort=oldest-first" +notmuch show --entire-thread=true '*' | grep ^depth:0 > EXPECTED +notmuch show --entire-thread=true --sort=oldest-first '*' | grep ^depth:0 > OLDEST +perl -e 'print reverse<>' OLDEST > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "notmuch show --sort for single thread" +QUERY="id:yun1vjwegii@aiko.keithp.com" +notmuch show --entire-thread=true --sort=newest-first $QUERY > EXPECTED +notmuch show --entire-thread=true --sort=oldest-first $QUERY > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + test_done -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
New --sort for notmuch show emacs notmuch-tree-mode (v3)
version 3, rebased against master and superseding 20210626022846.233052-1-jao%40gnu.org and 20210626180650.342569-1-jao%40gnu.org [PATCH v3 1/5] CLI/show: accept --sort [PATCH v3 2/5] CLI/show: tests for the new --sort option [PATCH v3 3/5] emacs/hello: honouring :sort-order in threaded queries [PATCH v3 4/5] emacs/tree: command to toggle search sort order in [PATCH v3 5/5] doc: new notmuch show --sort and related emacs ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 5/5] doc: new notmuch show --sort and related emacs commands
New --sort CLI option documented in notmuch-show's man page, and notmuch-search-toggle-order mentioned in doc/notmuch-emacs.rst and devel/emacs-keybindings.org (in the latter, there's also some whitespace changes in a table introduced by org-mode). --- devel/emacs-keybindings.org | 10 +- doc/man1/notmuch-show.rst | 13 + doc/notmuch-emacs.rst | 7 +++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/devel/emacs-keybindings.org b/devel/emacs-keybindings.org index 65dfe0eb..f7df3040 100644 --- a/devel/emacs-keybindings.org +++ b/devel/emacs-keybindings.org @@ -15,7 +15,7 @@ | l | notmuch-search-filter | notmuch-show-filter-thread| | | m | notmuch-mua-new-mail | notmuch-mua-new-mail | notmuch-mua-new-mail| | n | notmuch-search-next-thread | notmuch-show-next-open-message| notmuch-tree-next-matching-message | -| o | notmuch-search-toggle-order| | | +| o | notmuch-search-toggle-order| | notmuch-tree-toggle-order | | p | notmuch-search-previous-thread | notmuch-show-previous-open-message| notmuch-tree-prev-matching-message | | q | notmuch-bury-or-kill-this-buffer | notmuch-bury-or-kill-this-buffer | notmuch-bury-or-kill-this-buffer| | r | notmuch-search-reply-to-thread-sender | notmuch-show-reply-sender | notmuch-show-reply-sender | @@ -38,10 +38,10 @@ | V || notmuch-show-view-raw-message | notmuch-show-view-raw-message | | X || notmuch-show-archive-thread-then-exit | | | Z | notmuch-tree-from-search-current-query | notmuch-tree-from-show-current-query | | -| =!= || notmuch-show-toggle-elide-non-matching| | -| =#= || notmuch-show-print-message| | -| =$= || notmuch-show-toggle-process-crypto| | -| =*= | notmuch-search-tag-all | notmuch-show-tag-all | notmuch-tree-tag-thread | +| =!= || notmuch-show-toggle-elide-non-matching| | +| =#= || notmuch-show-print-message| | +| =$= || notmuch-show-toggle-process-crypto| | +| =*= | notmuch-search-tag-all | notmuch-show-tag-all | notmuch-tree-tag-thread | | + | notmuch-search-add-tag | notmuch-show-add-tag | notmuch-tree-add-tag| | - | notmuch-search-remove-tag | notmuch-show-remove-tag | notmuch-tree-remove-tag | | . || notmuch-show-part-map | | diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst index fc6bec62..64639174 100644 --- a/doc/man1/notmuch-show.rst +++ b/doc/man1/notmuch-show.rst @@ -111,6 +111,19 @@ Supported options for **show** include part still has two MIME parts: part 0 is the whole message (headers and body) and part 1 is just the body. +.. option:: --sort=(newest-first|oldest-first) + + This option can be used to present results in either chronological + order (**oldest-first**) or reverse chronological order + (**newest-first**). + + Only threads as a whole are reordered. Ordering of messages within + each thread will not be affected by this flag, since that order is + always determined by the thread's replies. + + By default, results will be displayed in reverse chronological + order, (that is, the newest results will be displayed first). + .. option:: --verify Compute and
[PATCH 4/5] emacs/tree: command to toggle search sort order in tree mode
New command notmuch-tree-toggle-order for switching the sort order (by reissuing the search with a different flag) in a notmuch-tree buffer. --- emacs/notmuch-tree.el | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 6ef8e439..c421cf3f 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -326,6 +326,7 @@ then NAME behaves like CMD." (define-key map [remap notmuch-mua-new-mail] 'notmuch-tree-new-mail) (define-key map [remap notmuch-jump-search] 'notmuch-tree-jump-search) +(define-key map "o" 'notmuch-tree-toggle-order) (define-key map "S" 'notmuch-search-from-tree-current-query) (define-key map "U" 'notmuch-unthreaded-from-tree-current-query) (define-key map "Z" 'notmuch-tree-from-unthreaded-current-query) @@ -749,7 +750,8 @@ nil otherwise." query-context target nil -unthreaded))) +unthreaded +notmuch-search-oldest-first))) (defun notmuch-tree-thread-top () (when (notmuch-tree-get-message-properties) @@ -1071,6 +1073,7 @@ the same as for the function notmuch-tree." (interactive) (notmuch-tree-mode) (add-hook 'post-command-hook #'notmuch-tree-command-hook t t) + (setq notmuch-search-oldest-first oldest-first) (setq notmuch-tree-unthreaded unthreaded) (setq notmuch-tree-basic-query basic-query) (setq notmuch-tree-query-context (if (or (string= query-context "") @@ -1115,6 +1118,15 @@ the same as for the function notmuch-tree." ")") notmuch-tree-basic-query)) +(defun notmuch-tree-toggle-order () + "Toggle the current search order. + +This command toggles the sort order for the current search. The +default sort order is defined by `notmuch-search-oldest-first'." + (interactive) + (setq notmuch-search-oldest-first (not notmuch-search-oldest-first)) + (notmuch-tree-refresh-view)) + (defun notmuch-tree ( query query-context target buffer-name open-target unthreaded parent-buffer oldest-first) "Display threads matching QUERY in tree view. -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 3/5] emacs/hello: honouring :sort-order in threaded queries
Now that notmuch show accepts --sort, we can, on the emacs side, use it according to the value of :sort-order in the definition of saved queries. --- emacs/notmuch-hello.el | 4 +++- emacs/notmuch-tree.el | 10 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 531f209d..5e1ff5fe 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -484,7 +484,9 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms))) +(notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil nil nil nil nil + (widget-get widget :notmuch-search-oldest-first))) (unthreaded (notmuch-unthreaded (widget-get widget :notmuch-search-terms))) (t diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 00ee78d6..6ef8e439 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1062,7 +1062,8 @@ Complete list of currently available key bindings: (notmuch-sexp-parse-partial-list 'notmuch-tree-insert-forest-thread results-buf) -(defun notmuch-tree-worker (basic-query query-context target open-target unthreaded) +(defun notmuch-tree-worker (basic-query query-context target + open-target unthreaded oldest-first) "Insert the tree view of the search in the current buffer. This is is a helper function for notmuch-tree. The arguments are @@ -1088,6 +1089,7 @@ the same as for the function notmuch-tree." (let* ((search-args (concat basic-query (and query-context (concat " and (" query-context ")" +(sort-arg (if oldest-first "--sort=oldest-first" "--sort=newest-first")) (message-arg (if unthreaded "--unthreaded" "--entire-thread"))) (when (equal (car (process-lines notmuch-command "count" search-args)) "0") (setq search-args basic-query)) @@ -1095,7 +1097,7 @@ the same as for the function notmuch-tree." (let ((proc (notmuch-start-notmuch "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel "show" "--body=false" "--format=sexp" "--format-version=4" -message-arg search-args)) +sort-arg message-arg search-args)) ;; Use a scratch buffer to accumulate partial output. ;; This buffer will be killed by the sentinel, which ;; should be called no matter how the process dies. @@ -1114,7 +1116,7 @@ the same as for the function notmuch-tree." notmuch-tree-basic-query)) (defun notmuch-tree ( query query-context target buffer-name - open-target unthreaded parent-buffer) + open-target unthreaded parent-buffer oldest-first) "Display threads matching QUERY in tree view. The arguments are: @@ -1143,7 +1145,7 @@ The arguments are: (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer (setq buffer-undo-list t) - (notmuch-tree-worker query query-context target open-target unthreaded) + (notmuch-tree-worker query query-context target open-target unthreaded oldest-first) (setq notmuch-tree-parent-buffer parent-buffer) (setq truncate-lines t)) -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 1/5] CLI/show: accept --sort
Add the command-line option --sort to the show command of the CLI notmuch interface, with the same possible values as the same option in notmuch search. --- notmuch-show.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/notmuch-show.c b/notmuch-show.c index bdb87321..947ffa8d 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1244,8 +1244,13 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) bool single_message; bool unthreaded = FALSE; notmuch_status_t status; +int sort = NOTMUCH_SORT_NEWEST_FIRST; notmuch_opt_desc_t options[] = { + { .opt_keyword = , .name = "sort", .keywords = + (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST }, + { "newest-first", NOTMUCH_SORT_NEWEST_FIRST }, + { 0, 0 } } }, { .opt_keyword = , .name = "format", .keywords = (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON }, { "text", NOTMUCH_FORMAT_TEXT }, @@ -1362,6 +1367,8 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) return EXIT_FAILURE; } +notmuch_query_set_sort (query, sort); + /* Create structure printer. */ formatter = formatters[format]; sprinter = formatter->new_sprinter (notmuch, stdout); -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 2/5] CLI/show: tests for the new --sort option
New unit tests for notmuch show --sort, covering the basic use cases. --- test/T520-show.sh | 17 + 1 file changed, 17 insertions(+) diff --git a/test/T520-show.sh b/test/T520-show.sh index 16222650..6f42ca12 100755 --- a/test/T520-show.sh +++ b/test/T520-show.sh @@ -10,4 +10,21 @@ notmuch show foo.. exit_code=$? test_expect_equal 1 $exit_code +test_begin_subtest "notmuch show --sort=newest-first" +notmuch show --entire-thread=true '*' > EXPECTED +notmuch show --entire-thread=true --sort=newest-first '*' > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "notmuch show --sort=oldest-first" +notmuch show --entire-thread=true '*' | grep ^depth:0 > EXPECTED +notmuch show --entire-thread=true --sort=oldest-first '*' | grep ^depth:0 > OLDEST +perl -e 'print reverse<>' OLDEST > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "notmuch show --sort for single thread" +QUERY="id:yun1vjwegii@aiko.keithp.com" +notmuch show --entire-thread=true --sort=newest-first $QUERY > EXPECTED +notmuch show --entire-thread=true --sort=oldest-first $QUERY > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + test_done -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
Here's a re-roll, with review comments so far addressed
[PATCH 1/5] CLI/show: accept --sort [PATCH 2/5] CLI/show: tests for the new --sort option [PATCH 3/5] emacs/hello: honouring :sort-order in threaded queries [PATCH 4/5] emacs/tree: command to toggle search sort order in tree [PATCH 5/5] doc: new notmuch show --sort and related emacs commands ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 1/5] CLI/show: accept --sort
Add the command-line option --sort to the show command of the CLI notmuch interface, with the same possible values as the same option in notmuch search. --- notmuch-show.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/notmuch-show.c b/notmuch-show.c index bdb87321..947ffa8d 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1244,8 +1244,13 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) bool single_message; bool unthreaded = FALSE; notmuch_status_t status; +int sort = NOTMUCH_SORT_NEWEST_FIRST; notmuch_opt_desc_t options[] = { + { .opt_keyword = , .name = "sort", .keywords = + (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST }, + { "newest-first", NOTMUCH_SORT_NEWEST_FIRST }, + { 0, 0 } } }, { .opt_keyword = , .name = "format", .keywords = (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON }, { "text", NOTMUCH_FORMAT_TEXT }, @@ -1362,6 +1367,8 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) return EXIT_FAILURE; } +notmuch_query_set_sort (query, sort); + /* Create structure printer. */ formatter = formatters[format]; sprinter = formatter->new_sprinter (notmuch, stdout); -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 7/7] emacs: fix notmuch-tree-toggle-order keybinding
Really assign the new emacs command notmuch-tree-toggle-order to o, as previously documented. --- emacs/notmuch-tree.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index c23dacfc..c421cf3f 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -322,11 +322,11 @@ then NAME behaves like CMD." ;; that additionally close the message window. (define-key map [remap notmuch-bury-or-kill-this-buffer] 'notmuch-tree-quit) (define-key map [remap notmuch-search] 'notmuch-tree-to-search) -(define-key map [remap notmuch-search] 'notmuch-tree-toggle-order) (define-key map [remap notmuch-help] 'notmuch-tree-help) (define-key map [remap notmuch-mua-new-mail] 'notmuch-tree-new-mail) (define-key map [remap notmuch-jump-search] 'notmuch-tree-jump-search) +(define-key map "o" 'notmuch-tree-toggle-order) (define-key map "S" 'notmuch-search-from-tree-current-query) (define-key map "U" 'notmuch-unthreaded-from-tree-current-query) (define-key map "Z" 'notmuch-tree-from-unthreaded-current-query) -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 6/7] doc: clarifications for the new --sort flag and emacs command
Improvements to the notmuch show manpage regarding the behaviour of --sort, and description in doc/notmuch-emacs.rst of the new notmuch-tree-toggle-order command for notmuch-tree buffers. --- doc/man1/notmuch-show.rst | 4 doc/notmuch-emacs.rst | 7 +++ 2 files changed, 11 insertions(+) diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst index 581d15b5..64639174 100644 --- a/doc/man1/notmuch-show.rst +++ b/doc/man1/notmuch-show.rst @@ -117,6 +117,10 @@ Supported options for **show** include order (**oldest-first**) or reverse chronological order (**newest-first**). + Only threads as a whole are reordered. Ordering of messages within + each thread will not be affected by this flag, since that order is + always determined by the thread's replies. + By default, results will be displayed in reverse chronological order, (that is, the newest results will be displayed first). diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst index 7772871b..952fe2a5 100644 --- a/doc/notmuch-emacs.rst +++ b/doc/notmuch-emacs.rst @@ -299,12 +299,19 @@ tags. ``p`` Move to previous matching message +``o`` ``notmuch-tree-toggle-order`` + |docstring::notmuch-tree-toggle-order| + ``g`` ``=`` Refresh the buffer ``?`` Display full set of key bindings +As is the case with :ref:`notmuch-search`, the presentation of results +can be controlled by the variable ``notmuch-search-oldest-first``. + + Global key bindings === -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 5/7] CLI/show: tests for the new --sort option
New unit tests for notmuch show --sort, covering the basic use cases. --- test/T520-show.sh | 17 + 1 file changed, 17 insertions(+) diff --git a/test/T520-show.sh b/test/T520-show.sh index 16222650..6f42ca12 100755 --- a/test/T520-show.sh +++ b/test/T520-show.sh @@ -10,4 +10,21 @@ notmuch show foo.. exit_code=$? test_expect_equal 1 $exit_code +test_begin_subtest "notmuch show --sort=newest-first" +notmuch show --entire-thread=true '*' > EXPECTED +notmuch show --entire-thread=true --sort=newest-first '*' > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "notmuch show --sort=oldest-first" +notmuch show --entire-thread=true '*' | grep ^depth:0 > EXPECTED +notmuch show --entire-thread=true --sort=oldest-first '*' | grep ^depth:0 > OLDEST +perl -e 'print reverse<>' OLDEST > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "notmuch show --sort for single thread" +QUERY="id:yun1vjwegii@aiko.keithp.com" +notmuch show --entire-thread=true --sort=newest-first $QUERY > EXPECTED +notmuch show --entire-thread=true --sort=oldest-first $QUERY > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + test_done -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 4/7] doc: updates for new --sort and related emacs commands
New --sort CLI option documented in notmuch-show's man page, and notmuch-search-toggle-order mentioned in devel/emacs-keybindings.org. --- devel/emacs-keybindings.org | 10 +- doc/man1/notmuch-show.rst | 9 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/devel/emacs-keybindings.org b/devel/emacs-keybindings.org index 65dfe0eb..f7df3040 100644 --- a/devel/emacs-keybindings.org +++ b/devel/emacs-keybindings.org @@ -15,7 +15,7 @@ | l | notmuch-search-filter | notmuch-show-filter-thread| | | m | notmuch-mua-new-mail | notmuch-mua-new-mail | notmuch-mua-new-mail| | n | notmuch-search-next-thread | notmuch-show-next-open-message| notmuch-tree-next-matching-message | -| o | notmuch-search-toggle-order| | | +| o | notmuch-search-toggle-order| | notmuch-tree-toggle-order | | p | notmuch-search-previous-thread | notmuch-show-previous-open-message| notmuch-tree-prev-matching-message | | q | notmuch-bury-or-kill-this-buffer | notmuch-bury-or-kill-this-buffer | notmuch-bury-or-kill-this-buffer| | r | notmuch-search-reply-to-thread-sender | notmuch-show-reply-sender | notmuch-show-reply-sender | @@ -38,10 +38,10 @@ | V || notmuch-show-view-raw-message | notmuch-show-view-raw-message | | X || notmuch-show-archive-thread-then-exit | | | Z | notmuch-tree-from-search-current-query | notmuch-tree-from-show-current-query | | -| =!= || notmuch-show-toggle-elide-non-matching| | -| =#= || notmuch-show-print-message| | -| =$= || notmuch-show-toggle-process-crypto| | -| =*= | notmuch-search-tag-all | notmuch-show-tag-all | notmuch-tree-tag-thread | +| =!= || notmuch-show-toggle-elide-non-matching| | +| =#= || notmuch-show-print-message| | +| =$= || notmuch-show-toggle-process-crypto| | +| =*= | notmuch-search-tag-all | notmuch-show-tag-all | notmuch-tree-tag-thread | | + | notmuch-search-add-tag | notmuch-show-add-tag | notmuch-tree-add-tag| | - | notmuch-search-remove-tag | notmuch-show-remove-tag | notmuch-tree-remove-tag | | . || notmuch-show-part-map | | diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst index fc6bec62..581d15b5 100644 --- a/doc/man1/notmuch-show.rst +++ b/doc/man1/notmuch-show.rst @@ -111,6 +111,15 @@ Supported options for **show** include part still has two MIME parts: part 0 is the whole message (headers and body) and part 1 is just the body. +.. option:: --sort=(newest-first|oldest-first) + + This option can be used to present results in either chronological + order (**oldest-first**) or reverse chronological order + (**newest-first**). + + By default, results will be displayed in reverse chronological + order, (that is, the newest results will be displayed first). + .. option:: --verify Compute and report the validity of any MIME cryptographic -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 3/7] emacs/tree: command to toggle search sort order in tree mode
New command notmuch-tree-toggle-order for switching the sort order (by reissuing the search with a different flag) in a notmuch-tree buffer. --- emacs/notmuch-tree.el | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 6ef8e439..c23dacfc 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -322,6 +322,7 @@ then NAME behaves like CMD." ;; that additionally close the message window. (define-key map [remap notmuch-bury-or-kill-this-buffer] 'notmuch-tree-quit) (define-key map [remap notmuch-search] 'notmuch-tree-to-search) +(define-key map [remap notmuch-search] 'notmuch-tree-toggle-order) (define-key map [remap notmuch-help] 'notmuch-tree-help) (define-key map [remap notmuch-mua-new-mail] 'notmuch-tree-new-mail) (define-key map [remap notmuch-jump-search] 'notmuch-tree-jump-search) @@ -749,7 +750,8 @@ nil otherwise." query-context target nil -unthreaded))) +unthreaded +notmuch-search-oldest-first))) (defun notmuch-tree-thread-top () (when (notmuch-tree-get-message-properties) @@ -1071,6 +1073,7 @@ the same as for the function notmuch-tree." (interactive) (notmuch-tree-mode) (add-hook 'post-command-hook #'notmuch-tree-command-hook t t) + (setq notmuch-search-oldest-first oldest-first) (setq notmuch-tree-unthreaded unthreaded) (setq notmuch-tree-basic-query basic-query) (setq notmuch-tree-query-context (if (or (string= query-context "") @@ -1115,6 +1118,15 @@ the same as for the function notmuch-tree." ")") notmuch-tree-basic-query)) +(defun notmuch-tree-toggle-order () + "Toggle the current search order. + +This command toggles the sort order for the current search. The +default sort order is defined by `notmuch-search-oldest-first'." + (interactive) + (setq notmuch-search-oldest-first (not notmuch-search-oldest-first)) + (notmuch-tree-refresh-view)) + (defun notmuch-tree ( query query-context target buffer-name open-target unthreaded parent-buffer oldest-first) "Display threads matching QUERY in tree view. -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 1/7] CLI/show: accept --sort
Add the command-line option --sort to the show command of the CLI notmuch interface, with the same possible values as the same option in notmuch search. --- notmuch-show.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/notmuch-show.c b/notmuch-show.c index bdb87321..947ffa8d 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1244,8 +1244,13 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) bool single_message; bool unthreaded = FALSE; notmuch_status_t status; +int sort = NOTMUCH_SORT_NEWEST_FIRST; notmuch_opt_desc_t options[] = { + { .opt_keyword = , .name = "sort", .keywords = + (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST }, + { "newest-first", NOTMUCH_SORT_NEWEST_FIRST }, + { 0, 0 } } }, { .opt_keyword = , .name = "format", .keywords = (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON }, { "text", NOTMUCH_FORMAT_TEXT }, @@ -1362,6 +1367,8 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]) return EXIT_FAILURE; } +notmuch_query_set_sort (query, sort); + /* Create structure printer. */ formatter = formatters[format]; sprinter = formatter->new_sprinter (notmuch, stdout); -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
[PATCH 2/7] emacs/hello: honouring :sort-order in threaded queries
Now that notmuch show accepts --sort, we can, on the emacs side, use it according to the value of :sort-order in the definition of saved queries. --- emacs/notmuch-hello.el | 4 +++- emacs/notmuch-tree.el | 10 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 531f209d..5e1ff5fe 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -484,7 +484,9 @@ diagonal." (defun notmuch-hello-widget-search (widget _ignore) (cl-case (widget-get widget :notmuch-search-type) (tree -(notmuch-tree (widget-get widget :notmuch-search-terms))) +(notmuch-tree (widget-get widget :notmuch-search-terms) + nil nil nil nil nil nil + (widget-get widget :notmuch-search-oldest-first))) (unthreaded (notmuch-unthreaded (widget-get widget :notmuch-search-terms))) (t diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 00ee78d6..6ef8e439 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -1062,7 +1062,8 @@ Complete list of currently available key bindings: (notmuch-sexp-parse-partial-list 'notmuch-tree-insert-forest-thread results-buf) -(defun notmuch-tree-worker (basic-query query-context target open-target unthreaded) +(defun notmuch-tree-worker (basic-query query-context target + open-target unthreaded oldest-first) "Insert the tree view of the search in the current buffer. This is is a helper function for notmuch-tree. The arguments are @@ -1088,6 +1089,7 @@ the same as for the function notmuch-tree." (let* ((search-args (concat basic-query (and query-context (concat " and (" query-context ")" +(sort-arg (if oldest-first "--sort=oldest-first" "--sort=newest-first")) (message-arg (if unthreaded "--unthreaded" "--entire-thread"))) (when (equal (car (process-lines notmuch-command "count" search-args)) "0") (setq search-args basic-query)) @@ -1095,7 +1097,7 @@ the same as for the function notmuch-tree." (let ((proc (notmuch-start-notmuch "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel "show" "--body=false" "--format=sexp" "--format-version=4" -message-arg search-args)) +sort-arg message-arg search-args)) ;; Use a scratch buffer to accumulate partial output. ;; This buffer will be killed by the sentinel, which ;; should be called no matter how the process dies. @@ -1114,7 +1116,7 @@ the same as for the function notmuch-tree." notmuch-tree-basic-query)) (defun notmuch-tree ( query query-context target buffer-name - open-target unthreaded parent-buffer) + open-target unthreaded parent-buffer oldest-first) "Display threads matching QUERY in tree view. The arguments are: @@ -1143,7 +1145,7 @@ The arguments are: (pop-to-buffer-same-window buffer)) ;; Don't track undo information for this buffer (setq buffer-undo-list t) - (notmuch-tree-worker query query-context target open-target unthreaded) + (notmuch-tree-worker query query-context target open-target unthreaded oldest-first) (setq notmuch-tree-parent-buffer parent-buffer) (setq truncate-lines t)) -- 2.32.0 ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org
New --sort for notmuch show and using it in emacs notmuch-tree-mode
The accompanying patches implement the new --sort for notmuch show and its use in emacs to honour :sort-order in saved queries of tree type. [PATCH 1/7] CLI/show: accept --sort [PATCH 2/7] emacs/hello: honouring :sort-order in threaded queries [PATCH 3/7] emacs/tree: command to toggle search sort order in tree [PATCH 4/7] doc: updates for new --sort and related emacs commands [PATCH 5/7] CLI/show: tests for the new --sort option [PATCH 6/7] doc: clarifications for the new --sort flag and emacs [PATCH 7/7] emacs: fix notmuch-tree-toggle-order keybinding ___ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org