Merge branch 'master' of https://git.gnus.org/gnus
[gnus] / lisp / gnus-start.el
1 ;;; gnus-start.el --- startup functions for Gnus
2
3 ;; Copyright (C) 1996-2013 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 3 of the License, or
13 ;; (at your option) 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.  If not, see <http://www.gnu.org/licenses/>.
22
23 ;;; Commentary:
24
25 ;;; Code:
26
27 (require 'gnus)
28 (require 'gnus-win)
29 (require 'gnus-int)
30 (require 'gnus-spec)
31 (require 'gnus-range)
32 (require 'gnus-util)
33 (autoload 'message-make-date "message")
34 (autoload 'gnus-agent-read-servers-validate "gnus-agent")
35 (autoload 'gnus-agent-save-local "gnus-agent")
36 (autoload 'gnus-agent-possibly-alter-active "gnus-agent")
37
38 (eval-when-compile
39   (require 'cl))
40
41 (defvar gnus-agent-covered-methods)
42 (defvar gnus-agent-file-loading-local)
43 (defvar gnus-agent-file-loading-cache)
44
45 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
46   "Your `.newsrc' file.
47 `.newsrc-SERVER' will be used instead if that exists."
48   :group 'gnus-start
49   :type 'file)
50
51 (defcustom gnus-backup-startup-file 'never
52   "Control use of version numbers for backups of `gnus-startup-file'.
53 This variable takes the same values as the `version-control'
54 variable."
55   :version "22.1"
56   :group 'gnus-start
57   :type '(choice (const :tag "Never" never)
58                  (const :tag "If existing" nil)
59                  (other :tag "Always" t)))
60
61 (defcustom gnus-save-startup-file-via-temp-buffer t
62   "Whether to write the startup file contents to a buffer then save
63 the buffer or write directly to the file.  The buffer is faster
64 because all of the contents are written at once.  The direct write
65 uses considerably less memory."
66   :version "22.1"
67   :group 'gnus-start
68   :type '(choice (const :tag "Write via buffer" t)
69                  (const :tag "Write directly to file" nil)))
70
71 (defcustom gnus-init-file (nnheader-concat gnus-home-directory ".gnus")
72   "Your Gnus Emacs-Lisp startup file name.
73 If a file with the `.el' or `.elc' suffixes exists, it will be read instead."
74   :group 'gnus-start
75   :type 'file)
76
77 (defcustom gnus-site-init-file
78   (condition-case nil
79       (concat (file-name-directory
80                (directory-file-name installation-directory))
81               "site-lisp/gnus-init")
82     (error nil))
83   "The site-wide Gnus Emacs-Lisp startup file name, or nil if none.
84 If a file with the `.el' or `.elc' suffixes exists, it will be read instead."
85   :group 'gnus-start
86   :type '(choice file (const nil)))
87
88 (defcustom gnus-use-dribble-file t
89   "*Non-nil means that Gnus will use a dribble file to store user updates.
90 If Emacs should crash without saving the .newsrc files, complete
91 information can be restored from the dribble file."
92   :group 'gnus-dribble-file
93   :type 'boolean)
94
95 (defcustom gnus-dribble-directory nil
96   "*The directory where dribble files will be saved.
97 If this variable is nil, the directory where the .newsrc files are
98 saved will be used."
99   :group 'gnus-dribble-file
100   :type '(choice directory (const nil)))
101
102 (defcustom gnus-check-new-newsgroups 'ask-server
103   "*Non-nil means that Gnus will run `gnus-find-new-newsgroups' at startup.
104 This normally finds new newsgroups by comparing the active groups the
105 servers have already reported with those Gnus already knows, either alive
106 or killed.
107
108 When any of the following are true, `gnus-find-new-newsgroups' will instead
109 ask the servers (primary, secondary, and archive servers) to list new
110 groups since the last time it checked:
111   1. This variable is `ask-server'.
112   2. This variable is a list of select methods (see below).
113   3. Option `gnus-read-active-file' is nil or `some'.
114   4. A prefix argument is given to `gnus-find-new-newsgroups' interactively.
115
116 Thus, if this variable is `ask-server' or a list of select methods or
117 `gnus-read-active-file' is nil or `some', then the killed list is no
118 longer necessary, so you could safely set `gnus-save-killed-list' to nil.
119
120 This variable can be a list of select methods which Gnus will query with
121 the `ask-server' method in addition to the primary, secondary, and archive
122 servers.
123
124 E.g.:
125   (setq gnus-check-new-newsgroups
126         '((nntp \"some.server\") (nntp \"other.server\")))
127
128 If this variable is nil, then you have to tell Gnus explicitly to
129 check for new newsgroups with \\<gnus-group-mode-map>\\[gnus-find-new-newsgroups]."
130   :group 'gnus-start
131   :type '(choice (const :tag "no" nil)
132                  (const :tag "by brute force" t)
133                  (const :tag "ask servers" ask-server)
134                  (repeat :menu-tag "ask additional servers"
135                          :tag "ask additional servers"
136                          :value ((nntp ""))
137                          (sexp :format "%v"))))
138
139 (defcustom gnus-check-bogus-newsgroups nil
140   "*Non-nil means that Gnus will check and remove bogus newsgroup at startup.
141 If this variable is nil, then you have to tell Gnus explicitly to
142 check for bogus newsgroups with \\<gnus-group-mode-map>\\[gnus-group-check-bogus-groups]."
143   :group 'gnus-start-server
144   :type 'boolean)
145
146 (defcustom gnus-read-active-file 'some
147   "*Non-nil means that Gnus will read the entire active file at startup.
148 If this variable is nil, Gnus will only know about the groups in your
149 `.newsrc' file.
150
151 If this variable is `some', Gnus will try to only read the relevant
152 parts of the active file from the server.  Not all servers support
153 this, and it might be quite slow with other servers, but this should
154 generally be faster than both the t and nil value.
155
156 If you set this variable to nil or `some', you probably still want to
157 be told about new newsgroups that arrive.  To do that, set
158 `gnus-check-new-newsgroups' to `ask-server'.  This may not work
159 properly with all servers."
160   :group 'gnus-start-server
161   :type '(choice (const nil)
162                  (const some)
163                  (const t)))
164
165 (defconst gnus-level-subscribed 5
166   "Groups with levels less than or equal to this variable are subscribed.")
167
168 (defconst gnus-level-unsubscribed 7
169   "Groups with levels less than or equal to this variable are unsubscribed.
170
171 Groups with levels less than `gnus-level-subscribed', which
172 should be less than this variable, are subscribed.  Groups with
173 levels from `gnus-level-subscribed' (exclusive) upto this
174 variable (inclusive) are unsubscribed.  See also
175 `gnus-level-zombie', `gnus-level-killed' and the Info node `(gnus)Group
176 Levels' for details.")
177
178 (defconst gnus-level-zombie 8
179   "Groups with this level are zombie groups.")
180
181 (defconst gnus-level-killed 9
182   "Groups with this level are killed.")
183
184 (defcustom gnus-level-default-subscribed 3
185   "*New subscribed groups will be subscribed at this level."
186   :group 'gnus-group-levels
187   :type 'integer)
188
189 (defcustom gnus-level-default-unsubscribed 6
190   "*New unsubscribed groups will be unsubscribed at this level."
191   :group 'gnus-group-levels
192   :type 'integer)
193
194 (defcustom gnus-activate-level (1+ gnus-level-subscribed)
195   "*Groups higher than this level won't be activated on startup.
196 Setting this variable to something low might save lots of time when
197 you have many groups that you aren't interested in."
198   :group 'gnus-group-levels
199   :type 'integer)
200
201 (defcustom gnus-activate-foreign-newsgroups 4
202   "*If nil, Gnus will not check foreign newsgroups at startup.
203 If it is non-nil, it should be a number between one and nine.  Foreign
204 newsgroups that have a level lower or equal to this number will be
205 activated on startup.  For instance, if you want to active all
206 subscribed newsgroups, but not the rest, you'd set this variable to
207 `gnus-level-subscribed'.
208
209 If you subscribe to lots of newsgroups from different servers, startup
210 might take a while.  By setting this variable to nil, you'll save time,
211 but you won't be told how many unread articles there are in the
212 groups."
213   :group 'gnus-group-levels
214   :type '(choice integer
215                  (const :tag "none" nil)))
216
217 (defcustom gnus-read-newsrc-file t
218   "*Non-nil means that Gnus will read the `.newsrc' file.
219 Gnus always reads its own startup file, which is called
220 \".newsrc.eld\".  The file called \".newsrc\" is in a format that can
221 be readily understood by other newsreaders.  If you don't plan on
222 using other newsreaders, set this variable to nil to save some time on
223 entry."
224   :version "21.1"
225   :group 'gnus-newsrc
226   :type 'boolean)
227
228 (defcustom gnus-save-newsrc-file t
229   "*Non-nil means that Gnus will save the `.newsrc' file.
230 Gnus always saves its own startup file, which is called
231 \".newsrc.eld\".  The file called \".newsrc\" is in a format that can
232 be readily understood by other newsreaders.  If you don't plan on
233 using other newsreaders, set this variable to nil to save some time on
234 exit."
235   :group 'gnus-newsrc
236   :type 'boolean)
237
238 (defcustom gnus-save-killed-list t
239   "*If non-nil, save the list of killed groups to the startup file.
240 If you set this variable to nil, you'll save both time (when starting
241 and quitting) and space (both memory and disk), but it will also mean
242 that Gnus has no record of which groups are new and which are old, so
243 the automatic new newsgroups subscription methods become meaningless.
244
245 You should always set `gnus-check-new-newsgroups' to `ask-server' or
246 nil if you set this variable to nil.
247
248 This variable can also be a regexp.  In that case, all groups that do
249 not match this regexp will be removed before saving the list."
250   :group 'gnus-newsrc
251   :type '(radio (sexp :format "Non-nil\n"
252                       :match (lambda (widget value)
253                                (and value (not (stringp value))))
254                       :value t)
255                 (const nil)
256                 regexp))
257
258 (defcustom gnus-ignored-newsgroups
259   (mapconcat 'identity
260              '("^to\\."                 ; not "real" groups
261                "^[0-9. \t]+\\( \\|$\\)" ; all digits in name
262                "^[\"][\"#'()]"  ; bogus characters
263                )
264              "\\|")
265   "*A regexp to match uninteresting newsgroups in the active file.
266 Any lines in the active file matching this regular expression are
267 removed from the newsgroup list before anything else is done to it,
268 thus making them effectively non-existent."
269   :group 'gnus-group-new
270   :type 'regexp)
271
272 (defcustom gnus-subscribe-newsgroup-method 'gnus-subscribe-zombies
273   "*Function(s) called with a group name when new group is detected.
274 A few pre-made functions are supplied: `gnus-subscribe-randomly'
275 inserts new groups at the beginning of the list of groups;
276 `gnus-subscribe-alphabetically' inserts new groups in strict
277 alphabetic order; `gnus-subscribe-hierarchically' inserts new groups
278 in hierarchical newsgroup order; `gnus-subscribe-interactively' asks
279 for your decision; `gnus-subscribe-killed' kills all new groups;
280 `gnus-subscribe-zombies' will make all new groups into zombies;
281 `gnus-subscribe-topics' will enter groups into the topics that
282 claim them."
283   :group 'gnus-group-new
284   :type '(radio (function-item gnus-subscribe-randomly)
285                 (function-item gnus-subscribe-alphabetically)
286                 (function-item gnus-subscribe-hierarchically)
287                 (function-item gnus-subscribe-interactively)
288                 (function-item gnus-subscribe-killed)
289                 (function-item gnus-subscribe-zombies)
290                 (function-item gnus-subscribe-topics)
291                 function
292                 (repeat function)))
293
294 (define-obsolete-variable-alias 'gnus-subscribe-newsgroup-hooks
295   'gnus-subscribe-newsgroup-functions "24.3")
296 (defcustom gnus-subscribe-newsgroup-functions nil
297   "*Hooks run after you subscribe to a new group.
298 The hooks will be called with new group's name as argument."
299   :version "22.1"
300   :group 'gnus-group-new
301   :type 'hook)
302
303 (defcustom gnus-subscribe-options-newsgroup-method
304   'gnus-subscribe-alphabetically
305   "*Function(s) called to subscribe newsgroups mentioned on \"options -n\" lines.
306 If, for instance, you want to subscribe to all newsgroups in the
307 \"no\" and \"alt\" hierarchies, you'd put the following in your
308 .newsrc file:
309
310 options -n no.all alt.all
311
312 Gnus will then subscribe all new newsgroups in these hierarchies
313 with the subscription method in this variable."
314   :group 'gnus-group-new
315   :type '(radio (function-item gnus-subscribe-randomly)
316                 (function-item gnus-subscribe-alphabetically)
317                 (function-item gnus-subscribe-hierarchically)
318                 (function-item gnus-subscribe-interactively)
319                 (function-item gnus-subscribe-killed)
320                 (function-item gnus-subscribe-zombies)
321                 (function-item gnus-subscribe-topics)
322                 function
323                 (repeat function)))
324
325 (defcustom gnus-subscribe-hierarchical-interactive nil
326   "*If non-nil, Gnus will offer to subscribe hierarchically.
327 When a new hierarchy appears, Gnus will ask the user:
328
329 'alt.binaries': Do you want to subscribe to this hierarchy? ([d]ys):
330
331 If the user pressed `d', Gnus will descend the hierarchy, `y' will
332 subscribe to all newsgroups in the hierarchy and `s' will skip this
333 hierarchy in its entirety."
334   :group 'gnus-group-new
335   :type 'boolean)
336
337 (defcustom gnus-auto-subscribed-categories '(mail post-mail)
338   "*New groups from methods of these categories will be subscribed automatically.
339 Note that this variable only deals with new groups.  It has no
340 effect whatsoever on old groups.  The default is to automatically
341 subscribe all groups from mail-like backends."
342   :version "24.1"
343   :group 'gnus-group-new
344   :type '(repeat symbol))
345
346 (defcustom gnus-auto-subscribed-groups
347   "^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl\\|^nnmaildir\\|^nnimap"
348   "*All new groups that match this regexp will be subscribed automatically.
349 Note that this variable only deals with new groups.  It has no effect
350 whatsoever on old groups.
351
352 New groups that match this regexp will not be handled by
353 `gnus-subscribe-newsgroup-method'.  Instead, they will
354 be subscribed using `gnus-subscribe-options-newsgroup-method'."
355   :group 'gnus-group-new
356   :type 'regexp)
357
358 (defcustom gnus-options-subscribe nil
359   "*All new groups matching this regexp will be subscribed unconditionally.
360 Note that this variable deals only with new newsgroups.  This variable
361 does not affect old newsgroups.
362
363 New groups that match this regexp will not be handled by
364 `gnus-subscribe-newsgroup-method'.  Instead, they will
365 be subscribed using `gnus-subscribe-options-newsgroup-method'."
366   :group 'gnus-group-new
367   :type '(choice regexp
368                  (const :tag "none" nil)))
369
370 (defcustom gnus-options-not-subscribe nil
371   "*All new groups matching this regexp will be ignored.
372 Note that this variable deals only with new newsgroups.  This variable
373 does not affect old (already subscribed) newsgroups."
374   :group 'gnus-group-new
375   :type '(choice regexp
376                  (const :tag "none" nil)))
377
378 (defcustom gnus-modtime-botch nil
379   "*Non-nil means .newsrc should be deleted prior to save.
380 Its use is due to the bogus appearance that .newsrc was modified on
381 disc."
382   :group 'gnus-newsrc
383   :type 'boolean)
384
385 (defcustom gnus-check-bogus-groups-hook nil
386   "A hook run after removing bogus groups."
387   :group 'gnus-start-server
388   :type 'hook)
389
390 (defcustom gnus-startup-hook nil
391   "A hook called at startup.
392 This hook is called after Gnus is connected to the NNTP server."
393   :group 'gnus-start
394   :type 'hook)
395
396 (defcustom gnus-before-startup-hook nil
397   "A hook called before startup.
398 This hook is called as the first thing when Gnus is started.
399 See also `gnus-before-resume-hook'."
400   :group 'gnus-start
401   :type 'hook)
402
403 (defcustom gnus-before-resume-hook nil
404   "A hook called before resuming Gnus after suspend.
405 This hook is called as the first thing when Gnus is resumed after a suspend.
406 See also `gnus-before-startup-hook'."
407   :version "24.4"
408   :group 'gnus-start
409   :type 'hook)
410
411 (defcustom gnus-started-hook nil
412   "A hook called as the last thing after startup."
413   :group 'gnus-start
414   :type 'hook)
415
416 (defcustom gnus-setup-news-hook nil
417   "A hook after reading the .newsrc file, but before generating the buffer."
418   :group 'gnus-start