lisp/ChangeLog addition:
[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, 2007 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 500
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 an article on group entry.
312 An article is selected automatically when entering a group
313 e.g. with \\<gnus-group-mode-map>\\[gnus-group-read-group], or via `gnus-summary-next-page' or
314 `gnus-summary-catchup-and-goto-next-group'.
315
316 Which article is selected is controlled by the variable
317 `gnus-auto-select-subject'.
318
319 If you want to prevent automatic selection of articles in some
320 newsgroups, set the variable to nil in `gnus-select-group-hook'."
321   ;; Commands include...
322   ;; \\<gnus-group-mode-map>\\[gnus-group-read-group]
323   ;; \\<gnus-summary-mode-map>\\[gnus-summary-next-page]
324   ;; \\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]
325   :group 'gnus-group-select
326   :type '(choice (const :tag "none" nil)
327                  (sexp :menu-tag "first" t)))
328
329 (defcustom gnus-auto-select-subject 'unread
330   "*Says what subject to place under point when entering a group.
331
332 This variable can either be the symbols `first' (place point on the
333 first subject), `unread' (place point on the subject line of the first
334 unread article), `best' (place point on the subject line of the
335 higest-scored article), `unseen' (place point on the subject line of
336 the first unseen article), `unseen-or-unread' (place point on the subject
337 line of the first unseen article or, if all article have been seen, on the
338 subject line of the first unread article), or a function to be called to
339 place point on some subject line."
340   :version "22.1"
341   :group 'gnus-group-select
342   :type '(choice (const best)
343                  (const unread)
344                  (const first)
345                  (const unseen)
346                  (const unseen-or-unread)))
347
348 (defcustom gnus-auto-select-next t
349   "*If non-nil, offer to go to the next group from the end of the previous.
350 If the value is t and the next newsgroup is empty, Gnus will exit
351 summary mode and go back to group mode.  If the value is neither nil
352 nor t, Gnus will select the following unread newsgroup.  In
353 particular, if the value is the symbol `quietly', the next unread
354 newsgroup will be selected without any confirmation, and if it is
355 `almost-quietly', the next group will be selected without any
356 confirmation if you are located on the last article in the group.
357 Finally, if this variable is `slightly-quietly', the `\\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]' command
358 will go to the next group without confirmation."
359   :group 'gnus-summary-maneuvering
360   :type '(choice (const :tag "off" nil)
361                  (const quietly)
362                  (const almost-quietly)
363                  (const slightly-quietly)
364                  (sexp :menu-tag "on" t)))
365
366 (defcustom gnus-auto-select-same nil
367   "*If non-nil, select the next article with the same subject.
368 If there are no more articles with the same subject, go to
369 the first unread article."
370   :group 'gnus-summary-maneuvering
371   :type 'boolean)
372
373 (defcustom gnus-auto-goto-ignores 'unfetched
374   "*Says how to handle unfetched articles when maneuvering.
375
376 This variable can either be the symbols nil (maneuver to any
377 article), `undownloaded' (maneuvering while unplugged ignores articles
378 that have not been fetched), `always-undownloaded' (maneuvering always
379 ignores articles that have not been fetched), `unfetched' (maneuvering
380 ignores articles whose headers have not been fetched).
381
382 NOTE: The list of unfetched articles will always be nil when plugged
383 and, when unplugged, a subset of the undownloaded article list."
384   :version "22.1"
385   :group 'gnus-summary-maneuvering
386   :type '(choice (const :tag "None" nil)
387                  (const :tag "Undownloaded when unplugged" undownloaded)
388                  (const :tag "Undownloaded" always-undownloaded)
389                  (const :tag "Unfetched" unfetched)))
390
391 (defcustom gnus-summary-check-current nil
392   "*If non-nil, consider the current article when moving.
393 The \"unread\" movement commands will stay on the same line if the
394 current article is unread."
395   :group 'gnus-summary-maneuvering
396   :type 'boolean)
397
398 (defcustom gnus-auto-center-summary 2
399   "*If non-nil, always center the current summary buffer.
400 In particular, if `vertical' do only vertical recentering.  If non-nil
401 and non-`vertical', do both horizontal and vertical recentering."
402   :group 'gnus-summary-maneuvering
403   :type '(choice (const :tag "none" nil)
404                  (const vertical)
405                  (integer :tag "height")
406                  (sexp :menu-tag "both" t)))
407
408 (defvar gnus-auto-center-group t
409   "*If non-nil, always center the group buffer.")
410
411 (defcustom gnus-show-all-headers nil
412   "*If non-nil, don't hide any headers."
413   :group 'gnus-article-hiding
414   :group 'gnus-article-headers
415   :type 'boolean)
416
417 (defcustom gnus-summary-ignore-duplicates nil
418   "*If non-nil, ignore articles with identical Message-ID headers."
419   :group 'gnus-summary
420   :type 'boolean)
421
422 (defcustom gnus-single-article-buffer t
423   "*If non-nil, display all articles in the same buffer.
424 If nil, each group will get its own article buffer."
425   :group 'gnus-article-various
426   :type 'boolean)
427
428 (defcustom gnus-break-pages t
429   "*If non-nil, do page breaking on articles.
430 The page delimiter is specified by the `gnus-page-delimiter'
431 variable."
432   :group 'gnus-article-various
433   :type 'boolean)
434
435 (defcustom gnus-move-split-methods nil
436   "*Variable used to suggest where articles are to be moved to.
437 It uses the same syntax as the `gnus-split-methods' variable.
438 However, whereas `gnus-split-methods' specifies file names as targets,
439 this variable specifies group names."
440   :group 'gnus-summary-mail
441   :type '(repeat (choice (list :value (fun) function)
442                          (cons :value ("" "") regexp (repeat string))
443                          (sexp :value nil))))
444
445 (defcustom gnus-move-group-prefix-function 'gnus-group-real-prefix
446   "Function used to compute default prefix for article move/copy/etc prompts.
447 The function should take one argument, a group name, and return a
448 string with the suggested prefix."
449   :group 'gnus-summary-mail
450   :type 'function)
451
452 ;; FIXME: Although the custom type is `character' for the following variables,
453 ;; using multibyte characters (Latin-1, UTF-8) doesn't work.  -- rs
454
455 (defcustom gnus-unread-mark ?           ;Whitespace
456   "*Mark used for unread articles."
457   :group 'gnus-summary-marks
458   :type 'character)
459
460 (defcustom gnus-ticked-mark ?!
461   "*Mark used for ticked articles."
462   :group 'gnus-summary-marks
463   :type 'character)
464
465 (defcustom gnus-dormant-mark ??
466   "*Mark used for dormant articles."
467   :group 'gnus-summary-marks
468   :type 'character)
469
470 (defcustom gnus-del-mark ?r
471   "*Mark used for del'd articles."
472   :group 'gnus-summary-marks
473   :type 'character)
474
475 (defcustom gnus-read-mark ?R
476   "*Mark used for read articles."
477   :group 'gnus-summary-marks
478   :type 'character)
479
480 (defcustom gnus-expirable-mark ?E
481   "*Mark used for expirable articles."
482   :group 'gnus-summary-marks
483   :type 'character)
484
485 (defcustom gnus-killed-mark ?K
486   "*Mark used for killed articles."
487   :group 'gnus-summary-marks
488   :type 'character)
489
490 (defcustom gnus-spam-mark ?$
491   "*Mark used for spam articles."
492   :version "22.1"
493   :group 'gnus-summary-marks
494   :type 'character)
495
496 (defcustom gnus-souped-mark ?F
497   "*Mark used for souped articles."
498   :group 'gnus-summary-marks
499   :type 'character)
500
501 (defcustom gnus-kill-file-mark ?X
502   "*Mark used for articles killed by kill files."
503   :group 'gnus-summary-marks
504   :type 'character)
505
506 (defcustom gnus-low-score-mark ?Y
507   "*Mark used for articles with a low score."
508   :group 'gnus-summary-marks
509   :type 'character)
510
511 (defcustom gnus-catchup-mark ?C
512   "*Mark used for articles that are caught up."
513   :group 'gnus-summary-marks
514   :type 'character)
515
516 (defcustom gnus-replied-mark ?A
517   "*Mark used for articles that have been replied to."
518   :group 'gnus-summary-marks
519   :type 'character)
520
521 (defcustom gnus-forwarded-mark ?F
522   "*Mark used for articles that have been forwarded."
523   :version "22.1"
524   :group 'gnus-summary-marks
525   :type 'character)
526
527 (defcustom gnus-recent-mark ?N
528   "*Mark used for articles that are recent."
529   :version "22.1"
530   :group 'gnus-summary-marks
531   :type 'character)
532
533 (defcustom gnus-cached-mark ?*
534   "*Mark used for articles that are in the cache."
535   :group 'gnus-summary-marks
536   :type 'character)
537
538 (defcustom gnus-saved-mark ?S
539   "*Mark used for articles that have been saved."
540   :group 'gnus-summary-marks
541   :type 'character)
542
543 (defcustom gnus-unseen-mark ?.
544   "*Mark used for articles that haven't been seen."
545   :version "22.1"
546   :group 'gnus-summary-marks
547   :type 'character)
548
549 (defcustom gnus-no-mark ?               ;Whitespace
550   "*Mark used for articles that have no other secondary mark."
551   :version "22.1"
552   :group 'gnus-summary-marks
553   :type 'character)
554
555 (defcustom gnus-ancient-mark ?O
556   "*Mark used for ancient articles."
557   :group 'gnus-summary-marks
558   :type 'character)
559
560 (defcustom gnus-sparse-mark ?Q
561   "*Mark used for sparsely reffed articles."
562   :group 'gnus-summary-marks
563   :type 'character)
564
565 (defcustom gnus-canceled-mark ?G
566   "*Mark used for canceled articles."
567   :group 'gnus-summary-marks
568   :type 'character)
569
570 (defcustom gnus-duplicate-mark ?M
571   "*Mark used for duplicate articles."
572   :group 'gnus-summary-marks
573   :type 'character)
574
575 (defcustom gnus-undownloaded-mark ?-
576   "*Mark used for articles that weren't downloaded."
577   :version "22.1"
578   :group 'gnus-summary-marks
579   :type 'character)
580
581 (defcustom gnus-downloaded-mark ?+
582   "*Mark used for articles that were downloaded."
583   :group 'gnus-summary-marks
584   :type 'character)
585
586 (defcustom gnus-downloadable-mark ?%
587   "*Mark used for articles that are to be downloaded."
588   :group 'gnus-summary-marks
589   :type 'character)
590
591 (defcustom gnus-unsendable-mark ?=
592   "*Mark used for articles that won't be sent."
593   :group 'gnus-summary-marks
594   :type 'character)
595
596 (defcustom gnus-score-over-mark ?+
597   "*Score mark used for articles with high scores."
598   :group 'gnus-summary-marks
599   :type 'character)
600
601 (defcustom gnus-score-below-mark ?-
602   "*Score mark used for articles with low scores."
603   :group 'gnus-summary-marks
604   :type 'character)
605
606 (defcustom gnus-empty-thread-mark ?     ;Whitespace
607   "*There is no thread under the article."
608   :group 'gnus-summary-marks
609   :type 'character)
610
611 (defcustom gnus-not-empty-thread-mark ?=
612   "*There is a thread under the article."
613   :group 'gnus-summary-marks
614   :type 'character)
615
616 (defcustom gnus-view-pseudo-asynchronously nil
617   "*If non-nil, Gnus will view pseudo-articles asynchronously."
618   :group 'gnus-extract-view
619   :type 'boolean)
620
621 (defcustom gnus-auto-expirable-marks
622   (list gnus-killed-mark gnus-del-mark gnus-catchup-mark
623         gnus-low-score-mark gnus-ancient-mark gnus-read-mark
624         gnus-souped-mark gnus-duplicate-mark)
625   "*The list of marks converted into expiration if a group is auto-expirable."
626   :version "21.1"
627   :group 'gnus-summary
628   :type '(repeat character))
629
630 (defcustom gnus-inhibit-user-auto-expire t
631   "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
632   :version "21.1"
633   :group 'gnus-summary
634   :type 'boolean)
635
636 (defcustom gnus-view-pseudos nil
637   "*If `automatic', pseudo-articles will be viewed automatically.
638 If `not-confirm', pseudos will be viewed automatically, and the user
639 will not be asked to confirm the command."
640   :group 'gnus-extract-view
641   :type '(choice (const :tag "off" nil)
642                  (const automatic)
643                  (const not-confirm)))
644
645 (defcustom gnus-view-pseudos-separately t
646   "*If non-nil, one pseudo-article will be created for each file to be viewed.
647 If nil, all files that use the same viewing command will be given as a
648 list of parameters to that command."
649   :group 'gnus-extract-view
650   :type 'boolean)
651
652 (defcustom gnus-insert-pseudo-articles t
653   "*If non-nil, insert pseudo-articles when decoding articles."
654   :group 'gnus-extract-view
655   :type 'boolean)
656
657 (defcustom gnus-summary-dummy-line-format
658   "   %(:                             :%) %S\n"
659   "*The format specification for the dummy roots in the summary buffer.
660 It works along the same lines as a normal formatting string,
661 with some simple extensions.
662
663 %S  The subject
664
665 General format specifiers can also be used.
666 See `(gnus)Formatting Variables'."
667   :link '(custom-manual "(gnus)Formatting Variables")
668   :group 'gnus-threading
669   :type 'string)
670
671 (defcustom gnus-summary-mode-line-format "Gnus: %g [%A] %Z"
672   "*The format specification for the summary mode line.
673 It works along the same lines as a normal formatting string,
674 with some simple extensions:
675
676 %G  Group name
677 %p  Unprefixed group name
678 %A  Current article number
679 %z  Current article score
680 %V  Gnus version
681 %U  Number of unread articles in the group
682 %e  Number of unselected articles in the group
683 %Z  A string with unread/unselected article counts
684 %g  Shortish group name
685 %S  Subject of the current article
686 %u  User-defined spec
687 %s  Current score file name
688 %d  Number of dormant articles
689 %r  Number of articles that have been marked as read in this session
690 %E  Number of articles expunged by the score files"
691   :group 'gnus-summary-format
692   :type 'string)
693
694 (defcustom gnus-list-identifiers nil
695   "Regexp that matches list identifiers to be removed from subject.
696 This can also be a list of regexps."
697   :version "21.1"
698   :group 'gnus-summary-format
699   :group 'gnus-article-hiding
700   :type '(choice (const :tag "none" nil)
701                  (regexp :value ".*")
702                  (repeat :value (".*") regexp)))
703
704 (defcustom gnus-summary-mark-below 0
705   "*Mark all articles with a score below this variable as read.
706 This variable is local to each summary buffer and usually set by the
707 score file."
708   :group 'gnus-score-default
709   :type 'integer)
710
711 (defun gnus-widget-reversible-match (widget value)
712   "Ignoring WIDGET, convert VALUE to internal form.
713 VALUE should have the form `FOO' or `(not FOO)', where FOO is an symbol."
714   ;; (debug value)
715   (or (symbolp value)
716       (and (listp value)
717            (eq (length value) 2)
718            (eq (nth 0 value) 'not)
719            (symbolp (nth 1 value)))))
720
721 (defun gnus-widget-reversible-to-internal (widget value)
722   "Ignoring WIDGET, convert VALUE to internal form.
723 VALUE should have the form `FOO' or `(not FOO)', where FOO is an atom.
724 FOO is converted to (FOO nil) and (not FOO) is converted to (FOO t)."
725   ;; (debug value)
726   (if (atom value)
727       (list value nil)
728     (list (nth 1 value) t)))
729
730 (defun gnus-widget-reversible-to-external (widget value)
731   "Ignoring WIDGET, convert VALUE to external form.
732 VALUE should have the form `(FOO nil)' or `(FOO t)', where FOO is an atom.
733 \(FOO  nil) is converted to FOO and (FOO t) is converted to (not FOO)."
734   ;; (debug value)
735   (if (nth 1 value)
736       (list 'not (nth 0 value))
737     (nth 0 value)))
738
739 (define-widget 'gnus-widget-reversible 'group
740   "A `group' that convert values."
741   :match 'gnus-widget-reversible-match
742   :value-to-internal 'gnus-widget-reversible-to-internal
743   :value-to-external 'gnus-widget-reversible-to-external)
744
745 (defcustom gnus-article-sort-functions '(gnus-article-sort-by-number)
746   "*List of functions used for sorting articles in the summary buffer.
747
748 Each function takes two articles and returns non-nil if the first
749 article should be sorted before the other.  If you use more than one
750 function, the primary sort function should be the last.  You should
751 probably always include `gnus-article-sort-by-number' in the list of
752 sorting functions -- preferably first.  Also note that sorting by date
753 is often much slower than sorting by number, and the sorting order is
754 very similar.  (Sorting by date means sorting by the time the message
755 was sent, sorting by number means sorting by arrival time.)
756
757 Each item can also be a list `(not F)' where F is a function;
758 this reverses the sort order.
759
760 Ready-made functions include `gnus-article-sort-by-number',
761 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
762 `gnus-article-sort-by-date', `gnus-article-sort-by-random'
763 and `gnus-article-sort-by-score'.
764
765 When threading is turned on, the variable `gnus-thread-sort-functions'
766 controls how articles are sorted."
767   :group 'gnus-summary-sort
768   :type '(repeat (gnus-widget-reversible
769                   (choice (function-item gnus-article-sort-by-number)
770                           (function-item gnus-article-sort-by-author)
771                           (function-item gnus-article-sort-by-subject)
772                           (function-item gnus-article-sort-by-date)
773                           (function-item gnus-article-sort-by-score)
774                           (function-item gnus-article-sort-by-random)
775                           (function :tag "other"))
776                   (boolean :tag "Reverse order"))))
777
778
779 (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
780   "*List of functions used for sorting threads in the summary buffer.
781 By default, threads are sorted by article number.
782
783 Each function takes two threads and returns non-nil if the first
784 thread should be sorted before the other.  If you use more than one
785 function, the primary sort function should be the last.  You should
786 probably always include `gnus-thread-sort-by-number' in the list of
787 sorting functions -- preferably first.  Also note that sorting by date
788 is often much slower than sorting by number, and the sorting order is
789 very similar.  (Sorting by date means sorting by the time the message
790 was sent, sorting by number means sorting by arrival time.)
791
792 Each list item can also be a list `(not F)' where F is a
793 function; this specifies reversed sort order.
794
795 Ready-made functions include `gnus-thread-sort-by-number',
796 `gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
797 `gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
798 `gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
799 `gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
800 and `gnus-thread-sort-by-total-score' (see
801 `gnus-thread-score-function').
802
803 When threading is turned off, the variable
804 `gnus-article-sort-functions' controls how articles are sorted."
805   :group 'gnus-summary-sort
806   :type '(repeat
807           (gnus-widget-reversible
808            (choice (function-item gnus-thread-sort-by-number)
809                    (function-item gnus-thread-sort-by-author)
810                    (function-item gnus-thread-sort-by-recipient)
811                    (function-item gnus-thread-sort-by-subject)
812                    (function-item gnus-thread-sort-by-date)
813                    (function-item gnus-thread-sort-by-score)
814                    (function-item gnus-thread-sort-by-most-recent-number)
815                    (function-item gnus-thread-sort-by-most-recent-date)
816                    (function-item gnus-thread-sort-by-random)
817                    (function-item gnus-thread-sort-by-total-score)
818                    (function :tag "other"))
819            (boolean :tag "Reverse order"))))
820
821 (defcustom gnus-thread-score-function '+
822   "*Function used for calculating the total score of a thread.
823
824 The function is called with the scores of the article and each
825 subthread and should then return the score of the thread.
826
827 Some functions you can use are `+', `max', or `min'."
828   :group 'gnus-summary-sort
829   :type 'function)
830
831 (defcustom gnus-summary-expunge-below nil
832   "All articles that have a score less than this variable will be expunged.
833 This variable is local to the summary buffers."
834   :group 'gnus-score-default
835   :type '(choice (const :tag "off" nil)
836                  integer))
837
838 (defcustom gnus-thread-expunge-below nil
839   "All threads that have a total score less than this variable will be expunged.
840 See `gnus-thread-score-function' for en explanation of what a
841 \"thread score\" is.
842
843 This variable is local to the summary buffers."
844   :group 'gnus-threading
845   :group 'gnus-score-default
846   :type '(choice (const :tag "off" nil)
847                  integer))
848
849 (defcustom gnus-summary-mode-hook nil
850   "*A hook for Gnus summary mode.
851 This hook is run before any variables are set in the summary buffer."
852   :options '(turn-on-gnus-mailing-list-mode gnus-pick-mode)
853   :group 'gnus-summary-various
854   :type 'hook)
855
856 ;; Extracted from gnus-xmas-redefine in order to preserve user settings
857 (when (featurep 'xemacs)
858   (add-hook 'gnus-summary-mode-hook 'gnus-xmas-summary-menu-add)
859   (add-hook 'gnus-summary-mode-hook 'gnus-xmas-setup-summary-toolbar)
860   (add-hook 'gnus-summary-mode-hook
861             'gnus-xmas-switch-horizontal-scrollbar-off))
862
863 (defcustom gnus-summary-menu-hook nil
864   "*Hook run after the creation of the summary mode menu."
865   :group 'gnus-summary-visual
866   :type 'hook)
867
868 (defcustom gnus-summary-exit-hook nil
869   "*A hook called on exit from the summary buffer.
870 It will be called with point in the group buffer."
871   :group 'gnus-summary-exit
872   :type 'hook)
873
874 (defcustom gnus-summary-prepare-hook nil
875   "*A hook called after the summary buffer has been generated.
876 If you want to modify the summary buffer, you can use this hook."
877   :group 'gnus-summary-various
878   :type 'hook)
879
880 (defcustom gnus-summary-prepared-hook nil
881   "*A hook called as the last thing after the summary buffer has been generated."
882   :group 'gnus-summary-various
883   :type 'hook)
884
885 (defcustom gnus-summary-generate-hook nil
886   "*A hook run just before generating the summary buffer.
887 This hook is commonly used to customize threading variables and the
888 like."
889   :group 'gnus-summary-various
890   :type 'hook)
891
892 (defcustom gnus-select-group-hook nil
893   "*A hook called when a newsgroup is selected.
894
895 If you'd like to simplify subjects like the
896 `gnus-summary-next-same-subject' command does, you can use the
897 following hook:
898
899  (add-hook gnus-select-group-hook
900            (lambda ()
901              (mapcar (lambda (header)
902                        (mail-header-set-subject
903                         header
904                         (gnus-simplify-subject
905                          (mail-header-subject header) 're-only)))
906                      gnus-newsgroup-headers)))"
907   :group 'gnus-group-select
908   :type 'hook)
909
910 (defcustom gnus-select-article-hook nil
911   "*A hook called when an article is selected."
912   :group 'gnus-summary-choose
913   :options '(gnus-agent-fetch-selected-article)
914   :type 'hook)
915
916 (defcustom gnus-visual-mark-article-hook
917   (list 'gnus-highlight-selected-summary)
918   "*Hook run after selecting an article in the summary buffer.
919 It is meant to be used for highlighting the article in some way.  It
920 is not run if `gnus-visual' is nil."
921   :group 'gnus-summary-visual
922   :type 'hook)
923
924 (defcustom gnus-parse-headers-hook nil
925   "*A hook called before parsing the headers."
926   :group 'gnus-various
927   :type 'hook)
928
929 (defcustom gnus-exit-group-hook nil
930   "*A hook called when exiting summary mode.
931 This hook is not called from the non-updating exit commands like `Q'."
932   :group 'gnus-various
933   :type 'hook)
934
935 (defcustom gnus-summary-update-hook
936   (list 'gnus-summary-highlight-line)
937   "*A hook called when a summary line is changed.
938 The hook will not be called if `gnus-visual' is nil.
939
940 The default function `gnus-summary-highlight-line' will
941 highlight the line according to the `gnus-summary-highlight'
942 variable."
943   :group 'gnus-summary-visual
944   :type 'hook)
945
946 (defcustom gnus-mark-article-hook '(gnus-summary-mark-read-and-unread-as-read)
947   "*A hook called when an article is selected for the first time.
948 The hook is intended to mark an article as read (or unread)
949 automatically when it is selected."
950   :group 'gnus-summary-choose
951   :type 'hook)
952
953 (defcustom gnus-group-no-more-groups-hook nil
954   "*A hook run when returning to group mode having no more (unread) groups."
955   :group 'gnus-group-select
956   :type 'hook)
957
958 (defcustom gnus-ps-print-hook nil
959   "*A hook run before ps-printing something from Gnus."
960   :group 'gnus-summary
961   :type 'hook)
962
963 (defcustom gnus-summary-article-move-hook nil
964   "*A hook called after an article is moved, copied, respooled, or crossposted."
965   :version "22.1"
966   :group 'gnus-summary
967   :type 'hook)
968
969 (defcustom gnus-summary-article-delete-hook nil
970   "*A hook called after an article is deleted."
971   :version "22.1"
972   :group 'gnus-summary
973   :type 'hook)
974
975 (defcustom gnus-summary-article-expire-hook nil
976   "*A hook called after an article is expired."
977   :version "22.1"
978   :group 'gnus-summary
979   :type 'hook)
980
981 (defcustom gnus-summary-display-arrow
982   (and (fboundp 'display-graphic-p)
983        (display-graphic-p))
984   "*If non-nil, display an arrow highlighting the current article."
985   :version "22.1"
986   :group 'gnus-summary
987   :type 'boolean)
988
989 (defcustom gnus-summary-selected-face 'gnus-summary-selected
990   "Face used for highlighting the current article in the summary buffer."
991   :group 'gnus-summary-visual
992   :type 'face)
993
994 (defvar gnus-tmp-downloaded nil)
995
996 (defcustom gnus-summary-highlight
997   '(((eq mark gnus-canceled-mark)
998      . gnus-summary-cancelled)
999     ((and uncached (> score default-high))
1000      . gnus-summary-high-undownloaded)
1001     ((and uncached (< score default-low))
1002      . gnus-summary-low-undownloaded)
1003     (uncached
1004      . gnus-summary-normal-undownloaded)
1005     ((and (> score default-high)
1006           (or (eq mark gnus-dormant-mark)
1007               (eq mark gnus-ticked-mark)))
1008      . gnus-summary-high-ticked)
1009     ((and (< score default-low)
1010           (or (eq mark gnus-dormant-mark)
1011               (eq mark gnus-ticked-mark)))
1012      . gnus-summary-low-ticked)
1013     ((or (eq mark gnus-dormant-mark)
1014          (eq mark gnus-ticked-mark))
1015      . gnus-summary-normal-ticked)
1016     ((and (> score default-high) (eq mark gnus-ancient-mark))
1017      . gnus-summary-high-ancient)
1018     ((and (< score default-low) (eq mark gnus-ancient-mark))
1019      . gnus-summary-low-ancient)
1020     ((eq mark gnus-ancient-mark)
1021      . gnus-summary-normal-ancient)
1022     ((and (> score default-high) (eq mark gnus-unread-mark))
1023      . gnus-summary-high-unread)
1024     ((and (< score default-low) (eq mark gnus-unread-mark))
1025      . gnus-summary-low-unread)
1026     ((eq mark gnus-unread-mark)
1027      . gnus-summary-normal-unread)
1028     ((> score default-high)
1029      . gnus-summary-high-read)
1030     ((< score default-low)
1031      . gnus-summary-low-read)
1032     (t
1033      . gnus-summary-normal-read))
1034   "*Controls the highlighting of summary buffer lines.
1035
1036 A list of (FORM . FACE) pairs.  When deciding how a a particular
1037 summary line should be displayed, each form is evaluated.  The content
1038 of the face field after the first true form is used.  You can change
1039 how those summary lines are displayed, by editing the face field.
1040
1041 You can use the following variables in the FORM field.
1042
1043 score:        The article's score
1044 default:      The default article score.
1045 default-high: The default score for high scored articles.
1046 default-low:  The default score for low scored articles.
1047 below:        The score below which articles are automatically marked as read.
1048 mark:         The article's mark.
1049 uncached:     Non-nil if the article is uncached."
1050   :group 'gnus-summary-visual
1051   :type '(repeat (cons (sexp :tag "Form" nil)
1052                        face)))
1053
1054 (defcustom gnus-alter-header-function nil
1055   "Function called to allow alteration of article header structures.
1056 The function is called with one parameter, the article header vector,
1057 which it may alter in any way."
1058   :type '(choice (const :tag "None" nil)
1059                  function)
1060   :group 'gnus-summary)
1061
1062 (defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
1063   "Function used to decode a string with encoded words.")
1064
1065 (defvar gnus-decode-encoded-address-function
1066   'mail-decode-encoded-address-string
1067   "Function used to decode addresses with encoded words.")
1068
1069 (defcustom gnus-extra-headers '(To Newsgroups)
1070   "*Extra headers to parse."
1071   :version "21.1"
1072   :group 'gnus-summary
1073   :type '(repeat symbol))
1074
1075 (defcustom gnus-ignored-from-addresses
1076   (and user-mail-address
1077        (not (string= user-mail-address ""))
1078        (regexp-quote user-mail-address))
1079   "*From headers that may be suppressed in favor of To headers.
1080 This can be a regexp or a list of regexps."
1081   :version "21.1"
1082   :group 'gnus-summary
1083   :type '(choice regexp
1084                  (repeat :tag "Regexp List" regexp)))
1085
1086 (defsubst gnus-ignored-from-addresses ()
1087   (gmm-regexp-concat gnus-ignored-from-addresses))
1088
1089 (defcustom gnus-summary-to-prefix "-> "
1090   "*String prefixed to the To field in the summary line when
1091 using `gnus-ignored-from-addresses'."
1092   :version "22.1"
1093   :group 'gnus-summary
1094   :type 'string)
1095
1096 (defcustom gnus-summary-newsgroup-prefix "=> "
1097   "*String prefixed to the Newsgroup field in the summary
1098 line when using `gnus-ignored-from-addresses'."
1099   :version "22.1"
1100   :group 'gnus-summary
1101   :type 'string)
1102
1103 (defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
1104   "List of charsets that should be ignored.
1105 When these charsets are used in the \"charset\" parameter, the
1106 default charset will be used instead."
1107   :version "21.1"
1108   :type '(repeat symbol)
1109   :group 'gnus-charset)
1110
1111 (gnus-define-group-parameter
1112  ignored-charsets
1113  :type list
1114  :function-document
1115  "Return the ignored charsets of GROUP."
1116  :variable gnus-group-ignored-charsets-alist
1117  :variable-default
1118  '(("alt\\.chinese\\.text" iso-8859-1))
1119  :variable-document
1120  "Alist of regexps (to match group names) and charsets that should be ignored.
1121 When these charsets are used in the \"charset\" parameter, the
1122 default charset will be used instead."
1123  :variable-group gnus-charset
1124  :variable-type '(repeat (cons (regexp :tag "Group")
1125                                (repeat symbol)))
1126  :parameter-type '(choice :tag "Ignored charsets"
1127                           :value nil
1128                           (repeat (symbol)))
1129  :parameter-document       "\
1130 List of charsets that should be ignored.
1131
1132 When these charsets are used in the \"charset\" parameter, the
1133 default charset will be used instead.")
1134
1135 (defcustom gnus-group-highlight-words-alist nil
1136   "Alist of group regexps and highlight regexps.
1137 This variable uses the same syntax as `gnus-emphasis-alist'."
1138   :version "21.1"
1139   :type '(repeat (cons (regexp :tag "Group")
1140                        (repeat (list (regexp :tag "Highlight regexp")
1141                                      (number :tag "Group for entire word" 0)
1142                                      (number :tag "Group for displayed part" 0)
1143                                      (symbol :tag "Face"
1144                                              gnus-emphasis-highlight-words)))))
1145   :group 'gnus-summary-visual)
1146
1147 (defcustom gnus-summary-show-article-charset-alist
1148   nil
1149   "Alist of number and charset.
1150 The article will be shown with the charset corresponding to the
1151 numbered argument.
1152 For example: ((1 . cn-gb-2312) (2 . big5))."
1153   :version "21.1"
1154   :type '(repeat (cons (number :tag "Argument" 1)
1155                        (symbol :tag "Charset")))
1156   :group 'gnus-charset)
1157
1158 (defcustom gnus-preserve-marks t
1159   "Whether marks are preserved when moving, copying and respooling messages."
1160   :version "21.1"
1161   :type 'boolean
1162   :group 'gnus-summary-marks)
1163
1164 (defcustom gnus-alter-articles-to-read-function nil
1165   "Function to be called to alter the list of articles to be selected."
1166   :type '(choice (const nil) function)
1167   :group 'gnus-summary)
1168
1169 (defcustom gnus-orphan-score nil
1170   "*All orphans get this score added.  Set in the score file."
1171   :group 'gnus-score-default
1172   :type '(choice (const nil)
1173                  integer))
1174
1175 (defcustom gnus-summary-save-parts-default-mime "image/.*"
1176   "*A regexp to match MIME parts when saving multiple parts of a
1177 message with `gnus-summary-save-parts' (\\<gnus-summary-mode-map>\\[gnus-summary-save-parts]).
1178 This regexp will be used by default when prompting the user for which
1179 type of files to save."
1180   :group 'gnus-summary
1181   :type 'regexp)
1182
1183 (defcustom gnus-read-all-available-headers nil
1184   "Whether Gnus should parse all headers made available to it.
1185 This is mostly relevant for slow back ends where the user may
1186 wish to widen the summary buffer to include all headers
1187 that were fetched.  Say, for nnultimate groups."
1188   :version "22.1"
1189   :group 'gnus-summary
1190   :type '(choice boolean regexp))
1191
1192 (defcustom gnus-summary-muttprint-program "muttprint"
1193   "Command (and optional arguments) used to run Muttprint."
1194   :version "22.1"
1195   :group 'gnus-summary
1196   :type 'string)
1197
1198 (defcustom gnus-article-loose-mime t
1199   "If non-nil, don't require MIME-Version header.
1200 Some brain-damaged MUA/MTA, e.g. Lotus Domino 5.0.6 clients, does not
1201 supply the MIME-Version header or deliberately strip it from the mail.
1202 If non-nil (the default), Gnus will treat some articles as MIME
1203 even if the MIME-Version header is missing."
1204   :version "22.1"
1205   :type 'boolean
1206   :group 'gnus-article-mime)
1207
1208 (defcustom gnus-article-emulate-mime t
1209   "If non-nil, use MIME emulation for uuencode and the like.
1210 This means that Gnus will search message bodies for text that look
1211 like uuencoded bits, yEncoded bits, and so on, and present that using
1212 the normal Gnus MIME machinery."
1213   :version "22.1"
1214   :type 'boolean
1215   :group 'gnus-article-mime)
1216
1217 ;;; Internal variables
1218
1219 (defvar gnus-summary-display-cache nil)
1220 (defvar gnus-article-mime-handles nil)
1221 (defvar gnus-article-decoded-p nil)
1222 (defvar gnus-article-charset nil)
1223 (defvar gnus-article-ignored-charsets nil)
1224 (defvar gnus-scores-exclude-files nil)
1225 (defvar gnus-page-broken nil)
1226
1227 (defvar gnus-original-article nil)
1228 (defvar gnus-article-internal-prepare-hook nil)
1229 (defvar gnus-newsgroup-process-stack nil)
1230
1231 (defvar gnus-thread-indent-array nil)
1232 (defvar gnus-thread-indent-array-level gnus-thread-indent-level)
1233 (defvar gnus-sort-gathered-threads-function 'gnus-thread-sort-by-number
1234   "Function called to sort the articles within a thread after it has been gathered together.")
1235
1236 (defvar gnus-summary-save-parts-type-history nil)
1237 (defvar gnus-summary-save-parts-last-directory mm-default-directory)
1238
1239 ;; Avoid highlighting in kill files.
1240 (defvar gnus-summary-inhibit-highlight nil)
1241 (defvar gnus-newsgroup-selected-overlay nil)
1242 (defvar gnus-inhibit-limiting nil)
1243 (defvar gnus-newsgroup-adaptive-score-file nil)
1244 (defvar gnus-current-score-file nil)
1245 (defvar gnus-current-move-group nil)
1246 (defvar gnus-current-copy-group nil)
1247 (defvar gnus-current-crosspost-group nil)
1248 (defvar gnus-newsgroup-display nil)
1249
1250 (defvar gnus-newsgroup-dependencies nil)
1251 (defvar gnus-newsgroup-adaptive nil)
1252 (defvar gnus-summary-display-article-function nil)
1253 (defvar gnus-summary-highlight-line-function nil
1254   "Function called after highlighting a summary line.")
1255
1256 (defvar gnus-summary-line-format-alist
1257   `((?N ,(macroexpand '(mail-header-number gnus-tmp-header)) ?d)
1258     (?S ,(macroexpand '(mail-header-subject gnus-tmp-header)) ?s)
1259     (?s gnus-tmp-subject-or-nil ?s)
1260     (?n gnus-tmp-name ?s)
1261     (?A (car (cdr (funcall gnus-extract-address-components gnus-tmp-from)))
1262         ?s)
1263     (?a (or (car (funcall gnus-extract-address-components gnus-tmp-from))
1264             gnus-tmp-from) ?s)
1265     (?F gnus-tmp-from ?s)
1266     (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s)
1267     (?D ,(macroexpand '(mail-header-date gnus-tmp-header)) ?s)
1268     (?d (gnus-dd-mmm (mail-header-date gnus-tmp-header)) ?s)
1269     (?o (gnus-date-iso8601 (mail-header-date gnus-tmp-header)) ?s)
1270     (?M ,(macroexpand '(mail-header-id gnus-tmp-header)) ?s)
1271     (?r ,(macroexpand '(mail-header-references gnus-tmp-header)) ?s)
1272     (?c (or (mail-header-chars gnus-tmp-header) 0) ?d)
1273     (?k (gnus-summary-line-message-size gnus-tmp-header) ?s)
1274     (?L gnus-tmp-lines ?s)
1275     (?O gnus-tmp-downloaded ?c)
1276     (?I gnus-tmp-indentation ?s)
1277     (?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s)
1278     (?R gnus-tmp-replied ?c)
1279     (?\[ gnus-tmp-opening-bracket ?c)
1280     (?\] gnus-tmp-closing-bracket ?c)
1281     (?\> (make-string gnus-tmp-level ? ) ?s)
1282     (?\< (make-string (max 0 (- 20 gnus-tmp-level)) ? ) ?s)
1283     (?i gnus-tmp-score ?d)
1284     (?z gnus-tmp-score-char ?c)
1285     (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d)
1286     (?U gnus-tmp-unread ?c)
1287     (?f (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header gnus-tmp-from)
1288         ?s)
1289     (?t (gnus-summary-number-of-articles-in-thread
1290          (and (boundp 'thread) (car thread)) gnus-tmp-level)
1291         ?d)
1292     (?e (gnus-summary-number-of-articles-in-thread
1293          (and (boundp 'thread) (car thread)) gnus-tmp-level t)
1294         ?c)
1295     (?u gnus-tmp-user-defined ?s)
1296     (?P (gnus-pick-line-number) ?d)
1297     (?B gnus-tmp-thread-tree-header-string ?s)
1298     (user-date (gnus-user-date
1299                 ,(macroexpand '(mail-header-date gnus-tmp-header))) ?s))
1300   "An alist of format specifications that can appear in summary lines.
1301 These are paired with what variables they correspond with, along with
1302 the type of the variable (string, integer, character, etc).")
1303
1304 (defvar gnus-summary-dummy-line-format-alist
1305   `((?S gnus-tmp-subject ?s)
1306     (?N gnus-tmp-number ?d)
1307     (?u gnus-tmp-user-defined ?s)))
1308
1309 (defvar gnus-summary-mode-line-format-alist
1310   `((?G gnus-tmp-group-name ?s)
1311     (?g (gnus-short-group-name gnus-tmp-group-name) ?s)
1312     (?p (gnus-group-real-name gnus-tmp-group-name) ?s)
1313     (?A gnus-tmp-article-number ?d)
1314     (?Z gnus-tmp-unread-and-unselected ?s)
1315     (?V gnus-version ?s)
1316     (?U gnus-tmp-unread-and-unticked ?d)
1317     (?S gnus-tmp-subject ?s)
1318     (?e gnus-tmp-unselected ?d)
1319     (?u gnus-tmp-user-defined ?s)
1320     (?d (length gnus-newsgroup-dormant) ?d)
1321     (?t (length gnus-newsgroup-marked) ?d)
1322     (?h (length gnus-newsgroup-spam-marked) ?d)
1323     (?r (length gnus-newsgroup-reads) ?d)
1324     (?z (gnus-summary-article-score gnus-tmp-article-number) ?d)
1325     (?E gnus-newsgroup-expunged-tally ?d)
1326     (?s (gnus-current-score-file-nondirectory) ?s)))
1327
1328 (defvar gnus-last-search-regexp nil
1329   "Default regexp for article search command.")
1330
1331 (defvar gnus-last-shell-command nil
1332   "Default shell command on article.")
1333
1334 (defvar gnus-newsgroup-agentized nil
1335   "Locally bound in each summary buffer to indicate whether the server has been agentized.")
1336 (defvar gnus-newsgroup-begin nil)
1337 (defvar gnus-newsgroup-end nil)
1338 (defvar gnus-newsgroup-last-rmail nil)
1339 (defvar gnus-newsgroup-last-mail nil)
1340 (defvar gnus-newsgroup-last-folder nil)
1341 (defvar gnus-newsgroup-last-file nil)
1342 (defvar gnus-newsgroup-last-directory nil)
1343 (defvar gnus-newsgroup-auto-expire nil)
1344 (defvar gnus-newsgroup-active nil)
1345
1346 (defvar gnus-newsgroup-data nil)
1347 (defvar gnus-newsgroup-data-reverse nil)
1348 (defvar gnus-newsgroup-limit nil)
1349 (defvar gnus-newsgroup-limits nil)
1350 (defvar gnus-summary-use-undownloaded-faces nil)
1351
1352 (defvar gnus-newsgroup-unreads nil
1353   "Sorted list of unread articles in the current newsgroup.")
1354
1355 (defvar gnus-newsgroup-unselected nil
1356   "Sorted list of unselected unread articles in the current newsgroup.")
1357
1358 (defvar gnus-newsgroup-reads nil
1359   "Alist of read articles and article marks in the current newsgroup.")
1360
1361 (defvar gnus-newsgroup-expunged-tally nil)
1362
1363 (defvar gnus-newsgroup-marked nil
1364   "Sorted list of ticked articles in the current newsgroup (a subset of unread art).")
1365
1366 (defvar gnus-newsgroup-spam-marked nil
1367   "List of ranges of articles that have been marked as spam.")
1368
1369 (defvar gnus-newsgroup-killed nil
1370   "List of ranges of articles that have been through the scoring process.")
1371
1372 (defvar gnus-newsgroup-cached nil
1373   "Sorted list of articles that come from the article cache.")
1374
1375 (defvar gnus-newsgroup-saved nil
1376   "List of articles that have been saved.")
1377
1378 (defvar gnus-newsgroup-kill-headers nil)
1379
1380 (defvar gnus-newsgroup-replied nil
1381   "List of articles that have been replied to in the current newsgroup.")
1382
1383 (defvar gnus-newsgroup-forwarded nil
1384   "List of articles that have been forwarded in the current newsgroup.")
1385
1386 (defvar gnus-newsgroup-recent nil
1387   "List of articles that have are recent in the current newsgroup.")
1388
1389 (defvar gnus-newsgroup-expirable nil
1390   "Sorted list of articles in the current newsgroup that can be expired.")
1391
1392 (defvar gnus-newsgroup-processable nil
1393   "List of articles in the current newsgroup that can be processed.")
1394
1395 (defvar gnus-newsgroup-downloadable nil
1396   "Sorted list of articles in the current newsgroup that can be processed.")
1397
1398 (defvar gnus-newsgroup-unfetched nil
1399   "Sorted list of articles in the current newsgroup whose headers have
1400 not been fetched into the agent.
1401
1402 This list will always be a subset of gnus-newsgroup-undownloaded.")
1403
1404 (defvar gnus-newsgroup-undownloaded nil
1405   "List of articles in the current newsgroup that haven't been downloaded.")
1406
1407 (defvar gnus-newsgroup-unsendable nil
1408   "List of articles in the current newsgroup that won't be sent.")
1409
1410 (defvar gnus-newsgroup-bookmarks nil
1411   "List of articles in the current newsgroup that have bookmarks.")
1412
1413 (defvar gnus-newsgroup-dormant nil
1414   "Sorted list of dormant articles in the current newsgroup.")
1415
1416 (defvar gnus-newsgroup-unseen nil
1417   "List of unseen articles in the current newsgroup.")
1418
1419 (defvar gnus-newsgroup-seen nil
1420   "Range of seen articles in the current newsgroup.")
1421
1422 (defvar gnus-newsgroup-articles nil
1423   "List of articles in the current newsgroup.")
1424
1425 (defvar gnus-newsgroup-scored nil
1426   "List of scored articles in the current newsgroup.")
1427
1428 (defvar gnus-newsgroup-headers nil
1429   "List of article headers in the current newsgroup.")
1430
1431 (defvar gnus-newsgroup-threads nil)
1432
1433 (defvar gnus-newsgroup-prepared nil
1434   "Whether the current group has been prepared properly.")
1435
1436 (defvar gnus-newsgroup-ancient nil
1437   "List of `gnus-fetch-old-headers' articles in the current newsgroup.")
1438
1439 (defvar gnus-newsgroup-sparse nil)
1440
1441 (defvar gnus-current-article nil)
1442 (defvar gnus-article-current nil)
1443 (defvar gnus-current-headers nil)
1444 (defvar gnus-have-all-headers nil)
1445 (defvar gnus-last-article nil)
1446 (defvar gnus-newsgroup-history nil)
1447 (defvar gnus-newsgroup-charset nil)
1448 (defvar gnus-newsgroup-ephemeral-charset nil)
1449 (defvar gnus-newsgroup-ephemeral-ignored-charsets nil)
1450
1451 (defvar gnus-article-before-search nil)
1452
1453 (defvar gnus-summary-local-variables
1454   '(gnus-newsgroup-name
1455     gnus-newsgroup-begin gnus-newsgroup-end
1456     gnus-newsgroup-last-rmail gnus-newsgroup-last-mail
1457     gnus-newsgroup-last-folder gnus-newsgroup-last-file
1458     gnus-newsgroup-last-directory
1459     gnus-newsgroup-auto-expire gnus-newsgroup-unreads
1460     gnus-newsgroup-unselected gnus-newsgroup-marked
1461     gnus-newsgroup-spam-marked
1462     gnus-newsgroup-reads gnus-newsgroup-saved
1463     gnus-newsgroup-replied gnus-newsgroup-forwarded
1464     gnus-newsgroup-recent
1465     gnus-newsgroup-expirable
1466     gnus-newsgroup-processable gnus-newsgroup-killed
1467     gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
1468     gnus-newsgroup-unfetched
1469     gnus-newsgroup-unsendable gnus-newsgroup-unseen
1470     gnus-newsgroup-seen gnus-newsgroup-articles
1471     gnus-newsgroup-bookmarks gnus-newsgroup-dormant
1472     gnus-newsgroup-headers gnus-newsgroup-threads
1473     gnus-newsgroup-prepared gnus-summary-highlight-line-function
1474     gnus-current-article gnus-current-headers gnus-have-all-headers
1475     gnus-last-article gnus-article-internal-prepare-hook
1476     gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay
1477     gnus-newsgroup-scored gnus-newsgroup-kill-headers
1478     gnus-thread-expunge-below
1479     gnus-score-alist gnus-current-score-file
1480     (gnus-summary-expunge-below . global)
1481     (gnus-summary-mark-below . global)
1482     (gnus-orphan-score . global)
1483     gnus-newsgroup-active gnus-scores-exclude-files
1484     gnus-newsgroup-history gnus-newsgroup-ancient
1485     gnus-newsgroup-sparse gnus-newsgroup-process-stack
1486     (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
1487     gnus-newsgroup-adaptive-score-file (gnus-reffed-article-number . -1)
1488     (gnus-newsgroup-expunged-tally . 0)
1489     gnus-cache-removable-articles gnus-newsgroup-cached
1490     gnus-newsgroup-data gnus-newsgroup-data-reverse
1491     gnus-newsgroup-limit gnus-newsgroup-limits
1492     gnus-newsgroup-charset gnus-newsgroup-display
1493     gnus-summary-use-undownloaded-faces)
1494   "Variables that are buffer-local to the summary buffers.")
1495
1496 (defvar gnus-newsgroup-variables nil
1497   "A list of variables that have separate values in different newsgroups.
1498 A list of newsgroup (summary buffer) local variables, or cons of
1499 variables and their default expressions to be evalled (when the default
1500 values are not nil), that should be made global while the summary buffer
1501 is active.
1502
1503 Note: The default expressions will be evaluated (using function `eval')
1504 before assignment to the local variable rather than just assigned to it.
1505 If the default expression is the symbol `global', that symbol will not
1506 be evaluated but the global value of the local variable will be used
1507 instead.
1508
1509 These variables can be used to set variables in the group parameters
1510 while still allowing them to affect operations done in other buffers.
1511 For example:
1512
1513 \(setq gnus-newsgroup-variables
1514      '(message-use-followup-to
1515        (gnus-visible-headers .
1516          \"^From:\\\\|^Newsgroups:\\\\|^Subject:\\\\|^Date:\\\\|^To:\")))
1517 ")
1518
1519 ;; Byte-compiler warning.
1520 (eval-when-compile
1521   ;; Bind features so that require will believe that gnus-sum has
1522   ;; already been loaded (avoids infinite recursion)
1523   (let ((features (cons 'gnus-sum features)))
1524     ;; Several of the declarations in gnus-sum are needed to load the
1525     ;; following files. Right now, these definitions have been
1526     ;; compiled but not defined (evaluated).  We could either do a
1527     ;; eval-and-compile about all of the declarations or evaluate the
1528     ;; source file.
1529     (if (boundp 'gnus-newsgroup-variables)
1530         nil
1531       (load "gnus-sum.el" t t t))
1532     (require 'gnus)
1533     (require 'gnus-art)))
1534
1535 ;; MIME stuff.
1536
1537 (defvar gnus-decode-encoded-word-methods
1538   '(mail-decode-encoded-word-string)
1539   "List of methods used to decode encoded words.
1540
1541 This variable is a list of FUNCTION or (REGEXP . FUNCTION).  If item
1542 is FUNCTION, FUNCTION will be apply to all newsgroups.  If item is a
1543 \(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups
1544 whose names match REGEXP.
1545
1546 For example:
1547 \((\"chinese\" . gnus-decode-encoded-word-string-by-guess)
1548  mail-decode-encoded-word-string
1549  (\"chinese\" . rfc1843-decode-string))")
1550
1551 (defvar gnus-decode-encoded-word-methods-cache nil)
1552
1553 (defun gnus-multi-decode-encoded-word-string (string)
1554   "Apply the functions from `gnus-encoded-word-methods' that match."
1555   (unless (and gnus-decode-encoded-word-methods-cache
1556                (eq gnus-newsgroup-name
1557                    (car gnus-decode-encoded-word-methods-cache)))
1558     (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
1559     (mapcar (lambda (x)
1560               (if (symbolp x)
1561                   (nconc gnus-decode-encoded-word-methods-cache (list x))
1562                 (if (and gnus-newsgroup-name
1563                          (string-match (car x) gnus-newsgroup-name))
1564                     (nconc gnus-decode-encoded-word-methods-cache
1565                            (list (cdr x))))))
1566             gnus-decode-encoded-word-methods))
1567   (let ((xlist gnus-decode-encoded-word-methods-cache))
1568     (pop xlist)
1569     (while xlist
1570       (setq string (funcall (pop xlist) string))))
1571   string)
1572
1573 ;; Subject simplification.
1574
1575 (defun gnus-simplify-whitespace (str)
1576   "Remove excessive whitespace from STR."
1577   ;; Multiple spaces.
1578   (while (string-match "[ \t][ \t]+" str)
1579     (setq str (concat (substring str 0 (match-beginning 0))
1580                         " "
1581                         (substring str (match-end 0)))))
1582   ;; Leading spaces.
1583   (when (string-match "^[ \t]+" str)
1584     (setq str (substring str (match-end 0))))
1585   ;; Trailing spaces.
1586   (when (string-match "[ \t]+$" str)
1587     (setq str (substring str 0 (match-beginning 0))))
1588   str)
1589
1590 (defun gnus-simplify-all-whitespace (str)
1591   "Remove all whitespace from STR."
1592   (while (string-match "[ \t\n]+" str)
1593     (setq str (replace-match "" nil nil str)))
1594   str)
1595
1596 (defsubst gnus-simplify-subject-re (subject)
1597   "Remove \"Re:\" from subject lines."
1598   (if (string-match message-subject-re-regexp subject)
1599       (substring subject (match-end 0))
1600     subject))
1601
1602 (defun gnus-simplify-subject (subject &optional re-only)
1603   "Remove `Re:' and words in parentheses.
1604 If RE-ONLY is non-nil, strip leading `Re:'s only."
1605   (let ((case-fold-search t))           ;Ignore case.
1606     ;; Remove `Re:', `Re^N:', `Re(n)', and `Re[n]:'.
1607     (when (string-match "\\`\\(re\\([[(^][0-9]+[])]?\\)?:[ \t]*\\)+" subject)
1608       (setq subject (substring subject (match-end 0))))
1609     ;; Remove uninteresting prefixes.
1610     (when (and (not re-only)
1611                gnus-simplify-ignored-prefixes
1612                (string-match gnus-simplify-ignored-prefixes subject))
1613       (setq subject (substring subject (match-end 0))))
1614     ;; Remove words in parentheses from end.
1615     (unless re-only
1616       (while (string-match "[ \t\n]*([^()]*)[ \t\n]*\\'" subject)
1617         (setq subject (substring subject 0 (match-beginning 0)))))
1618     ;; Return subject string.
1619     subject))
1620
1621 ;; Remove any leading "re:"s, any trailing paren phrases, and simplify
1622 ;; all whitespace.
1623 (defsubst gnus-simplify-buffer-fuzzy-step (regexp &optional newtext)
1624   (goto-char (point-min))
1625   (while (re-search-forward regexp nil t)
1626     (replace-match (or newtext ""))))
1627
1628 (defun gnus-simplify-buffer-fuzzy ()
1629   "Simplify string in the buffer fuzzily.
1630 The string in the accessible portion of the current buffer is simplified.
1631 It is assumed to be a single-line subject.
1632 Whitespace is generally cleaned up, and miscellaneous leading/trailing
1633 matter is removed.  Additional things can be deleted by setting
1634 `gnus-simplify-subject-fuzzy-regexp'."
1635   (let ((case-fold-search t)
1636         (modified-tick))
1637     (gnus-simplify-buffer-fuzzy-step "\t" " ")
1638
1639     (while (not (eq modified-tick (buffer-modified-tick)))
1640       (setq modified-tick (buffer-modified-tick))
1641       (cond
1642        ((listp gnus-simplify-subject-fuzzy-regexp)
1643         (mapcar 'gnus-simplify-buffer-fuzzy-step
1644                 gnus-simplify-subject-fuzzy-regexp))
1645        (gnus-simplify-subject-fuzzy-regexp
1646         (gnus-simplify-buffer-fuzzy-step gnus-simplify-subject-fuzzy-regexp)))
1647       (gnus-simplify-buffer-fuzzy-step "^ *\\[[-+?*!][-+?*!]\\] *")
1648       (gnus-simplify-buffer-fuzzy-step
1649        "^ *\\(re\\|fw\\|fwd\\)[[{(^0-9]*[])}]?[:;] *")
1650       (gnus-simplify-buffer-fuzzy-step "^[[].*:\\( .*\\)[]]$" "\\1"))
1651
1652     (gnus-simplify-buffer-fuzzy-step " *[[{(][^()\n]*[]})] *$")
1653     (gnus-simplify-buffer-fuzzy-step "  +" " ")
1654     (gnus-simplify-buffer-fuzzy-step " $")
1655     (gnus-simplify-buffer-fuzzy-step "^ +")))
1656
1657 (defun gnus-simplify-subject-fuzzy (subject)
1658   "Simplify a subject string fuzzily.
1659 See `gnus-simplify-buffer-fuzzy' for details."
1660   (save-excursion
1661     (gnus-set-work-buffer)
1662     (let ((case-fold-search t))
1663       ;; Remove uninteresting prefixes.
1664       (when (and gnus-simplify-ignored-prefixes
1665                  (string-match gnus-simplify-ignored-prefixes subject))
1666         (setq subject (substring subject (match-end 0))))
1667       (insert subject)
1668       (inline (gnus-simplify-buffer-fuzzy))
1669       (buffer-string))))
1670
1671 (defsubst gnus-simplify-subject-fully (subject)
1672   "Simplify a subject string according to `gnus-summary-gather-subject-limit'."
1673   (cond
1674    (gnus-simplify-subject-functions
1675     (gnus-map-function gnus-simplify-subject-functions subject))
1676    ((null gnus-summary-gather-subject-limit)
1677     (gnus-simplify-subject-re subject))
1678    ((eq gnus-summary-gather-subject-limit 'fuzzy)
1679     (gnus-simplify-subject-fuzzy subject))
1680    ((numberp gnus-summary-gather-subject-limit)
1681     (gnus-limit-string (gnus-simplify-subject-re subject)
1682                        gnus-summary-gather-subject-limit))
1683    (t
1684     subject)))
1685
1686 (defsubst gnus-subject-equal (s1 s2 &optional simple-first)
1687   "Check whether two subjects are equal.
1688 If optional argument SIMPLE-FIRST is t, first argument is already
1689 simplified."
1690   (cond
1691    ((null simple-first)
1692     (equal (gnus-simplify-subject-fully s1)
1693            (gnus-simplify-subject-fully s2)))
1694    (t
1695     (equal s1
1696            (gnus-simplify-subject-fully s2)))))
1697
1698 (defun gnus-summary-bubble-group ()
1699   "Increase the score of the current group.
1700 This is a handy function to add to `gnus-summary-exit-hook' to
1701 increase the score of each group you read."
1702   (gnus-group-add-score gnus-newsgroup-name))
1703
1704 \f
1705 ;;;
1706 ;;; Gnus summary mode
1707 ;;;
1708
1709 (put 'gnus-summary-mode 'mode-class 'special)
1710
1711 (defvar gnus-article-commands-menu)
1712
1713 ;; Non-orthogonal keys
1714
1715 (gnus-define-keys gnus-summary-mode-map
1716   " " gnus-summary-next-page
1717   "\177" gnus-summary-prev-page
1718   [delete] gnus-summary-prev-page
1719   [backspace] gnus-summary-prev-page
1720   "\r" gnus-summary-scroll-up
1721   "\M-\r" gnus-summary-scroll-down
1722   "n" gnus-summary-next-unread-article
1723   "p" gnus-summary-prev-unread-article
1724   "N" gnus-summary-next-article
1725   "P" gnus-summary-prev-article
1726   "\M-\C-n" gnus-summary-next-same-subject
1727   "\M-\C-p" gnus-summary-prev-same-subject
1728   "\M-n" gnus-summary-next-unread-subject
1729   "\M-p" gnus-summary-prev-unread-subject
1730   "." gnus-summary-first-unread-article
1731   "," gnus-summary-best-unread-article
1732   "\M-s" gnus-summary-search-article-forward
1733   "\M-r" gnus-summary-search-article-backward
1734   "\M-S" gnus-summary-repeat-search-article-forward
1735   "\M-R" gnus-summary-repeat-search-article-backward
1736   "<" gnus-summary-beginning-of-article
1737   ">" gnus-summary-end-of-article
1738   "j" gnus-summary-goto-article
1739   "^" gnus-summary-refer-parent-article
1740   "\M-^" gnus-summary-refer-article
1741   "u" gnus-summary-tick-article-forward
1742   "!" gnus-summary-tick-article-forward
1743   "U" gnus-summary-tick-article-backward
1744   "d" gnus-summary-mark-as-read-forward
1745   "D" gnus-summary-mark-as-read-backward
1746   "E" gnus-summary-mark-as-expirable
1747   "\M-u" gnus-summary-clear-mark-forward
1748   "\M-U" gnus-summary-clear-mark-backward
1749   "k" gnus-summary-kill-same-subject-and-select
1750   "\C-k" gnus-summary-kill-same-subject
1751   "\M-\C-k" gnus-summary-kill-thread
1752   "\M-\C-l" gnus-summary-lower-thread
1753   "e" gnus-summary-edit-article
1754   "#" gnus-summary-mark-as-processable
1755   "\M-#" gnus-summary-unmark-as-processable
1756   "\M-\C-t" gnus-summary-toggle-threads
1757   "\M-\C-s" gnus-summary-show-thread
1758   "\M-\C-h" gnus-summary-hide-thread
1759   "\M-\C-f" gnus-summary-next-thread
1760   "\M-\C-b" gnus-summary-prev-thread
1761   [(meta down)] gnus-summary-next-thread
1762   [(meta up)] gnus-summary-prev-thread
1763   "\M-\C-u" gnus-summary-up-thread
1764   "\M-\C-d" gnus-summary-down-thread
1765   "&" gnus-summary-execute-command
1766   "c" gnus-summary-catchup-and-exit
1767   "\C-w" gnus-summary-mark-region-as-read
1768   "\C-t" gnus-summary-toggle-truncation
1769   "?" gnus-summary-mark-as-dormant
1770   "\C-c\M-\C-s" gnus-summary-limit-include-expunged
1771   "\C-c\C-s\C-n" gnus-summary-sort-by-number
1772   "\C-c\C-s\C-l" gnus-summary-sort-by-lines
1773   "\C-c\C-s\C-c" gnus-summary-sort-by-chars
1774   "\C-c\C-s\C-a" gnus-summary-sort-by-author
1775   "\C-c\C-s\C-t" gnus-summary-sort-by-recipient
1776   "\C-c\C-s\C-s" gnus-summary-sort-by-subject
1777   "\C-c\C-s\C-d" gnus-summary-sort-by-date
1778   "\C-c\C-s\C-i" gnus-summary-sort-by-score
1779   "\C-c\C-s\C-o" gnus-summary-sort-by-original
1780   "\C-c\C-s\C-r" gnus-summary-sort-by-random
1781   "=" gnus-summary-expand-window
1782   "\C-x\C-s" gnus-summary-reselect-current-group
1783   "\M-g" gnus-summary-rescan-group
1784   "w" gnus-summary-stop-page-breaking
1785   "\C-c\C-r" gnus-summary-caesar-message
1786   "f" gnus-summary-followup
1787   "F" gnus-summary-followup-with-original
1788   "C" gnus-summary-cancel-article
1789   "r" gnus-summary-reply
1790   "R" gnus-summary-reply-with-original
1791   "\C-c\C-f" gnus-summary-mail-forward
1792   "o" gnus-summary-save-article
1793   "\C-o" gnus-summary-save-article-mail
1794   "|" gnus-summary-pipe-output
1795   "\M-k" gnus-summary-edit-local-kill
1796   "\M-K" gnus-summary-edit-global-kill
1797   ;; "V" gnus-version
1798   "\C-c\C-d" gnus-summary-describe-group
1799   "q" gnus-summary-exit
1800   "Q" gnus-summary-exit-no-update
1801   "\C-c\C-i" gnus-info-find-node
1802   gnus-mouse-2 gnus-mouse-pick-article
1803   [follow-link] mouse-face
1804   "m" gnus-summary-mail-other-window
1805   "a" gnus-summary-post-news
1806   "i" gnus-summary-news-other-window
1807   "x" gnus-summary-limit-to-unread
1808   "s" gnus-summary-isearch-article
1809   "t" gnus-summary-toggle-header
1810   "g" gnus-summary-show-article
1811   "l" gnus-summary-goto-last-article
1812   "\C-c\C-v\C-v" gnus-uu-decode-uu-view
1813   "\C-d" gnus-summary-enter-digest-group
1814   "\M-\C-d" gnus-summary-read-document
1815   "\M-\C-e" gnus-summary-edit-parameters
1816   "\M-\C-a" gnus-summary-customize-parameters
1817   "\C-c\C-b" gnus-bug
1818   "*" gnus-cache-enter-article
1819   "\M-*" gnus-cache-remove-article
1820   "\M-&" gnus-summary-universal-argument
1821   "\C-l" gnus-recenter
1822   "I" gnus-summary-increase-score
1823   "L" gnus-summary-lower-score
1824   "\M-i" gnus-symbolic-argument
1825   "h" gnus-summary-select-article-buffer
1826
1827   "b" gnus-article-view-part
1828   "\M-t" gnus-summary-toggle-display-buttonized
1829
1830   "V" gnus-summary-score-map
1831   "X" gnus-uu-extract-map
1832   "S" gnus-summary-send-map)
1833
1834 ;; Sort of orthogonal keymap
1835 (gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
1836   "t" gnus-summary-tick-article-forward
1837   "!" gnus-summary-tick-article-forward
1838   "d" gnus-summary-mark-as-read-forward
1839   "r" gnus-summary-mark-as-read-forward
1840   "c" gnus-summary-clear-mark-forward
1841   " " gnus-summary-clear-mark-forward
1842   "e" gnus-summary-mark-as-expirable
1843   "x" gnus-summary-mark-as-expirable
1844   "?" gnus-summary-mark-as-dormant
1845   "b" gnus-summary-set-bookmark
1846   "B" gnus-summary-remove-bookmark
1847   "#" gnus-summary-mark-as-processable
1848   "\M-#" gnus-summary-unmark-as-processable
1849   "S" gnus-summary-limit-include-expunged
1850   "C" gnus-summary-catchup
1851   "H" gnus-summary-catchup-to-here
1852   "h" gnus-summary-catchup-from-here
1853   "\C-c" gnus-summary-catchup-all
1854   "k" gnus-summary-kill-same-subject-and-select
1855   "K" gnus-summary-kill-same-subject
1856   "P" gnus-uu-mark-map)
1857
1858 (gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
1859   "c" gnus-summary-clear-above
1860   "u" gnus-summary-tick-above
1861   "m" gnus-summary-mark-above
1862   "k" gnus-summary-kill-below)
1863
1864 (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
1865   "/" gnus-summary-limit-to-subject
1866   "n" gnus-summary-limit-to-articles
1867   "b" gnus-summary-limit-to-bodies
1868   "h" gnus-summary-limit-to-headers
1869   "w" gnus-summary-pop-limit
1870   "s" gnus-summary-limit-to-subject
1871   "a" gnus-summary-limit-to-author
1872   "u" gnus-summary-limit-to-unread
1873   "m" gnus-summary-limit-to-marks
1874   "M" gnus-summary-limit-exclude-marks
1875   "v" gnus-summary-limit-to-score
1876   "*" gnus-summary-limit-include-cached
1877   "D" gnus-summary-limit-include-dormant
1878   "T" gnus-summary-limit-include-thread
1879   "d" gnus-summary-limit-exclude-dormant
1880   "t" gnus-summary-limit-to-age
1881   "." gnus-summary-limit-to-unseen
1882   "x" gnus-summary-limit-to-extra
1883   "p" gnus-summary-limit-to-display-predicate
1884   "E" gnus-summary-limit-include-expunged
1885   "c" gnus-summary-limit-exclude-childless-dormant
1886   "C" gnus-summary-limit-mark-excluded-as-read
1887   "o" gnus-summary-insert-old-articles
1888   "N" gnus-summary-insert-new-articles
1889   "S" gnus-summary-limit-to-singletons
1890   "r" gnus-summary-limit-to-replied
1891   "R" gnus-summary-limit-to-recipient)
1892
1893 (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
1894   "n" gnus-summary-next-unread-article
1895   "p" gnus-summary-prev-unread-article
1896   "N" gnus-summary-next-article
1897   "P" gnus-summary-prev-article
1898   "\C-n" gnus-summary-next-same-subject
1899   "\C-p" gnus-summary-prev-same-subject
1900   "\M-n" gnus-summary-next-unread-subject
1901   "\M-p" gnus-summary-prev-unread-subject
1902   "f" gnus-summary-first-unread-article
1903   "b" gnus-summary-best-unread-article
1904   "j" gnus-summary-goto-article
1905   "g" gnus-summary-goto-subject
1906   "l" gnus-summary-goto-last-article
1907   "o" gnus-summary-pop-article)
1908
1909 (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
1910   "k" gnus-summary-kill-thread
1911   "l" gnus-summary-lower-thread
1912   "i" gnus-summary-raise-thread
1913   "T" gnus-summary-toggle-threads
1914   "t" gnus-summary-rethread-current
1915   "^" gnus-summary-reparent-thread
1916   "\M-^" gnus-summary-reparent-children
1917   "s" gnus-summary-show-thread
1918   "S" gnus-summary-show-all-threads
1919   "h" gnus-summary-hide-thread
1920   "H" gnus-summary-hide-all-threads
1921   "n" gnus-summary-next-thread
1922   "p" gnus-summary-prev-thread
1923   "u" gnus-summary-up-thread
1924   "o" gnus-summary-top-thread
1925   "d" gnus-summary-down-thread
1926   "#" gnus-uu-mark-thread
1927   "\M-#" gnus-uu-unmark-thread)
1928
1929 (gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
1930   "g" gnus-summary-prepare
1931   "c" gnus-summary-insert-cached-articles
1932   "d" gnus-summary-insert-dormant-articles
1933   "t" gnus-summary-insert-ticked-articles)
1934
1935 (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
1936   "c" gnus-summary-catchup-and-exit
1937   "C" gnus-summary-catchup-all-and-exit
1938   "E" gnus-summary-exit-no-update
1939   "Q" gnus-summary-exit
1940   "Z" gnus-summary-exit
1941   "n" gnus-summary-catchup-and-goto-next-group
1942   "p" gnus-summary-catchup-and-goto-prev-group
1943   "R" gnus-summary-reselect-current-group
1944   "G" gnus-summary-rescan-group
1945   "N" gnus-summary-next-group
1946   "s" gnus-summary-save-newsrc
1947   "P" gnus-summary-prev-group)
1948
1949 (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
1950   " " gnus-summary-next-page
1951   "n" gnus-summary-next-page
1952   "\177" gnus-summary-prev-page
1953   [delete] gnus-summary-prev-page
1954   "p" gnus-summary-prev-page
1955   "\r" gnus-summary-scroll-up
1956   "\M-\r" gnus-summary-scroll-down
1957   "<" gnus-summary-beginning-of-article
1958   ">" gnus-summary-end-of-article
1959   "b" gnus-summary-beginning-of-article
1960   "e" gnus-summary-end-of-article
1961   "^" gnus-summary-refer-parent-article
1962   "r" gnus-summary-refer-parent-article
1963   "D" gnus-summary-enter-digest-group
1964   "R" gnus-summary-refer-references
1965   "T" gnus-summary-refer-thread
1966   "g" gnus-summary-show-article
1967   "s" gnus-summary-isearch-article
1968   "P" gnus-summary-print-article
1969   "M" gnus-mailing-list-insinuate
1970   "t" gnus-article-babel)
1971
1972 (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
1973   "b" gnus-article-add-buttons
1974   "B" gnus-article-add-buttons-to-head
1975   "o" gnus-article-treat-overstrike
1976   "e" gnus-article-emphasize
1977   "w" gnus-article-fill-cited-article
1978   "Q" gnus-article-fill-long-lines
1979   "L" gnus-article-toggle-truncate-lines
1980   "C" gnus-article-capitalize-sentences
1981   "c" gnus-article-remove-cr
1982   "q" gnus-article-de-quoted-unreadable
1983   "6" gnus-article-de-base64-unreadable
1984   "Z" gnus-article-decode-HZ
1985   "A" gnus-article-treat-ansi-sequences
1986   "h" gnus-article-wash-html
1987   "u" gnus-article-unsplit-urls
1988   "s" gnus-summary-force-verify-and-decrypt
1989   "f" gnus-article-display-x-face
1990   "l" gnus-summary-stop-page-breaking
1991   "r" gnus-summary-caesar-message
1992   "m" gnus-summary-morse-message
1993   "t" gnus-summary-toggle-header
1994   "g" gnus-treat-smiley
1995   "v" gnus-summary-verbose-headers
1996   "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
1997   "p" gnus-article-verify-x-pgp-sig
1998   "d" gnus-article-treat-dumbquotes
1999   "i" gnus-summary-idna-message)
2000
2001 (gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
2002   ;; mnemonic: deuglif*Y*
2003   "u" gnus-article-outlook-unwrap-lines
2004   "a" gnus-article-outlook-repair-attribution
2005   "c" gnus-article-outlook-rearrange-citation
2006   "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
2007
2008 (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
2009   "a" gnus-article-hide
2010   "h" gnus-article-hide-headers
2011   "b" gnus-article-hide-boring-headers
2012   "s" gnus-article-hide-signature
2013   "c" gnus-article-hide-citation
2014   "C" gnus-article-hide-citation-in-followups
2015   "l" gnus-article-hide-list-identifiers
2016   "B" gnus-article-strip-banner
2017   "P" gnus-article-hide-pem
2018   "\C-c" gnus-article-hide-citation-maybe)
2019
2020 (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
2021   "a" gnus-article-highlight
2022   "h" gnus-article-highlight-headers
2023   "c" gnus-article-highlight-citation
2024   "s" gnus-article-highlight-signature)
2025
2026 (gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
2027   "f" gnus-article-treat-fold-headers
2028   "u" gnus-article-treat-unfold-headers
2029   "n" gnus-article-treat-fold-newsgroups)
2030
2031 (gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
2032   "x" gnus-article-display-x-face
2033   "d" gnus-article-display-face
2034   "s" gnus-treat-smiley
2035   "D" gnus-article-remove-images
2036   "f" gnus-treat-from-picon
2037   "m" gnus-treat-mail-picon
2038   "n" gnus-treat-newsgroups-picon)
2039
2040 (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
2041   "w" gnus-article-decode-mime-words
2042   "c" gnus-article-decode-charset
2043   "v" gnus-mime-view-all-parts
2044   "b" gnus-article-view-part)
2045
2046 (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
2047   "z" gnus-article-date-ut
2048   "u" gnus-article-date-ut
2049   "l" gnus-article-date-local
2050   "p" gnus-article-date-english
2051   "e" gnus-article-date-lapsed
2052   "o" gnus-article-date-original
2053   "i" gnus-article-date-iso8601
2054   "s" gnus-article-date-user)
2055
2056 (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
2057   "t" gnus-article-remove-trailing-blank-lines
2058   "l" gnus-article-strip-leading-blank-lines
2059   "m" gnus-article-strip-multiple-blank-lines
2060   "a" gnus-article-strip-blank-lines
2061   "A" gnus-article-strip-all-blank-lines
2062   "s" gnus-article-strip-leading-space
2063   "e" gnus-article-strip-trailing-space
2064   "w" gnus-article-remove-leading-whitespace)
2065
2066 (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
2067   "v" gnus-version
2068   "f" gnus-summary-fetch-faq
2069   "d" gnus-summary-describe-group
2070   "h" gnus-summary-describe-briefly
2071   "i" gnus-info-find-node
2072   "c" gnus-group-fetch-charter
2073   "C" gnus-group-fetch-control)
2074
2075 (gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
2076   "e" gnus-summary-expire-articles
2077   "\M-\C-e" gnus-summary-expire-articles-now
2078   "\177" gnus-summary-delete-article
2079   [delete] gnus-summary-delete-article
2080   [backspace] gnus-summary-delete-article
2081   "m" gnus-summary-move-article
2082   "r" gnus-summary-respool-article
2083   "w" gnus-summary-edit-article
2084   "c" gnus-summary-copy-article
2085   "B" gnus-summary-crosspost-article
2086   "q" gnus-summary-respool-query
2087   "t" gnus-summary-respool-trace
2088   "i" gnus-summary-import-article
2089   "I" gnus-summary-create-article
2090   "p" gnus-summary-article-posted-p)
2091
2092 (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
2093   "o" gnus-summary-save-article
2094   "m" gnus-summary-save-article-mail
2095   "F" gnus-summary-write-article-file
2096   "r" gnus-summary-save-article-rmail
2097   "f" gnus-summary-save-article-file
2098   "b" gnus-summary-save-article-body-file
2099   "B" gnus-summary-write-article-body-file
2100   "h" gnus-summary-save-article-folder
2101   "v" gnus-summary-save-article-vm
2102   "p" gnus-summary-pipe-output
2103   "P" gnus-summary-muttprint
2104   "s" gnus-soup-add-article)
2105
2106 (gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
2107   "b" gnus-summary-display-buttonized
2108   "m" gnus-summary-repair-multipart
2109   "v" gnus-article-view-part
2110   "o" gnus-article-save-part
2111   "O" gnus-article-save-part-and-strip
2112   "r" gnus-article-replace-part
2113   "d" gnus-article-delete-part
2114   "t" gnus-article-view-part-as-type
2115   "j" gnus-article-jump-to-part
2116   "c" gnus-article-copy-part
2117   "C" gnus-article-view-part-as-charset
2118   "e" gnus-article-view-part-externally
2119   "H" gnus-article-browse-html-article
2120   "E" gnus-article-encrypt-body
2121   "i" gnus-article-inline-part
2122   "|" gnus-article-pipe-part)
2123
2124 (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
2125   "p" gnus-summary-mark-as-processable
2126   "u" gnus-summary-unmark-as-processable
2127   "U" gnus-summary-unmark-all-processable
2128   "v" gnus-uu-mark-over
2129   "s" gnus-uu-mark-series
2130   "r" gnus-uu-mark-region
2131   "g" gnus-uu-unmark-region
2132   "R" gnus-uu-mark-by-regexp
2133   "G" gnus-uu-unmark-by-regexp
2134   "t" gnus-uu-mark-thread
2135   "T" gnus-uu-unmark-thread
2136   "a" gnus-uu-mark-all
2137   "b" gnus-uu-mark-buffer
2138   "S" gnus-uu-mark-sparse
2139   "k" gnus-summary-kill-process-mark
2140   "y" gnus-summary-yank-process-mark
2141   "w" gnus-summary-save-process-mark
2142   "i" gnus-uu-invert-processable)
2143
2144 (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
2145   ;;"x" gnus-uu-extract-any
2146   "m" gnus-summary-save-parts
2147   "u" gnus-uu-decode-uu
2148   "U" gnus-uu-decode-uu-and-save
2149   "s" gnus-uu-decode-unshar
2150   "S" gnus-uu-decode-unshar-and-save
2151   "o" gnus-uu-decode-save
2152   "O" gnus-uu-decode-save
2153   "b" gnus-uu-decode-binhex
2154   "B" gnus-uu-decode-binhex
2155   "p" gnus-uu-decode-postscript
2156   "P" gnus-uu-decode-postscript-and-save)
2157
2158 (gnus-define-keys
2159     (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
2160   "u" gnus-uu-decode-uu-view
2161   "U" gnus-uu-decode-uu-and-save-view
2162   "s" gnus-uu-decode-unshar-view
2163   "S" gnus-uu-decode-unshar-and-save-view
2164   "o" gnus-uu-decode-save-view
2165   "O" gnus-uu-decode-save-view
2166   "b" gnus-uu-decode-binhex-view
2167   "B" gnus-uu-decode-binhex-view
2168   "p" gnus-uu-decode-postscript-view
2169   "P" gnus-uu-decode-postscript-and-save-view)
2170
2171 (defvar gnus-article-post-menu nil)
2172
2173 (defconst gnus-summary-menu-maxlen 20)
2174
2175 (defun gnus-summary-menu-split (menu)
2176   ;; If we have lots of elements, divide them into groups of 20
2177   ;; and make a pane (or submenu) for each one.
2178   (if (> (length menu) (/ (* gnus-summary-menu-maxlen 3) 2))
2179       (let ((menu menu) sublists next
2180             (i 1))
2181         (while menu
2182           ;; Pull off the next gnus-summary-menu-maxlen elements
2183           ;; and make them the next element of sublist.
2184           (setq next (nthcdr gnus-summary-menu-maxlen menu))
2185           (if next
2186               (setcdr (nthcdr (1- gnus-summary-menu-maxlen) menu)
2187                       nil))
2188           (setq sublists (cons (cons (format "%s ... %s" (aref (car menu) 0)
2189                                              (aref (car (last menu)) 0)) menu)
2190                                sublists))
2191           (setq i (1+ i))
2192           (setq menu next))
2193         (nreverse sublists))
2194     ;; Few elements--put them all in one pane.
2195     menu))
2196
2197 (defun gnus-summary-make-menu-bar ()
2198   (gnus-turn-off-edit-menu 'summary)
2199
2200   (unless (boundp 'gnus-summary-misc-menu)
2201
2202     (easy-menu-define
2203       gnus-summary-kill-menu gnus-summary-mode-map ""
2204       (cons
2205        "Score"
2206        (nconc
2207         (list
2208          ["Customize" gnus-score-customize t])
2209         (gnus-make-score-map 'increase)
2210         (gnus-make-score-map 'lower)
2211         '(("Mark"
2212            ["Kill below" gnus-summary-kill-below t]
2213            ["Mark above" gnus-summary-mark-above t]
2214            ["Tick above" gnus-summary-tick-above t]
2215            ["Clear above" gnus-summary-clear-above t])
2216           ["Current score" gnus-summary-current-score t]
2217           ["Set score" gnus-summary-set-score t]
2218           ["Switch current score file..." gnus-score-change-score-file t]
2219           ["Set mark below..." gnus-score-set-mark-below t]
2220           ["Set expunge below..." gnus-score-set-expunge-below t]
2221           ["Edit current score file" gnus-score-edit-current-scores t]
2222           ["Edit score file" gnus-score-edit-file t]
2223           ["Trace score" gnus-score-find-trace t]
2224           ["Find words" gnus-score-find-favourite-words t]
2225           ["Rescore buffer" gnus-summary-rescore t]
2226           ["Increase score..." gnus-summary-increase-score t]
2227           ["Lower score..." gnus-summary-lower-score t]))))
2228
2229     ;; Define both the Article menu in the summary buffer and the
2230     ;; equivalent Commands menu in the article buffer here for
2231     ;; consistency.
2232     (let ((innards
2233            `(("Hide"
2234               ["All" gnus-article-hide t]
2235               ["Headers" gnus-article-hide-headers t]
2236               ["Signature" gnus-article-hide-signature t]
2237               ["Citation" gnus-article-hide-citation t]
2238               ["List identifiers" gnus-article-hide-list-identifiers t]
2239               ["Banner" gnus-article-strip-banner t]
2240               ["Boring headers" gnus-article-hide-boring-headers t])
2241              ("Highlight"
2242               ["All" gnus-article-highlight t]
2243               ["Headers" gnus-article-highlight-headers t]
2244               ["Signature" gnus-article-highlight-signature t]
2245               ["Citation" gnus-article-highlight-citation t])
2246              ("MIME"
2247               ["Words" gnus-article-decode-mime-words t]
2248               ["Charset" gnus-article-decode-charset t]
2249               ["QP" gnus-article-de-quoted-unreadable t]
2250               ["Base64" gnus-article-de-base64-unreadable t]
2251               ["View MIME buttons" gnus-summary-display-buttonized t]
2252               ["View all" gnus-mime-view-all-parts t]
2253               ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
2254               ["Encrypt body" gnus-article-encrypt-body
2255                :active (not (gnus-group-read-only-p))
2256                ,@(if (featurep 'xemacs) nil
2257                    '(:help "Encrypt the message body on disk"))]
2258               ["Extract all parts..." gnus-summary-save-parts t]
2259               ("Multipart"
2260                ["Repair multipart" gnus-summary-repair-multipart t]
2261                ["Pipe part..." gnus-article-pipe-part t]
2262                ["Inline part" gnus-article-inline-part t]
2263                ["View part as type..." gnus-article-view-part-as-type t]
2264                ["Encrypt body" gnus-article-encrypt-body
2265                 :active (not (gnus-group-read-only-p))
2266                ,@(if (featurep 'xemacs) nil
2267                    '(:help "Encrypt the message body on disk"))]
2268                ["View part externally" gnus-article-view-part-externally t]
2269                ["View HTML parts in browser" gnus-article-browse-html-article t]
2270                ["View part with charset..." gnus-article-view-part-as-charset t]
2271                ["Copy part" gnus-article-copy-part t]
2272                ["Save part..." gnus-article-save-part t]
2273                ["View part" gnus-article-view-part t]))
2274              ("Date"
2275               ["Local" gnus-article-date-local t]
2276               ["ISO8601" gnus-article-date-iso8601 t]
2277               ["UT" gnus-article-date-ut t]
2278               ["Original" gnus-article-date-original t]
2279               ["Lapsed" gnus-article-date-lapsed t]
2280               ["User-defined" gnus-article-date-user t])
2281              ("Display"
2282               ["Remove images" gnus-article-remove-images t]
2283               ["Toggle smiley" gnus-treat-smiley t]
2284               ["Show X-Face" gnus-article-display-x-face t]