(spam-necessary-extra-headers): get the extra headers we
[gnus] / lisp / gnus-sum.el
1 ;;; gnus-sum.el --- summary mode commands for Gnus
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 ;;        Free Software Foundation, Inc.
4
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6 ;; Keywords: news
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Commentary:
26
27 ;;; Code:
28
29 (eval-when-compile
30   (require 'cl)
31   (defvar tool-bar-map))
32
33 (require 'gnus)
34 (require 'gnus-group)
35 (require 'gnus-spec)
36 (require 'gnus-range)
37 (require 'gnus-int)
38 (require 'gnus-undo)
39 (require 'gnus-util)
40 (require 'mm-decode)
41 (require 'nnoo)
42
43 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
44 (autoload 'gnus-cache-write-active "gnus-cache")
45 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
46 (autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
47 (autoload 'gnus-pick-line-number "gnus-salt" nil t)
48 (autoload 'mm-uu-dissect "mm-uu")
49 (autoload 'gnus-article-outlook-deuglify-article "deuglify"
50   "Deuglify broken Outlook (Express) articles and redisplay."
51   t)
52 (autoload 'gnus-article-outlook-unwrap-lines "deuglify" nil t)
53 (autoload 'gnus-article-outlook-repair-attribution "deuglify" nil t)
54 (autoload 'gnus-article-outlook-rearrange-citation "deuglify" nil t)
55
56 (defcustom gnus-kill-summary-on-exit t
57   "*If non-nil, kill the summary buffer when you exit from it.
58 If nil, the summary will become a \"*Dead Summary*\" buffer, and
59 it will be killed sometime later."
60   :group 'gnus-summary-exit
61   :type 'boolean)
62
63 (defcustom gnus-fetch-old-headers nil
64   "*Non-nil means that Gnus will try to build threads by grabbing old headers.
65 If an unread article in the group refers to an older, already read (or
66 just marked as read) article, the old article will not normally be
67 displayed in the Summary buffer.  If this variable is non-nil, Gnus
68 will attempt to grab the headers to the old articles, and thereby
69 build complete threads.  If it has the value `some', only enough
70 headers to connect otherwise loose threads will be displayed.  This
71 variable can also be a number.  In that case, no more than that number
72 of old headers will be fetched.  If it has the value `invisible', all
73 old headers will be fetched, but none will be displayed.
74
75 The server has to support NOV for any of this to work."
76   :group 'gnus-thread
77   :type '(choice (const :tag "off" nil)
78                  (const some)
79                  number
80                  (sexp :menu-tag "other" t)))
81
82 (defcustom gnus-refer-thread-limit 200
83   "*The number of old headers to fetch when doing \\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
84 If t, fetch all the available old headers."
85   :group 'gnus-thread
86   :type '(choice number
87                  (sexp :menu-tag "other" t)))
88
89 (defcustom gnus-summary-make-false-root 'adopt
90   "*nil means that Gnus won't gather loose threads.
91 If the root of a thread has expired or been read in a previous
92 session, the information necessary to build a complete thread has been
93 lost.  Instead of having many small sub-threads from this original thread
94 scattered all over the summary buffer, Gnus can gather them.
95
96 If non-nil, Gnus will try to gather all loose sub-threads from an
97 original thread into one large thread.
98
99 If this variable is non-nil, it should be one of `none', `adopt',
100 `dummy' or `empty'.
101
102 If this variable is `none', Gnus will not make a false root, but just
103 present the sub-threads after another.
104 If this variable is `dummy', Gnus will create a dummy root that will
105 have all the sub-threads as children.
106 If this variable is `adopt', Gnus will make one of the \"children\"
107 the parent and mark all the step-children as such.
108 If this variable is `empty', the \"children\" are printed with empty
109 subject fields.  (Or rather, they will be printed with a string
110 given by the `gnus-summary-same-subject' variable.)"
111   :group 'gnus-thread
112   :type '(choice (const :tag "off" nil)
113                  (const none)
114                  (const dummy)
115                  (const adopt)
116                  (const empty)))
117
118 (defcustom gnus-summary-make-false-root-always nil
119   "Always make a false dummy root."
120   :group 'gnus-thread
121   :type 'boolean)
122
123 (defcustom gnus-summary-gather-exclude-subject "^ *$\\|^(none)$"
124   "*A regexp to match subjects to be excluded from loose thread gathering.
125 As loose thread gathering is done on subjects only, that means that
126 there can be many false gatherings performed.  By rooting out certain
127 common subjects, gathering might become saner."
128   :group 'gnus-thread
129   :type 'regexp)
130
131 (defcustom gnus-summary-gather-subject-limit nil
132   "*Maximum length of subject comparisons when gathering loose threads.
133 Use nil to compare full subjects.  Setting this variable to a low
134 number will help gather threads that have been corrupted by
135 newsreaders chopping off subject lines, but it might also mean that
136 unrelated articles that have subject that happen to begin with the
137 same few characters will be incorrectly gathered.
138
139 If this variable is `fuzzy', Gnus will use a fuzzy algorithm when
140 comparing subjects."
141   :group 'gnus-thread
142   :type '(choice (const :tag "off" nil)
143                  (const fuzzy)
144                  (sexp :menu-tag "on" t)))
145
146 (defcustom gnus-simplify-subject-functions nil
147   "List of functions taking a string argument that simplify subjects.
148 The functions are applied recursively.
149
150 Useful functions to put in this list include:
151 `gnus-simplify-subject-re', `gnus-simplify-subject-fuzzy',
152 `gnus-simplify-whitespace', and `gnus-simplify-all-whitespace'."
153   :group 'gnus-thread
154   :type '(repeat function))
155
156 (defcustom gnus-simplify-ignored-prefixes nil
157   "*Remove matches for this regexp from subject lines when simplifying fuzzily."
158   :group 'gnus-thread
159   :type '(choice (const :tag "off" nil)
160                  regexp))
161
162 (defcustom gnus-build-sparse-threads nil
163   "*If non-nil, fill in the gaps in threads.
164 If `some', only fill in the gaps that are needed to tie loose threads
165 together.  If `more', fill in all leaf nodes that Gnus can find.  If
166 non-nil and non-`some', fill in all gaps that Gnus manages to guess."
167   :group 'gnus-thread
168   :type '(choice (const :tag "off" nil)
169                  (const some)
170                  (const more)
171                  (sexp :menu-tag "all" t)))
172
173 (defcustom gnus-summary-thread-gathering-function
174   'gnus-gather-threads-by-subject
175   "*Function used for gathering loose threads.
176 There are two pre-defined functions: `gnus-gather-threads-by-subject',
177 which only takes Subjects into consideration; and
178 `gnus-gather-threads-by-references', which compared the References
179 headers of the articles to find matches."
180   :group 'gnus-thread
181   :type '(radio (function-item gnus-gather-threads-by-subject)
182                 (function-item gnus-gather-threads-by-references)
183                 (function :tag "other")))
184
185 (defcustom gnus-summary-same-subject ""
186   "*String indicating that the current article has the same subject as the previous.
187 This variable will only be used if the value of
188 `gnus-summary-make-false-root' is `empty'."
189   :group 'gnus-summary-format
190   :type 'string)
191
192 (defcustom gnus-summary-goto-unread t
193   "*If t, many commands will go to the next unread article.
194 This applies to marking commands as well as other commands that
195 \"naturally\" select the next article, like, for instance, `SPC' at
196 the end of an article.
197
198 If nil, the marking commands do NOT go to the next unread article
199 \(they go to the next article instead).  If `never', commands that
200 usually go to the next unread article, will go to the next article,
201 whether it is read or not."
202   :group 'gnus-summary-marks
203   :link '(custom-manual "(gnus)Setting Marks")
204   :type '(choice (const :tag "off" nil)
205                  (const never)
206                  (sexp :menu-tag "on" t)))
207
208 (defcustom gnus-summary-default-score 0
209   "*Default article score level.
210 All scores generated by the score files will be added to this score.
211 If this variable is nil, scoring will be disabled."
212   :group 'gnus-score-default
213   :type '(choice (const :tag "disable")
214                  integer))
215
216 (defcustom gnus-summary-default-high-score 0
217   "*Default threshold for a high scored article.
218 An article will be highlighted as high scored if its score is greater
219 than this score."
220   :group 'gnus-score-default
221   :type 'integer)
222
223 (defcustom gnus-summary-default-low-score 0
224   "*Default threshold for a low scored article.
225 An article will be highlighted as low scored if its score is smaller
226 than this score."
227   :group 'gnus-score-default
228   :type 'integer)
229
230 (defcustom gnus-summary-zcore-fuzz 0
231   "*Fuzziness factor for the zcore in the summary buffer.
232 Articles with scores closer than this to `gnus-summary-default-score'
233 will not be marked."
234   :group 'gnus-summary-format
235   :type 'integer)
236
237 (defcustom gnus-simplify-subject-fuzzy-regexp nil
238   "*Strings to be removed when doing fuzzy matches.
239 This can either be a regular expression or list of regular expressions
240 that will be removed from subject strings if fuzzy subject
241 simplification is selected."
242   :group 'gnus-thread
243   :type '(repeat regexp))
244
245 (defcustom gnus-show-threads t
246   "*If non-nil, display threads in summary mode."
247   :group 'gnus-thread
248   :type 'boolean)
249
250 (defcustom gnus-thread-hide-subtree nil
251   "*If non-nil, hide all threads initially.
252 This can be a predicate specifier which says which threads to hide.
253 If threads are hidden, you have to run the command
254 `gnus-summary-show-thread' by hand or use `gnus-select-article-hook'
255 to expose hidden threads."
256   :group 'gnus-thread
257   :type '(radio (sexp :format "Non-nil\n"
258                       :match (lambda (widget value)
259                                (not (or (consp value) (functionp value))))
260                       :value t)
261                 (const nil)
262                 (sexp :tag "Predicate specifier" :size 0)))
263
264 (defcustom gnus-thread-hide-killed t
265   "*If non-nil, hide killed threads automatically."
266   :group 'gnus-thread
267   :type 'boolean)
268
269 (defcustom gnus-thread-ignore-subject t
270   "*If non-nil, which is the default, ignore subjects and do all threading based on the Reference header.
271 If nil, articles that have different subjects from their parents will
272 start separate threads."
273   :group 'gnus-thread
274   :type 'boolean)
275
276 (defcustom gnus-thread-operation-ignore-subject t
277   "*If non-nil, subjects will be ignored when doing thread commands.
278 This affects commands like `gnus-summary-kill-thread' and
279 `gnus-summary-lower-thread'.
280
281 If this variable is nil, articles in the same thread with different
282 subjects will not be included in the operation in question.  If this
283 variable is `fuzzy', only articles that have subjects that are fuzzily
284 equal will be included."
285   :group 'gnus-thread
286   :type '(choice (const :tag "off" nil)
287                  (const fuzzy)
288                  (sexp :tag "on" t)))
289
290 (defcustom gnus-thread-indent-level 4
291   "*Number that says how much each sub-thread should be indented."
292   :group 'gnus-thread
293   :type 'integer)
294
295 (defcustom gnus-auto-extend-newsgroup t
296   "*If non-nil, extend newsgroup forward and backward when requested."
297   :group 'gnus-summary-choose
298   :type 'boolean)
299
300 (defcustom gnus-auto-select-first t
301   "*If non-nil, select the article under point.
302 Which article this is is controlled by the `gnus-auto-select-subject'
303 variable.
304
305 If you want to prevent automatic selection of articles in some
306 newsgroups, set the variable to nil in `gnus-select-group-hook'."
307   :group 'gnus-group-select
308   :type '(choice (const :tag "none" nil)
309                  (sexp :menu-tag "first" t)))
310
311 (defcustom gnus-auto-select-subject 'unread
312   "*Says what subject to place under point when entering a group.
313
314 This variable can either be the symbols `first' (place point on the
315 first subject), `unread' (place point on the subject line of the first
316 unread article), `best' (place point on the subject line of the
317 higest-scored article), `unseen' (place point on the subject line of
318 the first unseen article), 'unseen-or-unread' (place point on the subject
319 line of the first unseen article or, if all article have been seen, on the
320 subject line of the first unread article), or a function to be called to
321 place point on some subject line."
322   :group 'gnus-group-select
323   :type '(choice (const best)
324                  (const unread)
325                  (const first)
326                  (const unseen)
327                  (const unseen-or-unread)))
328
329 (defcustom gnus-auto-select-next t
330   "*If non-nil, offer to go to the next group from the end of the previous.
331 If the value is t and the next newsgroup is empty, Gnus will exit
332 summary mode and go back to group mode.  If the value is neither nil
333 nor t, Gnus will select the following unread newsgroup.  In
334 particular, if the value is the symbol `quietly', the next unread
335 newsgroup will be selected without any confirmation, and if it is
336 `almost-quietly', the next group will be selected without any
337 confirmation if you are located on the last article in the group.
338 Finally, if this variable is `slightly-quietly', the `\\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]' command
339 will go to the next group without confirmation."
340   :group 'gnus-summary-maneuvering
341   :type '(choice (const :tag "off" nil)
342                  (const quietly)
343                  (const almost-quietly)
344                  (const slightly-quietly)
345                  (sexp :menu-tag "on" t)))
346
347 (defcustom gnus-auto-select-same nil
348   "*If non-nil, select the next article with the same subject.
349 If there are no more articles with the same subject, go to
350 the first unread article."
351   :group 'gnus-summary-maneuvering
352   :type 'boolean)
353
354 (defcustom gnus-auto-goto-ignores 'unfetched
355   "*Says how to handle unfetched articles when maneuvering.
356
357 This variable can either be the symbols nil (maneuver to any
358 article), `undownloaded' (maneuvering while unplugged ignores articles
359 that have not been fetched), `always-undownloaded' (maneuvering always
360 ignores articles that have not been fetched), `unfetched' (maneuvering
361 ignores articles whose headers have not been fetched).
362
363 NOTE: The list of unfetched articles will always be nil when plugged
364 and, when unplugged, a subset of the undownloaded article list."
365   :group 'gnus-summary-maneuvering
366   :type '(choice (const :tag "None" nil)
367                  (const :tag "Undownloaded when unplugged" undownloaded)
368                  (const :tag "Undownloaded" always-undownloaded)
369                  (const :tag "Unfetched" unfetched)))
370
371 (defcustom gnus-summary-check-current nil
372   "*If non-nil, consider the current article when moving.
373 The \"unread\" movement commands will stay on the same line if the
374 current article is unread."
375   :group 'gnus-summary-maneuvering
376   :type 'boolean)
377
378 (defcustom gnus-auto-center-summary t
379   "*If non-nil, always center the current summary buffer.
380 In particular, if `vertical' do only vertical recentering.  If non-nil
381 and non-`vertical', do both horizontal and vertical recentering."
382   :group 'gnus-summary-maneuvering
383   :type '(choice (const :tag "none" nil)
384                  (const vertical)
385                  (integer :tag "height")
386                  (sexp :menu-tag "both" t)))
387
388 (defvar gnus-auto-center-group t
389   "*If non-nil, always center the group buffer.")
390
391 (defcustom gnus-show-all-headers nil
392   "*If non-nil, don't hide any headers."
393   :group 'gnus-article-hiding
394   :group 'gnus-article-headers
395   :type 'boolean)
396
397 (defcustom gnus-summary-ignore-duplicates nil
398   "*If non-nil, ignore articles with identical Message-ID headers."
399   :group 'gnus-summary
400   :type 'boolean)
401
402 (defcustom gnus-single-article-buffer t
403   "*If non-nil, display all articles in the same buffer.
404 If nil, each group will get its own article buffer."
405   :group 'gnus-article-various
406   :type 'boolean)
407
408 (defcustom gnus-break-pages t
409   "*If non-nil, do page breaking on articles.
410 The page delimiter is specified by the `gnus-page-delimiter'
411 variable."
412   :group 'gnus-article-various
413   :type 'boolean)
414
415 (defcustom gnus-move-split-methods nil
416   "*Variable used to suggest where articles are to be moved to.
417 It uses the same syntax as the `gnus-split-methods' variable.
418 However, whereas `gnus-split-methods' specifies file names as targets,
419 this variable specifies group names."
420   :group 'gnus-summary-mail
421   :type '(repeat (choice (list :value (fun) function)
422                          (cons :value ("" "") regexp (repeat string))
423                          (sexp :value nil))))
424
425 (defcustom gnus-move-group-prefix-function 'gnus-group-real-prefix
426   "Function used to compute default prefix for article move/copy/etc prompts.
427 The function should take one argument, a group name, and return a
428 string with the suggested prefix."
429   :group 'gnus-summary-mail
430   :type 'function)
431
432 (defcustom gnus-unread-mark ?           ;Whitespace
433   "*Mark used for unread articles."
434   :group 'gnus-summary-marks
435   :type 'character)
436
437 (defcustom gnus-ticked-mark ?!
438   "*Mark used for ticked articles."
439   :group 'gnus-summary-marks
440   :type 'character)
441
442 (defcustom gnus-dormant-mark ??
443   "*Mark used for dormant articles."
444   :group 'gnus-summary-marks
445   :type 'character)
446
447 (defcustom gnus-del-mark ?r
448   "*Mark used for del'd articles."
449   :group 'gnus-summary-marks
450   :type 'character)
451
452 (defcustom gnus-read-mark ?R
453   "*Mark used for read articles."
454   :group 'gnus-summary-marks
455   :type 'character)
456
457 (defcustom gnus-expirable-mark ?E
458   "*Mark used for expirable articles."
459   :group 'gnus-summary-marks
460   :type 'character)
461
462 (defcustom gnus-killed-mark ?K
463   "*Mark used for killed articles."
464   :group 'gnus-summary-marks
465   :type 'character)
466
467 (defcustom gnus-spam-mark ?$
468   "*Mark used for spam articles."
469   :group 'gnus-summary-marks
470   :type 'character)
471
472 (defcustom gnus-souped-mark ?F
473   "*Mark used for souped articles."
474   :group 'gnus-summary-marks
475   :type 'character)
476
477 (defcustom gnus-kill-file-mark ?X
478   "*Mark used for articles killed by kill files."
479   :group 'gnus-summary-marks
480   :type 'character)
481
482 (defcustom gnus-low-score-mark ?Y
483   "*Mark used for articles with a low score."
484   :group 'gnus-summary-marks
485   :type 'character)
486
487 (defcustom gnus-catchup-mark ?C
488   "*Mark used for articles that are caught up."
489   :group 'gnus-summary-marks
490   :type 'character)
491
492 (defcustom gnus-replied-mark ?A
493   "*Mark used for articles that have been replied to."
494   :group 'gnus-summary-marks
495   :type 'character)
496
497 (defcustom gnus-forwarded-mark ?F
498   "*Mark used for articles that have been forwarded."
499   :group 'gnus-summary-marks
500   :type 'character)
501
502 (defcustom gnus-recent-mark ?N
503   "*Mark used for articles that are recent."
504   :group 'gnus-summary-marks
505   :type 'character)
506
507 (defcustom gnus-cached-mark ?*
508   "*Mark used for articles that are in the cache."
509   :group 'gnus-summary-marks
510   :type 'character)
511
512 (defcustom gnus-saved-mark ?S
513   "*Mark used for articles that have been saved."
514   :group 'gnus-summary-marks
515   :type 'character)
516
517 (defcustom gnus-unseen-mark ?.
518   "*Mark used for articles that haven't been seen."
519   :group 'gnus-summary-marks
520   :type 'character)
521
522 (defcustom gnus-no-mark ?               ;Whitespace
523   "*Mark used for articles that have no other secondary mark."
524   :group 'gnus-summary-marks
525   :type 'character)
526
527 (defcustom gnus-ancient-mark ?O
528   "*Mark used for ancient articles."
529   :group 'gnus-summary-marks
530   :type 'character)
531
532 (defcustom gnus-sparse-mark ?Q
533   "*Mark used for sparsely reffed articles."
534   :group 'gnus-summary-marks
535   :type 'character)
536
537 (defcustom gnus-canceled-mark ?G
538   "*Mark used for canceled articles."
539   :group 'gnus-summary-marks
540   :type 'character)
541
542 (defcustom gnus-duplicate-mark ?M
543   "*Mark used for duplicate articles."
544   :group 'gnus-summary-marks
545   :type 'character)
546
547 (defcustom gnus-undownloaded-mark ?-
548   "*Mark used for articles that weren't downloaded."
549   :group 'gnus-summary-marks
550   :type 'character)
551
552 (defcustom gnus-downloaded-mark ?+
553   "*Mark used for articles that were downloaded."
554   :group 'gnus-summary-marks
555   :type 'character)
556
557 (defcustom gnus-downloadable-mark ?%
558   "*Mark used for articles that are to be downloaded."
559   :group 'gnus-summary-marks
560   :type 'character)
561
562 (defcustom gnus-unsendable-mark ?=
563   "*Mark used for articles that won't be sent."
564   :group 'gnus-summary-marks
565   :type 'character)
566
567 (defcustom gnus-score-over-mark ?+
568   "*Score mark used for articles with high scores."
569   :group 'gnus-summary-marks
570   :type 'character)
571
572 (defcustom gnus-score-below-mark ?-
573   "*Score mark used for articles with low scores."
574   :group 'gnus-summary-marks
575   :type 'character)
576
577 (defcustom gnus-empty-thread-mark ?     ;Whitespace
578   "*There is no thread under the article."
579   :group 'gnus-summary-marks
580   :type 'character)
581
582 (defcustom gnus-not-empty-thread-mark ?=
583   "*There is a thread under the article."
584   :group 'gnus-summary-marks
585   :type 'character)
586
587 (defcustom gnus-view-pseudo-asynchronously nil
588   "*If non-nil, Gnus will view pseudo-articles asynchronously."
589   :group 'gnus-extract-view
590   :type 'boolean)
591
592 (defcustom gnus-auto-expirable-marks
593   (list gnus-killed-mark gnus-del-mark gnus-catchup-mark
594         gnus-low-score-mark gnus-ancient-mark gnus-read-mark
595         gnus-souped-mark gnus-duplicate-mark)
596   "*The list of marks converted into expiration if a group is auto-expirable."
597   :version "21.1"
598   :group 'gnus-summary
599   :type '(repeat character))
600
601 (defcustom gnus-inhibit-user-auto-expire t
602   "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
603   :version "21.1"
604   :group 'gnus-summary
605   :type 'boolean)
606
607 (defcustom gnus-view-pseudos nil
608   "*If `automatic', pseudo-articles will be viewed automatically.
609 If `not-confirm', pseudos will be viewed automatically, and the user
610 will not be asked to confirm the command."
611   :group 'gnus-extract-view
612   :type '(choice (const :tag "off" nil)
613                  (const automatic)
614                  (const not-confirm)))
615
616 (defcustom gnus-view-pseudos-separately t
617   "*If non-nil, one pseudo-article will be created for each file to be viewed.
618 If nil, all files that use the same viewing command will be given as a
619 list of parameters to that command."
620   :group 'gnus-extract-view
621   :type 'boolean)
622
623 (defcustom gnus-insert-pseudo-articles t
624   "*If non-nil, insert pseudo-articles when decoding articles."
625   :group 'gnus-extract-view
626   :type 'boolean)
627
628 (defcustom gnus-summary-dummy-line-format
629   "   %(:                             :%) %S\n"
630   "*The format specification for the dummy roots in the summary buffer.
631 It works along the same lines as a normal formatting string,
632 with some simple extensions.
633
634 %S  The subject
635
636 General format specifiers can also be used.
637 See `(gnus)Formatting Variables'."
638   :link '(custom-manual "(gnus)Formatting Variables")
639   :group 'gnus-threading
640   :type 'string)
641
642 (defcustom gnus-summary-mode-line-format "Gnus: %g [%A] %Z"
643   "*The format specification for the summary mode line.
644 It works along the same lines as a normal formatting string,
645 with some simple extensions:
646
647 %G  Group name
648 %p  Unprefixed group name
649 %A  Current article number
650 %z  Current article score
651 %V  Gnus version