(gnus-summary-tool-bar-gnome): Don't use
[gnus] / lisp / gnus-sum.el
1 ;;; gnus-sum.el --- summary mode commands for Gnus
2
3 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 ;;   2005, 2006 Free Software Foundation, Inc.
5
6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
7 ;; Keywords: news
8
9 ;; This file is part of GNU Emacs.
10
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
25
26 ;;; Commentary:
27
28 ;;; Code:
29
30 (eval-when-compile
31   (require 'cl)
32   (defvar tool-bar-mode))
33
34 (require 'gnus)
35 (require 'gnus-group)
36 (require 'gnus-spec)
37 (require 'gnus-range)
38 (require 'gnus-int)
39 (require 'gnus-undo)
40 (require 'gnus-util)
41 (require 'gmm-utils)
42 (require 'mm-decode)
43 (require 'nnoo)
44
45 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
46 (autoload 'gnus-cache-write-active "gnus-cache")
47 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
48 (autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
49 (autoload 'gnus-pick-line-number "gnus-salt" nil t)
50 (autoload 'mm-uu-dissect "mm-uu")
51 (autoload 'gnus-article-outlook-deuglify-article "deuglify"
52   "Deuglify broken Outlook (Express) articles and redisplay."
53   t)
54 (autoload 'gnus-article-outlook-unwrap-lines "deuglify" nil t)
55 (autoload 'gnus-article-outlook-repair-attribution "deuglify" nil t)
56 (autoload 'gnus-article-outlook-rearrange-citation "deuglify" nil t)
57
58 (defcustom gnus-kill-summary-on-exit t
59   "*If non-nil, kill the summary buffer when you exit from it.
60 If nil, the summary will become a \"*Dead Summary*\" buffer, and
61 it will be killed sometime later."
62   :group 'gnus-summary-exit
63   :type 'boolean)
64
65 (defcustom gnus-fetch-old-headers nil
66   "*Non-nil means that Gnus will try to build threads by grabbing old headers.
67 If an unread article in the group refers to an older, already
68 read (or just marked as read) article, the old article will not
69 normally be displayed in the Summary buffer.  If this variable is
70 t, Gnus will attempt to grab the headers to the old articles, and
71 thereby build complete threads.  If it has the value `some', all
72 old headers will be fetched but only enough headers to connect
73 otherwise loose threads will be displayed.  This variable can
74 also be a number.  In that case, no more than that number of old
75 headers will be fetched.  If it has the value `invisible', all
76 old headers will be fetched, but none will be displayed.
77
78 The server has to support NOV for any of this to work.
79
80 This feature can seriously impact performance it ignores all
81 locally cached header entries."
82   :group 'gnus-thread
83   :type '(choice (const :tag "off" nil)
84                  (const :tag "on" t)
85                  (const some)
86                  (const invisible)
87                  number
88                  (sexp :menu-tag "other" t)))
89
90 (defcustom gnus-refer-thread-limit 200
91   "*The number of old headers to fetch when doing \\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
92 If t, fetch all the available old headers."
93   :group 'gnus-thread
94   :type '(choice number
95                  (sexp :menu-tag "other" t)))
96
97 (defcustom gnus-summary-make-false-root 'adopt
98   "*nil means that Gnus won't gather loose threads.
99 If the root of a thread has expired or been read in a previous
100 session, the information necessary to build a complete thread has been
101 lost.  Instead of having many small sub-threads from this original thread
102 scattered all over the summary buffer, Gnus can gather them.
103
104 If non-nil, Gnus will try to gather all loose sub-threads from an
105 original thread into one large thread.
106
107 If this variable is non-nil, it should be one of `none', `adopt',
108 `dummy' or `empty'.
109
110 If this variable is `none', Gnus will not make a false root, but just
111 present the sub-threads after another.
112 If this variable is `dummy', Gnus will create a dummy root that will
113 have all the sub-threads as children.
114 If this variable is `adopt', Gnus will make one of the \"children\"
115 the parent and mark all the step-children as such.
116 If this variable is `empty', the \"children\" are printed with empty
117 subject fields.  (Or rather, they will be printed with a string
118 given by the `gnus-summary-same-subject' variable.)"
119   :group 'gnus-thread
120   :type '(choice (const :tag "off" nil)
121                  (const none)
122                  (const dummy)
123                  (const adopt)
124                  (const empty)))
125
126 (defcustom gnus-summary-make-false-root-always nil
127   "Always make a false dummy root."
128   :version "22.1"
129   :group 'gnus-thread
130   :type 'boolean)
131
132 (defcustom gnus-summary-gather-exclude-subject "^ *$\\|^(none)$"
133   "*A regexp to match subjects to be excluded from loose thread gathering.
134 As loose thread gathering is done on subjects only, that means that
135 there can be many false gatherings performed.  By rooting out certain
136 common subjects, gathering might become saner."
137   :group 'gnus-thread
138   :type 'regexp)
139
140 (defcustom gnus-summary-gather-subject-limit nil
141   "*Maximum length of subject comparisons when gathering loose threads.
142 Use nil to compare full subjects.  Setting this variable to a low
143 number will help gather threads that have been corrupted by
144 newsreaders chopping off subject lines, but it might also mean that
145 unrelated articles that have subject that happen to begin with the
146 same few characters will be incorrectly gathered.
147
148 If this variable is `fuzzy', Gnus will use a fuzzy algorithm when
149 comparing subjects."
150   :group 'gnus-thread
151   :type '(choice (const :tag "off" nil)
152                  (const fuzzy)
153                  (sexp :menu-tag "on" t)))
154
155 (defcustom gnus-simplify-subject-functions nil
156   "List of functions taking a string argument that simplify subjects.
157 The functions are applied recursively.
158
159 Useful functions to put in this list include:
160 `gnus-simplify-subject-re', `gnus-simplify-subject-fuzzy',
161 `gnus-simplify-whitespace', and `gnus-simplify-all-whitespace'."
162   :group 'gnus-thread
163   :type '(repeat function))
164
165 (defcustom gnus-simplify-ignored-prefixes nil
166   "*Remove matches for this regexp from subject lines when simplifying fuzzily."
167   :group 'gnus-thread
168   :type '(choice (const :tag "off" nil)
169                  regexp))
170
171 (defcustom gnus-build-sparse-threads nil
172   "*If non-nil, fill in the gaps in threads.
173 If `some', only fill in the gaps that are needed to tie loose threads
174 together.  If `more', fill in all leaf nodes that Gnus can find.  If
175 non-nil and non-`some', fill in all gaps that Gnus manages to guess."
176   :group 'gnus-thread
177   :type '(choice (const :tag "off" nil)
178                  (const some)
179                  (const more)
180                  (sexp :menu-tag "all" t)))
181
182 (defcustom gnus-summary-thread-gathering-function
183   'gnus-gather-threads-by-subject
184   "*Function used for gathering loose threads.
185 There are two pre-defined functions: `gnus-gather-threads-by-subject',
186 which only takes Subjects into consideration; and
187 `gnus-gather-threads-by-references', which compared the References
188 headers of the articles to find matches."
189   :group 'gnus-thread
190   :type '(radio (function-item gnus-gather-threads-by-subject)
191                 (function-item gnus-gather-threads-by-references)
192                 (function :tag "other")))
193
194 (defcustom gnus-summary-same-subject ""
195   "*String indicating that the current article has the same subject as the previous.
196 This variable will only be used if the value of
197 `gnus-summary-make-false-root' is `empty'."
198   :group 'gnus-summary-format
199   :type 'string)
200
201 (defcustom gnus-summary-goto-unread t
202   "*If t, many commands will go to the next unread article.
203 This applies to marking commands as well as other commands that
204 \"naturally\" select the next article, like, for instance, `SPC' at
205 the end of an article.
206
207 If nil, the marking commands do NOT go to the next unread article
208 \(they go to the next article instead).  If `never', commands that
209 usually go to the next unread article, will go to the next article,
210 whether it is read or not."
211   :group 'gnus-summary-marks
212   :link '(custom-manual "(gnus)Setting Marks")
213   :type '(choice (const :tag "off" nil)
214                  (const never)
215                  (sexp :menu-tag "on" t)))
216
217 (defcustom gnus-summary-default-score 0
218   "*Default article score level.
219 All scores generated by the score files will be added to this score.
220 If this variable is nil, scoring will be disabled."
221   :group 'gnus-score-default
222   :type '(choice (const :tag "disable")
223                  integer))
224
225 (defcustom gnus-summary-default-high-score 0
226   "*Default threshold for a high scored article.
227 An article will be highlighted as high scored if its score is greater
228 than this score."
229   :version "22.1"
230   :group 'gnus-score-default
231   :type 'integer)
232
233 (defcustom gnus-summary-default-low-score 0
234   "*Default threshold for a low scored article.
235 An article will be highlighted as low scored if its score is smaller
236 than this score."
237   :version "22.1"
238   :group 'gnus-score-default
239   :type 'integer)
240
241 (defcustom gnus-summary-zcore-fuzz 0
242   "*Fuzziness factor for the zcore in the summary buffer.
243 Articles with scores closer than this to `gnus-summary-default-score'
244 will not be marked."
245   :group 'gnus-summary-format
246   :type 'integer)
247
248 (defcustom gnus-simplify-subject-fuzzy-regexp nil
249   "*Strings to be removed when doing fuzzy matches.
250 This can either be a regular expression or list of regular expressions
251 that will be removed from subject strings if fuzzy subject
252 simplification is selected."
253   :group 'gnus-thread
254   :type '(repeat regexp))
255
256 (defcustom gnus-show-threads t
257   "*If non-nil, display threads in summary mode."
258   :group 'gnus-thread
259   :type 'boolean)
260
261 (defcustom gnus-thread-hide-subtree nil
262   "*If non-nil, hide all threads initially.
263 This can be a predicate specifier which says which threads to hide.
264 If threads are hidden, you have to run the command
265 `gnus-summary-show-thread' by hand or select an article."
266   :group 'gnus-thread
267   :type '(radio (sexp :format "Non-nil\n"
268                       :match (lambda (widget value)
269                                (not (or (consp value) (functionp value))))
270                       :value t)
271                 (const nil)
272                 (sexp :tag "Predicate specifier")))
273
274 (defcustom gnus-thread-hide-killed t
275   "*If non-nil, hide killed threads automatically."
276   :group 'gnus-thread
277   :type 'boolean)
278
279 (defcustom gnus-thread-ignore-subject t
280   "*If non-nil, which is the default, ignore subjects and do all threading based on the Reference header.
281 If nil, articles that have different subjects from their parents will
282 start separate threads."
283   :group 'gnus-thread
284   :type 'boolean)
285
286 (defcustom gnus-thread-operation-ignore-subject t
287   "*If non-nil, subjects will be ignored when doing thread commands.
288 This affects commands like `gnus-summary-kill-thread' and
289 `gnus-summary-lower-thread'.
290
291 If this variable is nil, articles in the same thread with different
292 subjects will not be included in the operation in question.  If this
293 variable is `fuzzy', only articles that have subjects that are fuzzily
294 equal will be included."
295   :group 'gnus-thread
296   :type '(choice (const :tag "off" nil)
297                  (const fuzzy)
298                  (sexp :tag "on" t)))
299
300 (defcustom gnus-thread-indent-level 4
301   "*Number that says how much each sub-thread should be indented."
302   :group 'gnus-thread
303   :type 'integer)
304
305 (defcustom gnus-auto-extend-newsgroup t
306   "*If non-nil, extend newsgroup forward and backward when requested."
307   :group 'gnus-summary-choose
308   :type 'boolean)
309
310 (defcustom gnus-auto-select-first t
311   "*If non-nil, select the article under point.
312 Which article this is is controlled by the `gnus-auto-select-subject'
313 variable.
314
315 If you want to prevent automatic selection of articles in some
316 newsgroups, set the variable to nil in `gnus-select-group-hook'."
317   :group 'gnus-group-select
318   :type '(choice (const :tag "none" nil)
319                  (sexp :menu-tag "first" t)))
320
321 (defcustom gnus-auto-select-subject 'unread
322   "*Says what subject to place under point when entering a group.
323
324 This variable can either be the symbols `first' (place point on the
325 first subject), `unread' (place point on the subject line of the first
326 unread article), `best' (place point on the subject line of the
327 higest-scored article), `unseen' (place point on the subject line of
328 the first unseen article), `unseen-or-unread' (place point on the subject
329 line of the first unseen article or, if all article have been seen, on the
330 subject line of the first unread article), or a function to be called to
331 place point on some subject line."
332   :version "22.1"
333   :group 'gnus-group-select
334   :type '(choice (const best)
335                  (const unread)
336                  (const first)
337                  (const unseen)
338                  (const unseen-or-unread)))
339
340 (defcustom gnus-auto-select-next t
341   "*If non-nil, offer to go to the next group from the end of the previous.
342 If the value is t and the next newsgroup is empty, Gnus will exit
343 summary mode and go back to group mode.  If the value is neither nil
344 nor t, Gnus will select the following unread newsgroup.  In
345 particular, if the value is the symbol `quietly', the next unread
346 newsgroup will be selected without any confirmation, and if it is
347 `almost-quietly', the next group will be selected without any
348 confirmation if you are located on the last article in the group.
349 Finally, if this variable is `slightly-quietly', the `\\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]' command
350 will go to the next group without confirmation."
351   :group 'gnus-summary-maneuvering
352   :type '(choice (const :tag "off" nil)
353                  (const quietly)
354                  (const almost-quietly)
355                  (const slightly-quietly)
356                  (sexp :menu-tag "on" t)))
357
358 (defcustom gnus-auto-select-same nil
359   "*If non-nil, select the next article with the same subject.
360 If there are no more articles with the same subject, go to
361 the first unread article."
362   :group 'gnus-summary-maneuvering
363   :type 'boolean)
364
365 (defcustom gnus-auto-goto-ignores 'unfetched
366   "*Says how to handle unfetched articles when maneuvering.
367
368 This variable can either be the symbols nil (maneuver to any
369 article), `undownloaded' (maneuvering while unplugged ignores articles
370 that have not been fetched), `always-undownloaded' (maneuvering always
371 ignores articles that have not been fetched), `unfetched' (maneuvering
372 ignores articles whose headers have not been fetched).
373
374 NOTE: The list of unfetched articles will always be nil when plugged
375 and, when unplugged, a subset of the undownloaded article list."
376   :version "22.1"
377   :group 'gnus-summary-maneuvering
378   :type '(choice (const :tag "None" nil)
379                  (const :tag "Undownloaded when unplugged" undownloaded)
380                  (const :tag "Undownloaded" always-undownloaded)
381                  (const :tag "Unfetched" unfetched)))
382
383 (defcustom gnus-summary-check-current nil
384   "*If non-nil, consider the current article when moving.
385 The \"unread\" movement commands will stay on the same line if the
386 current article is unread."
387   :group 'gnus-summary-maneuvering
388   :type 'boolean)
389
390 (defcustom gnus-auto-center-summary 2
391   "*If non-nil, always center the current summary buffer.
392 In particular, if `vertical' do only vertical recentering.  If non-nil
393 and non-`vertical', do both horizontal and vertical recentering."
394   :group 'gnus-summary-maneuvering
395   :type '(choice (const :tag "none" nil)
396                  (const vertical)
397                  (integer :tag "height")
398                  (sexp :menu-tag "both" t)))
399
400 (defvar gnus-auto-center-group t
401   "*If non-nil, always center the group buffer.")
402
403 (defcustom gnus-show-all-headers nil
404   "*If non-nil, don't hide any headers."
405   :group 'gnus-article-hiding
406   :group 'gnus-article-headers
407   :type 'boolean)
408
409 (defcustom gnus-summary-ignore-duplicates nil
410   "*If non-nil, ignore articles with identical Message-ID headers."
411   :group 'gnus-summary
412   :type 'boolean)
413
414 (defcustom gnus-single-article-buffer t
415   "*If non-nil, display all articles in the same buffer.
416 If nil, each group will get its own article buffer."
417   :group 'gnus-article-various
418   :type 'boolean)
419
420 (defcustom gnus-break-pages t
421   "*If non-nil, do page breaking on articles.
422 The page delimiter is specified by the `gnus-page-delimiter'
423 variable."
424   :group 'gnus-article-various
425   :type 'boolean)
426
427 (defcustom gnus-move-split-methods nil
428   "*Variable used to suggest where articles are to be moved to.
429 It uses the same syntax as the `gnus-split-methods' variable.
430 However, whereas `gnus-split-methods' specifies file names as targets,
431 this variable specifies group names."
432   :group 'gnus-summary-mail
433   :type '(repeat (choice (list :value (fun) function)
434                          (cons :value ("" "") regexp (repeat string))
435                          (sexp :value nil))))
436
437 (defcustom gnus-move-group-prefix-function 'gnus-group-real-prefix
438   "Function used to compute default prefix for article move/copy/etc prompts.
439 The function should take one argument, a group name, and return a
440 string with the suggested prefix."
441   :group 'gnus-summary-mail
442   :type 'function)
443
444 ;; FIXME: Although the custom type is `character' for the following variables,
445 ;; using multibyte characters (Latin-1, UTF-8) doesn't work.  -- rs
446
447 (defcustom gnus-unread-mark ?           ;Whitespace
448   "*Mark used for unread articles."
449   :group 'gnus-summary-marks
450   :type 'character)
451
452 (defcustom gnus-ticked-mark ?!
453   "*Mark used for ticked articles."
454   :group 'gnus-summary-marks
455   :type 'character)
456
457 (defcustom gnus-dormant-mark ??
458   "*Mark used for dormant articles."
459   :group 'gnus-summary-marks
460   :type 'character)
461
462 (defcustom gnus-del-mark ?r
463   "*Mark used for del'd articles."
464   :group 'gnus-summary-marks
465   :type 'character)
466
467 (defcustom gnus-read-mark ?R
468   "*Mark used for read articles."
469   :group 'gnus-summary-marks
470   :type 'character)
471
472 (defcustom gnus-expirable-mark ?E
473   "*Mark used for expirable articles."
474   :group 'gnus-summary-marks
475   :type 'character)
476
477 (defcustom gnus-killed-mark ?K
478   "*Mark used for killed articles."
479   :group 'gnus-summary-marks
480   :type 'character)
481
482 (defcustom gnus-spam-mark ?$
483   "*Mark used for spam articles."
484   :version "22.1"
485   :group 'gnus-summary-marks
486   :type 'character)
487
488 (defcustom gnus-souped-mark ?F
489   "*Mark used for souped articles."
490   :group 'gnus-summary-marks
491   :type 'character)
492
493 (defcustom gnus-kill-file-mark ?X
494   "*Mark used for articles killed by kill files."
495   :group 'gnus-summary-marks
496   :type 'character)
497
498 (defcustom gnus-low-score-mark ?Y
499   "*Mark used for articles with a low score."
500   :group 'gnus-summary-marks
501   :type 'character)
502
503 (defcustom gnus-catchup-mark ?C
504   "*Mark used for articles that are caught up."
505   :group 'gnus-summary-marks
506   :type 'character)
507
508 (defcustom gnus-replied-mark ?A
509   "*Mark used for articles that have been replied to."
510   :group 'gnus-summary-marks
511   :type 'character)
512
513 (defcustom gnus-forwarded-mark ?F
514   "*Mark used for articles that have been forwarded."
515   :version "22.1"
516   :group 'gnus-summary-marks
517   :type 'character)
518
519 (defcustom gnus-recent-mark ?N
520   "*Mark used for articles that are recent."
521   :version "22.1"
522   :group 'gnus-summary-marks
523   :type 'character)
524
525 (defcustom gnus-cached-mark ?*
526   "*Mark used for articles that are in the cache."
527   :group 'gnus-summary-marks
528   :type 'character)
529
530 (defcustom gnus-saved-mark ?S
531   "*Mark used for articles that have been saved."
532   :group 'gnus-summary-marks
533   :type 'character)
534
535 (defcustom gnus-unseen-mark ?.
536   "*Mark used for articles that haven't been seen."
537   :version "22.1"
538   :group 'gnus-summary-marks
539   :type 'character)
540
541 (defcustom gnus-no-mark ?               ;Whitespace
542   "*Mark used for articles that have no other secondary mark."
543   :version "22.1"
544   :group 'gnus-summary-marks
545   :type 'character)
546
547 (defcustom gnus-ancient-mark ?O
548   "*Mark used for ancient articles."
549   :group 'gnus-summary-marks
550   :type 'character)
551
552 (defcustom gnus-sparse-mark ?Q
553   "*Mark used for sparsely reffed articles."
554   :group 'gnus-summary-marks
555   :type 'character)
556
557 (defcustom gnus-canceled-mark ?G
558   "*Mark used for canceled articles."
559   :group 'gnus-summary-marks
560   :type 'character)
561
562 (defcustom gnus-duplicate-mark ?M
563   "*Mark used for duplicate articles."
564   :group 'gnus-summary-marks
565   :type 'character)
566
567 (defcustom gnus-undownloaded-mark ?-
568   "*Mark used for articles that weren't downloaded."
569   :version "22.1"
570   :group 'gnus-summary-marks
571   :type 'character)
572
573 (defcustom gnus-downloaded-mark ?+
574   "*Mark used for articles that were downloaded."
575   :group 'gnus-summary-marks
576   :type 'character)
577
578 (defcustom gnus-downloadable-mark ?%
579   "*Mark used for articles that are to be downloaded."
580   :group 'gnus-summary-marks
581   :type 'character)
582
583 (defcustom gnus-unsendable-mark ?=
584   "*Mark used for articles that won't be sent."
585   :group 'gnus-summary-marks
586   :type 'character)
587
588 (defcustom gnus-score-over-mark ?+
589   "*Score mark used for articles with high scores."
590   :group 'gnus-summary-marks
591   :type 'character)
592
593 (defcustom gnus-score-below-mark ?-
594   "*Score mark used for articles with low scores."
595   :group 'gnus-summary-marks
596   :type 'character)
597
598 (defcustom gnus-empty-thread-mark ?     ;Whitespace
599   "*There is no thread under the article."
600   :group 'gnus-summary-marks
601   :type 'character)
602
603 (defcustom gnus-not-empty-thread-mark ?=
604   "*There is a thread under the article."
605   :group 'gnus-summary-marks
606   :type 'character)
607
608 (defcustom gnus-view-pseudo-asynchronously nil
609   "*If non-nil, Gnus will view pseudo-articles asynchronously."
610   :group 'gnus-extract-view
611   :type 'boolean)
612
613 (defcustom gnus-auto-expirable-marks
614   (list gnus-killed-mark gnus-del-mark gnus-catchup-mark
615         gnus-low-score-mark gnus-ancient-mark gnus-read-mark
616         gnus-souped-mark gnus-duplicate-mark)
617   "*The list of marks converted into expiration if a group is auto-expirable."
618   :version "21.1"
619   :group 'gnus-summary
620   :type '(repeat character))
621
622 (defcustom gnus-inhibit-user-auto-expire t
623   "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
624   :version "21.1"
625   :group 'gnus-summary
626   :type 'boolean)
627
628 (defcustom gnus-view-pseudos nil
629   "*If `automatic', pseudo-articles will be viewed automatically.
630 If `not-confirm', pseudos will be viewed automatically, and the user
631 will not be asked to confirm the command."
632   :group 'gnus-extract-view
633   :type '(choice (const :tag "off" nil)
634                  (const automatic)
635                  (const not-confirm)))
636
637 (defcustom gnus-view-pseudos-separately t
638   "*If non-nil, one pseudo-article will be created for each file to be viewed.
639 If nil, all files that use the same viewing command will be given as a
640 list of parameters to that command."
641   :group 'gnus-extract-view
642   :type 'boolean)
643
644 (defcustom gnus-insert-pseudo-articles t
645   "*If non-nil, insert pseudo-articles when decoding articles."
646   :group 'gnus-extract-view
647   :type 'boolean)
648
649 (defcustom gnus-summary-dummy-line-format
650   "   %(:                             :%) %S\n"
651   "*The format specification for the dummy roots in the summary buffer.
652 It works along the same lines as a normal formatting string,
653 with some simple extensions.
654
655 %S  The subject
656
657 General format specifiers can also be used.
658 See `(gnus)Formatting Variables'."
659   :link '(custom-manual "(gnus)Formatting Variables")
660   :group 'gnus-threading
661   :type 'string)
662
663 (defcustom gnus-summary-mode-line-format "Gnus: %g [%A] %Z"
664   "*The format specification for the summary mode line.
665 It works along the same lines as a normal formatting string,
666 with some simple extensions:
667
668 %G  Group name
669 %p  Unprefixed group name
670 %A  Current article number
671 %z  Current article score
672 %V  Gnus version
673 %U  Number of unread articles in the group
674 %e  Number of unselected articles in the group
675 %Z  A string with unread/unselected article counts
676 %g  Shortish group name
677 %S  Subject of the current article
678 %u  User-defined spec
679 %s  Current score file name
680 %d  Number of dormant articles
681 %r  Number of articles that have been marked as read in this session
682 %E  Number of articles expunged by the score files"
683   :group 'gnus-summary-format
684   :type 'string)
685
686 (defcustom gnus-list-identifiers nil
687   "Regexp that matches list identifiers to be removed from subject.
688 This can also be a list of regexps."
689   :version "21.1"
690   :group 'gnus-summary-format
691   :group 'gnus-article-hiding
692   :type '(choice (const :tag "none" nil)
693                  (regexp :value ".*")
694                  (repeat :value (".*") regexp)))
695
696 (defcustom gnus-summary-mark-below 0
697   "*Mark all articles with a score below this variable as read.
698 This variable is local to each summary buffer and usually set by the
699 score file."
700   :group 'gnus-score-default
701   :type 'integer)
702
703 (defun gnus-widget-reversible-match (widget value)
704   "Ignoring WIDGET, convert VALUE to internal form.
705 VALUE should have the form `FOO' or `(not FOO)', where FOO is an symbol."
706   ;; (debug value)
707   (or (symbolp value)
708       (and (listp value)
709            (eq (length value) 2)
710            (eq (nth 0 value) 'not)
711            (symbolp (nth 1 value)))))
712
713 (defun gnus-widget-reversible-to-internal (widget value)
714   "Ignoring WIDGET, convert VALUE to internal form.
715 VALUE should have the form `FOO' or `(not FOO)', where FOO is an atom.
716 FOO is converted to (FOO nil) and (not FOO) is converted to (FOO t)."
717   ;; (debug value)
718   (if (atom value)
719       (list value nil)
720     (list (nth 1 value) t)))
721
722 (defun gnus-widget-reversible-to-external (widget value)
723   "Ignoring WIDGET, convert VALUE to external form.
724 VALUE should have the form `(FOO nil)' or `(FOO t)', where FOO is an atom.
725 \(FOO  nil) is converted to FOO and (FOO t) is converted to (not FOO)."
726   ;; (debug value)
727   (if (nth 1 value)
728       (list 'not (nth 0 value))
729     (nth 0 value)))
730
731 (define-widget 'gnus-widget-reversible 'group
732   "A `group' that convert values."
733   :match 'gnus-widget-reversible-match
734   :value-to-internal 'gnus-widget-reversible-to-internal
735   :value-to-external 'gnus-widget-reversible-to-external)
736
737 (defcustom gnus-article-sort-functions '(gnus-article-sort-by-number)
738   "*List of functions used for sorting articles in the summary buffer.
739
740 Each function takes two articles and returns non-nil if the first
741 article should be sorted before the other.  If you use more than one
742 function, the primary sort function should be the last.  You should
743 probably always include `gnus-article-sort-by-number' in the list of
744 sorting functions -- preferably first.  Also note that sorting by date
745 is often much slower than sorting by number, and the sorting order is
746 very similar.  (Sorting by date means sorting by the time the message
747 was sent, sorting by number means sorting by arrival time.)
748
749 Each item can also be a list `(not F)' where F is a function;
750 this reverses the sort order.
751
752 Ready-made functions include `gnus-article-sort-by-number',
753 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
754 `gnus-article-sort-by-date', `gnus-article-sort-by-random'
755 and `gnus-article-sort-by-score'.
756
757 When threading is turned on, the variable `gnus-thread-sort-functions'
758 controls how articles are sorted."
759   :group 'gnus-summary-sort
760   :type '(repeat (gnus-widget-reversible
761                   (choice (function-item gnus-article-sort-by-number)
762                           (function-item gnus-article-sort-by-author)
763                           (function-item gnus-article-sort-by-subject)
764                           (function-item gnus-article-sort-by-date)
765                           (function-item gnus-article-sort-by-score)
766                           (function-item gnus-article-sort-by-random)
767                           (function :tag "other"))
768                   (boolean :tag "Reverse order"))))
769
770
771 (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
772   "*List of functions used for sorting threads in the summary buffer.
773 By default, threads are sorted by article number.
774
775 Each function takes two threads and returns non-nil if the first
776 thread should be sorted before the other.  If you use more than one
777 function, the primary sort function should be the last.  You should
778 probably always include `gnus-thread-sort-by-number' in the list of
779 sorting functions -- preferably first.  Also note that sorting by date
780 is often much slower than sorting by number, and the sorting order is
781 very similar.  (Sorting by date means sorting by the time the message
782 was sent, sorting by number means sorting by arrival time.)
783
784 Each list item can also be a list `(not F)' where F is a
785 function; this specifies reversed sort order.
786
787 Ready-made functions include `gnus-thread-sort-by-number',
788 `gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
789 `gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
790 `gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
791 `gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
792 and `gnus-thread-sort-by-total-score' (see
793 `gnus-thread-score-function').
794
795 When threading is turned off, the variable
796 `gnus-article-sort-functions' controls how articles are sorted."
797   :group 'gnus-summary-sort
798   :type '(repeat
799           (gnus-widget-reversible
800            (choice (function-item gnus-thread-sort-by-number)
801                    (function-item gnus-thread-sort-by-author)
802                    (function-item gnus-thread-sort-by-recipient)
803                    (function-item gnus-thread-sort-by-subject)
804                    (function-item gnus-thread-sort-by-date)
805                    (function-item gnus-thread-sort-by-score)
806                    (function-item gnus-thread-sort-by-most-recent-number)
807                    (function-item gnus-thread-sort-by-most-recent-date)
808                    (function-item gnus-thread-sort-by-random)
809                    (function-item gnus-thread-sort-by-total-score)
810                    (function :tag "other"))
811            (boolean :tag "Reverse order"))))
812
813 (defcustom gnus-thread-score-function '+
814   "*Function used for calculating the total score of a thread.
815
816 The function is called with the scores of the article and each
817 subthread and should then return the score of the thread.
818
819 Some functions you can use are `+', `max', or `min'."
820   :group 'gnus-summary-sort
821   :type 'function)
822
823 (defcustom gnus-summary-expunge-below nil
824   "All articles that have a score less than this variable will be expunged.
825 This variable is local to the summary buffers."
826   :group 'gnus-score-default
827   :type '(choice (const :tag "off" nil)
828                  integer))
829
830 (defcustom gnus-thread-expunge-below nil
831   "All threads that have a total score less than this variable will be expunged.
832 See `gnus-thread-score-function' for en explanation of what a
833 \"thread score\" is.
834
835 This variable is local to the summary buffers."
836   :group 'gnus-threading
837   :group 'gnus-score-default
838   :type '(choice (const :tag "off" nil)
839                  integer))
840
841 (defcustom gnus-summary-mode-hook nil
842   "*A hook for Gnus summary mode.
843 This hook is run before any variables are set in the summary buffer."
844   :options '(turn-on-gnus-mailing-list-mode gnus-pick-mode)
845   :group 'gnus-summary-various
846   :type 'hook)
847
848 ;; Extracted from gnus-xmas-redefine in order to preserve user settings
849 (when (featurep 'xemacs)
850   (add-hook 'gnus-summary-mode-hook 'gnus-xmas-summary-menu-add)
851   (add-hook 'gnus-summary-mode-hook 'gnus-xmas-setup-summary-toolbar)
852   (add-hook 'gnus-summary-mode-hook
853             'gnus-xmas-switch-horizontal-scrollbar-off))
854
855 (defcustom gnus-summary-menu-hook nil
856   "*Hook run after the creation of the summary mode menu."
857   :group 'gnus-summary-visual
858   :type 'hook)
859
860 (defcustom gnus-summary-exit-hook nil
861   "*A hook called on exit from the summary buffer.
862 It will be called with point in the group buffer."
863   :group 'gnus-summary-exit
864   :type 'hook)
865
866 (defcustom gnus-summary-prepare-hook nil
867   "*A hook called after the summary buffer has been generated.
868 If you want to modify the summary buffer, you can use this hook."
869   :group 'gnus-summary-various
870   :type 'hook)
871
872 (defcustom gnus-summary-prepared-hook nil
873   "*A hook called as the last thing after the summary buffer has been generated."
874   :group 'gnus-summary-various
875   :type 'hook)
876
877 (defcustom gnus-summary-generate-hook nil
878   "*A hook run just before generating the summary buffer.
879 This hook is commonly used to customize threading variables and the
880 like."
881   :group 'gnus-summary-various
882   :type 'hook)
883
884 (defcustom gnus-select-group-hook nil
885   "*A hook called when a newsgroup is selected.
886
887 If you'd like to simplify subjects like the
888 `gnus-summary-next-same-subject' command does, you can use the
889 following hook:
890
891  (add-hook gnus-select-group-hook
892            (lambda ()
893              (mapcar (lambda (header)
894                        (mail-header-set-subject
895                         header
896                         (gnus-simplify-subject
897                          (mail-header-subject header) 're-only)))
898                      gnus-newsgroup-headers)))"
899   :group 'gnus-group-select
900   :type 'hook)
901
902 (defcustom gnus-select-article-hook nil
903   "*A hook called when an article is selected."
904   :group 'gnus-summary-choose
905   :options '(gnus-agent-fetch-selected-article)
906   :type 'hook)
907
908 (defcustom gnus-visual-mark-article-hook
909   (list 'gnus-highlight-selected-summary)
910   "*Hook run after selecting an article in the summary buffer.
911 It is meant to be used for highlighting the article in some way.  It
912 is not run if `gnus-visual' is nil."
913   :group 'gnus-summary-visual
914   :type 'hook)
915
916 (defcustom gnus-parse-headers-hook nil
917   "*A hook called before parsing the headers."
918   :group 'gnus-various
919   :type 'hook)
920
921 (defcustom gnus-exit-group-hook nil
922   "*A hook called when exiting summary mode.
923 This hook is not called from the non-updating exit commands like `Q'."
924   :group 'gnus-various
925   :type 'hook)
926
927 (defcustom gnus-summary-update-hook
928   (list 'gnus-summary-highlight-line)
929   "*A hook called when a summary line is changed.
930 The hook will not be called if `gnus-visual' is nil.
931
932 The default function `gnus-summary-highlight-line' will
933 highlight the line according to the `gnus-summary-highlight'
934 variable."
935   :group 'gnus-summary-visual
936   :type 'hook)
937
938 (defcustom gnus-mark-article-hook '(gnus-summary-mark-read-and-unread-as-read)
939   "*A hook called when an article is selected for the first time.
940 The hook is intended to mark an article as read (or unread)
941 automatically when it is selected."
942   :group 'gnus-summary-choose
943   :type 'hook)
944
945 (defcustom gnus-group-no-more-groups-hook nil
946   "*A hook run when returning to group mode having no more (unread) groups."
947   :group 'gnus-group-select
948   :type 'hook)
949
950 (defcustom gnus-ps-print-hook nil
951   "*A hook run before ps-printing something from Gnus."
952   :group 'gnus-summary
953   :type 'hook)
954
955 (defcustom gnus-summary-article-move-hook nil
956   "*A hook called after an article is moved, copied, respooled, or crossposted."
957   :version "22.1"
958   :group 'gnus-summary
959   :type 'hook)
960
961 (defcustom gnus-summary-article-delete-hook nil
962   "*A hook called after an article is deleted."
963   :version "22.1"
964   :group 'gnus-summary
965   :type 'hook)
966
967 (defcustom gnus-summary-article-expire-hook nil
968   "*A hook called after an article is expired."
969   :version "22.1"
970   :group 'gnus-summary
971   :type 'hook)
972
973 (defcustom gnus-summary-display-arrow
974   (and (fboundp 'display-graphic-p)
975        (display-graphic-p))
976   "*If non-nil, display an arrow highlighting the current article."
977   :version "22.1"
978   :group 'gnus-summary
979   :type 'boolean)
980
981 (defcustom gnus-summary-selected-face 'gnus-summary-selected
982   "Face used for highlighting the current article in the summary buffer."
983   :group 'gnus-summary-visual
984   :type 'face)
985
986 (defvar gnus-tmp-downloaded nil)
987
988 (defcustom gnus-summary-highlight
989   '(((eq mark gnus-canceled-mark)
990      . gnus-summary-cancelled)
991     ((and uncached (> score default-high))
992      . gnus-summary-high-undownloaded)
993     ((and uncached (< score default-low))
994      . gnus-summary-low-undownloaded)
995     (uncached
996      . gnus-summary-normal-undownloaded)
997     ((and (> score default-high)
998           (or (eq mark gnus-dormant-mark)
999               (eq mark gnus-ticked-mark)))
1000      . gnus-summary-high-ticked)
1001     ((and (< score default-low)
1002           (or (eq mark gnus-dormant-mark)
1003               (eq mark gnus-ticked-mark)))
1004      . gnus-summary-low-ticked)
1005     ((or (eq mark gnus-dormant-mark)
1006          (eq mark gnus-ticked-mark))
1007      . gnus-summary-normal-ticked)
1008     ((and (> score default-high) (eq mark gnus-ancient-mark))
1009      . gnus-summary-high-ancient)
1010     ((and (< score default-low) (eq mark gnus-ancient-mark))
1011      . gnus-summary-low-ancient)
1012     ((eq mark gnus-ancient-mark)
1013      . gnus-summary-normal-ancient)
1014     ((and (> score default-high) (eq mark gnus-unread-mark))
1015      . gnus-summary-high-unread)
1016     ((and (< score default-low) (eq mark gnus-unread-mark))
1017      . gnus-summary-low-unread)
1018     ((eq mark gnus-unread-mark)
1019      . gnus-summary-normal-unread)
1020     ((> score default-high)
1021      . gnus-summary-high-read)
1022     ((< score default-low)
1023      . gnus-summary-low-read)
1024     (t
1025      . gnus-summary-normal-read))
1026   "*Controls the highlighting of summary buffer lines.
1027
1028 A list of (FORM . FACE) pairs.  When deciding how a a particular
1029 summary line should be displayed, each form is evaluated.  The content
1030 of the face field after the first true form is used.  You can change
1031 how those summary lines are displayed, by editing the face field.
1032
1033 You can use the following variables in the FORM field.
1034
1035 score:        The article's score
1036 default:      The default article score.
1037 default-high: The default score for high scored articles.
1038 default-low:  The default score for low scored articles.
1039 below:        The score below which articles are automatically marked as read.
1040 mark:         The article's mark.
1041 uncached:     Non-nil if the article is uncached."
1042   :group 'gnus-summary-visual
1043   :type '(repeat (cons (sexp :tag "Form" nil)
1044                        face)))
1045
1046 (defcustom gnus-alter-header-function nil
1047   "Function called to allow alteration of article header structures.
1048 The function is called with one parameter, the article header vector,
1049 which it may alter in any way."
1050   :type '(choice (const :tag "None" nil)
1051                  function)
1052   :group 'gnus-summary)
1053
1054 (defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
1055   "Variable that says which function should be used to decode a string with encoded words.")
1056
1057 (defcustom gnus-extra-headers '(To Newsgroups)
1058   "*Extra headers to parse."
1059   :version "21.1"
1060   :group 'gnus-summary
1061   :type '(repeat symbol))
1062
1063 (defcustom gnus-ignored-from-addresses
1064   (and user-mail-address  
1065        (not (string= user-mail-address ""))
1066        (regexp-quote user-mail-address))
1067   "*Regexp of From headers that may be suppressed in favor of To headers."
1068   :version "21.1"
1069   :group 'gnus-summary
1070   :type 'regexp)
1071
1072 (defcustom gnus-summary-to-prefix "-> "
1073   "*String prefixed to the To field in the summary line when
1074 using `gnus-ignored-from-addresses'."
1075   :version "22.1"
1076   :group 'gnus-summary
1077   :type 'string)
1078
1079 (defcustom gnus-summary-newsgroup-prefix "=> "
1080   "*String prefixed to the Newsgroup field in the summary
1081 line when using `gnus-ignored-from-addresses'."
1082   :version "22.1"
1083   :group 'gnus-summary
1084   :type 'string)
1085
1086 (defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
1087   "List of charsets that should be ignored.
1088 When these charsets are used in the \"charset\" parameter, the
1089 default charset will be used instead."
1090   :version "21.1"
1091   :type '(repeat symbol)
1092   :group 'gnus-charset)
1093
1094 (gnus-define-group-parameter
1095  ignored-charsets
1096  :type list
1097  :function-document
1098  "Return the ignored charsets of GROUP."
1099  :variable gnus-group-ignored-charsets-alist
1100  :variable-default
1101  '(("alt\\.chinese\\.text" iso-8859-1))
1102  :variable-document
1103  "Alist of regexps (to match group names) and charsets that should be ignored.
1104 When these charsets are used in the \"charset\" parameter, the
1105 default charset will be used instead."
1106  :variable-group gnus-charset
1107  :variable-type '(repeat (cons (regexp :tag "Group")
1108                                (repeat symbol)))
1109  :parameter-type '(choice :tag "Ignored charsets"
1110                           :value nil
1111                           (repeat (symbol)))
1112  :parameter-document       "\
1113 List of charsets that should be ignored.
1114
1115 When these charsets are used in the \"charset\" parameter, the
1116 default charset will be used instead.")
1117
1118 (defcustom gnus-group-highlight-words-alist nil
1119   "Alist of group regexps and highlight regexps.
1120 This variable uses the same syntax as `gnus-emphasis-alist'."
1121   :version "21.1"
1122   :type '(repeat (cons (regexp :tag "Group")
1123                        (repeat (list (regexp :tag "Highlight regexp")
1124                                      (number :tag "Group for entire word" 0)
1125                                      (number :tag "Group for displayed part" 0)
1126                                      (symbol :tag "Face"
1127                                              gnus-emphasis-highlight-words)))))
1128   :group 'gnus-summary-visual)
1129
1130 (defcustom gnus-summary-show-article-charset-alist
1131   nil
1132   "Alist of number and charset.
1133 The article will be shown with the charset corresponding to the
1134 numbered argument.
1135 For example: ((1 . cn-gb-2312) (2 . big5))."
1136   :version "21.1"
1137   :type '(repeat (cons (number :tag "Argument" 1)
1138                        (symbol :tag "Charset")))
1139   :group 'gnus-charset)
1140
1141 (defcustom gnus-preserve-marks t
1142   "Whether marks are preserved when moving, copying and respooling messages."
1143   :version "21.1"
1144   :type 'boolean
1145   :group 'gnus-summary-marks)
1146
1147 (defcustom gnus-alter-articles-to-read-function nil
1148   "Function to be called to alter the list of articles to be selected."
1149   :type '(choice (const nil) function)
1150   :group 'gnus-summary)
1151
1152 (defcustom gnus-orphan-score nil
1153   "*All orphans get this score added.  Set in the score file."
1154   :group 'gnus-score-default
1155   :type '(choice (const nil)
1156                  integer))
1157
1158 (defcustom gnus-summary-save-parts-default-mime "image/.*"
1159   "*A regexp to match MIME parts when saving multiple parts of a
1160 message with `gnus-summary-save-parts' (\\<gnus-summary-mode-map>\\[gnus-summary-save-parts]).
1161 This regexp will be used by default when prompting the user for which
1162 type of files to save."
1163   :group 'gnus-summary
1164   :type 'regexp)
1165
1166 (defcustom gnus-read-all-available-headers nil
1167   "Whether Gnus should parse all headers made available to it.
1168 This is mostly relevant for slow back ends where the user may
1169 wish to widen the summary buffer to include all headers
1170 that were fetched.  Say, for nnultimate groups."
1171   :version "22.1"
1172   :group 'gnus-summary
1173   :type '(choice boolean regexp))
1174
1175 (defcustom gnus-summary-muttprint-program "muttprint"
1176   "Command (and optional arguments) used to run Muttprint."
1177   :version "22.1"
1178   :group 'gnus-summary
1179   :type 'string)
1180
1181 (defcustom gnus-article-loose-mime t
1182   "If non-nil, don't require MIME-Version header.
1183 Some brain-damaged MUA/MTA, e.g. Lotus Domino 5.0.6 clients, does not
1184 supply the MIME-Version header or deliberately strip it from the mail.
1185 If non-nil (the default), Gnus will treat some articles as MIME
1186 even if the MIME-Version header is missing."
1187   :version "22.1"
1188   :type 'boolean
1189   :group 'gnus-article-mime)
1190
1191 (defcustom gnus-article-emulate-mime t
1192   "If non-nil, use MIME emulation for uuencode and the like.
1193 This means that Gnus will search message bodies for text that look
1194 like uuencoded bits, yEncoded bits, and so on, and present that using
1195 the normal Gnus MIME machinery."
1196   :version "22.1"
1197   :type 'boolean
1198   :group 'gnus-article-mime)
1199
1200 ;;; Internal variables
1201
1202 (defvar gnus-summary-display-cache nil)
1203 (defvar gnus-article-mime-handles nil)
1204 (defvar gnus-article-decoded-p nil)
1205 (defvar gnus-article-charset nil)
1206 (defvar gnus-article-ignored-charsets nil)
1207 (defvar gnus-scores-exclude-files nil)
1208 (defvar gnus-page-broken nil)
1209
1210 (defvar gnus-original-article nil)
1211 (defvar gnus-article-internal-prepare-hook nil)
1212 (defvar gnus-newsgroup-process-stack nil)
1213
1214 (defvar gnus-thread-indent-array nil)
1215 (defvar gnus-thread-indent-array-level gnus-thread-indent-level)
1216 (defvar gnus-sort-gathered-threads-function 'gnus-thread-sort-by-number
1217   "Function called to sort the articles within a thread after it has been gathered together.")
1218
1219 (defvar gnus-summary-save-parts-type-history nil)
1220 (defvar gnus-summary-save-parts-last-directory mm-default-directory)
1221
1222 ;; Avoid highlighting in kill files.
1223 (defvar gnus-summary-inhibit-highlight nil)
1224 (defvar gnus-newsgroup-selected-overlay nil)
1225 (defvar gnus-inhibit-limiting nil)
1226 (defvar gnus-newsgroup-adaptive-score-file nil)
1227 (defvar gnus-current-score-file nil)
1228 (defvar gnus-current-move-group nil)
1229 (defvar gnus-current-copy-group nil)
1230 (defvar gnus-current-crosspost-group nil)
1231 (defvar gnus-newsgroup-display nil)
1232
1233 (defvar gnus-newsgroup-dependencies nil)
1234 (defvar gnus-newsgroup-adaptive nil)
1235 (defvar gnus-summary-display-article-function nil)
1236 (defvar gnus-summary-highlight-line-function nil
1237   "Function called after highlighting a summary line.")
1238
1239 (defvar gnus-summary-line-format-alist
1240   `((?N ,(macroexpand '(mail-header-number gnus-tmp-header)) ?d)
1241     (?S ,(macroexpand '(mail-header-subject gnus-tmp-header)) ?s)
1242     (?s gnus-tmp-subject-or-nil ?s)
1243     (?n gnus-tmp-name ?s)
1244     (?A (car (cdr (funcall gnus-extract-address-components gnus-tmp-from)))
1245         ?s)
1246     (?a (or (car (funcall gnus-extract-address-components gnus-tmp-from))
1247             gnus-tmp-from) ?s)
1248     (?F gnus-tmp-from ?s)
1249     (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s)
1250     (?D ,(macroexpand '(mail-header-date gnus-tmp-header)) ?s)
1251     (?d (gnus-dd-mmm (mail-header-date gnus-tmp-header)) ?s)
1252     (?o (gnus-date-iso8601 (mail-header-date gnus-tmp-header)) ?s)
1253     (?M ,(macroexpand '(mail-header-id gnus-tmp-header)) ?s)
1254     (?r ,(macroexpand '(mail-header-references gnus-tmp-header)) ?s)
1255     (?c (or (mail-header-chars gnus-tmp-header) 0) ?d)
1256     (?k (gnus-summary-line-message-size gnus-tmp-header) ?s)
1257     (?L gnus-tmp-lines ?s)
1258     (?O gnus-tmp-downloaded ?c)
1259     (?I gnus-tmp-indentation ?s)
1260     (?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s)
1261     (?R gnus-tmp-replied ?c)
1262     (?\[ gnus-tmp-opening-bracket ?c)
1263     (?\] gnus-tmp-closing-bracket ?c)
1264     (?\> (make-string gnus-tmp-level ? ) ?s)
1265     (?\< (make-string (max 0 (- 20 gnus-tmp-level)) ? ) ?s)
1266     (?i gnus-tmp-score ?d)
1267     (?z gnus-tmp-score-char ?c)
1268     (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d)
1269     (?U gnus-tmp-unread ?c)
1270     (?f (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header gnus-tmp-from)
1271         ?s)
1272     (?t (gnus-summary-number-of-articles-in-thread
1273          (and (boundp 'thread) (car thread)) gnus-tmp-level)
1274         ?d)
1275     (?e (gnus-summary-number-of-articles-in-thread
1276          (and (boundp 'thread) (car thread)) gnus-tmp-level t)
1277         ?c)
1278     (?u gnus-tmp-user-defined ?s)
1279     (?P (gnus-pick-line-number) ?d)
1280     (?B gnus-tmp-thread-tree-header-string ?s)
1281     (user-date (gnus-user-date
1282                 ,(macroexpand '(mail-header-date gnus-tmp-header))) ?s))
1283   "An alist of format specifications that can appear in summary lines.
1284 These are paired with what variables they correspond with, along with
1285 the type of the variable (string, integer, character, etc).")
1286
1287 (defvar gnus-summary-dummy-line-format-alist
1288   `((?S gnus-tmp-subject ?s)
1289     (?N gnus-tmp-number ?d)
1290     (?u gnus-tmp-user-defined ?s)))
1291
1292 (defvar gnus-summary-mode-line-format-alist
1293   `((?G gnus-tmp-group-name ?s)
1294     (?g (gnus-short-group-name gnus-tmp-group-name) ?s)
1295     (?p (gnus-group-real-name gnus-tmp-group-name) ?s)
1296     (?A gnus-tmp-article-number ?d)
1297     (?Z gnus-tmp-unread-and-unselected ?s)
1298     (?V gnus-version ?s)
1299     (?U gnus-tmp-unread-and-unticked ?d)
1300     (?S gnus-tmp-subject ?s)
1301     (?e gnus-tmp-unselected ?d)
1302     (?u gnus-tmp-user-defined ?s)
1303     (?d (length gnus-newsgroup-dormant) ?d)
1304     (?t (length gnus-newsgroup-marked) ?d)
1305     (?h (length gnus-newsgroup-spam-marked) ?d)
1306     (?r (length gnus-newsgroup-reads) ?d)
1307     (?z (gnus-summary-article-score gnus-tmp-article-number) ?d)
1308     (?E gnus-newsgroup-expunged-tally ?d)
1309     (?s (gnus-current-score-file-nondirectory) ?s)))
1310
1311 (defvar gnus-last-search-regexp nil
1312   "Default regexp for article search command.")
1313
1314 (defvar gnus-last-shell-command nil
1315   "Default shell command on article.")
1316
1317 (defvar gnus-newsgroup-agentized nil
1318   "Locally bound in each summary buffer to indicate whether the server has been agentized.")
1319 (defvar gnus-newsgroup-begin nil)
1320 (defvar gnus-newsgroup-end nil)
1321 (defvar gnus-newsgroup-last-rmail nil)
1322 (defvar gnus-newsgroup-last-mail nil)
1323 (defvar gnus-newsgroup-last-folder nil)
1324 (defvar gnus-newsgroup-last-file nil)
1325 (defvar gnus-newsgroup-auto-expire nil)
1326 (defvar gnus-newsgroup-active nil)
1327
1328 (defvar gnus-newsgroup-data nil)
1329 (defvar gnus-newsgroup-data-reverse nil)
1330 (defvar gnus-newsgroup-limit nil)
1331 (defvar gnus-newsgroup-limits nil)
1332 (defvar gnus-summary-use-undownloaded-faces nil)
1333
1334 (defvar gnus-newsgroup-unreads nil
1335   "Sorted list of unread articles in the current newsgroup.")
1336
1337 (defvar gnus-newsgroup-unselected nil
1338   "Sorted list of unselected unread articles in the current newsgroup.")
1339
1340 (defvar gnus-newsgroup-reads nil
1341   "Alist of read articles and article marks in the current newsgroup.")
1342
1343 (defvar gnus-newsgroup-expunged-tally nil)
1344
1345 (defvar gnus-newsgroup-marked nil
1346   "Sorted list of ticked articles in the current newsgroup (a subset of unread art).")
1347
1348 (defvar gnus-newsgroup-spam-marked nil
1349   "List of ranges of articles that have been marked as spam.")
1350
1351 (defvar gnus-newsgroup-killed nil
1352   "List of ranges of articles that have been through the scoring process.")
1353
1354 (defvar gnus-newsgroup-cached nil
1355   "Sorted list of articles that come from the article cache.")
1356
1357 (defvar gnus-newsgroup-saved nil
1358   "List of articles that have been saved.")
1359
1360 (defvar gnus-newsgroup-kill-headers nil)
1361
1362 (defvar gnus-newsgroup-replied nil
1363   "List of articles that have been replied to in the current newsgroup.")
1364
1365 (defvar gnus-newsgroup-forwarded nil
1366   "List of articles that have been forwarded in the current newsgroup.")
1367
1368 (defvar gnus-newsgroup-recent nil
1369   "List of articles that have are recent in the current newsgroup.")
1370
1371 (defvar gnus-newsgroup-expirable nil
1372   "Sorted list of articles in the current newsgroup that can be expired.")
1373
1374 (defvar gnus-newsgroup-processable nil
1375   "List of articles in the current newsgroup that can be processed.")
1376
1377 (defvar gnus-newsgroup-downloadable nil
1378   "Sorted list of articles in the current newsgroup that can be processed.")
1379
1380 (defvar gnus-newsgroup-unfetched nil
1381   "Sorted list of articles in the current newsgroup whose headers have
1382 not been fetched into the agent.
1383
1384 This list will always be a subset of gnus-newsgroup-undownloaded.")
1385
1386 (defvar gnus-newsgroup-undownloaded nil
1387   "List of articles in the current newsgroup that haven't been downloaded.")
1388
1389 (defvar gnus-newsgroup-unsendable nil
1390   "List of articles in the current newsgroup that won't be sent.")
1391
1392 (defvar gnus-newsgroup-bookmarks nil
1393   "List of articles in the current newsgroup that have bookmarks.")
1394
1395 (defvar gnus-newsgroup-dormant nil
1396   "Sorted list of dormant articles in the current newsgroup.")
1397
1398 (defvar gnus-newsgroup-unseen nil
1399   "List of unseen articles in the current newsgroup.")
1400
1401 (defvar gnus-newsgroup-seen nil
1402   "Range of seen articles in the current newsgroup.")
1403
1404 (defvar gnus-newsgroup-articles nil
1405   "List of articles in the current newsgroup.")
1406
1407 (defvar gnus-newsgroup-scored nil
1408   "List of scored articles in the current newsgroup.")
1409
1410 (defvar gnus-newsgroup-headers nil
1411   "List of article headers in the current newsgroup.")
1412
1413 (defvar gnus-newsgroup-threads nil)
1414
1415 (defvar gnus-newsgroup-prepared nil
1416   "Whether the current group has been prepared properly.")
1417
1418 (defvar gnus-newsgroup-ancient nil
1419   "List of `gnus-fetch-old-headers' articles in the current newsgroup.")
1420
1421 (defvar gnus-newsgroup-sparse nil)
1422
1423 (defvar gnus-current-article nil)
1424 (defvar gnus-article-current nil)
1425 (defvar gnus-current-headers nil)
1426 (defvar gnus-have-all-headers nil)
1427 (defvar gnus-last-article nil)
1428 (defvar gnus-newsgroup-history nil)
1429 (defvar gnus-newsgroup-charset nil)
1430 (defvar gnus-newsgroup-ephemeral-charset nil)
1431 (defvar gnus-newsgroup-ephemeral-ignored-charsets nil)
1432
1433 (defvar gnus-article-before-search nil)
1434
1435 (defvar gnus-summary-local-variables
1436   '(gnus-newsgroup-name
1437     gnus-newsgroup-begin gnus-newsgroup-end
1438     gnus-newsgroup-last-rmail gnus-newsgroup-last-mail
1439     gnus-newsgroup-last-folder gnus-newsgroup-last-file
1440     gnus-newsgroup-auto-expire gnus-newsgroup-unreads
1441     gnus-newsgroup-unselected gnus-newsgroup-marked
1442     gnus-newsgroup-spam-marked
1443     gnus-newsgroup-reads gnus-newsgroup-saved
1444     gnus-newsgroup-replied gnus-newsgroup-forwarded
1445     gnus-newsgroup-recent
1446     gnus-newsgroup-expirable
1447     gnus-newsgroup-processable gnus-newsgroup-killed
1448     gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
1449     gnus-newsgroup-unfetched
1450     gnus-newsgroup-unsendable gnus-newsgroup-unseen
1451     gnus-newsgroup-seen gnus-newsgroup-articles
1452     gnus-newsgroup-bookmarks gnus-newsgroup-dormant
1453     gnus-newsgroup-headers gnus-newsgroup-threads
1454     gnus-newsgroup-prepared gnus-summary-highlight-line-function
1455     gnus-current-article gnus-current-headers gnus-have-all-headers
1456     gnus-last-article gnus-article-internal-prepare-hook
1457     gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay
1458     gnus-newsgroup-scored gnus-newsgroup-kill-headers
1459     gnus-thread-expunge-below
1460     gnus-score-alist gnus-current-score-file
1461     (gnus-summary-expunge-below . global)
1462     (gnus-summary-mark-below . global)
1463     (gnus-orphan-score . global)
1464     gnus-newsgroup-active gnus-scores-exclude-files
1465     gnus-newsgroup-history gnus-newsgroup-ancient
1466     gnus-newsgroup-sparse gnus-newsgroup-process-stack
1467     (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
1468     gnus-newsgroup-adaptive-score-file (gnus-reffed-article-number . -1)
1469     (gnus-newsgroup-expunged-tally . 0)
1470     gnus-cache-removable-articles gnus-newsgroup-cached
1471     gnus-newsgroup-data gnus-newsgroup-data-reverse
1472     gnus-newsgroup-limit gnus-newsgroup-limits
1473     gnus-newsgroup-charset gnus-newsgroup-display
1474     gnus-summary-use-undownloaded-faces)
1475   "Variables that are buffer-local to the summary buffers.")
1476
1477 (defvar gnus-newsgroup-variables nil
1478   "A list of variables that have separate values in different newsgroups.
1479 A list of newsgroup (summary buffer) local variables, or cons of
1480 variables and their default expressions to be evalled (when the default
1481 values are not nil), that should be made global while the summary buffer
1482 is active.
1483
1484 Note: The default expressions will be evaluated (using function `eval')
1485 before assignment to the local variable rather than just assigned to it.
1486 If the default expression is the symbol `global', that symbol will not
1487 be evaluated but the global value of the local variable will be used
1488 instead.
1489
1490 These variables can be used to set variables in the group parameters
1491 while still allowing them to affect operations done in other buffers.
1492 For example:
1493
1494 \(setq gnus-newsgroup-variables
1495      '(message-use-followup-to
1496        (gnus-visible-headers .
1497          \"^From:\\\\|^Newsgroups:\\\\|^Subject:\\\\|^Date:\\\\|^To:\")))
1498 ")
1499
1500 ;; Byte-compiler warning.
1501 (eval-when-compile
1502   ;; Bind features so that require will believe that gnus-sum has
1503   ;; already been loaded (avoids infinite recursion)
1504   (let ((features (cons 'gnus-sum features)))
1505     ;; Several of the declarations in gnus-sum are needed to load the
1506     ;; following files. Right now, these definitions have been
1507     ;; compiled but not defined (evaluated).  We could either do a
1508     ;; eval-and-compile about all of the declarations or evaluate the
1509     ;; source file.
1510     (if (boundp 'gnus-newsgroup-variables)
1511         nil
1512       (load "gnus-sum.el" t t t))
1513     (require 'gnus)
1514     (require 'gnus-art)))
1515
1516 ;; MIME stuff.
1517
1518 (defvar gnus-decode-encoded-word-methods
1519   '(mail-decode-encoded-word-string)
1520   "List of methods used to decode encoded words.
1521
1522 This variable is a list of FUNCTION or (REGEXP . FUNCTION).  If item
1523 is FUNCTION, FUNCTION will be apply to all newsgroups.  If item is a
1524 \(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups
1525 whose names match REGEXP.
1526
1527 For example:
1528 \((\"chinese\" . gnus-decode-encoded-word-string-by-guess)
1529  mail-decode-encoded-word-string
1530  (\"chinese\" . rfc1843-decode-string))")
1531
1532 (defvar gnus-decode-encoded-word-methods-cache nil)
1533
1534 (defun gnus-multi-decode-encoded-word-string (string)
1535   "Apply the functions from `gnus-encoded-word-methods' that match."
1536   (unless (and gnus-decode-encoded-word-methods-cache
1537                (eq gnus-newsgroup-name
1538                    (car gnus-decode-encoded-word-methods-cache)))
1539     (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
1540     (mapcar (lambda (x)
1541               (if (symbolp x)
1542                   (nconc gnus-decode-encoded-word-methods-cache (list x))
1543                 (if (and gnus-newsgroup-name
1544                          (string-match (car x) gnus-newsgroup-name))
1545                     (nconc gnus-decode-encoded-word-methods-cache
1546                            (list (cdr x))))))
1547             gnus-decode-encoded-word-methods))
1548   (let ((xlist gnus-decode-encoded-word-methods-cache))
1549     (pop xlist)
1550     (while xlist
1551       (setq string (funcall (pop xlist) string))))
1552   string)
1553
1554 ;; Subject simplification.
1555
1556 (defun gnus-simplify-whitespace (str)
1557   "Remove excessive whitespace from STR."
1558   ;; Multiple spaces.
1559   (while (string-match "[ \t][ \t]+" str)
1560     (setq str (concat (substring str 0 (match-beginning 0))
1561                         " "
1562                         (substring str (match-end 0)))))
1563   ;; Leading spaces.
1564   (when (string-match "^[ \t]+" str)
1565     (setq str (substring str (match-end 0))))
1566   ;; Trailing spaces.
1567   (when (string-match "[ \t]+$" str)
1568     (setq str (substring str 0 (match-beginning 0))))
1569   str)
1570
1571 (defun gnus-simplify-all-whitespace (str)
1572   "Remove all whitespace from STR."
1573   (while (string-match "[ \t\n]+" str)
1574     (setq str (replace-match "" nil nil str)))
1575   str)
1576
1577 (defsubst gnus-simplify-subject-re (subject)
1578   "Remove \"Re:\" from subject lines."
1579   (if (string-match message-subject-re-regexp subject)
1580       (substring subject (match-end 0))
1581     subject))
1582
1583 (defun gnus-simplify-subject (subject &optional re-only)
1584   "Remove `Re:' and words in parentheses.
1585 If RE-ONLY is non-nil, strip leading `Re:'s only."
1586   (let ((case-fold-search t))           ;Ignore case.
1587     ;; Remove `Re:', `Re^N:', `Re(n)', and `Re[n]:'.
1588     (when (string-match "\\`\\(re\\([[(^][0-9]+[])]?\\)?:[ \t]*\\)+" subject)
1589       (setq subject (substring subject (match-end 0))))
1590     ;; Remove uninteresting prefixes.
1591     (when (and (not re-only)
1592                gnus-simplify-ignored-prefixes
1593                (string-match gnus-simplify-ignored-prefixes subject))
1594       (setq subject (substring subject (match-end 0))))
1595     ;; Remove words in parentheses from end.
1596     (unless re-only
1597       (while (string-match "[ \t\n]*([^()]*)[ \t\n]*\\'" subject)
1598         (setq subject (substring subject 0 (match-beginning 0)))))
1599     ;; Return subject string.
1600     subject))
1601
1602 ;; Remove any leading "re:"s, any trailing paren phrases, and simplify
1603 ;; all whitespace.
1604 (defsubst gnus-simplify-buffer-fuzzy-step (regexp &optional newtext)
1605   (goto-char (point-min))
1606   (while (re-search-forward regexp nil t)
1607     (replace-match (or newtext ""))))
1608
1609 (defun gnus-simplify-buffer-fuzzy ()
1610   "Simplify string in the buffer fuzzily.
1611 The string in the accessible portion of the current buffer is simplified.
1612 It is assumed to be a single-line subject.
1613 Whitespace is generally cleaned up, and miscellaneous leading/trailing
1614 matter is removed.  Additional things can be deleted by setting
1615 `gnus-simplify-subject-fuzzy-regexp'."
1616   (let ((case-fold-search t)
1617         (modified-tick))
1618     (gnus-simplify-buffer-fuzzy-step "\t" " ")
1619
1620     (while (not (eq modified-tick (buffer-modified-tick)))
1621       (setq modified-tick (buffer-modified-tick))
1622       (cond
1623        ((listp gnus-simplify-subject-fuzzy-regexp)
1624         (mapcar 'gnus-simplify-buffer-fuzzy-step
1625                 gnus-simplify-subject-fuzzy-regexp))
1626        (gnus-simplify-subject-fuzzy-regexp
1627         (gnus-simplify-buffer-fuzzy-step gnus-simplify-subject-fuzzy-regexp)))
1628       (gnus-simplify-buffer-fuzzy-step "^ *\\[[-+?*!][-+?*!]\\] *")
1629       (gnus-simplify-buffer-fuzzy-step
1630        "^ *\\(re\\|fw\\|fwd\\)[[{(^0-9]*[])}]?[:;] *")
1631       (gnus-simplify-buffer-fuzzy-step "^[[].*:\\( .*\\)[]]$" "\\1"))
1632
1633     (gnus-simplify-buffer-fuzzy-step " *[[{(][^()\n]*[]})] *$")
1634     (gnus-simplify-buffer-fuzzy-step "  +" " ")
1635     (gnus-simplify-buffer-fuzzy-step " $")
1636     (gnus-simplify-buffer-fuzzy-step "^ +")))
1637
1638 (defun gnus-simplify-subject-fuzzy (subject)
1639   "Simplify a subject string fuzzily.
1640 See `gnus-simplify-buffer-fuzzy' for details."
1641   (save-excursion
1642     (gnus-set-work-buffer)
1643     (let ((case-fold-search t))
1644       ;; Remove uninteresting prefixes.
1645       (when (and gnus-simplify-ignored-prefixes
1646                  (string-match gnus-simplify-ignored-prefixes subject))
1647         (setq subject (substring subject (match-end 0))))
1648       (insert subject)
1649       (inline (gnus-simplify-buffer-fuzzy))
1650       (buffer-string))))
1651
1652 (defsubst gnus-simplify-subject-fully (subject)
1653   "Simplify a subject string according to `gnus-summary-gather-subject-limit'."
1654   (cond
1655    (gnus-simplify-subject-functions
1656     (gnus-map-function gnus-simplify-subject-functions subject))
1657    ((null gnus-summary-gather-subject-limit)
1658     (gnus-simplify-subject-re subject))
1659    ((eq gnus-summary-gather-subject-limit 'fuzzy)
1660     (gnus-simplify-subject-fuzzy subject))
1661    ((numberp gnus-summary-gather-subject-limit)
1662     (gnus-limit-string (gnus-simplify-subject-re subject)
1663                        gnus-summary-gather-subject-limit))
1664    (t
1665     subject)))
1666
1667 (defsubst gnus-subject-equal (s1 s2 &optional simple-first)
1668   "Check whether two subjects are equal.
1669 If optional argument SIMPLE-FIRST is t, first argument is already
1670 simplified."
1671   (cond
1672    ((null simple-first)
1673     (equal (gnus-simplify-subject-fully s1)
1674            (gnus-simplify-subject-fully s2)))
1675    (t
1676     (equal s1
1677            (gnus-simplify-subject-fully s2)))))
1678
1679 (defun gnus-summary-bubble-group ()
1680   "Increase the score of the current group.
1681 This is a handy function to add to `gnus-summary-exit-hook' to
1682 increase the score of each group you read."
1683   (gnus-group-add-score gnus-newsgroup-name))
1684
1685 \f
1686 ;;;
1687 ;;; Gnus summary mode
1688 ;;;
1689
1690 (put 'gnus-summary-mode 'mode-class 'special)
1691
1692 (defvar gnus-article-commands-menu)
1693
1694 ;; Non-orthogonal keys
1695
1696 (gnus-define-keys gnus-summary-mode-map
1697   " " gnus-summary-next-page
1698   "\177" gnus-summary-prev-page
1699   [delete] gnus-summary-prev-page
1700   [backspace] gnus-summary-prev-page
1701   "\r" gnus-summary-scroll-up
1702   "\M-\r" gnus-summary-scroll-down
1703   "n" gnus-summary-next-unread-article
1704   "p" gnus-summary-prev-unread-article
1705   "N" gnus-summary-next-article
1706   "P" gnus-summary-prev-article
1707   "\M-\C-n" gnus-summary-next-same-subject
1708   "\M-\C-p" gnus-summary-prev-same-subject
1709   "\M-n" gnus-summary-next-unread-subject
1710   "\M-p" gnus-summary-prev-unread-subject
1711   "." gnus-summary-first-unread-article
1712   "," gnus-summary-best-unread-article
1713   "\M-s" gnus-summary-search-article-forward
1714   "\M-r" gnus-summary-search-article-backward
1715   "<" gnus-summary-beginning-of-article
1716   ">" gnus-summary-end-of-article
1717   "j" gnus-summary-goto-article
1718   "^" gnus-summary-refer-parent-article
1719   "\M-^" gnus-summary-refer-article
1720   "u" gnus-summary-tick-article-forward
1721   "!" gnus-summary-tick-article-forward
1722   "U" gnus-summary-tick-article-backward
1723   "d" gnus-summary-mark-as-read-forward
1724   "D" gnus-summary-mark-as-read-backward
1725   "E" gnus-summary-mark-as-expirable
1726   "\M-u" gnus-summary-clear-mark-forward
1727   "\M-U" gnus-summary-clear-mark-backward
1728   "k" gnus-summary-kill-same-subject-and-select
1729   "\C-k" gnus-summary-kill-same-subject
1730   "\M-\C-k" gnus-summary-kill-thread
1731   "\M-\C-l" gnus-summary-lower-thread
1732   "e" gnus-summary-edit-article
1733   "#" gnus-summary-mark-as-processable
1734   "\M-#" gnus-summary-unmark-as-processable
1735   "\M-\C-t" gnus-summary-toggle-threads
1736   "\M-\C-s" gnus-summary-show-thread
1737   "\M-\C-h" gnus-summary-hide-thread
1738   "\M-\C-f" gnus-summary-next-thread
1739   "\M-\C-b" gnus-summary-prev-thread
1740   [(meta down)] gnus-summary-next-thread
1741   [(meta up)] gnus-summary-prev-thread
1742   "\M-\C-u" gnus-summary-up-thread
1743   "\M-\C-d" gnus-summary-down-thread
1744   "&" gnus-summary-execute-command
1745   "c" gnus-summary-catchup-and-exit
1746   "\C-w" gnus-summary-mark-region-as-read
1747   "\C-t" gnus-summary-toggle-truncation
1748   "?" gnus-summary-mark-as-dormant
1749   "\C-c\M-\C-s" gnus-summary-limit-include-expunged
1750   "\C-c\C-s\C-n" gnus-summary-sort-by-number
1751   "\C-c\C-s\C-l" gnus-summary-sort-by-lines
1752   "\C-c\C-s\C-c" gnus-summary-sort-by-chars
1753   "\C-c\C-s\C-a" gnus-summary-sort-by-author
1754   "\C-c\C-s\C-t" gnus-summary-sort-by-recipient
1755   "\C-c\C-s\C-s" gnus-summary-sort-by-subject
1756   "\C-c\C-s\C-d" gnus-summary-sort-by-date
1757   "\C-c\C-s\C-i" gnus-summary-sort-by-score
1758   "\C-c\C-s\C-o" gnus-summary-sort-by-original
1759   "\C-c\C-s\C-r" gnus-summary-sort-by-random
1760   "=" gnus-summary-expand-window
1761   "\C-x\C-s" gnus-summary-reselect-current-group
1762   "\M-g" gnus-summary-rescan-group
1763   "w" gnus-summary-stop-page-breaking
1764   "\C-c\C-r" gnus-summary-caesar-message
1765   "f" gnus-summary-followup
1766   "F" gnus-summary-followup-with-original
1767   "C" gnus-summary-cancel-article
1768   "r" gnus-summary-reply
1769   "R" gnus-summary-reply-with-original
1770   "\C-c\C-f" gnus-summary-mail-forward
1771   "o" gnus-summary-save-article
1772   "\C-o" gnus-summary-save-article-mail
1773   "|" gnus-summary-pipe-output
1774   "\M-k" gnus-summary-edit-local-kill
1775   "\M-K" gnus-summary-edit-global-kill
1776   ;; "V" gnus-version
1777   "\C-c\C-d" gnus-summary-describe-group
1778   "q" gnus-summary-exit
1779   "Q" gnus-summary-exit-no-update
1780   "\C-c\C-i" gnus-info-find-node
1781   gnus-mouse-2 gnus-mouse-pick-article
1782   [follow-link] mouse-face
1783   "m" gnus-summary-mail-other-window
1784   "a" gnus-summary-post-news
1785   "i" gnus-summary-news-other-window
1786   "x" gnus-summary-limit-to-unread
1787   "s" gnus-summary-isearch-article
1788   "t" gnus-summary-toggle-header
1789   "g" gnus-summary-show-article
1790   "l" gnus-summary-goto-last-article
1791   "\C-c\C-v\C-v" gnus-uu-decode-uu-view
1792   "\C-d" gnus-summary-enter-digest-group
1793   "\M-\C-d" gnus-summary-read-document
1794   "\M-\C-e" gnus-summary-edit-parameters
1795   "\M-\C-a" gnus-summary-customize-parameters
1796   "\C-c\C-b" gnus-bug
1797   "*" gnus-cache-enter-article
1798   "\M-*" gnus-cache-remove-article
1799   "\M-&" gnus-summary-universal-argument
1800   "\C-l" gnus-recenter
1801   "I" gnus-summary-increase-score
1802   "L" gnus-summary-lower-score
1803   "\M-i" gnus-symbolic-argument
1804   "h" gnus-summary-select-article-buffer
1805
1806   "b" gnus-article-view-part
1807   "\M-t" gnus-summary-toggle-display-buttonized
1808
1809   "V" gnus-summary-score-map
1810   "X" gnus-uu-extract-map
1811   "S" gnus-summary-send-map)
1812
1813 ;; Sort of orthogonal keymap
1814 (gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
1815   "t" gnus-summary-tick-article-forward
1816   "!" gnus-summary-tick-article-forward
1817   "d" gnus-summary-mark-as-read-forward
1818   "r" gnus-summary-mark-as-read-forward
1819   "c" gnus-summary-clear-mark-forward
1820   " " gnus-summary-clear-mark-forward
1821   "e" gnus-summary-mark-as-expirable
1822   "x" gnus-summary-mark-as-expirable
1823   "?" gnus-summary-mark-as-dormant
1824   "b" gnus-summary-set-bookmark
1825   "B" gnus-summary-remove-bookmark
1826   "#" gnus-summary-mark-as-processable
1827   "\M-#" gnus-summary-unmark-as-processable
1828   "S" gnus-summary-limit-include-expunged
1829   "C" gnus-summary-catchup
1830   "H" gnus-summary-catchup-to-here
1831   "h" gnus-summary-catchup-from-here
1832   "\C-c" gnus-summary-catchup-all
1833   "k" gnus-summary-kill-same-subject-and-select
1834   "K" gnus-summary-kill-same-subject
1835   "P" gnus-uu-mark-map)
1836
1837 (gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
1838   "c" gnus-summary-clear-above
1839   "u" gnus-summary-tick-above
1840   "m" gnus-summary-mark-above
1841   "k" gnus-summary-kill-below)
1842
1843 (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
1844   "/" gnus-summary-limit-to-subject
1845   "n" gnus-summary-limit-to-articles
1846   "w" gnus-summary-pop-limit
1847   "s" gnus-summary-limit-to-subject
1848   "a" gnus-summary-limit-to-author
1849   "u" gnus-summary-limit-to-unread
1850   "m" gnus-summary-limit-to-marks
1851   "M" gnus-summary-limit-exclude-marks
1852   "v" gnus-summary-limit-to-score
1853   "*" gnus-summary-limit-include-cached
1854   "D" gnus-summary-limit-include-dormant
1855   "T" gnus-summary-limit-include-thread
1856   "d" gnus-summary-limit-exclude-dormant
1857   "t" gnus-summary-limit-to-age
1858   "." gnus-summary-limit-to-unseen
1859   "x" gnus-summary-limit-to-extra
1860   "p" gnus-summary-limit-to-display-predicate
1861   "E" gnus-summary-limit-include-expunged
1862   "c" gnus-summary-limit-exclude-childless-dormant
1863   "C" gnus-summary-limit-mark-excluded-as-read
1864   "o" gnus-summary-insert-old-articles
1865   "N" gnus-summary-insert-new-articles
1866   "r" gnus-summary-limit-to-replied
1867   "R" gnus-summary-limit-to-recipient)
1868
1869 (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
1870   "n" gnus-summary-next-unread-article
1871   "p" gnus-summary-prev-unread-article
1872   "N" gnus-summary-next-article
1873   "P" gnus-summary-prev-article
1874   "\C-n" gnus-summary-next-same-subject
1875   "\C-p" gnus-summary-prev-same-subject
1876   "\M-n" gnus-summary-next-unread-subject
1877   "\M-p" gnus-summary-prev-unread-subject
1878   "f" gnus-summary-first-unread-article
1879   "b" gnus-summary-best-unread-article
1880   "j" gnus-summary-goto-article
1881   "g" gnus-summary-goto-subject
1882   "l" gnus-summary-goto-last-article
1883   "o" gnus-summary-pop-article)
1884
1885 (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
1886   "k" gnus-summary-kill-thread
1887   "l" gnus-summary-lower-thread
1888   "i" gnus-summary-raise-thread
1889   "T" gnus-summary-toggle-threads
1890   "t" gnus-summary-rethread-current
1891   "^" gnus-summary-reparent-thread
1892   "s" gnus-summary-show-thread
1893   "S" gnus-summary-show-all-threads
1894   "h" gnus-summary-hide-thread
1895   "H" gnus-summary-hide-all-threads
1896   "n" gnus-summary-next-thread
1897   "p" gnus-summary-prev-thread
1898   "u" gnus-summary-up-thread
1899   "o" gnus-summary-top-thread
1900   "d" gnus-summary-down-thread
1901   "#" gnus-uu-mark-thread
1902   "\M-#" gnus-uu-unmark-thread)
1903
1904 (gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
1905   "g" gnus-summary-prepare
1906   "c" gnus-summary-insert-cached-articles
1907   "d" gnus-summary-insert-dormant-articles)
1908
1909 (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
1910   "c" gnus-summary-catchup-and-exit
1911   "C" gnus-summary-catchup-all-and-exit
1912   "E" gnus-summary-exit-no-update
1913   "Q" gnus-summary-exit
1914   "Z" gnus-summary-exit
1915   "n" gnus-summary-catchup-and-goto-next-group
1916   "p" gnus-summary-catchup-and-goto-prev-group
1917   "R" gnus-summary-reselect-current-group
1918   "G" gnus-summary-rescan-group
1919   "N" gnus-summary-next-group
1920   "s" gnus-summary-save-newsrc
1921   "P" gnus-summary-prev-group)
1922
1923 (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
1924   " " gnus-summary-next-page
1925   "n" gnus-summary-next-page
1926   "\177" gnus-summary-prev-page
1927   [delete] gnus-summary-prev-page
1928   "p" gnus-summary-prev-page
1929   "\r" gnus-summary-scroll-up
1930   "\M-\r" gnus-summary-scroll-down
1931   "<" gnus-summary-beginning-of-article
1932   ">" gnus-summary-end-of-article
1933   "b" gnus-summary-beginning-of-article
1934   "e" gnus-summary-end-of-article
1935   "^" gnus-summary-refer-parent-article
1936   "r" gnus-summary-refer-parent-article
1937   "D" gnus-summary-enter-digest-group
1938   "R" gnus-summary-refer-references
1939   "T" gnus-summary-refer-thread
1940   "g" gnus-summary-show-article
1941   "s" gnus-summary-isearch-article
1942   "P" gnus-summary-print-article
1943   "M" gnus-mailing-list-insinuate
1944   "t" gnus-article-babel)
1945
1946 (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
1947   "b" gnus-article-add-buttons
1948   "B" gnus-article-add-buttons-to-head
1949   "o" gnus-article-treat-overstrike
1950   "e" gnus-article-emphasize
1951   "w" gnus-article-fill-cited-article
1952   "Q" gnus-article-fill-long-lines
1953   "C" gnus-article-capitalize-sentences
1954   "c" gnus-article-remove-cr
1955   "q" gnus-article-de-quoted-unreadable
1956   "6" gnus-article-de-base64-unreadable
1957   "Z" gnus-article-decode-HZ
1958   "A" gnus-article-treat-ansi-sequences
1959   "h" gnus-article-wash-html
1960   "u" gnus-article-unsplit-urls
1961   "s" gnus-summary-force-verify-and-decrypt
1962   "f" gnus-article-display-x-face
1963   "l" gnus-summary-stop-page-breaking
1964   "r" gnus-summary-caesar-message
1965   "m" gnus-summary-morse-message
1966   "t" gnus-summary-toggle-header
1967   "g" gnus-treat-smiley
1968   "v" gnus-summary-verbose-headers
1969   "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
1970   "p" gnus-article-verify-x-pgp-sig
1971   "d" gnus-article-treat-dumbquotes
1972   "i" gnus-summary-idna-message)
1973
1974 (gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
1975   ;; mnemonic: deuglif*Y*
1976   "u" gnus-article-outlook-unwrap-lines
1977   "a" gnus-article-outlook-repair-attribution
1978   "c" gnus-article-outlook-rearrange-citation
1979   "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
1980
1981 (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
1982   "a" gnus-article-hide
1983   "h" gnus-article-hide-headers
1984   "b" gnus-article-hide-boring-headers
1985   "s" gnus-article-hide-signature
1986   "c" gnus-article-hide-citation
1987   "C" gnus-article-hide-citation-in-followups
1988   "l" gnus-article-hide-list-identifiers
1989   "B" gnus-article-strip-banner
1990   "P" gnus-article-hide-pem
1991   "\C-c" gnus-article-hide-citation-maybe)
1992
1993 (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
1994   "a" gnus-article-highlight
1995   "h" gnus-article-highlight-headers
1996   "c" gnus-article-highlight-citation
1997   "s" gnus-article-highlight-signature)
1998
1999 (gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
2000   "f" gnus-article-treat-fold-headers
2001   "u" gnus-article-treat-unfold-headers
2002   "n" gnus-article-treat-fold-newsgroups)
2003
2004 (gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
2005   "x" gnus-article-display-x-face
2006   "d" gnus-article-display-face
2007   "s" gnus-treat-smiley
2008   "D" gnus-article-remove-images
2009   "f" gnus-treat-from-picon
2010   "m" gnus-treat-mail-picon
2011   "n" gnus-treat-newsgroups-picon)
2012
2013 (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
2014   "w" gnus-article-decode-mime-words
2015   "c" gnus-article-decode-charset
2016   "v" gnus-mime-view-all-parts
2017   "b" gnus-article-view-part)
2018
2019 (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
2020   "z" gnus-article-date-ut
2021   "u" gnus-article-date-ut
2022   "l" gnus-article-date-local
2023   "p" gnus-article-date-english
2024   "e" gnus-article-date-lapsed
2025   "o" gnus-article-date-original
2026   "i" gnus-article-date-iso8601
2027   "s" gnus-article-date-user)
2028
2029 (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
2030   "t" gnus-article-remove-trailing-blank-lines
2031   "l" gnus-article-strip-leading-blank-lines
2032   "m" gnus-article-strip-multiple-blank-lines
2033   "a" gnus-article-strip-blank-lines
2034   "A" gnus-article-strip-all-blank-lines
2035   "s" gnus-article-strip-leading-space
2036   "e" gnus-article-strip-trailing-space
2037   "w" gnus-article-remove-leading-whitespace)
2038
2039 (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
2040   "v" gnus-version
2041   "f" gnus-summary-fetch-faq
2042   "d" gnus-summary-describe-group
2043   "h" gnus-summary-describe-briefly
2044   "i" gnus-info-find-node
2045   "c" gnus-group-fetch-charter
2046   "C" gnus-group-fetch-control)
2047
2048 (gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
2049   "e" gnus-summary-expire-articles
2050   "\M-\C-e" gnus-summary-expire-articles-now
2051   "\177" gnus-summary-delete-article
2052   [delete] gnus-summary-delete-article
2053   [backspace] gnus-summary-delete-article
2054   "m" gnus-summary-move-article
2055   "r" gnus-summary-respool-article
2056   "w" gnus-summary-edit-article
2057   "c" gnus-summary-copy-article
2058   "B" gnus-summary-crosspost-article
2059   "q" gnus-summary-respool-query
2060   "t" gnus-summary-respool-trace
2061   "i" gnus-summary-import-article
2062   "I" gnus-summary-create-article
2063   "p" gnus-summary-article-posted-p)
2064
2065 (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
2066   "o" gnus-summary-save-article
2067   "m" gnus-summary-save-article-mail
2068   "F" gnus-summary-write-article-file
2069   "r" gnus-summary-save-article-rmail
2070   "f" gnus-summary-save-article-file
2071   "b" gnus-summary-save-article-body-file
2072   "h" gnus-summary-save-article-folder
2073   "v" gnus-summary-save-article-vm
2074   "p" gnus-summary-pipe-output
2075   "P" gnus-summary-muttprint
2076   "s" gnus-soup-add-article)
2077
2078 (gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
2079   "b" gnus-summary-display-buttonized
2080   "m" gnus-summary-repair-multipart
2081   "v" gnus-article-view-part
2082   "o" gnus-article-save-part
2083   "O" gnus-article-save-part-and-strip
2084   "r" gnus-article-replace-part
2085   "d" gnus-article-delete-part
2086   "j" gnus-article-jump-to-part
2087   "c" gnus-article-copy-part
2088   "C" gnus-article-view-part-as-charset
2089   "e" gnus-article-view-part-externally
2090   "E" gnus-article-encrypt-body
2091   "i" gnus-article-inline-part
2092   "|" gnus-article-pipe-part)
2093
2094 (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
2095   "p" gnus-summary-mark-as-processable
2096   "u" gnus-summary-unmark-as-processable
2097   "U" gnus-summary-unmark-all-processable
2098   "v" gnus-uu-mark-over
2099   "s" gnus-uu-mark-series
2100   "r" gnus-uu-mark-region
2101   "g" gnus-uu-unmark-region
2102   "R" gnus-uu-mark-by-regexp
2103   "G" gnus-uu-unmark-by-regexp
2104   "t" gnus-uu-mark-thread
2105   "T" gnus-uu-unmark-thread
2106   "a" gnus-uu-mark-all
2107   "b" gnus-uu-mark-buffer
2108   "S" gnus-uu-mark-sparse
2109   "k" gnus-summary-kill-process-mark
2110   "y" gnus-summary-yank-process-mark
2111   "w" gnus-summary-save-process-mark
2112   "i" gnus-uu-invert-processable)
2113
2114 (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
2115   ;;"x" gnus-uu-extract-any
2116   "m" gnus-summary-save-parts
2117   "u" gnus-uu-decode-uu
2118   "U" gnus-uu-decode-uu-and-save
2119   "s" gnus-uu-decode-unshar
2120   "S" gnus-uu-decode-unshar-and-save
2121   "o" gnus-uu-decode-save
2122   "O" gnus-uu-decode-save
2123   "b" gnus-uu-decode-binhex
2124   "B" gnus-uu-decode-binhex
2125   "p" gnus-uu-decode-postscript
2126   "P" gnus-uu-decode-postscript-and-save)
2127
2128 (gnus-define-keys
2129     (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
2130   "u" gnus-uu-decode-uu-view
2131   "U" gnus-uu-decode-uu-and-save-view
2132   "s" gnus-uu-decode-unshar-view
2133   "S" gnus-uu-decode-unshar-and-save-view
2134   "o" gnus-uu-decode-save-view
2135   "O" gnus-uu-decode-save-view
2136   "b" gnus-uu-decode-binhex-view
2137   "B" gnus-uu-decode-binhex-view
2138   "p" gnus-uu-decode-postscript-view
2139   "P" gnus-uu-decode-postscript-and-save-view)
2140
2141 (defvar gnus-article-post-menu nil)
2142
2143 (defconst gnus-summary-menu-maxlen 20)
2144
2145 (defun gnus-summary-menu-split (menu)
2146   ;; If we have lots of elements, divide them into groups of 20
2147   ;; and make a pane (or submenu) for each one.
2148   (if (> (length menu) (/ (* gnus-summary-menu-maxlen 3) 2))
2149       (let ((menu menu) sublists next
2150             (i 1))
2151         (while menu
2152           ;; Pull off the next gnus-summary-menu-maxlen elements
2153           ;; and make them the next element of sublist.
2154           (setq next (nthcdr gnus-summary-menu-maxlen menu))
2155           (if next
2156               (setcdr (nthcdr (1- gnus-summary-menu-maxlen) menu)
2157                       nil))
2158           (setq sublists (cons (cons (format "%s ... %s" (aref (car menu) 0)
2159                                              (aref (car (last menu)) 0)) menu)
2160                                sublists))
2161           (setq i (1+ i))
2162           (setq menu next))
2163         (nreverse sublists))
2164     ;; Few elements--put them all in one pane.
2165     menu))
2166
2167 (defun gnus-summary-make-menu-bar ()
2168   (gnus-turn-off-edit-menu 'summary)
2169
2170   (unless (boundp 'gnus-summary-misc-menu)
2171
2172     (easy-menu-define
2173       gnus-summary-kill-menu gnus-summary-mode-map ""
2174       (cons
2175        "Score"
2176        (nconc
2177         (list
2178          ["Customize" gnus-score-customize t])
2179         (gnus-make-score-map 'increase)
2180         (gnus-make-score-map 'lower)
2181         '(("Mark"
2182            ["Kill below" gnus-summary-kill-below t]
2183            ["Mark above" gnus-summary-mark-above t]
2184            ["Tick above" gnus-summary-tick-above t]
2185            ["Clear above" gnus-summary-clear-above t])
2186           ["Current score" gnus-summary-current-score t]
2187           ["Set score" gnus-summary-set-score t]
2188           ["Switch current score file..." gnus-score-change-score-file t]
2189           ["Set mark below..." gnus-score-set-mark-below t]
2190           ["Set expunge below..." gnus-score-set-expunge-below t]
2191           ["Edit current score file" gnus-score-edit-current-scores t]
2192           ["Edit score file" gnus-score-edit-file t]
2193           ["Trace score" gnus-score-find-trace t]
2194           ["Find words" gnus-score-find-favourite-words t]
2195           ["Rescore buffer" gnus-summary-rescore t]
2196           ["Increase score..." gnus-summary-increase-score t]
2197           ["Lower score..." gnus-summary-lower-score t]))))
2198
2199     ;; Define both the Article menu in the summary buffer and the
2200     ;; equivalent Commands menu in the article buffer here for
2201     ;; consistency.
2202     (let ((innards
2203            `(("Hide"
2204               ["All" gnus-article-hide t]
2205               ["Headers" gnus-article-hide-headers t]
2206               ["Signature" gnus-article-hide-signature t]
2207               ["Citation" gnus-article-hide-citation t]
2208               ["List identifiers" gnus-article-hide-list-identifiers t]
2209               ["Banner" gnus-article-strip-banner t]
2210               ["Boring headers" gnus-article-hide-boring-headers t])
2211              ("Highlight"
2212               ["All" gnus-article-highlight t]
2213               ["Headers" gnus-article-highlight-headers t]
2214               ["Signature" gnus-article-highlight-signature t]
2215               ["Citation" gnus-article-highlight-citation t])
2216              ("MIME"
2217               ["Words" gnus-article-decode-mime-words t]
2218               ["Charset" gnus-article-decode-charset t]
2219               ["QP" gnus-article-de-quoted-unreadable t]
2220               ["Base64" gnus-article-de-base64-unreadable t]
2221               ["View MIME buttons" gnus-summary-display-buttonized t]
2222               ["View all" gnus-mime-view-all-parts t]
2223               ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
2224               ["Encrypt body" gnus-article-encrypt-body
2225                :active (not (gnus-group-read-only-p))
2226                ,@(if (featurep 'xemacs) nil
2227                    '(:help "Encrypt the message body on disk"))]
2228               ["Extract all parts..." gnus-summary-save-parts t]
2229               ("Multipart"
2230                ["Repair multipart" gnus-summary-repair-multipart t]
2231                ["Pipe part..." gnus-article-pipe-part t]
2232                ["Inline part" gnus-article-inline-part t]
2233                ["Encrypt body" gnus-article-encrypt-body
2234                 :active (not (gnus-group-read-only-p))
2235                ,@(if (featurep 'xemacs) nil
2236                    '(:help "Encrypt the message body on disk"))]
2237                ["View part externally" gnus-article-view-part-externally t]
2238                ["View part with charset..." gnus-article-view-part-as-charset t]
2239                ["Copy part" gnus-article-copy-part t]
2240                ["Save part..." gnus-article-save-part t]
2241                ["View part" gnus-article-view-part t]))
2242              ("Date"
2243               ["Local" gnus-article-date-local t]
2244               ["ISO8601" gnus-article-date-iso8601 t]
2245               ["UT" gnus-article-date-ut t]
2246               ["Original" gnus-article-date-original t]
2247               ["Lapsed" gnus-article-date-lapsed t]
2248               ["User-defined" gnus-article-date-user t])
2249              ("Display"
2250               ["Remove images" gnus-article-remove-images t]
2251               ["Toggle smiley" gnus-treat-smiley t]
2252               ["Show X-Face" gnus-article-display-x-face t]
2253               ["Show picons in From" gnus-treat-from-picon t]
2254               ["Show picons in mail headers" gnus-treat-mail-picon t]
2255               ["Show picons in news headers" gnus-treat-newsgroups-picon t]
2256               ("View as different encoding"
2257                ,@(gnus-summary-menu-split
2258                   (mapcar
2259                    (lambda (cs)
2260                      ;; Since easymenu under Emacs doesn't allow
2261                      ;; lambda forms for menu commands, we should
2262                      ;; provide intern'ed function symbols.
2263                      (let ((command (intern (format "\
2264 gnus-summary-show-article-from-menu-as-charset-%s" cs))))
2265                        (fset command
2266                              `(lambda ()
2267                                 (interactive)
2268                                 (let ((gnus-summary-show-article-charset-alist
2269                                        '((1 . ,cs))))
2270                                   (gnus-summary-show-article 1))))
2271                        `[,(symbol-name cs) ,command t]))
2272                    (sort (if (fboundp 'coding-system-list)
2273                              (coding-system-list)
2274                            (mapcar 'car mm-mime-mule-charset-alist))
2275                          'string<)))))
2276              ("Washing"
2277               ("Remove Blanks"
2278                ["Leading" gnus-article-strip-leading-blank-lines t]
2279                ["Multiple" gnus-article-strip-multiple-blank-lines t]
2280                ["Trailing" gnus-article-remove-trailing-blank-lines t]
2281                ["All of the above" gnus-article-strip-blank-lines t]
2282                ["All" gnus-article-strip-all-blank-lines t]
2283                ["Leading space" gnus-article-strip-leading-space t]
2284                ["Trailing space" gnus-article-strip-trailing-space t]
2285                ["Leading space in headers"
2286                 gnus-article-remove-leading-whitespace t])
2287               ["Overstrike" gnus-article-treat-overstrike t]
2288               ["Dumb quotes" gnus-article-treat-dumbquotes t]
2289               ["Emphasis" gnus-article-emphasize t]
2290               ["Word wrap" gnus-article-fill-cited-article t]
2291               ["Fill long lines" gnus-article-fill-long-lines t]
2292               ["Capitalize sentences" gnus-article-capitalize-sentences t]
2293               ["Remove CR" gnus-article-remove-cr t]
2294               ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
2295               ["Base64" gnus-article-de-base64-unreadable t]
2296               ["Rot 13" gnus-summary-caesar-message
2297                ,@(if (featurep 'xemacs) '(t)
2298                    '(:help "\"Caesar rotate\" article by 13"))]
2299               ["De-IDNA" gnus-summary-idna-message t]
2300               ["Morse decode" gnus-summary-morse-message t]
2301               ["Unix pipe..." gnus-summary-pipe-message t]
2302               ["Add buttons" gnus-article-add-buttons t]
2303               ["Add buttons to head" gnus-article-add-buttons-to-head t]
2304               ["Stop page breaking" gnus-summary-stop-page-breaking t]
2305               ["Verbose header" gnus-summary-verbose-headers t]
2306               ["Toggle header" gnus-summary-toggle-header t]
2307               ["Unfold headers" gnus-article-treat-unfold-headers t]
2308               ["Fold newsgroups" gnus-article-treat-fold-newsgroups t]
2309               ["Html" gnus-article-wash-html t]
2310               ["Unsplit URLs" gnus-article-unsplit-urls t]
2311               ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
2312               ["Decode HZ" gnus-article-decode-HZ t]
2313               ["ANSI sequences" gnus-article-treat-ansi-sequences t]
2314               ("(Outlook) Deuglify"
2315                ["Unwrap lines" gnus-article-outlook-unwrap-lines t]
2316                ["Repair attribution" gnus-article-outlook-repair-attribution t]
2317                ["Rearrange citation" gnus-article-outlook-rearrange-citation t]
2318                ["Full (Outlook) deuglify"
2319                 gnus-article-outlook-deuglify-article t])
2320               )
2321              ("Output"
2322               ["Save in default format..." gnus-summary-save-article
2323                ,@(if (featurep 'xemacs) '(t)
2324                    '(:help "Save article using default method"))]
2325               ["Save in file..." gnus-summary-save-article-file
2326                ,@(if (featurep 'xemacs) '(t)
2327                    '(:help "Save article in file"))]
2328               ["Save in Unix mail format..." gnus-summary-save-article-mail t]
2329               ["Save in MH folder..." gnus-summary-save-article-folder t]
2330               ["Save in VM folder..." gnus-summary-save-article-vm t]
2331               ["Save in RMAIL mbox..." gnus-summary-save-article-rmail t]
2332               ["Save body in file..." gnus-summary-save-article-body-file t]
2333               ["Pipe through a filter..." gnus-summary-pipe-output t]
2334               ["Add to SOUP packet" gnus-soup-add-article t]
2335               ["Print with Muttprint..." gnus-summary-muttprint t]
2336               ["Print" gnus-summary-print-article
2337                ,@(if (featurep 'xemacs) '(t)
2338                    '(:help "Generate and print a PostScript image"))])
2339              ("Copy, move,... (Backend)"
2340               ,@(if (featurep 'xemacs) nil
2341                   '(:help "Copying, moving, expiring articles..."))
2342               ["Respool article..." gnus-summary-respool-article t]
2343               ["Move article..." gnus-summary-move-article
2344                (gnus-check-backend-function
2345                 'request-move-article gnus-newsgroup-name)]
2346               ["Copy article..." gnus-summary-copy-article t]
2347               ["Crosspost article..." gnus-summary-crosspost-article
2348                (gnus-check-backend-function
2349                 'request-replace-article gnus-newsgroup-name)]
2350               ["Import file..." gnus-summary-import-article
2351                (gnus-check-backend-function
2352                 'request-accept-article gnus-newsgroup-name)]
2353               ["Create article..." gnus-summary-create-article
2354                (gnus-check-backend-function
2355                 'request-accept-article gnus-newsgroup-name)]
2356               ["Check if posted" gnus-summary-article-posted-p t]
2357               ["Edit article" gnus-summary-edit-article
2358                (not (gnus-group-read-only-p))]
2359               ["Delete article" gnus-summary-delete-article
2360                (gnus-check-backend-function
2361                 'request-expire-articles gnus-newsgroup-name)]
2362               ["Query respool" gnus-summary-respool-query t]
2363               ["Trace respool" gnus-summary-respool-trace t]
2364               ["Delete expirable articles" gnus-summary-expire-articles-now
2365                (gnus-check-backend-function
2366                 'request-expire-articles gnus-newsgroup-name)])
2367              ("Extract"
2368               ["Uudecode" gnus-uu-decode-uu
2369                ,@(if (featurep 'xemacs) '(t)
2370                    '(:help "Decode uuencoded article(s)"))]
2371               ["Uudecode and save" gnus-uu-decode-uu-and-save t]
2372               ["Unshar" gnus-uu-decode-unshar t]
2373               ["Unshar and save" gnus-uu-decode-unshar-and-save t]
2374               ["Save" gnus-uu-decode-save t]
2375               ["Binhex" gnus-uu-decode-binhex t]
2376               ["Postscript" gnus-uu-decode-postscript t]
2377               ["All MIME parts" gnus-summary-save-parts t])
2378              ("Cache"
2379               ["Enter article" gnus-cache-enter-article t]
2380               ["Remove article" gnus-cache-remove-article t])
2381              ["Translate" gnus-article-babel t]
2382              ["Select article buffer" gnus-summary-select-article-buffer t]
2383              ["Enter digest buffer" gnus-summary-enter-digest-group t]
2384              ["Isearch article..." gnus-summary-isearch-article t]
2385              ["Beginning of the article" gnus-summary-beginning-of-article t]
2386              ["End of the article" gnus-summary-end-of-article t]
2387              ["Fetch parent of article" gnus-summary-refer-parent-article t]
2388              ["Fetch referenced articles" gnus-summary-refer-references t]
2389              ["Fetch current thread" gnus-summary-refer-thread t]
2390              ["Fetch article with id..." gnus-summary-refer-article t]
2391              ["Setup Mailing List Params" gnus-mailing-list-insinuate t]
2392              ["Redisplay" gnus-summary-show-article t]
2393              ["Raw article" gnus-summary-show-raw-article :keys "C-u g"])))
2394       (easy-menu-define
2395         gnus-summary-article-menu gnus-summary-mode-map ""
2396         (cons "Article" innards))
2397
2398       (if (not (keymapp gnus-summary-article-menu))
2399           (easy-menu-define
2400             gnus-article-commands-menu gnus-article-mode-map ""
2401             (cons "Commands" innards))
2402         ;; in Emacs, don't share menu.
2403         (setq gnus-article-commands-menu
2404               (copy-keymap gnus-summary-article-menu))
2405         (define-key gnus-article-mode-map [menu-bar commands]
2406           (cons "Commands" gnus-article-commands-menu))))
2407
2408     (easy-menu-define
2409       gnus-summary-thread-menu gnus-summary-mode-map ""
2410       '("Threads"
2411         ["Find all messages in thread" gnus-summary-refer-thread t]
2412         ["Toggle threading" gnus-summary-toggle-threads t]
2413         ["Hide threads" gnus-summary-hide-all-threads t]
2414         ["Show threads" gnus-summary-show-all-threads t]
2415         ["Hide thread" gnus-summary-hide-thread t]
2416         ["Show thread" gnus-summary-show-thread t]
2417         ["Go to next thread" gnus-summary-next-thread t]
2418         ["Go to previous thread" gnus-summary-prev-thread t]
2419         ["Go down thread" gnus-summary-down-thread t]
2420         ["Go up thread" gnus-summary-up-thread t]
2421         ["Top of thread" gnus-summary-top-thread t]
2422         ["Mark thread as read" gnus-summary-kill-thread t]
2423         ["Lower thread score" gnus-summary-lower-thread t]
2424         ["Raise thread score" gnus-summary-raise-thread t]
2425         ["Rethread current" gnus-summary-rethread-current t]))
2426
2427     (easy-menu-define
2428       gnus-summary-post-menu gnus-summary-mode-map ""
2429       `("Post"
2430         ["Send a message (mail or news)" gnus-summary-post-news
2431          ,@(if (featurep 'xemacs) '(t)
2432              '(:help "Compose a new message (mail or news)"))]
2433         ["Followup" gnus-summary-followup
2434          ,@(if (featurep 'xemacs) '(t)
2435              '(:help "Post followup to this article"))]
2436         ["Followup and yank" gnus-summary-followup-with-original
2437          ,@(if (featurep 'xemacs) '(t)
2438              '(:help "Post followup to this article, quoting its contents"))]
2439         ["Supersede article" gnus-summary-supersede-article t]
2440         ["Cancel article" gnus-summary-cancel-article
2441          ,@(if (featurep 'xemacs) '(t)
2442              '(:help "Cancel an article you posted"))]
2443         ["Reply" gnus-summary-reply t]
2444         ["Reply and yank" gnus-summary-reply-with-original t]
2445         ["Wide reply" gnus-summary-wide-reply t]
2446         ["Wide reply and yank" gnus-summary-wide-reply-with-original
2447          ,@(if (featurep 'xemacs) '(t)
2448              '(:help "Mail a reply, quoting this article"))]
2449         ["Very wide reply" gnus-summary-very-wide-reply t]
2450         ["Very wide reply and yank" gnus-summary-very-wide-reply-with-original
2451          ,@(if (featurep 'xemacs) '(t)
2452              '(:help "Mail a very wide reply, quoting this article"))]
2453         ["Mail forward" gnus-summary-mail-forward t]
2454         ["Post forward" gnus-summary-post-forward t]
2455         ["Digest and mail" gnus-uu-digest-mail-forward t]
2456         ["Digest and post" gnus-uu-digest-post-forward t]
2457         ["Resend message" gnus-summary-resend-message t]
2458         ["Resend message edit" gnus-summary-resend-message-edit t]
2459         ["Send bounced mail" gnus-summary-resend-bounced-mail t]
2460         ["Send a mail" gnus-summary-mail-other-window t]
2461         ["Create a local message" gnus-summary-news-other-window t]
2462         ["Uuencode and post" gnus-uu-post-news
2463          ,@(if (featurep 'xemacs) '(t)
2464              '(:help "Post a uuencoded article"))]
2465         ["Followup via news" gnus-summary-followup-to-mail t]
2466         ["Followup via news and yank"
2467          gnus-summary-followup-to-mail-with-original t]
2468         ;;("Draft"
2469         ;;["Send" gnus-summary-send-draft t]
2470         ;;["Send bounced" gnus-resend-bounced-mail t])
2471         ))
2472
2473     (cond
2474      ((not (keymapp gnus-summary-post-menu))
2475       (setq gnus-article-post-menu gnus-summary-post-menu))
2476      ((not gnus-article-post-menu)
2477       ;; Don't share post menu.
2478       (setq gnus-article-post-menu
2479             (copy-keymap gnus-summary-post-menu))))
2480     (define-key gnus-article-mode-map [menu-bar post]
2481       (cons "Post" gnus-article-post-menu))
2482
2483     (easy-menu-define
2484       gnus-summary-misc-menu gnus-summary-mode-map ""
2485       `("Gnus"
2486         ("Mark Read"
2487          ["Mark as read" gnus-summary-mark-as-read-forward t]
2488          ["Mark same subject and select"
2489           gnus-summary-kill-same-subject-and-select t]
2490          ["Mark same subject" gnus-summary-kill-same-subject t]
2491          ["Catchup" gnus-summary-catchup
2492           ,@(if (featurep 'xemacs) '(t)
2493               '(:help "Mark unread articles in this group as read"))]
2494          ["Catchup all" gnus-summary-catchup-all t]
2495          ["Catchup to here" gnus-summary-catchup-to-here t]
2496          ["Catchup from here" gnus-summary-catchup-from-here t]
2497          ["Catchup region" gnus-summary-mark-region-as-read
2498           (gnus-mark-active-p)]
2499          ["Mark excluded" gnus-summary-limit-mark-excluded-as-read t])
2500         ("Mark Various"
2501          ["Tick" gnus-summary-tick-article-forward t]
2502          ["Mark as dormant" gnus-summary-mark-as-dormant t]
2503          ["Remove marks" gnus-summary-clear-mark-forward t]
2504          ["Set expirable mark" gnus-summary-mark-as-expirable t]
2505          ["Set bookmark" gnus-summary-set-bookmark t]
2506          ["Remove bookmark" gnus-summary-remove-bookmark t])
2507         ("Limit to"
2508          ["Marks..." gnus-summary-limit-to-marks t]
2509          ["Subject..." gnus-summary-limit-to-subject t]
2510          ["Author..." gnus-summary-limit-to-author t]
2511          ["Recipient..." gnus-summary-limit-to-recipient t]
2512          ["Age..." gnus-summary-limit-to-age t]
2513          ["Extra..." gnus-summary-limit-to-extra t]
2514          ["Score..." gnus-summary-limit-to-score t]
2515          ["Display Predicate" gnus-summary-limit-to-display-predicate t]
2516          ["Unread" gnus-summary-limit-to-unread t]
2517          ["Unseen" gnus-summary-limit-to-unseen t]
2518          ["Replied" gnus-summary-limit-to-replied t]
2519          ["Non-dormant" gnus-summary-limit-exclude-dormant t]
2520          ["Next articles" gnus-summary-limit-to-articles t]
2521          ["Pop limit" gnus-summary-pop-limit t]
2522          ["Show dormant" gnus-summary-limit-include-dormant t]
2523          ["Hide childless dormant"
2524           gnus-summary-limit-exclude-childless-dormant t]
2525          ;;["Hide thread" gnus-summary-limit-exclude-thread t]
2526          ["Hide marked" gnus-summary-limit-exclude-marks t]
2527          ["Show expunged" gnus-summary-limit-include-expunged t])
2528         ("Process Mark"
2529          ["Set mark" gnus-summary-mark-as-processable t]
2530          ["Remove mark" gnus-summary-unmark-as-processable t]
2531          ["Remove all marks" gnus-summary-unmark-all-processable t]
2532          ["Invert marks" gnus-uu-invert-processable t]
2533          ["Mark above" gnus-uu-mark-over t]
2534          ["Mark series" gnus-uu-mark-series t]
2535          ["Mark region" gnus-uu-mark-region (gnus-mark-active-p)]
2536          ["Unmark region" gnus-uu-unmark-region (gnus-mark-active-p)]
2537          ["Mark by regexp..." gnus-uu-mark-by-regexp t]
2538          ["Unmark by regexp..." gnus-uu-unmark-by-regexp t]
2539          ["Mark all" gnus-uu-mark-all t]
2540          ["Mark buffer" gnus-uu-mark-buffer t]
2541          ["Mark sparse" gnus-uu-mark-sparse t]
2542          ["Mark thread" gnus-uu-mark-thread t]
2543          ["Unmark thread" gnus-uu-unmark-thread t]
2544          ("Process Mark Sets"
2545           ["Kill" gnus-summary-kill-process-mark t]
2546           ["Yank" gnus-summary-yank-process-mark
2547            gnus-newsgroup-process-stack]
2548           ["Save" gnus-summary-save-process-mark t]
2549           ["Run command on marked..." gnus-summary-universal-argument t]))
2550         ("Scroll article"
2551          ["Page forward" gnus-summary-next-page
2552           ,@(if (featurep 'xemacs) '(t)
2553               '(:help "Show next page of article"))]
2554          ["Page backward" gnus-summary-prev-page
2555           ,@(if (featurep 'xemacs) '(t)
2556               '(:help "Show previous page of article"))]
2557          ["Line forward" gnus-summary-scroll-up t])
2558         ("Move"
2559          ["Next unread article" gnus-summary-next-unread-article t]
2560          ["Previous unread article" gnus-summary-prev-unread-article t]
2561          ["Next article" gnus-summary-next-article t]
2562          ["Previous article" gnus-summary-prev-article t]
2563          ["Next unread subject" gnus-summary-next-unread-subject t]
2564          ["Previous unread subject" gnus-summary-prev-unread-subject t]
2565          ["Next article same subject" gnus-summary-next-same-subject t]
2566          ["Previous article same subject" gnus-summary-prev-same-subject t]
2567          ["First unread article" gnus-summary-first-unread-article t]
2568          ["Best unread article" gnus-summary-best-unread-article t]
2569          ["Go to subject number..." gnus-summary-goto-subject t]
2570          ["Go to article number..." gnus-summary-goto-article t]
2571          ["Go to the last article" gnus-summary-goto-last-article t]
2572          ["Pop article off history" gnus-summary-pop-article t])
2573         ("Sort"
2574          ["Sort by number" gnus-summary-sort-by-number t]
2575          ["Sort by author" gnus-summary-sort-by-author t]
2576          ["Sort by recipient" gnus-summary-sort-by-recipient t]
2577          ["Sort by subject" gnus-summary-sort-by-subject t]
2578          ["Sort by date" gnus-summary-sort-by-date t]
2579          ["Sort by score" gnus-summary-sort-by-score t]
2580          ["Sort by lines" gnus-summary-sort-by-lines t]
2581          ["Sort by characters" gnus-summary-sort-by-chars t]
2582          ["Randomize" gnus-summary-sort-by-random t]
2583          ["Original sort" gnus-summary-sort-by-original t])
2584         ("Help"
2585          ["Fetch group FAQ" gnus-summary-fetch-faq t]
2586          ["Describe group" gnus-summary-describe-group t]
2587          ["Fetch charter" gnus-group-fetch-charter
2588           ,@(if (featurep 'xemacs) nil
2589               '(:help "Display the charter of the current group"))]
2590          ["Fetch control message" gnus-group-fetch-control
2591           ,@(if (featurep 'xemacs) nil
2592               '(:help "Display the archived control message for the current group"))]
2593          ["Read manual" gnus-info-find-node t])
2594         ("Modes"
2595          ["Pick and read" gnus-pick-mode t]
2596          ["Binary" gnus-binary-mode t])
2597         ("Regeneration"
2598          ["Regenerate" gnus-summary-prepare t]
2599          ["Insert cached articles" gnus-summary-insert-cached-articles t]
2600          ["Insert dormant articles" gnus-summary-insert-dormant-articles t]
2601          ["Toggle threading" gnus-summary-toggle-threads t])
2602         ["See old articles" gnus-summary-insert-old-articles t]
2603         ["See new articles" gnus-summary-insert-new-articles t]
2604         ["Filter articles..." gnus-summary-execute-command t]
2605         ["Run command on articles..." gnus-summary-universal-argument t]
2606         ["Search articles forward..." gnus-summary-search-article-forward t]
2607         ["Search articles backward..." gnus-summary-search-article-backward t]
2608         ["Toggle line truncation" gnus-summary-toggle-truncation t]
2609         ["Expand window" gnus-summary-expand-window t]
2610         ["Expire expirable articles" gnus-summary-expire-articles
2611          (gnus-check-backend-function
2612           'request-expire-articles gnus-newsgroup-name)]
2613         ["Edit local kill file" gnus-summary-edit-local-kill t]
2614         ["Edit main kill file" gnus-summary-edit-global-kill t]
2615         ["Edit group parameters" gnus-summary-edit-parameters t]
2616         ["Customize group parameters" gnus-summary-customize-parameters t]
2617         ["Send a bug report" gnus-bug t]
2618         ("Exit"
2619          ["Catchup and exit" gnus-summary-catchup-and-exit
2620           ,@(if (featurep 'xemacs) '(t)
2621               '(:help "Mark unread articles in this group as read, then exit"))]
2622          ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
2623          ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
2624          ["Catchup and goto prev" gnus-summary-catchup-and-goto-prev-group t]
2625          ["Exit group" gnus-summary-exit
2626           ,@(if (featurep 'xemacs) '(t)
2627               '(:help "Exit current group, return to group selection mode"))]
2628          ["Exit group without updating" gnus-summary-exit-no-update t]
2629          ["Exit and goto next group" gnus-summary-next-group t]
2630          ["Exit and goto prev group" gnus-summary-prev-group t]
2631          ["Reselect group" gnus-summary-reselect-current-group t]
2632          ["Rescan group" gnus-summary-rescan-group t]
2633          ["Update dribble" gnus-summary-save-newsrc t])))
2634
2635     (gnus-run-hooks 'gnus-summary-menu-hook)))
2636
2637 (defvar gnus-summary-tool-bar-map nil)
2638
2639 ;; Note: The :set function in the `gnus-summary-tool-bar*' variables will only
2640 ;; affect _new_ message buffers.  We might add a function that walks thru all
2641 ;; summary-mode buffers and force the update.
2642 (defun gnus-summary-tool-bar-update (&optional symbol value)
2643   "Update summary mode toolbar.
2644 Setter function for custom variables."
2645   (setq-default gnus-summary-tool-bar-map nil)
2646   (when symbol
2647     ;; When used as ":set" function:
2648     (set-default symbol value))
2649   (when (gnus-buffer-live-p gnus-summary-buffer)
2650     (with-current-buffer gnus-summary-buffer
2651       (gnus-summary-make-tool-bar))))
2652
2653 (defcustom gnus-summary-tool-bar (if (eq gmm-tool-bar-style 'gnome)
2654                                      'gnus-summary-tool-bar-gnome
2655                                    'gnus-summary-tool-bar-retro)
2656   "Specifies the Gnus summary tool bar.
2657
2658 It can be either a list or a symbol refering to a list.  See
2659 `gmm-tool-bar-from-list' for the format of the list.  The
2660 default key map is `gnus-summary-mode-map'.
2661
2662 Pre-defined symbols include `gnus-summary-tool-bar-gnome' and
2663 `gnus-summary-tool-bar-retro'."
2664   :type '(choice (const :tag "GNOME style" gnus-summary-tool-bar-gnome)
2665                  (const :tag "Retro look"  gnus-summary-tool-bar-retro)
2666                  (repeat :tag "User defined list" gmm-tool-bar-item)
2667                  (symbol))
2668   :version "23.0" ;; No Gnus
2669   :initialize 'custom-initialize-default
2670   :set 'gnus-summary-tool-bar-update
2671   :group 'gnus-summary)
2672
2673 (defcustom gnus-summary-tool-bar-gnome
2674   '((gnus-summary-post-news "mail/compose" nil)
2675     (gnus-summary-insert-new-articles "mail/inbox" nil
2676                                       :visible (or (not gnus-agent)
2677                                                    gnus-plugged))
2678     (gnus-summary-reply-with-original "mail/reply")
2679     (gnus-summary-reply "mail/reply" nil :visible nil)
2680     (gnus-summary-followup-with-original "mail/reply-all")
2681     (gnus-summary-followup "mail/reply-all" nil :visible nil)
2682     (gnus-summary-mail-forward "mail/forward")
2683     (gnus-summary-save-article "mail/save")
2684     (gnus-summary-search-article-forward "search" nil :visible nil)
2685     (gnus-summary-print-article "print")
2686     (gnus-summary-tick-article-forward "flag-followup" nil :visible nil)
2687     ;; Some new commands that may need more suitable icons:
2688     (gnus-summary-save-newsrc "save" nil :visible nil)
2689     ;; (gnus-summary-show-article "stock_message-display" nil :visible nil)
2690     (gnus-summary-prev-article "left-arrow")
2691     (gnus-summary-next-article "right-arrow")
2692     (gnus-summary-next-page "next-page")
2693     ;; (gnus-summary-enter-digest-group "right_arrow" nil :visible nil)
2694     ;;
2695     ;; Maybe some sort-by-... could be added:
2696     ;; (gnus-summary-sort-by-author "sort-a-z" nil :visible nil)
2697     ;; (gnus-summary-sort-by-date "sort-1-9" nil :visible nil)
2698     (gnus-summary-mark-as-expirable
2699      "delete" nil
2700      :visible (gnus-check-backend-function 'request-expire-articles
2701                                            gnus-newsgroup-name))
2702     (gnus-summary-mark-as-spam
2703      "mail/spam" t :visible (spam-group-ham-contents-p gnus-newsgroup-name)
2704      :help "Mark as spam")
2705     (gnus-summary-mark-as-read-forward
2706      "mail/not-spam" nil :visible (spam-group-spam-contents-p gnus-newsgroup-name))
2707     ;;
2708     (gnus-summary-exit "exit")
2709     (gmm-customize-mode "preferences" t :help "Edit mode preferences")
2710     (gnus-info-find-node "help"))
2711   "List of functions for the summary tool bar (GNOME style).
2712
2713 See `gmm-tool-bar-from-list' for the format of the list."
2714   :type '(repeat gmm-tool-bar-item)
2715   :version "23.0" ;; No Gnus
2716   :initialize 'custom-initialize-default
2717   :set 'gnus-summary-tool-bar-update
2718   :group 'gnus-summary)
2719
2720 (defcustom gnus-summary-tool-bar-retro
2721   '((gnus-summary-prev-unread-article "gnus/prev-ur")
2722     (gnus-summary-next-unread-article "gnus/next-ur")
2723     (gnus-summary-post-news "gnus/post")
2724     (gnus-summary-followup-with-original "gnus/fuwo")
2725     (gnus-summary-followup "gnus/followup")
2726     (gnus-summary-reply-with-original "gnus/reply-wo")
2727     (gnus-summary-reply "gnus/reply")
2728     (gnus-summary-caesar-message "gnus/rot13")
2729     (gnus-uu-decode-uu "gnus/uu-decode")
2730     (gnus-summary-save-article-file "gnus/save-aif")
2731     (gnus-summary-save-article "gnus/save-art")
2732     (gnus-uu-post-news "gnus/uu-post")
2733     (gnus-summary-catchup "gnus/catchup")
2734     (gnus-summary-catchup-and-exit "gnus/cu-exit")
2735     (gnus-summary-exit "gnus/exit-summ")
2736     ;; Some new command that may need more suitable icons:
2737     (gnus-summary-print-article "gnus/print" nil :visible nil)
2738     (gnus-summary-mark-as-expirable "gnus/close" nil :visible nil)
2739     (gnus-summary-save-newsrc "gnus/save" nil :visible nil)
2740     ;; (gnus-summary-enter-digest-group "gnus/right_arrow" nil :visible nil)
2741     (gnus-summary-search-article-forward "gnus/search" nil :visible nil)
2742     ;; (gnus-summary-insert-new-articles "gnus/paste" nil :visible nil)
2743     ;; (gnus-summary-toggle-threads "gnus/open" nil :visible nil)
2744     ;;
2745     (gnus-info-find-node "gnus/help" nil :visible nil))
2746   "List of functions for the summary tool bar (retro look).
2747
2748 See `gmm-tool-bar-from-list' for the format of the list."
2749   :type '(repeat gmm-tool-bar-item)
2750   :version "23.0" ;; No Gnus
2751   :initialize 'custom-initialize-default
2752   :set 'gnus-summary-tool-bar-update
2753   :group 'gnus-summary)
2754
2755 (defcustom gnus-summary-tool-bar-zap-list t
2756   "List of icon items from the global tool bar.
2757 These items are not displayed in the Gnus summary mode tool bar.
2758
2759 See `gmm-tool-bar-from-list' for the format of the list."
2760   :type 'gmm-tool-bar-zap-list
2761   :version "23.0" ;; No Gnus
2762   :initialize 'custom-initialize-default
2763   :set 'gnus-summary-tool-bar-update
2764   :group 'gnus-summary)
2765
2766 (defun gnus-summary-make-tool-bar (&optional force)
2767   "Make a summary mode tool bar from `gnus-summary-tool-bar'.
2768 When FORCE, rebuild the tool bar."
2769   (when (and (not (featurep 'xemacs))
2770              (boundp 'tool-bar-mode)
2771              tool-bar-mode
2772              (or (not gnus-summary-tool-bar-map) force))
2773     (let* ((load-path
2774             (gmm-image-load-path "gnus" "mail/save.xpm" 'load-path))
2775            (image-load-path
2776             (gmm-image-load-path "gnus" "mail/save.xpm" 'image-load-path))
2777            (map (gmm-tool-bar-from-list gnus-summary-tool-bar
2778                                         gnus-summary-tool-bar-zap-list
2779                                         'gnus-summary-mode-map)))
2780       (when map
2781         ;; Need to set `gnus-summary-tool-bar-map' because `gnus-article-mode'
2782         ;; uses it's value.
2783         (setq gnus-summary-tool-bar-map map))))
2784   (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map))
2785
2786 (defun gnus-score-set-default (var value)
2787   "A version of set that updates the GNU Emacs menu-bar."
2788   (set var value)
2789   ;; It is the message that forces the active status to be updated.
2790   (message ""))
2791
2792 (defun gnus-make-score-map (type)
2793   "Make a summary score map of type TYPE."
2794   (if t
2795       nil
2796     (let ((headers '(("author" "from" string)
2797                      ("subject" "subject" string)
2798                      ("article body" "body" string)
2799                      ("article head" "head" string)
2800                      ("xref" "xref" string)
2801                      ("extra header" "extra" string)
2802                      ("lines" "lines" number)
2803                      ("followups to author" "followup" string)))
2804           (types '((number ("less than" <)
2805                            ("greater than" >)
2806                            ("equal" =))
2807                    (string ("substring" s)
2808                            ("exact string" e)
2809                            ("fuzzy string" f)
2810                            ("regexp" r))))
2811           (perms '(("temporary" (current-time-string))
2812                    ("permanent" nil)
2813                    ("immediate" now)))
2814           header)
2815       (list
2816        (apply
2817         'nconc
2818         (list
2819          (if (eq type 'lower)
2820              "Lower score"
2821            "Increase score"))
2822         (let (outh)
2823           (while headers
2824             (setq header (car headers))
2825             (setq outh
2826                   (cons
2827                    (apply
2828                     'nconc
2829                     (list (car header))
2830                     (let ((ts (cdr (assoc (nth 2 header) types)))
2831                           outt)
2832                       (while ts
2833                         (setq outt
2834                               (cons
2835                                (apply
2836                                 'nconc
2837                                 (list (caar ts))
2838                                 (let ((ps perms)
2839                                       outp)
2840                                   (while ps
2841                                     (setq outp
2842                                           (cons
2843                                            (vector
2844                                             (caar ps)
2845                                             (list
2846                                              'gnus-summary-score-entry
2847                                              (nth 1 header)
2848                                              (if (or (string= (nth 1 header)
2849                                                               "head")
2850                                                      (string= (nth 1 header)
2851                                                               "body"))
2852                                                  ""
2853                                                (list 'gnus-summary-header
2854                                                      (nth 1 header)))
2855                                              (list 'quote (nth 1 (car ts)))
2856                                              (list 'gnus-score-delta-default
2857                                                    nil)
2858                                              (nth 1 (car ps))
2859                                              t)
2860                                             t)
2861                                            outp))
2862                                     (setq ps (cdr ps)))
2863                                   (list (nreverse outp))))
2864                                outt))
2865                         (setq ts (cdr ts)))
2866                       (list (nreverse outt))))
2867                    outh))
2868             (setq headers (cdr headers)))
2869           (list (nreverse outh))))))))
2870
2871 \f
2872
2873 (defun gnus-summary-mode (&optional group)
2874   "Major mode for reading articles.
2875
2876 All normal editing commands are switched off.
2877 \\<gnus-summary-mode-map>
2878 Each line in this buffer represents one article.  To read an
2879 article, you can, for instance, type `\\[gnus-summary-next-page]'.  To move forwards
2880 and backwards while displaying articles, type `\\[gnus-summary-next-unread-article]' and `\\[gnus-summary-prev-unread-article]',
2881 respectively.
2882
2883 You can also post articles and send mail from this buffer.  To
2884 follow up an article, type `\\[gnus-summary-followup]'.  To mail a reply to the author
2885 of an article, type `\\[gnus-summary-reply]'.
2886
2887 There are approx. one gazillion commands you can execute in this
2888 buffer; read the info pages for more information (`\\[gnus-info-find-node]').
2889
2890 The following commands are available:
2891
2892 \\{gnus-summary-mode-map}"
2893   (interactive)
2894   (kill-all-local-variables)
2895   (let ((gnus-summary-local-variables gnus-newsgroup-variables))
2896     (gnus-summary-make-local-variables))
2897   (gnus-summary-make-local-variables)
2898   (setq gnus-newsgroup-name group)
2899   (when (gnus-visual-p 'summary-menu 'menu)
2900     (gnus-summary-make-menu-bar)
2901     (gnus-summary-make-tool-bar))
2902   (gnus-make-thread-indent-array)
2903   (gnus-simplify-mode-line)
2904   (setq major-mode 'gnus-summary-mode)
2905   (setq mode-name "Summary")
2906   (make-local-variable 'minor-mode-alist)
2907   (use-local-map gnus-summary-mode-map)
2908   (buffer-disable-undo)
2909   (setq buffer-read-only t              ;Disable modification
2910         show-trailing-whitespace nil)
2911   (setq truncate-lines t)
2912   (setq selective-display t)
2913   (setq selective-display-ellipses t)   ;Display `...'
2914   (gnus-summary-set-display-table)
2915   (gnus-set-default-directory)
2916   (make-local-variable 'gnus-summary-line-format)
2917   (make-local-variable 'gnus-summary-line-format-spec)
2918   (make-local-variable 'gnus-summary-dummy-line-format)
2919   (make-local-variable 'gnus-summary-dummy-line-format-spec)
2920   (make-local-variable 'gnus-summary-mark-positions)
2921   (gnus-make-local-hook 'pre-command-hook)
2922   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
2923   (gnus-run-mode-hooks 'gnus-summary-mode-hook)
2924   (turn-on-gnus-mailing-list-mode)
2925   (mm-enable-multibyte)
2926   (gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
2927   (gnus-update-summary-mark-positions))
2928
2929 (defun gnus-summary-make-local-variables ()
2930   "Make all the local summary buffer variables."
2931   (let (global)
2932     (dolist (local gnus-summary-local-variables)
2933       (if (consp local)
2934           (progn
2935             (if (eq (cdr local) 'global)
2936                 ;; Copy the global value of the variable.
2937                 (setq global (symbol-value (car local)))
2938               ;; Use the value from the list.
2939               (setq global (eval (cdr local))))
2940             (set (make-local-variable (car local)) global))
2941         ;; Simple nil-valued local variable.
2942         (set (make-local-variable local) nil)))))
2943
2944 (defun gnus-summary-clear-local-variables ()
2945   (let ((locals gnus-summary-local-variables))
2946     (while locals
2947       (if (consp (car locals))
2948           (and (symbolp (caar locals))
2949                (set (caar locals) nil))
2950         (and (symbolp (car locals))
2951              (set (car locals) nil)))
2952       (setq locals (cdr locals)))))
2953
2954 ;; Summary data functions.
2955
2956 (defmacro gnus-data-number (data)
2957   `(car ,data))
2958
2959 (defmacro gnus-data-set-number (data number)
2960   `(setcar ,data ,number))
2961
2962 (defmacro gnus-data-mark (data)
2963   `(nth 1 ,data))
2964
2965 (defmacro gnus-data-set-mark (data mark)
2966   `(setcar (nthcdr 1 ,data) ,mark))
2967
2968 (defmacro gnus-data-pos (data)
2969   `(nth 2 ,data))
2970
2971 (defmacro gnus-data-set-pos (data pos)
2972   `(setcar (nthcdr 2 ,data) ,pos))
2973
2974 (defmacro gnus-data-header (data)
2975   `(nth 3 ,data))
2976
2977 (defmacro gnus-data-set-header (data header)
2978   `(setf (nth 3 ,data) ,header))
2979
2980 (defmacro gnus-data-level (data)
2981   `(nth 4 ,data))
2982
2983 (defmacro gnus-data-unread-p (data)
2984   `(= (nth 1 ,data) gnus-unread-mark))
2985
2986 (defmacro gnus-data-read-p (data)
2987   `(/= (nth 1 ,data) gnus-unread-mark))
2988
2989 (defmacro gnus-data-pseudo-p (data)
2990   `(consp (nth 3 ,data)))
2991
2992 (defmacro gnus-data-find (number)
2993   `(assq ,number gnus-newsgroup-data))
2994
2995 (defmacro gnus-data-find-list (number &optional data)
2996   `(let ((bdata ,(or data 'gnus-newsgroup-data)))
2997      (memq (assq ,number bdata)
2998            bdata)))
2999
3000 (defmacro gnus-data-make (number mark pos header level)
3001   `(list ,number ,mark ,pos ,header ,level))
3002
3003 (defun gnus-data-enter (after-article number mark pos header level offset)
3004   (let ((data (gnus-data-find-list after-article)))
3005     (unless data
3006       (error "No such article: %d" after-article))
3007     (setcdr data (cons (gnus-data-make number mark pos header level)
3008                        (cdr data)))
3009     (setq gnus-newsgroup-data-reverse nil)
3010     (gnus-data-update-list (cddr data) offset)))
3011
3012 (defun gnus-data-enter-list (after-article list &optional offset)
3013   (when list
3014     (let ((data (and after-article (gnus-data-find-list after-article)))
3015           (ilist list))
3016       (if (not (or data
3017                    after-article))
3018           (let ((odata gnus-newsgroup-data))
3019             (setq gnus-newsgroup-data (nconc list gnus-newsgroup-data))
3020             (when offset
3021               (gnus-data-update-list odata offset)))
3022         ;; Find the last element in the list to be spliced into the main
3023         ;; list.
3024         (setq list (last list))
3025         (if (not data)
3026             (progn
3027               (setcdr list gnus-newsgroup-data)
3028               (setq gnus-newsgroup-data ilist)
3029               (when offset
3030                 (gnus-data-update-list (cdr list) offset)))
3031           (setcdr list (cdr data))
3032           (setcdr data ilist)
3033           (when offset
3034             (gnus-data-update-list (cdr list) offset))))
3035       (setq gnus-newsgroup-data-reverse nil))))
3036
3037 (defun gnus-data-remove (article &optional offset)
3038   (let ((data gnus-newsgroup-data))
3039     (if (= (gnus-data-number (car data)) article)
3040         (progn
3041           (setq gnus-newsgroup-data (cdr gnus-newsgroup-data)
3042                 gnus-newsgroup-data-reverse nil)
3043           (when offset
3044             (gnus-data-update-list gnus-newsgroup-data offset)))
3045       (while (cdr data)
3046         (when (= (gnus-data-number (cadr data)) article)
3047           (setcdr data (cddr data))
3048           (when offset
3049             (gnus-data-update-list (cdr data) offset))
3050           (setq data nil
3051                 gnus-newsgroup-data-reverse nil))
3052         (setq data (cdr data))))))
3053
3054 (defmacro gnus-data-list (backward)
3055   `(if ,backward
3056        (or gnus-newsgroup-data-reverse
3057            (setq gnus-newsgroup-data-reverse
3058                  (reverse gnus-newsgroup-data)))
3059      gnus-newsgroup-data))
3060
3061 (defun gnus-data-update-list (data offset)
3062   "Add OFFSET to the POS of all data entries in DATA."
3063   (setq gnus-newsgroup-data-reverse nil)
3064   (while data
3065     (setcar (nthcdr 2 (car data)) (+ offset (nth 2 (car data))))
3066     (setq data (cdr data))))
3067
3068 (defun gnus-summary-article-pseudo-p (article)
3069   "Say whether this article is a pseudo article or not."
3070   (not (vectorp (gnus-data-header (gnus-data-find article)))))
3071
3072 (defmacro gnus-summary-article-sparse-p (article)
3073   "Say whether this article is a sparse article or not."
3074   `(memq ,article gnus-newsgroup-sparse))
3075
3076 (defmacro gnus-summary-article-ancient-p (article)
3077   "Say whether this article is a sparse article or not."
3078   `(memq ,article gnus-newsgroup-ancient))
3079
3080 (defun gnus-article-parent-p (number)
3081   "Say whether this article is a parent or not."
3082   (let ((data (gnus-data-find-list number)))
3083     (and (cdr data)              ; There has to be an article after...
3084          (< (gnus-data-level (car data)) ; And it has to have a higher level.
3085             (gnus-data-level (nth 1 data))))))
3086
3087 (defun gnus-article-children (number)
3088   "Return a list of all children to NUMBER."
3089   (let* ((data (gnus-data-find-list number))
3090          (level (gnus-data-level (car data)))
3091          children)
3092     (setq data (cdr data))
3093     (while (and data
3094                 (= (gnus-data-level (car data)) (1+ level)))
3095       (push (gnus-data-number (car data)) children)
3096       (setq data (cdr data)))
3097     children))
3098
3099 (defmacro gnus-summary-skip-intangible ()
3100   "If the current article is intangible, then jump to a different article."
3101   '(let ((to (get-text-property (point) 'gnus-intangible)))
3102      (and to (gnus-summary-goto-subject to))))
3103
3104 (defmacro gnus-summary-article-intangible-p ()
3105   "Say whether this article is intangible or not."
3106   '(get-text-property (point) 'gnus-intangible))
3107
3108 (defun gnus-article-read-p (article)
3109   "Say whether ARTICLE is read or not."
3110   (not (or (memq article gnus-newsgroup-marked)
3111            (memq article gnus-newsgroup-spam-marked)
3112            (memq article gnus-newsgroup-unreads)
3113            (memq article gnus-newsgroup-unselected)
3114            (memq article gnus-newsgroup-dormant))))
3115
3116 ;; Some summary mode macros.
3117
3118 (defmacro gnus-summary-article-number ()
3119   "The article number of the article on the current line.
3120 If there isn't an article number here, then we return the current
3121 article number."
3122   '(progn
3123      (gnus-summary-skip-intangible)
3124      (or (get-text-property (point) 'gnus-number)
3125          (gnus-summary-last-subject))))
3126
3127 (defmacro gnus-summary-article-header (&optional number)
3128   "Return the header of article NUMBER."
3129   `(gnus-data-header (gnus-data-find
3130                       ,(or number '(gnus-summary-article-number)))))
3131
3132 (defmacro gnus-summary-thread-level (&optional number)
3133   "Return the level of thread that starts with article NUMBER."
3134   `(if (and (eq gnus-summary-make-false-root 'dummy)
3135             (get-text-property (point) 'gnus-intangible))
3136        0
3137      (gnus-data-level (gnus-data-find
3138                        ,(or number '(gnus-summary-article-number))))))
3139
3140 (defmacro gnus-summary-article-mark (&optional number)
3141   "Return the mark of article NUMBER."
3142   `(gnus-data-mark (gnus-data-find
3143                     ,(or number '(gnus-summary-article-number)))))
3144
3145 (defmacro gnus-summary-article-pos (&optional number)
3146   "Return the position of the line of article NUMBER."
3147   `(gnus-data-pos (gnus-data-find
3148                    ,(or number '(gnus-summary-article-number)))))
3149
3150 (defalias 'gnus-summary-subject-string 'gnus-summary-article-subject)
3151 (defmacro gnus-summary-article-subject (&optional number)
3152   "Return current subject string or nil if nothing."
3153   `(let ((headers
3154           ,(if number
3155                `(gnus-data-header (assq ,number gnus-newsgroup-data))
3156              '(gnus-data-header (assq (gnus-summary-article-number)
3157                                       gnus-newsgroup-data)))))
3158      (and headers
3159           (vectorp headers)
3160           (mail-header-subject headers))))
3161
3162 (defmacro gnus-summary-article-score (&optional number)
3163   "Return current article score."
3164   `(or (cdr (assq ,(or number '(gnus-summary-article-number))
3165                   gnus-newsgroup-scored))
3166        gnus-summary-default-score 0))
3167
3168 (defun gnus-summary-article-children (&optional number)
3169   "Return a list of article numbers that are children of article NUMBER."
3170   (let* ((data (gnus-data-find-list (or number (gnus-summary-article-number))))
3171          (level (gnus-data-level (car data)))
3172          l children)
3173     (while (and (setq data (cdr data))
3174                 (> (setq l (gnus-data-level (car data))) level))
3175       (and (= (1+ level) l)
3176            (push (gnus-data-number (car data))
3177                  children)))
3178     (nreverse children)))
3179
3180 (defun gnus-summary-article-parent (&optional number)
3181   "Return the article number of the parent of article NUMBER."
3182   (let* ((data (gnus-data-find-list (or number (gnus-summary-article-number))
3183                                     (gnus-data-list t)))
3184          (level (gnus-data-level (car data))))
3185     (if (zerop level)
3186         ()                              ; This is a root.
3187       ;; We search until we find an article with a level less than
3188       ;; this one.  That function has to be the parent.
3189       (while (and (setq data (cdr data))
3190                   (not (< (gnus-data-level (car data)) level))))
3191       (and data (gnus-data-number (car data))))))
3192
3193 (defun gnus-unread-mark-p (mark)
3194   "Say whether MARK is the unread mark."
3195   (= mark gnus-unread-mark))
3196
3197 (defun gnus-read-mark-p (mark)
3198   "Say whether MARK is one of the marks that mark as read.
3199 This is all marks except unread, ticked, dormant, and expirable."
3200   (not (or (= mark gnus-unread-mark)
3201            (= mark gnus-ticked-mark)
3202            (= mark gnus-spam-mark)
3203            (= mark gnus-dormant-mark)
3204            (= mark gnus-expirable-mark))))
3205
3206 (defmacro gnus-article-mark (number)
3207   "Return the MARK of article NUMBER.
3208 This macro should only be used when computing the mark the \"first\"
3209 time; i.e., when generating the summary lines.  After that,
3210 `gnus-summary-article-mark' should be used to examine the
3211 marks of articles."
3212   `(cond
3213     ((memq ,number gnus-newsgroup-unsendable) gnus-unsendable-mark)
3214     ((memq ,number gnus-newsgroup-downloadable) gnus-downloadable-mark)
3215     ((memq ,number gnus-newsgroup-unreads) gnus-unread-mark)
3216     ((memq ,number gnus-newsgroup-marked) gnus-ticked-mark)
3217     ((memq ,number gnus-newsgroup-spam-marked) gnus-spam-mark)
3218     ((memq ,number gnus-newsgroup-dormant) gnus-dormant-mark)
3219     ((memq ,number gnus-newsgroup-expirable) gnus-expirable-mark)
3220     (t (or (cdr (assq ,number gnus-newsgroup-reads))
3221            gnus-ancient-mark))))
3222
3223 ;; Saving hidden threads.
3224
3225 (defmacro gnus-save-hidden-threads (&rest forms)
3226   "Save hidden threads, eval FORMS, and restore the hidden threads."
3227   (let ((config (make-symbol "config")))
3228     `(let ((,config (gnus-hidden-threads-configuration)))
3229        (unwind-protect
3230            (save-excursion
3231              ,@forms)
3232          (gnus-restore-hidden-threads-configuration ,config)))))
3233 (put 'gnus-save-hidden-threads 'lisp-indent-function 0)
3234 (put 'gnus-save-hidden-threads 'edebug-form-spec '(body))
3235
3236 (defun gnus-data-compute-positions ()
3237   "Compute the positions of all articles."
3238   (setq gnus-newsgroup-data-reverse nil)
3239   (let ((data gnus-newsgroup-data))
3240     (save-excursion
3241       (gnus-save-hidden-threads
3242         (gnus-summary-show-all-threads)
3243         (goto-char (point-min))
3244         (while data
3245           (while (get-text-property (point) 'gnus-intangible)
3246             (forward-line 1))
3247           (gnus-data-set-pos (car data) (+ (point) 3))
3248           (setq data (cdr data))
3249           (forward-line 1))))))
3250
3251 (defun gnus-hidden-threads-configuration ()
3252   "Return the current hidden threads configuration."
3253   (save-excursion
3254     (let (config)
3255       (goto-char (point-min))
3256       (while (search-forward "\r" nil t)
3257         (push (1- (point)) config))
3258       config)))
3259
3260 (defun gnus-restore-hidden-threads-configuration (config)
3261   "Restore hidden threads configuration from CONFIG."
3262   (save-excursion
3263     (let (point buffer-read-only)
3264       (while (setq point (pop config))
3265         (when (and (< point (point-max))
3266                    (goto-char point)
3267                    (eq (char-after) ?\n))
3268           (subst-char-in-region point (1+ point) ?\n ?\r))))))
3269
3270 ;; Various summary mode internalish functions.
3271
3272 (defun gnus-mouse-pick-article (e)
3273   (interactive "e")
3274   (mouse-set-point e)
3275   (gnus-summary-next-page nil t))
3276
3277 (defun gnus-summary-set-display-table ()
3278   "Change the display table.
3279 Odd characters have a tendency to mess
3280 up nicely formatted displays - we make all possible glyphs
3281 display only a single character."
3282
3283   ;; We start from the standard display table, if any.
3284   (let ((table (or (copy-sequence standard-display-table)
3285                    (make-display-table)))
3286         (i 32))
3287     ;; Nix out all the control chars...
3288     (while (>= (setq i (1- i)) 0)
3289       (aset table i [??]))
3290    ;; ... but not newline and cr, of course.  (cr is necessary for the
3291     ;; selective display).
3292     (aset table ?\n nil)
3293     (aset table ?\r nil)
3294     ;; We keep TAB as well.
3295     (aset table ?\t nil)
3296     ;; We nix out any glyphs over 126 that are not set already.
3297     (let ((i 256))
3298       (while (>= (setq i (1- i)) 127)
3299         ;; Only modify if the entry is nil.
3300         (unless (aref table i)
3301           (aset table i [??]))))
3302     (setq buffer-display-table table)))
3303
3304 (defun gnus-summary-set-article-display-arrow (pos)
3305   "Update the overlay arrow to point to line at position POS."
3306   (when (and gnus-summary-display-arrow
3307              (boundp 'overlay-arrow-position)
3308              (boundp 'overlay-arrow-string))
3309     (save-excursion
3310       (goto-char pos)