>From 8ae56beabc6792e7083a3604aa6ea5c02d5d6c2f Mon Sep 17 00:00:00 2001 From: Andrew G Cohen Date: Tue, 22 Mar 2022 12:11:14 +0800 Subject: [PATCH] Refactor gnus/nnselect artlist saving and getting * lisp/gnus/nnselect.el (nnselect-generate-run): New function that replaces nnselect-run. (nnselect-store-artlist): New function. (nnselect-get-artlist): Update function. (nnselect-request-group, nnselect-request-thread) (nnselect-request-create-group, nnselect-request-group-scan): Use the new functions. * doc/misc/gnus.texi (Selection Groups): Document artlist storage and retrieval. --- doc/misc/gnus.texi | 11 +++++ lisp/gnus/nnselect.el | 107 +++++++++++++++++++++++++++--------------- 2 files changed, 81 insertions(+), 37 deletions(-) diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index f87eab7e51..eb93269721 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -18078,6 +18078,17 @@ Selection Groups A refresh can always be invoked manually through @code{gnus-group-get-new-news-this-group}. +By default a compressed version of the selection is stored (for +permanent groups) along with other group information in the newsrc. +For cases where this might be undesirable (for example if the +selection is a very long list that doesn't compress well) a +non-@code{nil} group parameter of @code{nnselect-always-regenerate} +will prevent the list from being stored, and instead regenerate the +list each time it is needed. If more flexibility is desired, +@code{nnselect-get-artlist-override-function} and +@code{nnselect-store-artlist-override-function} may be set to +functions that get and store the list of articles. + Gnus includes engines for searching a variety of backends. While the details of each search engine vary, the result of a search is always a vector of the sort used by the nnselect method, and the results of diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el index d6289f1339..3a93c9e3dd 100644 --- a/lisp/gnus/nnselect.el +++ b/lisp/gnus/nnselect.el @@ -110,6 +110,7 @@ nnselect-uncompress-artlist selection))) (make-obsolete 'nnselect-group-server 'gnus-group-server "28.1") +(make-obsolete 'nnselect-run 'nnselect-generate-artlist "29.1") ;; Data type article list. @@ -231,11 +232,6 @@ nnselect-add-prefix `(gnus-group-prefixed-name (gnus-group-short-name ,group) '(nnselect "nnselect"))) -(defmacro nnselect-get-artlist (group) - "Retrieve the list of articles for GROUP." - `(when (gnus-nnselect-group-p ,group) - (nnselect-uncompress-artlist - (gnus-group-get-parameter ,group 'nnselect-artlist t)))) (defmacro nnselect-add-novitem (novitem) "Add NOVITEM to the list of headers." @@ -271,6 +267,63 @@ nnselect-retrieve-headers-override-function :version "28.1" :type '(repeat function)) +(defun nnselect-generate-artlist (group &optional specs) + "Generate the artlist for GROUP using SPECS. +SPECS should be an alist including an 'nnselect-function and an +'nnselect-args. The former applied to the latter should create +the artlist. If SPECS is nil retrieve the specs from the group +parameters." + (let* ((specs + (or specs (gnus-group-get-parameter group 'nnselect-specs t))) + (function (alist-get 'nnselect-function specs)) + (args (alist-get 'nnselect-args specs))) + (condition-case-unless-debug err + (funcall function args) + ;; Don't swallow gnus-search errors; the user should be made + ;; aware of them. + (gnus-search-error + (signal (car err) (cdr err))) + (error + (gnus-error + 3 + "nnselect-generate-artlist: %s on %s gave error %s" function args err) + [])))) + +(defmacro nnselect-get-artlist (group) + "Get the list of articles for GROUP. +If the group parameter 'nnselect-get-artlist-override-function is +non-nil call this function with argument GROUP to get the +artlist; if the group parameter 'nnselect-always-regenerate is +non-nil, regenerate the artlist; otherwise retrieve the artlist +directly from the group parameters." + `(when (gnus-nnselect-group-p group) + (let ((override (gnus-group-get-parameter + ,group + 'nnselect-get-artlist-override-function))) + (cond + (override (funcall override ,group)) + ((gnus-group-get-parameter ,group 'nnselect-always-regenerate) + (nnselect-generate-artlist ,group)) + (t + (nnselect-uncompress-artlist + (gnus-group-get-parameter ,group 'nnselect-artlist t))))))) + +(defmacro nnselect-store-artlist (group artlist) + "Store the ARTLIST for GROUP. +If the group parameter 'nnselect-store-artlist-override-function +is non-nil call this function on GROUP and ARTLIST; if the group +parameter 'nnselect-always-regenerate is non-nil don't store the +artlist; otherwise store the ARTLIST in the group parameters." + `(let ((override (gnus-group-get-parameter + ,group + 'nnselect-store-artlist-override-function))) + (cond + (override (funcall override ,group ,artlist)) + ((gnus-group-get-parameter ,group 'nnselect-always-regenerate) t) + (t + (gnus-group-set-parameter ,group 'nnselect-artlist + (nnselect-compress-artlist ,artlist)))))) + ;; Gnus backend interface functions. (deffoo nnselect-open-server (server &optional definitions) @@ -296,11 +349,8 @@ nnselect-request-group ;; Check for cached select result or run the selection and cache ;; the result. (unless nnselect-artlist - (gnus-group-set-parameter - group 'nnselect-artlist - (nnselect-compress-artlist (setq nnselect-artlist - (nnselect-run - (gnus-group-get-parameter group 'nnselect-specs t))))) + (nnselect-store-artlist group + (setq nnselect-artlist (nnselect-generate-artlist group))) (nnselect-request-update-info group (or info (gnus-get-info group)))) (if (zerop (setq length (nnselect-artlist-length nnselect-artlist))) @@ -671,10 +721,7 @@ nnselect-request-thread (append (sort old-arts #'<) (number-sequence first last)) nil t)) - (gnus-group-set-parameter - group - 'nnselect-artlist - (nnselect-compress-artlist gnus-newsgroup-selection)) + (nnselect-store-artlist group gnus-newsgroup-selection) (when (>= last first) (let (new-marks) (pcase-dolist (`(,artgroup . ,artids) @@ -721,6 +768,7 @@ nnselect-request-create-group (message "Creating nnselect group %s" group) (let* ((group (gnus-group-prefixed-name group '(nnselect "nnselect"))) (specs (assq 'nnselect-specs args)) + (otherargs (assq-delete-all 'nnselect-specs args)) (function-spec (or (alist-get 'nnselect-function specs) (intern (completing-read "Function: " obarray #'functionp)))) @@ -730,10 +778,12 @@ nnselect-request-create-group (nnselect-specs (list (cons 'nnselect-function function-spec) (cons 'nnselect-args args-spec)))) (gnus-group-set-parameter group 'nnselect-specs nnselect-specs) - (gnus-group-set-parameter - group 'nnselect-artlist - (nnselect-compress-artlist (or (alist-get 'nnselect-artlist args) - (nnselect-run nnselect-specs)))) + (dolist (arg otherargs) + (gnus-group-set-parameter group (car arg) (cdr arg))) + (nnselect-store-artlist + group + (or (alist-get 'nnselect-artlist args) + (nnselect-generate-artlist group nnselect-specs))) (nnselect-request-update-info group (gnus-get-info group))) t) @@ -765,13 +815,10 @@ nnselect-request-scan (deffoo nnselect-request-group-scan (group &optional _server _info) (let* ((group (nnselect-add-prefix group)) - (artlist (nnselect-uncompress-artlist (nnselect-run - (gnus-group-get-parameter group 'nnselect-specs t))))) + (artlist (nnselect-generate-artlist group))) (gnus-set-active group (cons 1 (nnselect-artlist-length artlist))) - (gnus-group-set-parameter - group 'nnselect-artlist - (nnselect-compress-artlist artlist)))) + (nnselect-store-artlist group artlist))) ;; Add any undefined required backend functions @@ -786,20 +833,6 @@ gnus-nnselect-group-p (eq 'nnselect (car gnus-command-method)))) -(defun nnselect-run (specs) - "Apply nnselect-function to nnselect-args from SPECS. -Return an article list." - (let ((func (alist-get 'nnselect-function specs)) - (args (alist-get 'nnselect-args specs))) - (condition-case-unless-debug err - (funcall func args) - ;; Don't swallow gnus-search errors; the user should be made - ;; aware of them. - (gnus-search-error - (signal (car err) (cdr err))) - (error (gnus-error 3 "nnselect-run: %s on %s gave error %s" func args err) - [])))) - (defun nnselect-search-thread (header) "Make an nnselect group containing the thread with article HEADER. The current server will be searched. If the registry is -- 2.34.1.575.g55b058a8bb