gnus-html-get-image-data: Search also for \r\n\r\n to get the start of data
[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, 2008, 2009, 2010 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 3 of the License, or
14 ;; (at your option) 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.  If not, see <http://www.gnu.org/licenses/>.
23
24 ;;; Commentary:
25
26 ;;; Code:
27
28 ;; For Emacs < 22.2.
29 (eval-and-compile
30   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
31 (eval-when-compile
32   (require 'cl))
33 (eval-when-compile
34   (when (featurep 'xemacs)
35     (require 'easy-mmode))) ; for `define-minor-mode'
36
37 (defvar tool-bar-mode)
38 (defvar gnus-tmp-header)
39
40 (require 'gnus)
41 (require 'gnus-group)
42 (require 'gnus-spec)
43 (require 'gnus-range)
44 (require 'gnus-int)
45 (require 'gnus-undo)
46 (require 'gnus-util)
47 (require 'gmm-utils)
48 (require 'mm-decode)
49 (require 'nnoo)
50
51 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
52 (autoload 'gnus-cache-write-active "gnus-cache")
53 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
54 (autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
55 (autoload 'gnus-pick-line-number "gnus-salt" nil t)
56 (autoload 'mm-uu-dissect "mm-uu")
57 (autoload 'gnus-article-outlook-deuglify-article "deuglify"
58   "Deuglify broken Outlook (Express) articles and redisplay."
59   t)
60 (autoload 'gnus-article-outlook-unwrap-lines "deuglify" nil t)
61 (autoload 'gnus-article-outlook-repair-attribution "deuglify" nil t)
62 (autoload 'gnus-article-outlook-rearrange-citation "deuglify" nil t)
63
64 (defcustom gnus-kill-summary-on-exit t
65   "*If non-nil, kill the summary buffer when you exit from it.
66 If nil, the summary will become a \"*Dead Summary*\" buffer, and
67 it will be killed sometime later."
68   :group 'gnus-summary-exit
69   :type 'boolean)
70
71 (defcustom gnus-summary-next-group-on-exit t
72   "If non-nil, go to the next unread newsgroup on summary exit.
73 See `gnus-group-goto-unread'."
74   :link '(custom-manual "(gnus)Group Maneuvering")
75   :group 'gnus-summary-exit
76   :version "23.1" ;; No Gnus
77   :type 'boolean)
78
79 (defcustom gnus-summary-stop-at-end-of-message nil
80   "If non-nil, don't select the next message when using `SPC'."
81   :link '(custom-manual "(gnus)Group Maneuvering")
82   :group 'gnus-summary-maneuvering
83   :version "24.1"
84   :type 'boolean)
85
86 (defcustom gnus-fetch-old-headers nil
87   "*Non-nil means that Gnus will try to build threads by grabbing old headers.
88 If an unread article in the group refers to an older, already
89 read (or just marked as read) article, the old article will not
90 normally be displayed in the Summary buffer.  If this variable is
91 t, Gnus will attempt to grab the headers to the old articles, and
92 thereby build complete threads.  If it has the value `some', all
93 old headers will be fetched but only enough headers to connect
94 otherwise loose threads will be displayed.  This variable can
95 also be a number.  In that case, no more than that number of old
96 headers will be fetched.  If it has the value `invisible', all
97 old headers will be fetched, but none will be displayed.
98
99 The server has to support NOV for any of this to work.
100
101 This feature can seriously impact performance it ignores all
102 locally cached header entries.  Setting it to t for groups for a
103 server that doesn't expire articles (such as news.gmane.org),
104 leads to very slow summary generation."
105   :group 'gnus-thread
106   :type '(choice (const :tag "off" nil)
107                  (const :tag "on" t)
108                  (const some)
109                  (const invisible)
110                  number
111                  (sexp :menu-tag "other" t)))
112
113 (defcustom gnus-refer-thread-limit 500
114   "*The number of old headers to fetch when doing \\<gnus-summary-mode-map>\\[gnus-summary-refer-thread].
115 If t, fetch all the available old headers."
116   :group 'gnus-thread
117   :type '(choice number
118                  (sexp :menu-tag "other" t)))
119
120 (defcustom gnus-summary-make-false-root 'adopt
121   "*nil means that Gnus won't gather loose threads.
122 If the root of a thread has expired or been read in a previous
123 session, the information necessary to build a complete thread has been
124 lost.  Instead of having many small sub-threads from this original thread
125 scattered all over the summary buffer, Gnus can gather them.
126
127 If non-nil, Gnus will try to gather all loose sub-threads from an
128 original thread into one large thread.
129
130 If this variable is non-nil, it should be one of `none', `adopt',
131 `dummy' or `empty'.
132
133 If this variable is `none', Gnus will not make a false root, but just
134 present the sub-threads after another.
135 If this variable is `dummy', Gnus will create a dummy root that will
136 have all the sub-threads as children.
137 If this variable is `adopt', Gnus will make one of the \"children\"
138 the parent and mark all the step-children as such.
139 If this variable is `empty', the \"children\" are printed with empty
140 subject fields.  (Or rather, they will be printed with a string
141 given by the `gnus-summary-same-subject' variable.)"
142   :group 'gnus-thread
143   :type '(choice (const :tag "off" nil)
144                  (const none)
145                  (const dummy)
146                  (const adopt)
147                  (const empty)))
148
149 (defcustom gnus-summary-make-false-root-always nil
150   "Always make a false dummy root."
151   :version "22.1"
152   :group 'gnus-thread
153   :type 'boolean)
154
155 (defcustom gnus-summary-gather-exclude-subject "^ *$\\|^(none)$"
156   "*A regexp to match subjects to be excluded from loose thread gathering.
157 As loose thread gathering is done on subjects only, that means that
158 there can be many false gatherings performed.  By rooting out certain
159 common subjects, gathering might become saner."
160   :group 'gnus-thread
161   :type 'regexp)
162
163 (defcustom gnus-summary-gather-subject-limit nil
164   "*Maximum length of subject comparisons when gathering loose threads.
165 Use nil to compare full subjects.  Setting this variable to a low
166 number will help gather threads that have been corrupted by
167 newsreaders chopping off subject lines, but it might also mean that
168 unrelated articles that have subject that happen to begin with the
169 same few characters will be incorrectly gathered.
170
171 If this variable is `fuzzy', Gnus will use a fuzzy algorithm when
172 comparing subjects."
173   :group 'gnus-thread
174   :type '(choice (const :tag "off" nil)
175                  (const fuzzy)
176                  (sexp :menu-tag "on" t)))
177
178 (defcustom gnus-simplify-subject-functions nil
179   "List of functions taking a string argument that simplify subjects.
180 The functions are applied recursively.
181
182 Useful functions to put in this list include:
183 `gnus-simplify-subject-re', `gnus-simplify-subject-fuzzy',
184 `gnus-simplify-whitespace', and `gnus-simplify-all-whitespace'."
185   :group 'gnus-thread
186   :type '(repeat function))
187
188 (defcustom gnus-simplify-ignored-prefixes nil
189   "*Remove matches for this regexp from subject lines when simplifying fuzzily."
190   :group 'gnus-thread
191   :type '(choice (const :tag "off" nil)
192                  regexp))
193
194 (defcustom gnus-build-sparse-threads nil
195   "*If non-nil, fill in the gaps in threads.
196 If `some', only fill in the gaps that are needed to tie loose threads
197 together.  If `more', fill in all leaf nodes that Gnus can find.  If
198 non-nil and non-`some', fill in all gaps that Gnus manages to guess."
199   :group 'gnus-thread
200   :type '(choice (const :tag "off" nil)
201                  (const some)
202                  (const more)
203                  (sexp :menu-tag "all" t)))
204
205 (defcustom gnus-summary-thread-gathering-function
206   'gnus-gather-threads-by-subject
207   "*Function used for gathering loose threads.
208 There are two pre-defined functions: `gnus-gather-threads-by-subject',
209 which only takes Subjects into consideration; and
210 `gnus-gather-threads-by-references', which compared the&nbs