diff options
| author | Andrew G Cohen | 2022-11-22 15:39:01 +0800 |
|---|---|---|
| committer | Andrew G Cohen | 2023-04-15 08:10:04 +0800 |
| commit | bf986c1faf53f3abd260f72cb36d9143afac353d (patch) | |
| tree | 4830dfb3a5b851d339f0ab86a195f2bdd7b9ae89 | |
| parent | 67ab357cdccbe6e04eb0b5cff1d6265d668116ce (diff) | |
| download | emacs-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.texi | 23 | ||||
| -rw-r--r-- | lisp/gnus/gnus-search.el | 78 | ||||
| -rw-r--r-- | lisp/gnus/gnus-sum.el | 117 | ||||
| -rw-r--r-- | lisp/gnus/nnimap.el | 14 | ||||
| -rw-r--r-- | lisp/gnus/nnselect.el | 177 |
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)} |
| 10529 | Display the full thread where the current article appears | 10529 | Display 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 |
| 10531 | articles only in the current group. Some backends (currently only | 10531 | articles 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 | 10532 | that has an associated search engine, articles are found by searching. |
| 10533 | other cases each header in the current group must be fetched and | 10533 | In other cases each header in the current group must be fetched and |
| 10534 | examined, so it usually takes a while. If you do it often, you may | 10534 | examined, so it usually takes a while. If you do it often, you may |
| 10535 | consider setting @code{gnus-fetch-old-headers} to @code{invisible} | 10535 | consider 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 | |||
| 10538 | course, it'll make group entry somewhat slow. | 10538 | course, it'll make group entry somewhat slow. |
| 10539 | 10539 | ||
| 10540 | @vindex gnus-refer-thread-use-search | 10540 | @vindex gnus-refer-thread-use-search |
| 10541 | If @code{gnus-refer-thread-use-search} is non-@code{nil} then those backends | 10541 | If @code{gnus-refer-thread-use-search} is @code{nil} (the default) |
| 10542 | that know how to find threads directly will search not just in the | 10542 | then thread-referral only looks for articles in the current group. If |
| 10543 | current group but all groups on the same server. | 10543 | this variable is @code{t} the server to which the current group |
| 10544 | belongs is searched (provided that searching is available for the | ||
| 10545 | server's backend). If this variable is a list of servers, each server | ||
| 10546 | in the list is searched. | ||
| 10544 | 10547 | ||
| 10545 | @vindex gnus-refer-thread-limit | 10548 | @vindex gnus-refer-thread-limit |
| 10546 | The @code{gnus-refer-thread-limit} variable says how many old (i.e., | 10549 | The @code{gnus-refer-thread-limit} variable says how many old (i.e., |
| 10547 | articles before the first displayed in the current group) headers to | 10550 | articles before the first displayed in the current group) headers to |
| 10548 | fetch when doing this command. The default is 200. If @code{t}, all | 10551 | fetch when referring a thread. The default is 500. If @code{t}, all |
| 10549 | the available headers will be fetched. This variable can be overridden | 10552 | the available headers will be fetched. This variable can be |
| 10550 | by giving the @kbd{A T} command a numerical prefix. | 10553 | overridden 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 |
| 10553 | In 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 |
| 10554 | the current summary buffer. (When @code{gnus-refer-thread-use-search} | 10557 | the current summary buffer. (When @code{gnus-refer-thread-use-search} |
| 10555 | is true and the initial referral starts from a summary buffer for a | 10558 | is true and the initial referral starts from a summary buffer for a |
| 10556 | non-virtual group this may not be possible. In this case a new | 10559 | non-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. |
| 2179 | header. The current server will be searched. If the registry is | 2179 | If gnus-refer-thread-use-search is nil only the current group is |
| 2180 | installed, the server that the registry reports the current | 2180 | checked for articles; if t all groups on the server containing |
| 2181 | article came from is also searched." | 2181 | the article's group will be searched; if a list then all servers |
| 2182 | (let* ((ids (cons (mail-header-id header) | 2182 | in this list will be searched. If possible the newly found |
| 2183 | (split-string | 2183 | articles are added to the summary buffer; otherwise the full |
| 2184 | (or (mail-header-references header) | 2184 | thread 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. |
| 145 | A nil value will only search for thread-related articles in the | 147 | A nil value restricts searches for thread-related articles to the |
| 146 | current group." | 148 | current group; a value of t searches all groups on the server; a |
| 149 | list of servers and groups (where each element is a list whose | ||
| 150 | car is the server and whose cdr is a list of groups on this | ||
| 151 | server or nil to search the entire server) searches these | ||
| 152 | server/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. |
| 9012 | For backends that know how to search for threads (currently only | 9019 | A non-numeric prefix arg will search the entire server; without a |
| 9013 | `nnimap') a non-numeric prefix arg will search the entire server; | 9020 | prefix arg only the current group is searched. If the variable |
| 9014 | without a prefix arg only the current group is searched. If the | 9021 | `gnus-refer-thread-use-search' is t the prefix arg has the |
| 9015 | variable `gnus-refer-thread-use-search' is non-nil the prefix arg | 9022 | reverse meaning. If searching is not enabled for the current |
| 9016 | has the reverse meaning. If no backend-specific `request-thread' | 9023 | group, fetch LIMIT (the numerical prefix) old headers. If LIMIT |
| 9017 | function is available fetch LIMIT (the numerical prefix) old | 9024 | is non-numeric or nil fetch the number specified by the |
| 9018 | headers. If LIMIT is non-numeric or nil fetch the number | 9025 | `gnus-refer-thread-limit' variable." |
| 9019 | specified 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) |