1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

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.
This commit is contained in:
Andrew G Cohen 2022-03-22 12:11:14 +08:00
parent c14ce74f33
commit eb25ae3f2d
2 changed files with 81 additions and 37 deletions

View file

@ -18078,6 +18078,17 @@ parameter of @code{nnselect-rescan} will allow automatic refreshing.
A refresh can always be invoked manually through A refresh can always be invoked manually through
@code{gnus-group-get-new-news-this-group}. @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 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 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 vector of the sort used by the nnselect method, and the results of

View file

@ -110,6 +110,7 @@
selection))) selection)))
(make-obsolete 'nnselect-group-server 'gnus-group-server "28.1") (make-obsolete 'nnselect-group-server 'gnus-group-server "28.1")
(make-obsolete 'nnselect-run 'nnselect-generate-artlist "29.1")
;; Data type article list. ;; Data type article list.
@ -231,11 +232,6 @@ as `(keyfunc member)' and the corresponding element is just
`(gnus-group-prefixed-name `(gnus-group-prefixed-name
(gnus-group-short-name ,group) '(nnselect "nnselect"))) (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) (defmacro nnselect-add-novitem (novitem)
"Add NOVITEM to the list of headers." "Add NOVITEM to the list of headers."
@ -271,6 +267,63 @@ If this variable is nil, or if the provided function returns nil,
:version "28.1" :version "28.1"
:type '(repeat function)) :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. ;; Gnus backend interface functions.
(deffoo nnselect-open-server (server &optional definitions) (deffoo nnselect-open-server (server &optional definitions)
@ -296,11 +349,8 @@ If this variable is nil, or if the provided function returns nil,
;; Check for cached select result or run the selection and cache ;; Check for cached select result or run the selection and cache
;; the result. ;; the result.
(unless nnselect-artlist (unless nnselect-artlist
(gnus-group-set-parameter (nnselect-store-artlist group
group 'nnselect-artlist (setq nnselect-artlist (nnselect-generate-artlist group)))
(nnselect-compress-artlist (setq nnselect-artlist
(nnselect-run
(gnus-group-get-parameter group 'nnselect-specs t)))))
(nnselect-request-update-info (nnselect-request-update-info
group (or info (gnus-get-info group)))) group (or info (gnus-get-info group))))
(if (zerop (setq length (nnselect-artlist-length nnselect-artlist))) (if (zerop (setq length (nnselect-artlist-length nnselect-artlist)))
@ -671,10 +721,7 @@ If this variable is nil, or if the provided function returns nil,
(append (sort old-arts #'<) (append (sort old-arts #'<)
(number-sequence first last)) (number-sequence first last))
nil t)) nil t))
(gnus-group-set-parameter (nnselect-store-artlist group gnus-newsgroup-selection)
group
'nnselect-artlist
(nnselect-compress-artlist gnus-newsgroup-selection))
(when (>= last first) (when (>= last first)
(let (new-marks) (let (new-marks)
(pcase-dolist (`(,artgroup . ,artids) (pcase-dolist (`(,artgroup . ,artids)
@ -721,6 +768,7 @@ If this variable is nil, or if the provided function returns nil,
(message "Creating nnselect group %s" group) (message "Creating nnselect group %s" group)
(let* ((group (gnus-group-prefixed-name group '(nnselect "nnselect"))) (let* ((group (gnus-group-prefixed-name group '(nnselect "nnselect")))
(specs (assq 'nnselect-specs args)) (specs (assq 'nnselect-specs args))
(otherargs (assq-delete-all 'nnselect-specs args))
(function-spec (function-spec
(or (alist-get 'nnselect-function specs) (or (alist-get 'nnselect-function specs)
(intern (completing-read "Function: " obarray #'functionp)))) (intern (completing-read "Function: " obarray #'functionp))))
@ -730,10 +778,12 @@ If this variable is nil, or if the provided function returns nil,
(nnselect-specs (list (cons 'nnselect-function function-spec) (nnselect-specs (list (cons 'nnselect-function function-spec)
(cons 'nnselect-args args-spec)))) (cons 'nnselect-args args-spec))))
(gnus-group-set-parameter group 'nnselect-specs nnselect-specs) (gnus-group-set-parameter group 'nnselect-specs nnselect-specs)
(gnus-group-set-parameter (dolist (arg otherargs)
group 'nnselect-artlist (gnus-group-set-parameter group (car arg) (cdr arg)))
(nnselect-compress-artlist (or (alist-get 'nnselect-artlist args) (nnselect-store-artlist
(nnselect-run nnselect-specs)))) group
(or (alist-get 'nnselect-artlist args)
(nnselect-generate-artlist group nnselect-specs)))
(nnselect-request-update-info group (gnus-get-info group))) (nnselect-request-update-info group (gnus-get-info group)))
t) t)
@ -765,13 +815,10 @@ If this variable is nil, or if the provided function returns nil,
(deffoo nnselect-request-group-scan (group &optional _server _info) (deffoo nnselect-request-group-scan (group &optional _server _info)
(let* ((group (nnselect-add-prefix group)) (let* ((group (nnselect-add-prefix group))
(artlist (nnselect-uncompress-artlist (nnselect-run (artlist (nnselect-generate-artlist group)))
(gnus-group-get-parameter group 'nnselect-specs t)))))
(gnus-set-active group (cons 1 (nnselect-artlist-length (gnus-set-active group (cons 1 (nnselect-artlist-length
artlist))) artlist)))
(gnus-group-set-parameter (nnselect-store-artlist group artlist)))
group 'nnselect-artlist
(nnselect-compress-artlist artlist))))
;; Add any undefined required backend functions ;; Add any undefined required backend functions
@ -786,20 +833,6 @@ If this variable is nil, or if the provided function returns nil,
(eq 'nnselect (car gnus-command-method)))) (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) (defun nnselect-search-thread (header)
"Make an nnselect group containing the thread with article HEADER. "Make an nnselect group containing the thread with article HEADER.
The current server will be searched. If the registry is The current server will be searched. If the registry is