1 ;;; gnus-sum.el --- summary mode commands for Gnus
3 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 ;; 2005, 2006 Free Software Foundation, Inc.
6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
9 ;; This file is part of GNU Emacs.
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)
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.
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.
32 (defvar tool-bar-mode))
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."
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)
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
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.
78 The server has to support NOV for any of this to work.
80 This feature can seriously impact performance it ignores all
81 locally cached header entries."
83 :type '(choice (const :tag "off" nil)
88 (sexp :menu-tag "other" t)))
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."
95 (sexp :menu-tag "other" t)))
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.
104 If non-nil, Gnus will try to gather all loose sub-threads from an
105 original thread into one large thread.
107 If this variable is non-nil, it should be one of `none', `adopt',
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.)"
120 :type '(choice (const :tag "off" nil)
126 (defcustom gnus-summary-make-false-root-always nil
127 "Always make a false dummy root."
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."
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.
148 If this variable is `fuzzy', Gnus will use a fuzzy algorithm when
151 :type '(choice (const :tag "off" nil)
153 (sexp :menu-tag "on" t)))
155 (defcustom gnus-simplify-subject-functions nil
156 "List of functions taking a string argument that simplify subjects.
157 The functions are applied recursively.
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'."
163 :type '(repeat function))
165 (defcustom gnus-simplify-ignored-prefixes nil
166 "*Remove matches for this regexp from subject lines when simplifying fuzzily."
168 :type '(choice (const :tag "off" nil)
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."
177 :type '(choice (const :tag "off" nil)
180 (sexp :menu-tag "all" t)))
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."
190 :type '(radio (function-item gnus-gather-threads-by-subject)
191 (function-item gnus-gather-threads-by-references)
192 (function :tag "other")))
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
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.
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)
215 (sexp :menu-tag "on" t)))
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")
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
230 :group 'gnus-score-default
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
238 :group 'gnus-score-default
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'
245 :group 'gnus-summary-format
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."
254 :type '(repeat regexp))
256 (defcustom gnus-show-threads t
257 "*If non-nil, display threads in summary mode."
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."
267 :type '(radio (sexp :format "Non-nil\n"
268 :match (lambda (widget value)
269 (not (or (consp value) (functionp value))))
272 (sexp :tag "Predicate specifier")))
274 (defcustom gnus-thread-hide-killed t
275 "*If non-nil, hide killed threads automatically."
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."
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'.
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."
296 :type '(choice (const :tag "off" nil)
300 (defcustom gnus-thread-indent-level 4
301 "*Number that says how much each sub-thread should be indented."
305 (defcustom gnus-auto-extend-newsgroup t
306 "*If non-nil, extend newsgroup forward and backward when requested."
307 :group 'gnus-summary-choose
310 (defcustom gnus-auto-select-first t
311 "*If non-nil, select the article under point.
312 Which article this is is controlled by the `gnus-auto-select-subject'
315 If you want to prevent automatic selection of articles in some
316 newsgroups, set the variable to nil in `gnus-select-group-hook'."
317 :group 'gnus-group-select
318 :type '(choice (const :tag "none" nil)
319 (sexp :menu-tag "first" t)))
321 (defcustom gnus-auto-select-subject 'unread
322 "*Says what subject to place under point when entering a group.
324 This variable can either be the symbols `first' (place point on the
325 first subject), `unread' (place point on the subject line of the first
326 unread article), `best' (place point on the subject line of the
327 higest-scored article), `unseen' (place point on the subject line of
328 the first unseen article), `unseen-or-unread' (place point on the subject
329 line of the first unseen article or, if all article have been seen, on the
330 subject line of the first unread article), or a function to be called to
331 place point on some subject line."
333 :group 'gnus-group-select
334 :type '(choice (const best)
338 (const unseen-or-unread)))
340 (defcustom gnus-auto-select-next t
341 "*If non-nil, offer to go to the next group from the end of the previous.
342 If the value is t and the next newsgroup is empty, Gnus will exit
343 summary mode and go back to group mode. If the value is neither nil
344 nor t, Gnus will select the following unread newsgroup. In
345 particular, if the value is the symbol `quietly', the next unread
346 newsgroup will be selected without any confirmation, and if it is
347 `almost-quietly', the next group will be selected without any
348 confirmation if you are located on the last article in the group.
349 Finally, if this variable is `slightly-quietly', the `\\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]' command
350 will go to the next group without confirmation."
351 :group 'gnus-summary-maneuvering
352 :type '(choice (const :tag "off" nil)
354 (const almost-quietly)
355 (const slightly-quietly)
356 (sexp :menu-tag "on" t)))
358 (defcustom gnus-auto-select-same nil
359 "*If non-nil, select the next article with the same subject.
360 If there are no more articles with the same subject, go to
361 the first unread article."
362 :group 'gnus-summary-maneuvering
365 (defcustom gnus-auto-goto-ignores 'unfetched
366 "*Says how to handle unfetched articles when maneuvering.
368 This variable can either be the symbols nil (maneuver to any
369 article), `undownloaded' (maneuvering while unplugged ignores articles
370 that have not been fetched), `always-undownloaded' (maneuvering always
371 ignores articles that have not been fetched), `unfetched' (maneuvering
372 ignores articles whose headers have not been fetched).
374 NOTE: The list of unfetched articles will always be nil when plugged
375 and, when unplugged, a subset of the undownloaded article list."
377 :group 'gnus-summary-maneuvering
378 :type '(choice (const :tag "None" nil)
379 (const :tag "Undownloaded when unplugged" undownloaded)
380 (const :tag "Undownloaded" always-undownloaded)
381 (const :tag "Unfetched" unfetched)))
383 (defcustom gnus-summary-check-current nil
384 "*If non-nil, consider the current article when moving.
385 The \"unread\" movement commands will stay on the same line if the
386 current article is unread."
387 :group 'gnus-summary-maneuvering
390 (defcustom gnus-auto-center-summary 2
391 "*If non-nil, always center the current summary buffer.
392 In particular, if `vertical' do only vertical recentering. If non-nil
393 and non-`vertical', do both horizontal and vertical recentering."
394 :group 'gnus-summary-maneuvering
395 :type '(choice (const :tag "none" nil)
397 (integer :tag "height")
398 (sexp :menu-tag "both" t)))
400 (defvar gnus-auto-center-group t
401 "*If non-nil, always center the group buffer.")
403 (defcustom gnus-show-all-headers nil
404 "*If non-nil, don't hide any headers."
405 :group 'gnus-article-hiding
406 :group 'gnus-article-headers
409 (defcustom gnus-summary-ignore-duplicates nil
410 "*If non-nil, ignore articles with identical Message-ID headers."
414 (defcustom gnus-single-article-buffer t
415 "*If non-nil, display all articles in the same buffer.
416 If nil, each group will get its own article buffer."
417 :group 'gnus-article-various
420 (defcustom gnus-break-pages t
421 "*If non-nil, do page breaking on articles.
422 The page delimiter is specified by the `gnus-page-delimiter'
424 :group 'gnus-article-various
427 (defcustom gnus-move-split-methods nil
428 "*Variable used to suggest where articles are to be moved to.
429 It uses the same syntax as the `gnus-split-methods' variable.
430 However, whereas `gnus-split-methods' specifies file names as targets,
431 this variable specifies group names."
432 :group 'gnus-summary-mail
433 :type '(repeat (choice (list :value (fun) function)
434 (cons :value ("" "") regexp (repeat string))
437 (defcustom gnus-move-group-prefix-function 'gnus-group-real-prefix
438 "Function used to compute default prefix for article move/copy/etc prompts.
439 The function should take one argument, a group name, and return a
440 string with the suggested prefix."
441 :group 'gnus-summary-mail
444 ;; FIXME: Although the custom type is `character' for the following variables,
445 ;; using multibyte characters (Latin-1, UTF-8) doesn't work. -- rs
447 (defcustom gnus-unread-mark ? ;Whitespace
448 "*Mark used for unread articles."
449 :group 'gnus-summary-marks
452 (defcustom gnus-ticked-mark ?!
453 "*Mark used for ticked articles."
454 :group 'gnus-summary-marks
457 (defcustom gnus-dormant-mark ??
458 "*Mark used for dormant articles."
459 :group 'gnus-summary-marks
462 (defcustom gnus-del-mark ?r
463 "*Mark used for del'd articles."
464 :group 'gnus-summary-marks
467 (defcustom gnus-read-mark ?R
468 "*Mark used for read articles."
469 :group 'gnus-summary-marks
472 (defcustom gnus-expirable-mark ?E
473 "*Mark used for expirable articles."
474 :group 'gnus-summary-marks
477 (defcustom gnus-killed-mark ?K
478 "*Mark used for killed articles."
479 :group 'gnus-summary-marks
482 (defcustom gnus-spam-mark ?$
483 "*Mark used for spam articles."
485 :group 'gnus-summary-marks
488 (defcustom gnus-souped-mark ?F
489 "*Mark used for souped articles."
490 :group 'gnus-summary-marks
493 (defcustom gnus-kill-file-mark ?X
494 "*Mark used for articles killed by kill files."
495 :group 'gnus-summary-marks
498 (defcustom gnus-low-score-mark ?Y
499 "*Mark used for articles with a low score."
500 :group 'gnus-summary-marks
503 (defcustom gnus-catchup-mark ?C
504 "*Mark used for articles that are caught up."
505 :group 'gnus-summary-marks
508 (defcustom gnus-replied-mark ?A
509 "*Mark used for articles that have been replied to."
510 :group 'gnus-summary-marks
513 (defcustom gnus-forwarded-mark ?F
514 "*Mark used for articles that have been forwarded."
516 :group 'gnus-summary-marks
519 (defcustom gnus-recent-mark ?N
520 "*Mark used for articles that are recent."
522 :group 'gnus-summary-marks
525 (defcustom gnus-cached-mark ?*
526 "*Mark used for articles that are in the cache."
527 :group 'gnus-summary-marks
530 (defcustom gnus-saved-mark ?S
531 "*Mark used for articles that have been saved."
532 :group 'gnus-summary-marks
535 (defcustom gnus-unseen-mark ?.
536 "*Mark used for articles that haven't been seen."
538 :group 'gnus-summary-marks
541 (defcustom gnus-no-mark ? ;Whitespace
542 "*Mark used for articles that have no other secondary mark."
544 :group 'gnus-summary-marks
547 (defcustom gnus-ancient-mark ?O
548 "*Mark used for ancient articles."
549 :group 'gnus-summary-marks
552 (defcustom gnus-sparse-mark ?Q
553 "*Mark used for sparsely reffed articles."
554 :group 'gnus-summary-marks
557 (defcustom gnus-canceled-mark ?G
558 "*Mark used for canceled articles."
559 :group 'gnus-summary-marks
562 (defcustom gnus-duplicate-mark ?M
563 "*Mark used for duplicate articles."
564 :group 'gnus-summary-marks
567 (defcustom gnus-undownloaded-mark ?-
568 "*Mark used for articles that weren't downloaded."
570 :group 'gnus-summary-marks
573 (defcustom gnus-downloaded-mark ?+
574 "*Mark used for articles that were downloaded."
575 :group 'gnus-summary-marks
578 (defcustom gnus-downloadable-mark ?%
579 "*Mark used for articles that are to be downloaded."
580 :group 'gnus-summary-marks
583 (defcustom gnus-unsendable-mark ?=
584 "*Mark used for articles that won't be sent."
585 :group 'gnus-summary-marks
588 (defcustom gnus-score-over-mark ?+
589 "*Score mark used for articles with high scores."
590 :group 'gnus-summary-marks
593 (defcustom gnus-score-below-mark ?-
594 "*Score mark used for articles with low scores."
595 :group 'gnus-summary-marks
598 (defcustom gnus-empty-thread-mark ? ;Whitespace
599 "*There is no thread under the article."
600 :group 'gnus-summary-marks
603 (defcustom gnus-not-empty-thread-mark ?=
604 "*There is a thread under the article."
605 :group 'gnus-summary-marks
608 (defcustom gnus-view-pseudo-asynchronously nil
609 "*If non-nil, Gnus will view pseudo-articles asynchronously."
610 :group 'gnus-extract-view
613 (defcustom gnus-auto-expirable-marks
614 (list gnus-killed-mark gnus-del-mark gnus-catchup-mark
615 gnus-low-score-mark gnus-ancient-mark gnus-read-mark
616 gnus-souped-mark gnus-duplicate-mark)
617 "*The list of marks converted into expiration if a group is auto-expirable."
620 :type '(repeat character))
622 (defcustom gnus-inhibit-user-auto-expire t
623 "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
628 (defcustom gnus-view-pseudos nil
629 "*If `automatic', pseudo-articles will be viewed automatically.
630 If `not-confirm', pseudos will be viewed automatically, and the user
631 will not be asked to confirm the command."
632 :group 'gnus-extract-view
633 :type '(choice (const :tag "off" nil)
635 (const not-confirm)))
637 (defcustom gnus-view-pseudos-separately t
638 "*If non-nil, one pseudo-article will be created for each file to be viewed.
639 If nil, all files that use the same viewing command will be given as a
640 list of parameters to that command."
641 :group 'gnus-extract-view
644 (defcustom gnus-insert-pseudo-articles t
645 "*If non-nil, insert pseudo-articles when decoding articles."
646 :group 'gnus-extract-view
649 (defcustom gnus-summary-dummy-line-format
651 "*The format specification for the dummy roots in the summary buffer.
652 It works along the same lines as a normal formatting string,
653 with some simple extensions.
657 General format specifiers can also be used.
658 See `(gnus)Formatting Variables'."
659 :link '(custom-manual "(gnus)Formatting Variables")
660 :group 'gnus-threading
663 (defcustom gnus-summary-mode-line-format "Gnus: %g [%A] %Z"
664 "*The format specification for the summary mode line.
665 It works along the same lines as a normal formatting string,
666 with some simple extensions:
669 %p Unprefixed group name
670 %A Current article number
671 %z Current article score
673 %U Number of unread articles in the group
674 %e Number of unselected articles in the group
675 %Z A string with unread/unselected article counts
676 %g Shortish group name
677 %S Subject of the current article
679 %s Current score file name
680 %d Number of dormant articles
681 %r Number of articles that have been marked as read in this session
682 %E Number of articles expunged by the score files"
683 :group 'gnus-summary-format
686 (defcustom gnus-list-identifiers nil
687 "Regexp that matches list identifiers to be removed from subject.
688 This can also be a list of regexps."
690 :group 'gnus-summary-format
691 :group 'gnus-article-hiding
692 :type '(choice (const :tag "none" nil)
694 (repeat :value (".*") regexp)))
696 (defcustom gnus-summary-mark-below 0
697 "*Mark all articles with a score below this variable as read.
698 This variable is local to each summary buffer and usually set by the
700 :group 'gnus-score-default
703 (defun gnus-widget-reversible-match (widget value)
704 "Ignoring WIDGET, convert VALUE to internal form.
705 VALUE should have the form `FOO' or `(not FOO)', where FOO is an symbol."
709 (eq (length value) 2)
710 (eq (nth 0 value) 'not)
711 (symbolp (nth 1 value)))))
713 (defun gnus-widget-reversible-to-internal (widget value)
714 "Ignoring WIDGET, convert VALUE to internal form.
715 VALUE should have the form `FOO' or `(not FOO)', where FOO is an atom.
716 FOO is converted to (FOO nil) and (not FOO) is converted to (FOO t)."
720 (list (nth 1 value) t)))
722 (defun gnus-widget-reversible-to-external (widget value)
723 "Ignoring WIDGET, convert VALUE to external form.
724 VALUE should have the form `(FOO nil)' or `(FOO t)', where FOO is an atom.
725 \(FOO nil) is converted to FOO and (FOO t) is converted to (not FOO)."
728 (list 'not (nth 0 value))
731 (define-widget 'gnus-widget-reversible 'group
732 "A `group' that convert values."
733 :match 'gnus-widget-reversible-match
734 :value-to-internal 'gnus-widget-reversible-to-internal
735 :value-to-external 'gnus-widget-reversible-to-external)
737 (defcustom gnus-article-sort-functions '(gnus-article-sort-by-number)
738 "*List of functions used for sorting articles in the summary buffer.
740 Each function takes two articles and returns non-nil if the first
741 article should be sorted before the other. If you use more than one
742 function, the primary sort function should be the last. You should
743 probably always include `gnus-article-sort-by-number' in the list of
744 sorting functions -- preferably first. Also note that sorting by date
745 is often much slower than sorting by number, and the sorting order is
746 very similar. (Sorting by date means sorting by the time the message
747 was sent, sorting by number means sorting by arrival time.)
749 Each item can also be a list `(not F)' where F is a function;
750 this reverses the sort order.
752 Ready-made functions include `gnus-article-sort-by-number',
753 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
754 `gnus-article-sort-by-date', `gnus-article-sort-by-random'
755 and `gnus-article-sort-by-score'.
757 When threading is turned on, the variable `gnus-thread-sort-functions'
758 controls how articles are sorted."
759 :group 'gnus-summary-sort
760 :type '(repeat (gnus-widget-reversible
761 (choice (function-item gnus-article-sort-by-number)
762 (function-item gnus-article-sort-by-author)
763 (function-item gnus-article-sort-by-subject)
764 (function-item gnus-article-sort-by-date)
765 (function-item gnus-article-sort-by-score)
766 (function-item gnus-article-sort-by-random)
767 (function :tag "other"))
768 (boolean :tag "Reverse order"))))
771 (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
772 "*List of functions used for sorting threads in the summary buffer.
773 By default, threads are sorted by article number.
775 Each function takes two threads and returns non-nil if the first
776 thread should be sorted before the other. If you use more than one
777 function, the primary sort function should be the last. You should
778 probably always include `gnus-thread-sort-by-number' in the list of
779 sorting functions -- preferably first. Also note that sorting by date
780 is often much slower than sorting by number, and the sorting order is
781 very similar. (Sorting by date means sorting by the time the message
782 was sent, sorting by number means sorting by arrival time.)
784 Each list item can also be a list `(not F)' where F is a
785 function; this specifies reversed sort order.
787 Ready-made functions include `gnus-thread-sort-by-number',
788 `gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
789 `gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
790 `gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
791 `gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
792 and `gnus-thread-sort-by-total-score' (see
793 `gnus-thread-score-function').
795 When threading is turned off, the variable
796 `gnus-article-sort-functions' controls how articles are sorted."
797 :group 'gnus-summary-sort
799 (gnus-widget-reversible
800 (choice (function-item gnus-thread-sort-by-number)
801 (function-item gnus-thread-sort-by-author)
802 (function-item gnus-thread-sort-by-recipient)
803 (function-item gnus-thread-sort-by-subject)
804 (function-item gnus-thread-sort-by-date)
805 (function-item gnus-thread-sort-by-score)
806 (function-item gnus-thread-sort-by-most-recent-number)
807 (function-item gnus-thread-sort-by-most-recent-date)
808 (function-item gnus-thread-sort-by-random)
809 (function-item gnus-thread-sort-by-total-score)
810 (function :tag "other"))
811 (boolean :tag "Reverse order"))))
813 (defcustom gnus-thread-score-function '+
814 "*Function used for calculating the total score of a thread.
816 The function is called with the scores of the article and each
817 subthread and should then return the score of the thread.
819 Some functions you can use are `+', `max', or `min'."
820 :group 'gnus-summary-sort
823 (defcustom gnus-summary-expunge-below nil
824 "All articles that have a score less than this variable will be expunged.
825 This variable is local to the summary buffers."
826 :group 'gnus-score-default
827 :type '(choice (const :tag "off" nil)
830 (defcustom gnus-thread-expunge-below nil
831 "All threads that have a total score less than this variable will be expunged.
832 See `gnus-thread-score-function' for en explanation of what a
835 This variable is local to the summary buffers."
836 :group 'gnus-threading
837 :group 'gnus-score-default
838 :type '(choice (const :tag "off" nil)
841 (defcustom gnus-summary-mode-hook nil
842 "*A hook for Gnus summary mode.
843 This hook is run before any variables are set in the summary buffer."
844 :options '(turn-on-gnus-mailing-list-mode gnus-pick-mode)
845 :group 'gnus-summary-various
848 ;; Extracted from gnus-xmas-redefine in order to preserve user settings
849 (when (featurep 'xemacs)
850 (add-hook 'gnus-summary-mode-hook 'gnus-xmas-summary-menu-add)
851 (add-hook 'gnus-summary-mode-hook 'gnus-xmas-setup-summary-toolbar)
852 (add-hook 'gnus-summary-mode-hook
853 'gnus-xmas-switch-horizontal-scrollbar-off))
855 (defcustom gnus-summary-menu-hook nil
856 "*Hook run after the creation of the summary mode menu."
857 :group 'gnus-summary-visual
860 (defcustom gnus-summary-exit-hook nil
861 "*A hook called on exit from the summary buffer.
862 It will be called with point in the group buffer."
863 :group 'gnus-summary-exit
866 (defcustom gnus-summary-prepare-hook nil
867 "*A hook called after the summary buffer has been generated.
868 If you want to modify the summary buffer, you can use this hook."
869 :group 'gnus-summary-various
872 (defcustom gnus-summary-prepared-hook nil
873 "*A hook called as the last thing after the summary buffer has been generated."
874 :group 'gnus-summary-various
877 (defcustom gnus-summary-generate-hook nil
878 "*A hook run just before generating the summary buffer.
879 This hook is commonly used to customize threading variables and the
881 :group 'gnus-summary-various
884 (defcustom gnus-select-group-hook nil
885 "*A hook called when a newsgroup is selected.
887 If you'd like to simplify subjects like the
888 `gnus-summary-next-same-subject' command does, you can use the
891 (add-hook gnus-select-group-hook
893 (mapcar (lambda (header)
894 (mail-header-set-subject
896 (gnus-simplify-subject
897 (mail-header-subject header) 're-only)))
898 gnus-newsgroup-headers)))"
899 :group 'gnus-group-select
902 (defcustom gnus-select-article-hook nil
903 "*A hook called when an article is selected."
904 :group 'gnus-summary-choose
905 :options '(gnus-agent-fetch-selected-article)
908 (defcustom gnus-visual-mark-article-hook
909 (list 'gnus-highlight-selected-summary)
910 "*Hook run after selecting an article in the summary buffer.
911 It is meant to be used for highlighting the article in some way. It
912 is not run if `gnus-visual' is nil."
913 :group 'gnus-summary-visual
916 (defcustom gnus-parse-headers-hook nil
917 "*A hook called before parsing the headers."
921 (defcustom gnus-exit-group-hook nil
922 "*A hook called when exiting summary mode.
923 This hook is not called from the non-updating exit commands like `Q'."
927 (defcustom gnus-summary-update-hook
928 (list 'gnus-summary-highlight-line)
929 "*A hook called when a summary line is changed.
930 The hook will not be called if `gnus-visual' is nil.
932 The default function `gnus-summary-highlight-line' will
933 highlight the line according to the `gnus-summary-highlight'
935 :group 'gnus-summary-visual
938 (defcustom gnus-mark-article-hook '(gnus-summary-mark-read-and-unread-as-read)
939 "*A hook called when an article is selected for the first time.
940 The hook is intended to mark an article as read (or unread)
941 automatically when it is selected."
942 :group 'gnus-summary-choose
945 (defcustom gnus-group-no-more-groups-hook nil
946 "*A hook run when returning to group mode having no more (unread) groups."
947 :group 'gnus-group-select
950 (defcustom gnus-ps-print-hook nil
951 "*A hook run before ps-printing something from Gnus."
955 (defcustom gnus-summary-article-move-hook nil
956 "*A hook called after an article is moved, copied, respooled, or crossposted."
961 (defcustom gnus-summary-article-delete-hook nil
962 "*A hook called after an article is deleted."
967 (defcustom gnus-summary-article-expire-hook nil
968 "*A hook called after an article is expired."
973 (defcustom gnus-summary-display-arrow
974 (and (fboundp 'display-graphic-p)
976 "*If non-nil, display an arrow highlighting the current article."
981 (defcustom gnus-summary-selected-face 'gnus-summary-selected
982 "Face used for highlighting the current article in the summary buffer."
983 :group 'gnus-summary-visual
986 (defvar gnus-tmp-downloaded nil)
988 (defcustom gnus-summary-highlight
989 '(((eq mark gnus-canceled-mark)
990 . gnus-summary-cancelled)
991 ((and uncached (> score default-high))
992 . gnus-summary-high-undownloaded)
993 ((and uncached (< score default-low))
994 . gnus-summary-low-undownloaded)
996 . gnus-summary-normal-undownloaded)
997 ((and (> score default-high)
998 (or (eq mark gnus-dormant-mark)
999 (eq mark gnus-ticked-mark)))
1000 . gnus-summary-high-ticked)
1001 ((and (< score default-low)
1002 (or (eq mark gnus-dormant-mark)
1003 (eq mark gnus-ticked-mark)))
1004 . gnus-summary-low-ticked)
1005 ((or (eq mark gnus-dormant-mark)
1006 (eq mark gnus-ticked-mark))
1007 . gnus-summary-normal-ticked)
1008 ((and (> score default-high) (eq mark gnus-ancient-mark))
1009 . gnus-summary-high-ancient)
1010 ((and (< score default-low) (eq mark gnus-ancient-mark))
1011 . gnus-summary-low-ancient)
1012 ((eq mark gnus-ancient-mark)
1013 . gnus-summary-normal-ancient)
1014 ((and (> score default-high) (eq mark gnus-unread-mark))
1015 . gnus-summary-high-unread)
1016 ((and (< score default-low) (eq mark gnus-unread-mark))
1017 . gnus-summary-low-unread)
1018 ((eq mark gnus-unread-mark)
1019 . gnus-summary-normal-unread)
1020 ((> score default-high)
1021 . gnus-summary-high-read)
1022 ((< score default-low)
1023 . gnus-summary-low-read)
1025 . gnus-summary-normal-read))
1026 "*Controls the highlighting of summary buffer lines.
1028 A list of (FORM . FACE) pairs. When deciding how a a particular
1029 summary line should be displayed, each form is evaluated. The content
1030 of the face field after the first true form is used. You can change
1031 how those summary lines are displayed, by editing the face field.
1033 You can use the following variables in the FORM field.
1035 score: The article's score
1036 default: The default article score.
1037 default-high: The default score for high scored articles.
1038 default-low: The default score for low scored articles.
1039 below: The score below which articles are automatically marked as read.
1040 mark: The article's mark.
1041 uncached: Non-nil if the article is uncached."
1042 :group 'gnus-summary-visual
1043 :type '(repeat (cons (sexp :tag "Form" nil)
1046 (defcustom gnus-alter-header-function nil
1047 "Function called to allow alteration of article header structures.
1048 The function is called with one parameter, the article header vector,
1049 which it may alter in any way."
1050 :type '(choice (const :tag "None" nil)
1052 :group 'gnus-summary)
1054 (defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
1055 "Function used to decode a string with encoded words.")
1057 (defvar gnus-decode-encoded-address-function
1058 'mail-decode-encoded-address-string
1059 "Function used to decode addresses with encoded words.")
1061 (defcustom gnus-extra-headers '(To Newsgroups)
1062 "*Extra headers to parse."
1064 :group 'gnus-summary
1065 :type '(repeat symbol))
1067 (defcustom gnus-ignored-from-addresses
1068 (and user-mail-address
1069 (not (string= user-mail-address ""))
1070 (regexp-quote user-mail-address))
1071 "*Regexp of From headers that may be suppressed in favor of To headers."
1073 :group 'gnus-summary
1076 (defcustom gnus-summary-to-prefix "-> "
1077 "*String prefixed to the To field in the summary line when
1078 using `gnus-ignored-from-addresses'."
1080 :group 'gnus-summary
1083 (defcustom gnus-summary-newsgroup-prefix "=> "
1084 "*String prefixed to the Newsgroup field in the summary
1085 line when using `gnus-ignored-from-addresses'."
1087 :group 'gnus-summary
1090 (defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
1091 "List of charsets that should be ignored.
1092 When these charsets are used in the \"charset\" parameter, the
1093 default charset will be used instead."
1095 :type '(repeat symbol)
1096 :group 'gnus-charset)
1098 (gnus-define-group-parameter
1102 "Return the ignored charsets of GROUP."
1103 :variable gnus-group-ignored-charsets-alist
1105 '(("alt\\.chinese\\.text" iso-8859-1))
1107 "Alist of regexps (to match group names) and charsets that should be ignored.
1108 When these charsets are used in the \"charset\" parameter, the
1109 default charset will be used instead."
1110 :variable-group gnus-charset
1111 :variable-type '(repeat (cons (regexp :tag "Group")
1113 :parameter-type '(choice :tag "Ignored charsets"
1116 :parameter-document "\
1117 List of charsets that should be ignored.
1119 When these charsets are used in the \"charset\" parameter, the
1120 default charset will be used instead.")
1122 (defcustom gnus-group-highlight-words-alist nil
1123 "Alist of group regexps and highlight regexps.
1124 This variable uses the same syntax as `gnus-emphasis-alist'."
1126 :type '(repeat (cons (regexp :tag "Group")
1127 (repeat (list (regexp :tag "Highlight regexp")
1128 (number :tag "Group for entire word" 0)
1129 (number :tag "Group for displayed part" 0)
1131 gnus-emphasis-highlight-words)))))
1132 :group 'gnus-summary-visual)
1134 (defcustom gnus-summary-show-article-charset-alist
1136 "Alist of number and charset.
1137 The article will be shown with the charset corresponding to the
1139 For example: ((1 . cn-gb-2312) (2 . big5))."
1141 :type '(repeat (cons (number :tag "Argument" 1)
1142 (symbol :tag "Charset")))
1143 :group 'gnus-charset)
1145 (defcustom gnus-preserve-marks t
1146 "Whether marks are preserved when moving, copying and respooling messages."
1149 :group 'gnus-summary-marks)
1151 (defcustom gnus-alter-articles-to-read-function nil
1152 "Function to be called to alter the list of articles to be selected."
1153 :type '(choice (const nil) function)
1154 :group 'gnus-summary)
1156 (defcustom gnus-orphan-score nil
1157 "*All orphans get this score added. Set in the score file."
1158 :group 'gnus-score-default
1159 :type '(choice (const nil)
1162 (defcustom gnus-summary-save-parts-default-mime "image/.*"
1163 "*A regexp to match MIME parts when saving multiple parts of a
1164 message with `gnus-summary-save-parts' (\\<gnus-summary-mode-map>\\[gnus-summary-save-parts]).
1165 This regexp will be used by default when prompting the user for which
1166 type of files to save."
1167 :group 'gnus-summary
1170 (defcustom gnus-read-all-available-headers nil
1171 "Whether Gnus should parse all headers made available to it.
1172 This is mostly relevant for slow back ends where the user may
1173 wish to widen the summary buffer to include all headers
1174 that were fetched. Say, for nnultimate groups."
1176 :group 'gnus-summary
1177 :type '(choice boolean regexp))