From: Andrea Monaco Date: Mon, 7 Nov 2022 14:13:13 +0000 (+0100) Subject: Improve progressive summaries in Rmail X-Git-Tag: emacs-29.0.90~1616^2~104 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f320663239a14aceee01868c465a4461e3a69954;p=emacs.git Improve progressive summaries in Rmail * lisp/mail/rmailsum.el (rmail-summary-progressively-narrow): Renamed from 'rmail-summary-apply-filters-consecutively'. Doc fix. (rmail-summary-invert): Renamed from 'rmail-summary-negate'. Doc fix. (rmail-summary-currently-displayed-msgs): Doc fix. (rmail-summary--exists-1): New function. (rmail-summary-by-labels, rmail-summary-by-recipients) (rmail-summary-by-regexp, rmail-summary-by-topic) (rmail-summary-by-senders): Call 'rmail-summary-exists' to verify that the summary is usable. --- diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el index 0144a34e5e7..d72464cb81a 100644 --- a/lisp/mail/rmailsum.el +++ b/lisp/mail/rmailsum.el @@ -50,21 +50,26 @@ Setting this option to nil might speed up the generation of summaries." :type 'boolean :group 'rmail-summary) -(defcustom rmail-summary-apply-filters-consecutively nil - "If non-nil, Rmail summary commands apply filtering on top existing filtering. -When this variable is non-nil, `rmail-summary-by-*' commands work on the -current summary, and so their filtering can be stacked one on top of another. -This allows gradual narrowing of the selection of the messages." +(defcustom rmail-summary-progressively-narrow nil + "Non-nil means progressively narrow the set of messages produced by summary. +This allows to apply the summary criteria on top one another, +thus progressively narrowing the selection of the messages produced +by each summary criteria. +For example, applying `rmail-summary-by-senders' on top +of `rmail-summary-by-topic' produces a summary of messages +with the specified Subjects that were sent from specified +sending addresses. +This way, the user can apply one summary on top of another, +and keep narrowing the resulting list of messages." :type 'boolean :version "29.1" :group 'rmail-summary) (defvar rmail-summary-currently-displayed-msgs nil - "String made of `y' and `n'. -The character at position i tells wether message i is shown in the -summary or not. First character is ignored. -Used when applying `rmail-summary-by-*' commands consecutively. Filled -by `rmail-summary-fill-displayed-messages'.") + "Boolean vector that tells which messages are displayed in the summary. +First element is ignored. Used when applying rmail-summary-by-* +commands consecutively. Filled by +`rmail-summary-populate-displayed-messages'.") (put 'rmail-summary-currently-displayed-msgs 'permanent-local t) (defvar rmail-summary-font-lock-keywords @@ -284,33 +289,40 @@ by `rmail-summary-fill-displayed-messages'.") (defun rmail-update-summary (&rest _) (apply (car rmail-summary-redo) (cdr rmail-summary-redo))) -(defun rmail-summary-fill-displayed-messages () - "Fill the rmail-summary-currently-displayed-msgs string." +(defun rmail-summary-populate-displayed-messages () + "Populate the `rmail-summary-currently-displayed-msgs' vector." (with-current-buffer rmail-buffer - (with-current-buffer rmail-summary-buffer - (setq rmail-summary-currently-displayed-msgs - (make-string (1+ rmail-total-messages) ?n)) - (goto-char (point-min)) - (while (not (eobp)) - (aset rmail-summary-currently-displayed-msgs - (string-to-number (thing-at-point 'line)) - ?y) - (forward-line 1))))) - -(defun rmail-summary-negate () - "Toggle display of messages that match the summary and those which do not." + (let ((totmsgs rmail-total-messages)) + (with-current-buffer rmail-summary-buffer + (setq rmail-summary-currently-displayed-msgs + (make-bool-vector (1+ totmsgs) nil)) + (goto-char (point-min)) + (while (not (eobp)) + (aset rmail-summary-currently-displayed-msgs + (string-to-number (thing-at-point 'line)) + t) + (forward-line 1)))))) + +(defun rmail-summary-invert () + "Invert the criteria of the current summary. +That is, show the messages that are not displayed, and hide +the messages that are displayed." (interactive) - (rmail-summary-fill-displayed-messages) - (rmail-new-summary "Negate" + (rmail-summary-populate-displayed-messages) + (rmail-new-summary "Invert" '(rmail-summary-by-regexp ".*") (lambda (msg) (if - (= (aref rmail-summary-currently-displayed-msgs msg) - ?n) - (progn - (aset rmail-summary-currently-displayed-msgs msg ?y) t) - (progn - (aset rmail-summary-currently-displayed-msgs msg ?n) nil))))) + (eq (aref rmail-summary-currently-displayed-msgs msg) + nil) + (aset rmail-summary-currently-displayed-msgs msg t) + (aset rmail-summary-currently-displayed-msgs msg nil))))) + +(defun rmail-summary--exists-1 () + "Like `rmail-summary-exists', but works in both main and summary buffers." + (with-current-buffer rmail-buffer + (and rmail-summary-buffer (buffer-name rmail-summary-buffer) + rmail-summary-buffer))) ;;;###autoload (defun rmail-summary () @@ -327,14 +339,16 @@ LABELS should be a string containing the desired labels, separated by commas." (setq labels (or rmail-last-multi-labels (error "No label specified")))) (setq rmail-last-multi-labels labels) - (if rmail-summary-apply-filters-consecutively - (rmail-summary-fill-displayed-messages)) + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) + (rmail-summary-populate-displayed-messages)) (rmail-new-summary (concat "labels " labels) (list 'rmail-summary-by-labels labels) - (if rmail-summary-apply-filters-consecutively + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) (lambda (msg l) - (and (= (aref rmail-summary-currently-displayed-msgs msg) - ?y) + (and (eq (aref rmail-summary-currently-displayed-msgs msg) + t) (rmail-message-labels-p msg l))) 'rmail-message-labels-p) (concat " \\(" @@ -349,15 +363,17 @@ but if PRIMARY-ONLY is non-nil (prefix arg given), only look in the To and From fields. RECIPIENTS is a regular expression." (interactive "sRecipients to summarize by: \nP") - (if rmail-summary-apply-filters-consecutively - (rmail-summary-fill-displayed-messages)) + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) + (rmail-summary-populate-displayed-messages)) (rmail-new-summary (concat "recipients " recipients) (list 'rmail-summary-by-recipients recipients primary-only) - (if rmail-summary-apply-filters-consecutively + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) (lambda (msg r &optional po) - (and (= (aref rmail-summary-currently-displayed-msgs msg) - ?y) + (and (eq (aref rmail-summary-currently-displayed-msgs msg) + t) (rmail-message-recipients-p msg r po))) 'rmail-message-recipients-p) recipients primary-only)) @@ -388,14 +404,16 @@ Emacs will list the message in the summary." (setq regexp (or rmail-last-regexp (error "No regexp specified")))) (setq rmail-last-regexp regexp) - (if rmail-summary-apply-filters-consecutively - (rmail-summary-fill-displayed-messages)) + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) + (rmail-summary-populate-displayed-messages)) (rmail-new-summary (concat "regexp " regexp) (list 'rmail-summary-by-regexp regexp) - (if rmail-summary-apply-filters-consecutively + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) (lambda (msg r) - (and (= (aref rmail-summary-currently-displayed-msgs msg) - ?y) + (and (eq (aref rmail-summary-currently-displayed-msgs msg) + t) (rmail-message-regexp-p msg r))) 'rmail-message-regexp-p) regexp)) @@ -443,15 +461,17 @@ SUBJECT is a regular expression." (if subject ", default current subject" "") "): "))) (list (read-string prompt nil nil subject) current-prefix-arg))) - (if rmail-summary-apply-filters-consecutively - (rmail-summary-fill-displayed-messages)) + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) + (rmail-summary-populate-displayed-messages)) (rmail-new-summary (concat "about " subject) (list 'rmail-summary-by-topic subject whole-message) - (if rmail-summary-apply-filters-consecutively + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) (lambda (msg s &optional wm) - (and (= (aref rmail-summary-currently-displayed-msgs msg) - ?y) + (and (eq (aref rmail-summary-currently-displayed-msgs msg) + t) (rmail-message-subject-p msg s wm))) 'rmail-message-subject-p) subject whole-message)) @@ -477,15 +497,17 @@ sender of the current message." (if sender ", default this message's sender" "") "): "))) (list (read-string prompt nil nil sender)))) - (if rmail-summary-apply-filters-consecutively - (rmail-summary-fill-displayed-messages)) + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) + (rmail-summary-populate-displayed-messages)) (rmail-new-summary (concat "senders " senders) (list 'rmail-summary-by-senders senders) - (if rmail-summary-apply-filters-consecutively + (if (and rmail-summary-progressively-narrow + (rmail-summary--exists-1)) (lambda (msg s) - (and (= (aref rmail-summary-currently-displayed-msgs msg) - ?y) + (and (eq (aref rmail-summary-currently-displayed-msgs msg) + t) (rmail-message-senders-p msg s))) 'rmail-message-senders-p) senders))