aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G Cohen2022-11-22 15:39:01 +0800
committerAndrew G Cohen2023-04-15 08:10:04 +0800
commitbf986c1faf53f3abd260f72cb36d9143afac353d (patch)
tree4830dfb3a5b851d339f0ab86a195f2bdd7b9ae89
parent67ab357cdccbe6e04eb0b5cff1d6265d668116ce (diff)
downloademacs-bf986c1faf53f3abd260f72cb36d9143afac353d.tar.gz
emacs-bf986c1faf53f3abd260f72cb36d9143afac353d.zip
Improve gnus thread-referral
Allow thread referral to use search whenever possible, displaying the results in the current summary buffer if possible and a new nnselect buffer if not. * lisp/gnus/nnimap.el (nnimap-request-thread): Obsolete function. * lisp/gnus/gnus-search.el (gnus-search-thread): Allow detailed specification of how/where to search. Add found articles to the current summary buffer if possible, or create a new ephemeral nnselect group if not. * lisp/gnus/gnus-sum.el (gnus-refer-thread-use-search): Allow a list of servers and groups to search. (gnus-summary-refer-thread): Find thread-related articles by using a backend-specific method, gnus-search, or retrieving nearby headers in the current group. * lisp/gnus/nnselect.el (nnselect-search-thread): Obsolete function. (nnselect-request-thread): Allow thread referral from nnselect groups. * doc/misc/gnus.texi (Finding the Parent): Document changes to thread referral.
-rw-r--r--doc/misc/gnus.texi23
-rw-r--r--lisp/gnus/gnus-search.el78
-rw-r--r--lisp/gnus/gnus-sum.el117
-rw-r--r--lisp/gnus/nnimap.el14
-rw-r--r--lisp/gnus/nnselect.el177
5 files changed, 218 insertions, 191 deletions
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index f0d3c75d055..3790a9b12bf 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -10528,9 +10528,9 @@ article (@code{gnus-summary-refer-references}).
10528@kindex A T @r{(Summary)} 10528@kindex A T @r{(Summary)}
10529Display the full thread where the current article appears 10529Display the full thread where the current article appears
10530(@code{gnus-summary-refer-thread}). By default this command looks for 10530(@code{gnus-summary-refer-thread}). By default this command looks for
10531articles only in the current group. Some backends (currently only 10531articles only in the current group. If the group belongs to a backend
10532@code{nnimap}) know how to find articles in the thread directly. In 10532that has an associated search engine, articles are found by searching.
10533other cases each header in the current group must be fetched and 10533In other cases each header in the current group must be fetched and
10534examined, so it usually takes a while. If you do it often, you may 10534examined, so it usually takes a while. If you do it often, you may
10535consider setting @code{gnus-fetch-old-headers} to @code{invisible} 10535consider setting @code{gnus-fetch-old-headers} to @code{invisible}
10536(@pxref{Filling In Threads}). This won't have any visible effects 10536(@pxref{Filling In Threads}). This won't have any visible effects
@@ -10538,19 +10538,22 @@ normally, but it'll make this command work a whole lot faster. Of
10538course, it'll make group entry somewhat slow. 10538course, it'll make group entry somewhat slow.
10539 10539
10540@vindex gnus-refer-thread-use-search 10540@vindex gnus-refer-thread-use-search
10541If @code{gnus-refer-thread-use-search} is non-@code{nil} then those backends 10541If @code{gnus-refer-thread-use-search} is @code{nil} (the default)
10542that know how to find threads directly will search not just in the 10542then thread-referral only looks for articles in the current group. If
10543current group but all groups on the same server. 10543this variable is @code{t} the server to which the current group
10544belongs is searched (provided that searching is available for the
10545server's backend). If this variable is a list of servers, each server
10546in the list is searched.
10544 10547
10545@vindex gnus-refer-thread-limit 10548@vindex gnus-refer-thread-limit
10546The @code{gnus-refer-thread-limit} variable says how many old (i.e., 10549The @code{gnus-refer-thread-limit} variable says how many old (i.e.,
10547articles before the first displayed in the current group) headers to 10550articles before the first displayed in the current group) headers to
10548fetch when doing this command. The default is 200. If @code{t}, all 10551fetch when referring a thread. The default is 500. If @code{t}, all
10549the available headers will be fetched. This variable can be overridden 10552the available headers will be fetched. This variable can be
10550by giving the @kbd{A T} command a numerical prefix. 10553overridden by giving the @kbd{A T} command a numerical prefix.
10551 10554
10552@vindex gnus-refer-thread-limit-to-thread 10555@vindex gnus-refer-thread-limit-to-thread
10553In most cases @code{gnus-refer-thread} adds any articles it finds to 10556@code{gnus-summary-refer-thread} tries to add any articles it finds to
10554the current summary buffer. (When @code{gnus-refer-thread-use-search} 10557the current summary buffer. (When @code{gnus-refer-thread-use-search}
10555is true and the initial referral starts from a summary buffer for a 10558is true and the initial referral starts from a summary buffer for a
10556non-virtual group this may not be possible. In this case a new 10559non-virtual group this may not be possible. In this case a new
diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index 22c84bc39cf..71980afa0ff 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -2174,37 +2174,53 @@ remaining string, then adds all that to the top-level spec."
2174 2174
2175(declare-function gnus-registry-get-id-key "gnus-registry" (id key)) 2175(declare-function gnus-registry-get-id-key "gnus-registry" (id key))
2176 2176
2177(defun gnus-search-thread (header) 2177(defun gnus-search-thread (header &optional group server)
2178 "Make an nnselect group based on the thread containing the article 2178 "Find articles in the thread containing HEADER from GROUP on SERVER.
2179header. The current server will be searched. If the registry is 2179If gnus-refer-thread-use-search is nil only the current group is
2180installed, the server that the registry reports the current 2180checked for articles; if t all groups on the server containing
2181article came from is also searched." 2181the article's group will be searched; if a list then all servers
2182 (let* ((ids (cons (mail-header-id header) 2182in this list will be searched. If possible the newly found
2183 (split-string 2183articles are added to the summary buffer; otherwise the full
2184 (or (mail-header-references header) 2184thread is displayed in a new ephemeral nnselect buffer."
2185 "")))) 2185 (let* ((group (or group gnus-newsgroup-name))
2186 (query 2186 (server (or server (gnus-group-server group)))
2187 (list (cons 'query (mapconcat (lambda (i) 2187 (query
2188 (format "id:%s" i)) 2188 (list
2189 ids " or ")) 2189 (cons 'query
2190 (cons 'thread t))) 2190 (mapconcat (lambda (i) (format "id:%s" i))
2191 (server 2191 (cons (mail-header-id header)
2192 (list (list (gnus-method-to-server 2192 (split-string
2193 (gnus-find-method-for-group gnus-newsgroup-name))))) 2193 (or (mail-header-references header) "")))
2194 (registry-group (and 2194 " or "))
2195 (bound-and-true-p gnus-registry-enabled) 2195 (cons 'thread t)))
2196 (car (gnus-registry-get-id-key 2196 (gnus-search-use-parsed-queries t))
2197 (mail-header-id header) 'group)))) 2197 (if (not gnus-refer-thread-use-search)
2198 (registry-server 2198 ;; Search only the current group and send the headers back to
2199 (and registry-group 2199 ;; the caller to add to the summary buffer.
2200 (gnus-method-to-server 2200 (gnus-fetch-headers
2201 (gnus-find-method-for-group registry-group))))) 2201 (sort
2202 (when registry-server 2202 (mapcar (lambda (x) (elt x 1))
2203 (cl-pushnew (list registry-server) server :test #'equal)) 2203 (gnus-search-run-query
2204 (gnus-group-make-search-group nil (list 2204 (list (cons 'search-query-spec query)
2205 (cons 'search-query-spec query) 2205 (cons 'search-group-spec
2206 (cons 'search-group-spec server))) 2206 (list (list server group))))))
2207 (gnus-summary-goto-subject (gnus-id-to-article (mail-header-id header))))) 2207 #'<) nil t)
2208 ;; Otherwise create an ephemeral search group. If we return to
2209 ;; the current summary buffer after exiting the thread we would
2210 ;; end up overwriting any changes we made, so we exit the
2211 ;; current summary buffer first.
2212 (gnus-summary-exit)
2213 (gnus-group-read-ephemeral-search-group
2214 nil
2215 (list (cons 'search-query-spec query)
2216 (cons 'search-group-spec
2217 (if (listp gnus-refer-thread-use-search)
2218 gnus-refer-thread-use-search
2219 (list (list server))))))
2220 (if (gnus-id-to-article (mail-header-id header))
2221 (gnus-summary-goto-subject
2222 (gnus-id-to-article (mail-header-id header)))
2223 (message "Thread search failed")))))
2208 2224
2209(defun gnus-search-get-active (srv) 2225(defun gnus-search-get-active (srv)
2210 (let ((method (gnus-server-to-method srv)) 2226 (let ((method (gnus-server-to-method srv))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 16a85cefcc7..35e867a3508 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -80,6 +80,8 @@
80(autoload 'nnselect-article-rsv "nnselect" nil nil) 80(autoload 'nnselect-article-rsv "nnselect" nil nil)
81(autoload 'nnselect-article-group "nnselect" nil nil) 81(autoload 'nnselect-article-group "nnselect" nil nil)
82(autoload 'gnus-nnselect-group-p "nnselect" nil nil) 82(autoload 'gnus-nnselect-group-p "nnselect" nil nil)
83(autoload 'gnus-search-thread "gnus-search" nil nil)
84(autoload 'gnus-search-server-to-engine "gnus-search" nil nil)
83 85
84(defcustom gnus-kill-summary-on-exit t 86(defcustom gnus-kill-summary-on-exit t
85 "If non-nil, kill the summary buffer when you exit from it. 87 "If non-nil, kill the summary buffer when you exit from it.
@@ -141,12 +143,17 @@ If t, fetch all the available old headers."
141 'gnus-refer-thread-use-search "28.1") 143 'gnus-refer-thread-use-search "28.1")
142 144
143(defcustom gnus-refer-thread-use-search nil 145(defcustom gnus-refer-thread-use-search nil
144 "Search an entire server when referring threads. 146 "Specify where to find articles when referring threads.
145A nil value will only search for thread-related articles in the 147A nil value restricts searches for thread-related articles to the
146current group." 148current group; a value of t searches all groups on the server; a
149list of servers and groups (where each element is a list whose
150car is the server and whose cdr is a list of groups on this
151server or nil to search the entire server) searches these
152server/groups. This may usefully be set as a group parameter."
147 :version "28.1" 153 :version "28.1"
148 :group 'gnus-thread 154 :group 'gnus-thread
149 :type 'boolean) 155 :type '(restricted-sexp :match-alternatives
156 (listp 't 'nil)))
150 157
151(defcustom gnus-refer-thread-limit-to-thread nil 158(defcustom gnus-refer-thread-limit-to-thread nil
152 "If non-nil referring a thread will limit the summary buffer to 159 "If non-nil referring a thread will limit the summary buffer to
@@ -9009,64 +9016,72 @@ Return the number of articles fetched."
9009 9016
9010(defun gnus-summary-refer-thread (&optional limit) 9017(defun gnus-summary-refer-thread (&optional limit)
9011 "Fetch all articles in the current thread. 9018 "Fetch all articles in the current thread.
9012For backends that know how to search for threads (currently only 9019A non-numeric prefix arg will search the entire server; without a
9013`nnimap') a non-numeric prefix arg will search the entire server; 9020prefix arg only the current group is searched. If the variable
9014without a prefix arg only the current group is searched. If the 9021`gnus-refer-thread-use-search' is t the prefix arg has the
9015variable `gnus-refer-thread-use-search' is non-nil the prefix arg 9022reverse meaning. If searching is not enabled for the current
9016has the reverse meaning. If no backend-specific `request-thread' 9023group, fetch LIMIT (the numerical prefix) old headers. If LIMIT
9017function is available fetch LIMIT (the numerical prefix) old 9024is non-numeric or nil fetch the number specified by the
9018headers. If LIMIT is non-numeric or nil fetch the number 9025`gnus-refer-thread-limit' variable."
9019specified by the `gnus-refer-thread-limit' variable."
9020 (interactive "P" gnus-summary-mode) 9026 (interactive "P" gnus-summary-mode)
9021 (let* ((header (gnus-summary-article-header)) 9027 (let* ((group gnus-newsgroup-name)
9022 (id (mail-header-id header)) 9028 (header (gnus-summary-article-header))
9023 (gnus-inhibit-demon t) 9029 (id (mail-header-id header))
9024 (gnus-summary-ignore-duplicates t) 9030 (gnus-inhibit-demon t)
9025 (gnus-read-all-available-headers t) 9031 (gnus-summary-ignore-duplicates t)
9026 (gnus-refer-thread-use-search 9032 (gnus-read-all-available-headers t)
9027 (if (and (not (null limit)) (listp limit)) 9033 (gnus-refer-thread-use-search
9028 (not gnus-refer-thread-use-search) gnus-refer-thread-use-search)) 9034 (if (or (null limit) (numberp limit))
9029 (new-headers 9035 gnus-refer-thread-use-search
9030 (if (gnus-check-backend-function 9036 (if (booleanp gnus-refer-thread-use-search)
9031 'request-thread gnus-newsgroup-name) 9037 (not gnus-refer-thread-use-search)
9032 (gnus-request-thread header gnus-newsgroup-name) 9038 gnus-refer-thread-use-search)))
9033 (let* ((limit (if (numberp limit) (prefix-numeric-value limit) 9039 article-ids new-unreads
9034 gnus-refer-thread-limit)) 9040 (new-headers
9035 (last (if (numberp limit) 9041 (cond
9036 (min (+ (mail-header-number header) 9042 ;; If there is a backend-specific method, use it.
9037 limit) 9043 ((gnus-check-backend-function
9038 gnus-newsgroup-highest) 9044 'request-thread group)
9039 gnus-newsgroup-highest)) 9045 (gnus-request-thread header group))
9040 (subject (gnus-simplify-subject 9046 ;; If a search engine is configured, use it.
9041 (mail-header-subject header))) 9047 ((ignore-errors
9042 (refs (split-string (or (mail-header-references header) 9048 (gnus-search-server-to-engine (gnus-group-server group)))
9043 ""))) 9049 (gnus-search-thread header))
9044 (gnus-parse-headers-hook 9050 ;; Otherwise just retrieve some headers.
9051 (t
9052 (let* ((limit (if (numberp limit)
9053 limit
9054 gnus-refer-thread-limit))
9055 (last (if (numberp limit)
9056 (min (+ (mail-header-number header) limit)
9057 gnus-newsgroup-highest)
9058 gnus-newsgroup-highest))
9059 (subject (gnus-simplify-subject
9060 (mail-header-subject header)))
9061 (refs (split-string
9062 (or (mail-header-references header) "")))
9063 (gnus-parse-headers-hook
9045 (let ((refs (append refs (list id subject)))) 9064 (let ((refs (append refs (list id subject))))
9046 (lambda () 9065 (lambda () (goto-char (point-min))
9047 (goto-char (point-min)) 9066 (keep-lines (regexp-opt refs))))))
9048 (keep-lines (regexp-opt refs)))))) 9067 (gnus-fetch-headers
9049 (gnus-fetch-headers (list last) (if (numberp limit) 9068 (list last) (if (numberp limit) (* 2 limit) limit) t))))))
9050 (* 2 limit) limit)
9051 t))))
9052 article-ids new-unreads)
9053 (when (listp new-headers) 9069 (when (listp new-headers)
9054 (dolist (header new-headers) 9070 (dolist (header new-headers)
9055 (push (mail-header-number header) article-ids)) 9071 (push (mail-header-number header) article-ids))
9056 (setq article-ids (nreverse article-ids)) 9072 (setq article-ids (nreverse article-ids))
9057 (setq new-unreads 9073 (setq new-unreads
9058 (gnus-sorted-intersection gnus-newsgroup-unselected article-ids)) 9074 (gnus-sorted-intersection gnus-newsgroup-unselected article-ids))
9059 (setq gnus-newsgroup-unselected 9075 (setq gnus-newsgroup-unselected
9060 (gnus-sorted-ndifference gnus-newsgroup-unselected new-unreads)) 9076 (gnus-sorted-ndifference gnus-newsgroup-unselected new-unreads))
9061 (setq gnus-newsgroup-unreads 9077 (setq gnus-newsgroup-unreads
9062 (gnus-sorted-nunion gnus-newsgroup-unreads new-unreads)) 9078 (gnus-sorted-nunion gnus-newsgroup-unreads new-unreads))
9063 (setq gnus-newsgroup-headers 9079 (setq gnus-newsgroup-headers
9064 (gnus-delete-duplicate-headers 9080 (gnus-delete-duplicate-headers
9065 (cl-merge 9081 (cl-merge 'list gnus-newsgroup-headers new-headers
9066 'list gnus-newsgroup-headers new-headers 9082 'gnus-article-sort-by-number)))
9067 'gnus-article-sort-by-number)))
9068 (setq gnus-newsgroup-articles 9083 (setq gnus-newsgroup-articles
9069 (gnus-sorted-nunion gnus-newsgroup-articles article-ids)) 9084 (gnus-sorted-nunion gnus-newsgroup-articles article-ids))
9070 (gnus-summary-limit-include-thread id gnus-refer-thread-limit-to-thread))) 9085 (gnus-summary-limit-include-thread id gnus-refer-thread-limit-to-thread)))
9071 (gnus-summary-show-thread)) 9086 (gnus-summary-show-thread))
9072 9087
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index de942993586..81449cb58b2 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -1908,19 +1908,7 @@ If LIMIT, first try to limit the search to the N last articles."
1908 1908
1909(autoload 'nnselect-search-thread "nnselect") 1909(autoload 'nnselect-search-thread "nnselect")
1910 1910
1911(deffoo nnimap-request-thread (header &optional group server) 1911(make-obsolete 'nnimap-request-thread 'gnus-search-thread "29.1")
1912 (if gnus-refer-thread-use-search
1913 (nnselect-search-thread header)
1914 (when (nnimap-change-group group server)
1915 (let* ((cmd (nnimap-make-thread-query header))
1916 (result (with-current-buffer (nnimap-buffer)
1917 (nnimap-command "UID SEARCH %s" cmd))))
1918 (when result
1919 (gnus-fetch-headers
1920 (and (car result)
1921 (delete 0 (mapcar #'string-to-number
1922 (cdr (assoc "SEARCH" (cdr result))))))
1923 nil t))))))
1924 1912
1925(defun nnimap-change-group (group &optional server no-reconnect read-only) 1913(defun nnimap-change-group (group &optional server no-reconnect read-only)
1926 "Change group to GROUP if non-nil. 1914 "Change group to GROUP if non-nil.
diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el
index 4eaaffe34a5..3db083c0511 100644
--- a/lisp/gnus/nnselect.el
+++ b/lisp/gnus/nnselect.el
@@ -112,6 +112,7 @@
112 112
113(make-obsolete 'nnselect-group-server 'gnus-group-server "28.1") 113(make-obsolete 'nnselect-group-server 'gnus-group-server "28.1")
114(make-obsolete 'nnselect-run 'nnselect-generate-artlist "29.1") 114(make-obsolete 'nnselect-run 'nnselect-generate-artlist "29.1")
115(make-obsolete 'nnselect-search-thread 'gnus-search-thread "29.1")
115 116
116;; Data type article list. 117;; Data type article list.
117 118
@@ -567,9 +568,9 @@ artlist; otherwise store the ARTLIST in the group parameters."
567 (artnumber (nnselect-article-number article)) 568 (artnumber (nnselect-article-number article))
568 (gmark (gnus-request-update-mark artgroup artnumber mark))) 569 (gmark (gnus-request-update-mark artgroup artnumber mark)))
569 (when (and artnumber 570 (when (and artnumber
570 (memq mark gnus-auto-expirable-marks) 571 (memq mark gnus-auto-expirable-marks)
571 (= mark gmark) 572 (= mark gmark)
572 (gnus-group-auto-expirable-p artgroup)) 573 (gnus-group-auto-expirable-p artgroup))
573 (setq gmark gnus-expirable-mark)) 574 (setq gmark gnus-expirable-mark))
574 gmark)) 575 gmark))
575 576
@@ -656,57 +657,48 @@ artlist; otherwise store the ARTLIST in the group parameters."
656 657
657(deffoo nnselect-request-thread (header &optional group server) 658(deffoo nnselect-request-thread (header &optional group server)
658 (with-current-buffer gnus-summary-buffer 659 (with-current-buffer gnus-summary-buffer
659 (let ((group (nnselect-add-prefix group)) 660 (let* ((group (nnselect-add-prefix group))
660 ;; find the best group for the originating article. if its a 661 ;; Find the best group for the originating article. If its
661 ;; pseudo-article look for real articles in the same thread 662 ;; a pseudo-article check for real articles in the same
662 ;; and see where they come from. 663 ;; thread to see where they come from.
663 (artgroup (nnselect-article-group 664 (artgroup
664 (if (> (mail-header-number header) 0) 665 (nnselect-article-group
665 (mail-header-number header) 666 (cond
666 (if (> (gnus-summary-article-number) 0) 667 ((> (mail-header-number header) 0)
667 (gnus-summary-article-number) 668 (mail-header-number header))
668 (let ((thread 669 ((> (gnus-summary-article-number) 0)
669 (gnus-id-to-thread (mail-header-id header)))) 670 (gnus-summary-article-number))
670 (when thread 671 (t (cl-some
671 (cl-some (lambda (x) 672 (lambda (x) (when (and x (> x 0)) x))
672 (when (and x (> x 0)) x)) 673 (gnus-articles-in-thread
673 (gnus-articles-in-thread thread))))))))) 674 (gnus-id-to-thread (mail-header-id header))))))))
674 ;; Check if search-based thread referral is permitted, and 675 (server (or server (gnus-group-server artgroup))))
675 ;; available. 676 ;; Check if search-based thread referral is available.
676 (if (and gnus-refer-thread-use-search 677 (if (ignore-errors (gnus-search-server-to-engine server))
677 (gnus-search-server-to-engine 678 ;; We perform the query, massage the result, and return
678 (gnus-method-to-server 679 ;; the new headers back to the caller to incorporate into
679 (gnus-find-method-for-group artgroup)))) 680 ;; the current summary buffer.
680 ;; If so we perform the query, massage the result, and return 681 (let* ((gnus-search-use-parsed-queries t)
681 ;; the new headers back to the caller to incorporate into the
682 ;; current summary buffer.
683 (let* ((gnus-search-use-parsed-queries t)
684 (group-spec 682 (group-spec
685 (list (delq nil (list 683 (if (not gnus-refer-thread-use-search)
686 (or server (gnus-group-server artgroup)) 684 (list (list server artgroup))
687 (unless gnus-refer-thread-use-search 685 (if (listp gnus-refer-thread-use-search)
688 artgroup))))) 686 gnus-refer-thread-use-search
689 (ids (cons (mail-header-id header) 687 (list (list server)))))
690 (split-string 688 (ids (cons (mail-header-id header)
691 (or (mail-header-references header) 689 (split-string
692 "")))) 690 (or (mail-header-references header)
693 (query-spec 691 ""))))
694 (list (cons 'query (mapconcat (lambda (i) 692 (query-spec
695 (format "id:%s" i)) 693 (list (cons 'query
696 ids " or ")) 694 (mapconcat (lambda (i) (format "id:%s" i))
697 (cons 'thread t))) 695 ids " or ")) (cons 'thread t)))
698 (last (nnselect-artlist-length gnus-newsgroup-selection)) 696 (last (nnselect-artlist-length gnus-newsgroup-selection))
699 (first (1+ last)) 697 (first (1+ last))
700 (new-nnselect-artlist 698 old-arts seq headers)
701 (gnus-search-run-query 699 (mapc
702 (list (cons 'search-query-spec query-spec)
703 (cons 'search-group-spec group-spec))))
704 old-arts seq
705 headers)
706 (mapc
707 (lambda (article) 700 (lambda (article)
708 (if 701 (if (setq seq
709 (setq seq
710 (cl-position 702 (cl-position
711 article 703 article
712 gnus-newsgroup-selection 704 gnus-newsgroup-selection
@@ -714,48 +706,61 @@ artlist; otherwise store the ARTLIST in the group parameters."
714 (lambda (x y) 706 (lambda (x y)
715 (and (equal (nnselect-artitem-group x) 707 (and (equal (nnselect-artitem-group x)
716 (nnselect-artitem-group y)) 708 (nnselect-artitem-group y))
717 (eql (nnselect-artitem-number x) 709 (eql (nnselect-artitem-number x)
718 (nnselect-artitem-number y)))))) 710 (nnselect-artitem-number y))))))
719 (push (1+ seq) old-arts) 711 (push (1+ seq) old-arts)
720 (setq gnus-newsgroup-selection 712 (setq gnus-newsgroup-selection
721 (vconcat gnus-newsgroup-selection (vector article))) 713 (vconcat gnus-newsgroup-selection (vector article)))
722 (cl-incf last))) 714 (cl-incf last)))
723 new-nnselect-artlist) 715 (gnus-search-run-query
724 (setq headers 716 (list (cons 'search-query-spec query-spec)
725 (gnus-fetch-headers 717 (cons 'search-group-spec group-spec))))
726 (append (sort old-arts #'<) 718 (setq headers
727 (number-sequence first last)) 719 (gnus-fetch-headers
728 nil t)) 720 (append (sort old-arts #'<) (number-sequence first last))
729 (nnselect-store-artlist group gnus-newsgroup-selection) 721 nil t))
730 (when (>= last first) 722 (nnselect-store-artlist group gnus-newsgroup-selection)
731 (let (new-marks) 723 (when (>= last first)
732 (pcase-dolist (`(,artgroup . ,artids) 724 (let (new-marks)
733 (ids-by-group (number-sequence first last))) 725 (pcase-dolist (`(,artgroup . ,artids)
734 (pcase-dolist (`(,type . ,marked) 726 (ids-by-group (number-sequence first last)))
735 (gnus-info-marks (gnus-get-info artgroup))) 727 (pcase-dolist (`(,type . ,marked)
736 (setq marked (gnus-uncompress-sequence marked)) 728 (gnus-info-marks (gnus-get-info artgroup)))
737 (when (setq new-marks 729 (when
738 (delq nil 730 (setq new-marks
739 (mapcar 731 (delq nil
732 (if (eq (gnus-article-mark-to-type type)
733 'tuple)
734 (mapcar
735 (lambda (art)
736 (let ((mtup
737 (assq (cdr art) marked)))
738 (when mtup
739 (cons (car art) (cdr mtup)))))
740 artids)
741 (setq marked
742 (gnus-uncompress-sequence marked))
743 (mapcar
740 (lambda (art) 744 (lambda (art)
741 (when (memq (cdr art) marked) 745 (when (memq (cdr art) marked)
742 (car art))) 746 (car art)))
743 artids))) 747 artids))))
744 (nconc 748 (nconc
745 (symbol-value 749 (symbol-value
746 (intern 750 (intern
747 (format "gnus-newsgroup-%s" 751 (format "gnus-newsgroup-%s"
748 (car (rassq type gnus-article-mark-lists))))) 752 (car
749 new-marks))))) 753 (rassq type gnus-article-mark-lists)))))
750 (setq gnus-newsgroup-active 754 new-marks)))))
751 (cons 1 (nnselect-artlist-length gnus-newsgroup-selection))) 755 (gnus-set-active
752 (gnus-set-active 756 group
753 group 757 (setq
754 (cons 1 (nnselect-artlist-length gnus-newsgroup-selection)))) 758 gnus-newsgroup-active
755 headers) 759 (cons 1 (nnselect-artlist-length gnus-newsgroup-selection)))))
756 ;; If we can't or won't use search, just warp to the original 760 headers)
757 ;; group and punt back to gnus-summary-refer-thread. 761 ;; If we can't use search, just warp to the original group and
758 (and (gnus-warp-to-article) (gnus-summary-refer-thread)))))) 762 ;; punt back to gnus-summary-refer-thread.
763 (and (gnus-warp-to-article) (gnus-summary-refer-thread))))))
759 764
760 765
761(deffoo nnselect-close-group (group &optional _server) 766(deffoo nnselect-close-group (group &optional _server)