;;; gnus-start.el --- startup functions for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-;; Free Software Foundation, Inc.
+
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
(autoload 'gnus-agent-save-local "gnus-agent")
(autoload 'gnus-agent-possibly-alter-active "gnus-agent")
-(eval-when-compile
+(eval-when-compile
(require 'cl)
(defvar gnus-agent-covered-methods nil)
"Whether to create backup files.
This variable takes the same values as the `version-control'
variable."
+ :version "22.1"
:group 'gnus-start
:type '(choice (const :tag "Never" never)
(const :tag "If existing" nil)
the buffer or write directly to the file. The buffer is faster
because all of the contents are written at once. The direct write
uses considerably less memory."
+ :version "22.1"
:group 'gnus-start
:type '(choice (const :tag "Write via buffer" t)
(const :tag "Write directly to file" nil)))
(and value (not (stringp value))))
:value t)
(const nil)
- (regexp :format "%t: %v\n" :size 0)))
+ regexp))
(defcustom gnus-ignored-newsgroups
(mapconcat 'identity
(defcustom gnus-subscribe-newsgroup-hooks nil
"*Hooks run after you subscribe to a new group.
The hooks will be called with new group's name as argument."
+ :version "22.1"
:group 'gnus-group-new
:type 'hook)
(defcustom gnus-get-top-new-news-hook nil
"A hook run just before Gnus checks for new news globally."
+ :version "22.1"
:group 'gnus-group-new
:type 'hook)
"Subscribe the new GROUP interactively.
It is inserted in hierarchical newsgroup order if subscribed. If not,
it is killed."
- (if (gnus-y-or-n-p (format "Subscribe new newsgroup: %s " group))
+ (if (gnus-y-or-n-p (format "Subscribe new newsgroup %s? " group))
(gnus-subscribe-hierarchically group)
(push group gnus-killed-list)))
(defun gnus-no-server-1 (&optional arg slave)
"Read network news.
-If ARG is a positive number, Gnus will use that as the
-startup level. If ARG is nil, Gnus will be started at level 2.
-If ARG is non-nil and not a positive number, Gnus will
-prompt the user for the name of an NNTP server to use.
-As opposed to `gnus', this command will not connect to the local server."
+If ARG is a positive number, Gnus will use that as the startup
+level. If ARG is nil, Gnus will be started at level 2
+\(`gnus-level-default-subscribed' minus one). If ARG is non-nil
+and not a positive number, Gnus will prompt the user for the name
+of an NNTP server to use. As opposed to \\[gnus], this command
+will not connect to the local server."
(interactive "P")
(let ((val (or arg (1- gnus-level-default-subscribed))))
(gnus val t slave)
(nnheader-init-server-buffer)
(setq gnus-slave slave)
(gnus-read-init-file)
+
+ ;; Add "native" to gnus-predefined-server-alist just to have a
+ ;; name for the native select method.
+ (when gnus-select-method
+ (push (cons "native" gnus-select-method)
+ gnus-predefined-server-alist))
+
(if gnus-agent
(gnus-agentize))
(gnus-request-create-group "drafts" '(nndraft ""))
(unless (gnus-group-entry "nndraft:drafts")
(let ((gnus-level-default-subscribed 1))
- (gnus-subscribe-group "nndraft:drafts" nil '(nndraft "")))
+ (gnus-subscribe-group "nndraft:drafts" nil '(nndraft ""))))
+ (unless (equal (gnus-group-get-parameter "nndraft:drafts" 'gnus-dummy t)
+ '((gnus-draft-mode)))
+ (gnus-message 3 "Setting up drafts group")
(gnus-group-set-parameter
"nndraft:drafts" 'gnus-dummy '((gnus-draft-mode)))))
(set-buffer (setq gnus-dribble-buffer
(gnus-get-buffer-create
(file-name-nondirectory dribble-file))))
+ (set (make-local-variable 'file-precious-flag) t)
(erase-buffer)
(setq buffer-file-name dribble-file)
(auto-save-mode t)
(when (and (file-exists-p gnus-current-startup-file)
(file-exists-p dribble-file)
(setq modes (file-modes gnus-current-startup-file)))
- (set-file-modes dribble-file modes))
+ (gnus-set-file-modes dribble-file modes))
(goto-char (point-min))
(when (search-forward "Gnus was exited on purpose" nil t)
(setq purpose t))
;; Make sure the archive server is available to all and sundry.
(when gnus-message-archive-method
(unless (assoc "archive" gnus-server-alist)
- (push `("archive"
- nnfolder
- "archive"
- (nnfolder-directory
- ,(nnheader-concat message-directory "archive"))
- (nnfolder-active-file
- ,(nnheader-concat message-directory "archive/active"))
- (nnfolder-get-new-mail nil)
- (nnfolder-inhibit-expiry t))
- gnus-server-alist)))
+ (let ((method (or (and (stringp gnus-message-archive-method)
+ (gnus-server-to-method
+ gnus-message-archive-method))
+ gnus-message-archive-method)))
+ ;; Check whether the archive method is writable.
+ (unless (or (stringp method)
+ (memq 'respool (assoc (format "%s" (car method))
+ gnus-valid-select-methods)))
+ (setq method "archive")) ;; The default.
+ (push (if (stringp method)
+ `("archive"
+ nnfolder
+ ,method
+ (nnfolder-directory
+ ,(nnheader-concat message-directory method))
+ (nnfolder-active-file
+ ,(nnheader-concat message-directory
+ (concat method "/active")))
+ (nnfolder-get-new-mail nil)
+ (nnfolder-inhibit-expiry t))
+ (cons "archive" method))
+ gnus-server-alist))))
;; If we don't read the complete active file, we fill in the
;; hashtb here.
(setcdr active (cdr cache-active))))))))
(defun gnus-activate-group (group &optional scan dont-check method)
- ;; Check whether a group has been activated or not.
- ;; If SCAN, request a scan of that group as well.
+ "Check whether a group has been activated or not.
+If SCAN, request a scan of that group as well."
(let ((method (or method (inline (gnus-find-method-for-group group))))
active)
(and (inline (gnus-check-server method))
;; command may have responded with the `(0 . 0)'. We
;; ignore this if we already have an active entry
;; for the group.
- (if (and (zerop (car active))
- (zerop (cdr active))
+ (if (and (zerop (or (car active) 0))
+ (zerop (or (cdr active) 0))
(gnus-active group))
(gnus-active group)
(cond ((and method (eq method-type 'foreign))
;; These groups are foreign. Check the level.
(if (<= (gnus-info-level info) foreign-level)
- (when (and (<= (gnus-info-level info) foreign-level)
- (setq active (gnus-activate-group group 'scan)))
+ (when (setq active (gnus-activate-group group 'scan))
;; Let the Gnus agent save the active file.
(when (and gnus-agent active (gnus-online method))
(gnus-agent-save-group-info
(defun gnus-make-hashtable-from-newsrc-alist ()
(let ((alist gnus-newsrc-alist)
(ohashtb gnus-newsrc-hashtb)
- prev)
+ prev info method rest methods)
(setq gnus-newsrc-hashtb (gnus-make-hashtable (length alist)))
(setq alist
(setq prev (setq gnus-newsrc-alist
gnus-newsrc-alist
(cons (list "dummy.group" 0 nil) alist)))))
(while alist
+ (setq info (car alist))
+ ;; Make the same select-methods identical Lisp objects.
+ (when (setq method (gnus-info-method info))
+ (if (setq rest (member method methods))
+ (gnus-info-set-method info (car rest))
+ (push method methods)))
(gnus-sethash
- (caar alist)
+ (car info)
;; Preserve number of unread articles in groups.
- (cons (and ohashtb (car (gnus-gethash (caar alist) ohashtb)))
+ (cons (and ohashtb (car (gnus-gethash (car info) ohashtb)))
prev)
gnus-newsrc-hashtb)
(setq prev alist
- alist (cdr alist)))))
+ alist (cdr alist)))
+ ;; Make the same select-methods in `gnus-server-alist' identical
+ ;; as well.
+ (while methods
+ (setq method (pop methods))
+ (when (setq rest (rassoc method gnus-server-alist))
+ (setcdr rest method)))))
(defun gnus-make-hashtable-from-killed ()
"Create a hash table from the killed and zombie lists."
(setcdr range (1- article))
(setq modified t)
ranges))))))))
-
+
(when modified
(when (eq modified 'remove-null)
(setq r (delq nil r)))
(defun gnus-convert-old-newsrc ()
"Convert old newsrc formats into the current format, if needed."
(let ((fcv (and gnus-newsrc-file-version
- (gnus-continuum-version gnus-newsrc-file-version))))
+ (gnus-continuum-version gnus-newsrc-file-version)))
+ (gcv (gnus-continuum-version)))
(when fcv
- ;; A .newsrc.eld file was loaded.
+ ;; A newsrc file was loaded.
(let (prompt-displayed
(converters
(sort
;; doesn't change with each release) and the
;; function that must be applied to convert the
;; previous version into the current version.
- '(("September Gnus v0.1" nil
+ '(("September Gnus v0.1" nil
gnus-convert-old-ticks)
("Oort Gnus v0.08" "legacy-gnus-agent"
gnus-agent-convert-to-compressed-agentview)
- ("No Gnus v0.2" "legacy-gnus-agent"
+ ("Gnus v5.10.7" "legacy-gnus-agent"
gnus-agent-unlist-expire-days)
- ("No Gnus v0.2" "legacy-gnus-agent"
+ ("Gnus v5.10.7" "legacy-gnus-agent"
gnus-agent-unhook-expire-days)))
#'car-less-than-car)))
;; Skip converters older than the file version
;; Perform converters to bring older version up to date.
(when (and converters (< fcv (caar converters)))
- (while (and converters (< fcv (caar converters)))
+ (while (and converters (< fcv (caar converters))
+ (<= (caar converters) gcv))
(let* ((converter-spec (pop converters))
(convert-to (nth 1 converter-spec))
(load-from (nth 2 converter-spec))
(when (and load-from
(not (fboundp func)))
(load load-from t))
-
(or prompt-displayed
(not (gnus-convert-converter-needs-prompt func))
(while (let (c
(cursor-in-echo-area t)
(echo-keystrokes 0))
- (message "Convert newsrc from version '%s' to '%s'? (n/y/?)"
+ (message "Convert gnus from version '%s' to '%s'? (n/y/?)"
gnus-newsrc-file-version gnus-version)
(setq c (read-char-exclusive))
(cond ((or (eq c ?n) (eq c ?N))
- (error "Can not start gnus using old (unconverted) newsrc"))
+ (error "Can not start gnus without converting"))
((or (eq c ?y) (eq c ?Y))
(setq prompt-displayed t)
nil)
((eq c ?\?)
(message "This conversion is irreversible. \
- You should backup your files before proceeding.")
+ To be safe, you should backup your files before proceeding.")
(sit-for 5)
t)
(t
t)))))
(funcall func convert-to)))
- (gnus-dribble-enter
- (format ";Converted newsrc from version '%s' to '%s'? (n/y/?)"
+ (gnus-dribble-enter
+ (format ";Converted gnus from version '%s' to '%s'."
gnus-newsrc-file-version gnus-version)))))))
(defun gnus-convert-mark-converter-prompt (converter no-prompt)
- (setplist converter
- (let* ((symbol 'gnus-convert-no-prompt)
- (value (delq symbol (symbol-plist converter))))
- (if no-prompt
- (cons symbol value)
- value))))
+ "Indicate whether CONVERTER requires gnus-convert-old-newsrc to
+ display the conversion prompt. NO-PROMPT may be nil (prompt),
+ t (no prompt), or any form that can be called as a function.
+ The form should return either t or nil."
+ (put converter 'gnus-convert-no-prompt no-prompt))
(defun gnus-convert-converter-needs-prompt (converter)
- (not (memq 'gnus-convert-no-prompt (symbol-plist converter))))
+ (let ((no-prompt (get converter 'gnus-convert-no-prompt)))
+ (not (if (memq no-prompt '(t nil))
+ no-prompt
+ (funcall no-prompt)))))
(defun gnus-convert-old-ticks (converting-to)
(let ((newsrc (cdr gnus-newsrc-alist))
(cond
((looking-at "[0-9]+")
;; We narrow and read a number instead of buffer-substring/
- ;; string-to-int because it's faster. narrow/widen is
+ ;; string-to-number because it's faster. narrow/widen is
;; faster than save-restriction/narrow, and save-restriction
;; produces a garbage object.
(setq num1 (progn
;; Replace the existing startup file with the temp file.
(rename-file working-file startup-file t)
- (set-file-modes startup-file setmodes)))
+ (gnus-set-file-modes startup-file setmodes)))
(condition-case nil
(delete-file working-file)
(file-error nil)))))
(print-escape-nonascii t)
(print-length nil)
(print-level nil)
+ (print-circle nil)
(print-escape-newlines t)
(gnus-killed-list
(if (and gnus-save-killed-list
(let ((coding-system-for-write gnus-ding-file-coding-system))
(gnus-write-buffer slave-name))
(when modes
- (set-file-modes slave-name modes)))))
+ (gnus-set-file-modes slave-name modes)))))
(defun gnus-master-read-slave-newsrc ()
(let ((slave-files
(file-name-as-directory (expand-file-name gnus-default-directory))
default-directory)))
-(eval-and-compile
-(defalias 'gnus-display-time-event-handler
- (if (gnus-boundp 'display-time-timer)
- 'display-time-event-handler
- (lambda () "Does nothing as `display-time-timer' is not bound.
-Would otherwise be an alias for `display-time-event-handler'." nil))))
+(defun gnus-display-time-event-handler ()
+ (if (and (fboundp 'display-time-event-handler)
+ (gnus-boundp 'display-time-timer))
+ (display-time-event-handler)))
;;;###autoload
(defun gnus-fixup-nnimap-unread-after-getting-new-news ()
(symbol-value 'nnimap-mailbox-info)
(make-vector 1 0)))))
+(defun gnus-check-reasonable-setup ()
+ ;; Check whether nnml and nnfolder share a directory.
+ (let ((display-warn
+ (if (fboundp 'display-warning)
+ 'display-warning
+ (lambda (type message)
+ (if noninteractive
+ (message "Warning (%s): %s" type message)
+ (let (window)
+ (with-current-buffer (get-buffer-create "*Warnings*")
+ (goto-char (point-max))
+ (unless (bolp)
+ (insert "\n"))
+ (insert (format "Warning (%s): %s\n" type message))
+ (setq window (display-buffer (current-buffer)))
+ (set-window-start
+ window
+ (prog2
+ (forward-line (- 1 (window-height window)))
+ (point)
+ (goto-char (point-max))))))))))
+ method active actives match)
+ (dolist (server gnus-server-alist)
+ (setq method (gnus-server-to-method server)
+ active (intern (format "%s-active-file" (car method))))
+ (when (and (member (car method) '(nnml nnfolder))
+ (gnus-server-opened method)
+ (boundp active))
+ (when (setq match (assoc (symbol-value active) actives))
+ (funcall display-warn 'gnus-server
+ (format "%s and %s share the same active file %s"
+ (car method)
+ (cadr match)
+ (car match))))
+ (push (list (symbol-value active) method) actives)))))
(provide 'gnus-start)
-;;; arch-tag: f4584a22-b7b7-4853-abfc-a637329af5d2
+;; arch-tag: f4584a22-b7b7-4853-abfc-a637329af5d2
;;; gnus-start.el ends here