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
@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

View file

@ -110,6 +110,7 @@
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 @@ as `(keyfunc member)' and the corresponding element is just
`(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 @@ If this variable is nil, or if the provided function returns nil,
: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 @@ If this variable is nil, or if the provided function returns nil,
;; 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 @@ If this variable is nil, or if the provided function returns nil,
(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 @@ If this variable is nil, or if the provided function returns nil,
(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 @@ If this variable is nil, or if the provided function returns nil,
(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 @@ If this variable is nil, or if the provided function returns nil,
(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 @@ If this variable is nil, or if the provided function returns nil,
(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