;;; gnus.el --- a newsreader for GNU Emacs
-;; Copyright (C) 1987,88,89,90,93,94,95 Free Software Foundation, Inc.
+
+;; Copyright (C) 1987,88,89,90,93,94,95,96 Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
;; GNU General Public License for more details.
;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; 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.
;;; Commentary:
(article ([summary 0.25 point]
(if gnus-carpal [summary-carpal 4])
[article 1.0]))
+ (pipe ([summary 0.25 point]
+ (if gnus-carpal [summary-carpal 4])
+ [pipe 1.0]))
(server ([server 1.0 point]
(if gnus-carpal [server-carpal 2])))
(browse ([browse 1.0 point]
(followup-yank ([post 1.0 point])))
"Window configuration for all possible Gnus buffers.
This variable is a list of lists. Each of these lists has a NAME and
-a RULE. The NAMEs are commonsense names like `group', which names a
+a RULE. The NAMEs are common-sense names like `group', which names a
rule used when displaying the group buffer; `summary', which names a
rule for what happens when you enter a group and do not display an
article buffer; and so on. See the value of this variable for a
(article . gnus-article-buffer)
(server . gnus-server-buffer)
(browse . "*Gnus Browse Server*")
+ (pipe . "*Shell Command Output*")
(edit-group . gnus-group-edit-buffer)
(edit-server . gnus-server-edit-buffer)
(group-carpal . gnus-carpal-group-buffer)
%S The subject")
-(defvar gnus-summary-mode-line-format "Gnus %G/%A %Z"
+(defvar gnus-summary-mode-line-format "Gnus: %b [%A] %Z"
"*The format specification for the summary mode line.")
-(defvar gnus-article-mode-line-format "Gnus %G/%A %S"
+(defvar gnus-article-mode-line-format "Gnus: %b %S"
"*The format specification for the article mode line.")
-(defvar gnus-group-mode-line-format "Gnus List of groups {%M:%S} "
+(defvar gnus-group-mode-line-format "Gnus: %b {%M:%S} "
"*The format specification for the group mode line.")
(defvar gnus-valid-select-methods
If this variable is nil, screen refresh may be quicker.")
;; Added by Keinonen Kari <kk85613@cs.tut.fi>.
-(defvar gnus-mode-non-string-length 21
+(defvar gnus-mode-non-string-length nil
"*Max length of mode-line non-string contents.
If this is nil, Gnus will take space as is needed, leaving the rest
of the modeline intact.")
(list ?S 'subject ?s)
(list ?e 'unselected ?d)
(list ?u 'user-defined ?s)
+ (list ?b 'buffer-name ?s)
(list ?s '(gnus-current-score-file-nondirectory) ?s)))
(defconst gnus-group-mode-line-format-alist
(list (list ?S 'news-server ?s)
(list ?M 'news-method ?s)
+ (list ?b '(buffer-name) ?s)
(list ?u 'user-defined ?s)))
(defvar gnus-have-read-active-file nil)
; Let the byte-compiler know that we know about this variable.
(defvar rmail-default-rmail-file)
-(defvar gnus-cache-removeable-articles nil)
+(defvar gnus-cache-removable-articles nil)
(defconst gnus-summary-local-variables
'(gnus-newsgroup-name
gnus-summary-mark-below gnus-newsgroup-active gnus-scores-exclude-files
gnus-newsgroup-history gnus-newsgroup-ancient
(gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
- gnus-cache-removeable-articles)
+ gnus-cache-removable-articles)
"Variables that are buffer-local to the summary buffers.")
(defconst gnus-bug-message
;;; Load the user startup file.
;; (eval '(gnus-read-init-file 'inhibit))
-;;; Load the compatability functions.
+;;; Load the compatibility functions.
(require 'gnus-cus)
(require 'gnus-ems)
(defun gnus-newsgroup-directory-form (newsgroup)
"Make hierarchical directory name from NEWSGROUP name."
- (let ((newsgroup (gnus-newsgroup-saveable-name newsgroup))
+ (let ((newsgroup (gnus-newsgroup-savable-name newsgroup))
(len (length newsgroup))
idx)
;; If this is a foreign group, we don't want to translate the
(setq idx (1+ idx)))
newsgroup))
-(defun gnus-newsgroup-saveable-name (group)
+(defun gnus-newsgroup-savable-name (group)
;; Replace any slashes in a group name (eg. an ange-ftp nndoc group)
;; with dots.
(gnus-replace-chars-in-string group ?/ ?.))
(setq hor (cdr hor))))
;; Go through the rules and eval the elements that are to be
- ;; evaled.
+ ;; evalled.
(while hor
(if (setq val (if (vectorp (car hor)) (car hor) (eval (car hor))))
(progn
(setq heights (nreverse heights)
hor (car rule))
- ;; We then go through these heighs and create windows for them.
+ ;; We then go through these heights and create windows for them.
(while heights
(setq height (car heights)
heights (cdr heights))
(defun gnus-all-windows-visible-p (rule)
(let (invisible hor jump-buffer val buffer)
;; Go through the rules and eval the elements that are to be
- ;; evaled.
+ ;; evalled.
(while (and rule (not invisible))
(setq hor (car rule)
rule (cdr rule))
(defun gnus-message (level &rest args)
(if (<= level gnus-verbose)
(apply 'message args)
- ;; We have to do this format thingie here even if the result isn't
+ ;; We have to do this format thingy here even if the result isn't
;; shown - the return value has to be the same as the return value
;; from `message'.
(apply 'format args)))
"Return the quit-config of GROUP."
(nth 1 (assoc 'quit-config (gnus-find-method-for-group group))))
+(defun gnus-simplify-mode-line ()
+ "Make mode lines a bit simpler."
+ (setq mode-line-modified "-- ")
+ (if (listp mode-line-format)
+ (progn
+ (make-local-variable 'mode-line-format)
+ (setq mode-line-format (copy-sequence mode-line-format))
+ (and (equal (nth 3 mode-line-format) " ")
+ (setcar (nthcdr 3 mode-line-format) "")))))
+
;;; List and range functions
(defun gnus-last-element (list)
(interactive)
(if gnus-visual (gnus-group-make-menu-bar))
(kill-all-local-variables)
- (setq mode-line-modified "-- ")
- (make-local-variable 'mode-line-format)
- (setq mode-line-format (copy-sequence mode-line-format))
- (and (equal (nth 3 mode-line-format) " ")
- (setcar (nthcdr 3 mode-line-format) ""))
+ (gnus-simplify-mode-line)
(setq major-mode 'gnus-group-mode)
(setq mode-name "Group")
(gnus-group-set-mode-line)
(gnus (or arg (1- gnus-level-default-subscribed)) t)
(setq gnus-tmp-prev-perm perm)))
+;;;###autoload
+(defun read-news (&optional arg dont-connect)
+ "Read network news. This is an alias for the `gnus' command."
+ (gnus arg dont-connect))
+
;;;###autoload
(defun gnus (&optional arg dont-connect)
"Read network news.
;; Go to the first group with unread articles.
(gnus-group-search-forward nil nil nil t)
;; Find the right group to put point on. If the current group
- ;; has disapeared in the new listing, try to find the next
+ ;; has disappeared in the new listing, try to find the next
;; one. If no next one can be found, just leave point at the
;; first newsgroup in the buffer.
(if (not (gnus-goto-char
(or all ; We list all groups?
(eq unread t) ; We list unactivated groups
(> unread 0) ; We list groups with unread articles
- (cdr (assq 'tick (nth 3 info)))) ; And groups with tickeds
+ (cdr (assq 'tick (nth 3 info)))) ; And ticked groups
(gnus-group-insert-group-line
nil group (car (cdr info)) (nth 3 info) unread (nth 4 info)))))
(run-hooks 'gnus-group-prepare-hook)))
(defun gnus-group-prepare-flat-list-dead (groups level mark regexp)
- ;; List zombies and killed lists somehwat faster, which was
+ ;; List zombies and killed lists somewhat faster, which was
;; suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>. It does
;; this by ignoring the group format specification altogether.
(let (group beg)
()
(or entry
(error "Trying to change non-existent group %s" method-only-group))
- ;; We have recevied parts of the actual group info - either the
+ ;; We have received parts of the actual group info - either the
;; select method or the group parameters. We first check
;; whether we have to extend the info, and if so, do that.
(let ((len (length info))
(news-server (car (cdr gnus-select-method)))
(news-method (car gnus-select-method))
(max-len 60)
+ header ;Dummy binding for user-defined specs.
(mode-string (eval gformat)))
(setq mode-string (eval gformat))
(if (> (length mode-string) max-len)
(defun gnus-group-make-help-group ()
"Create the Gnus documentation group."
(interactive)
- (let ((path (cons (concat installation-directory "etc/") load-path))
+ (let ((path (if installation-directory
+ (cons (concat installation-directory "etc/") load-path)
+ (cons data-directory load-path)))
(name (gnus-group-prefixed-name "gnus-help" '(nndoc "gnus-help")))
file)
(and (gnus-gethash name gnus-newsrc-hashtb)
(interactive)
(kill-all-local-variables)
(if gnus-visual (gnus-browse-make-menu-bar))
- (setq mode-line-modified "-- ")
- (make-local-variable 'mode-line-format)
- (setq mode-line-format (copy-sequence mode-line-format))
- (and (equal (nth 3 mode-line-format) " ")
- (setcar (nthcdr 3 mode-line-format) ""))
+ (gnus-simplify-mode-line)
(setq major-mode 'gnus-browse-mode)
(setq mode-name "Browse Server")
(setq mode-line-process nil)
(set (car locals) nil))
(setq locals (cdr locals))))
(gnus-make-thread-indent-array)
- (setq mode-line-modified "-- ")
- (make-local-variable 'mode-line-format)
- (setq mode-line-format (copy-sequence mode-line-format))
- (and (equal (nth 3 mode-line-format) " ")
- (setcar (nthcdr 3 mode-line-format) ""))
+ (gnus-simplify-mode-line)
(setq major-mode 'gnus-summary-mode)
(setq mode-name "Summary")
(make-local-variable 'minor-mode-alist)
(gnus-kill-buffer kill-buffer)
(if (not (get-buffer-window gnus-group-buffer))
()
- ;; gotta use windows, because recenter does wierd stuff if
+ ;; gotta use windows, because recenter does weird stuff if
;; the current buffer ain't the displayed window.
(let ((owin (selected-window)))
(select-window (get-buffer-window gnus-group-buffer))
(defun gnus-make-threads ()
;; This function takes the dependencies already made by
;; `gnus-get-newsgroup-headers' and builds the trees. First we go
- ;; through the dependecies in the hash table and finds all the
+ ;; through the dependencies in the hash table and finds all the
;; roots. Roots do not refer back to any valid articles.
(gnus-message 6 "Threading...")
(let (roots new-roots)
(defun gnus-make-threads-and-expunge ()
;; This function takes the dependencies already made by
;; `gnus-get-newsgroup-headers' and builds the trees. First we go
- ;; through the dependecies in the hash table and finds all the
+ ;; through the dependencies in the hash table and finds all the
;; roots. Roots do not refer back to any valid articles.
(gnus-message 6 "Threading...")
(let ((default (or gnus-summary-default-score 0))
"Prepare summary buffer from THREADS and indentation LEVEL.
THREADS is either a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...])'
or a straight list of headers."
- (message "Generating summary...")
+ (gnus-message 5 "Generating summary...")
(let ((level 0)
thread header number subject stack state gnus-tmp-gathered)
(if (vectorp (car threads))
(setq stack (cons (cons (max 0 level) (nthcdr 1 thread)) stack)))
(setq level (1+ level))
(setq threads (cdr (car thread))))))
- (message "Generating summary...done"))
+ (gnus-message 5 "Generating summary...done"))
(cond ((or (eq 'tick (car prev)) (eq 'dormant (car prev)))
;; Make sure that all ticked articles are a subset of the
;; unread/unselected articles.
- (while m
- (if (or (memq (car m) gnus-newsgroup-unreads)
- (memq (car m) gnus-newsgroup-unselected))
- (setq prev m)
- (setcdr prev (cdr m)))
- (setq m (cdr m))))
+ ;;(while m
+ ;; (if (or (memq (car m) gnus-newsgroup-unreads)
+ ;; (memq (car m) gnus-newsgroup-unselected))
+ ;; (setq prev m)
+ ;; (setcdr prev (cdr m)))
+ ;; (setq m (cdr m)))
+ )
((eq 'score (car prev))
;; Scored articles should be a subset of
;; unread/unselected articles.
(let* ((mformat (if (eq where 'article)
gnus-article-mode-line-format-spec
gnus-summary-mode-line-format-spec))
+ (buffer-name (if (eq where 'article)
+ (buffer-name
+ (get-buffer gnus-article-buffer))
+ (buffer-name)))
(group-name gnus-newsgroup-name)
(article-number (or gnus-current-article 0))
(unread (- (length gnus-newsgroup-unreads)
;; crossposted article that has a higher number than
;; Gnus believes possible. So we re-activate this
;; group as well. This might mean doing the
- ;; crossposting thingie will *increase* the number
+ ;; crossposting thingy will *increase* the number
;; of articles in some groups. Tsk, tsk.
(setq active (or (gnus-activate-group group) active))))
(if (or (> id (cdr active))
(if (setq art-group
(gnus-request-move-article
(car articles) ; Article to move
- gnus-newsgroup-name ; From newsgrouo
+ gnus-newsgroup-name ; From newsgroup
(nth 1 (gnus-find-method-for-group
gnus-newsgroup-name)) ; Server
(list 'gnus-request-accept-article
(setq es (gnus-request-expire-articles expirable gnus-newsgroup-name))
(or total (setq gnus-newsgroup-expirable es))
;; We go through the old list of expirable, and mark all
- ;; really expired articles as non-existant.
+ ;; really expired articles as nonexistent.
(or (eq es expirable) ;If nothing was expired, we don't mark.
(let ((gnus-use-cache nil))
(while expirable
(gnus-set-global-variables)
(let ((buffer-read-only nil)
(orig-article
- (progn
+ (let ((gnus-summary-check-current t))
(gnus-summary-search-forward t)
(gnus-summary-article-number)))
(marks (concat "^[" marks "]")))
(error "No default saver is defined."))))
(if (assq 'name header)
(gnus-copy-file (cdr (assq 'name header)))
- (gnus-message 1 "Article %d is unsaveable" (car articles)))))
+ (gnus-message 1 "Article %d is unsavable" (car articles)))))
(gnus-summary-remove-process-mark (car articles))
(setq articles (cdr articles)))
(gnus-summary-position-cursor)
(interactive "P")
(gnus-set-global-variables)
(let ((gnus-default-article-saver 'gnus-summary-save-in-pipe))
- (gnus-summary-save-article arg)))
+ (gnus-summary-save-article arg))
+ (gnus-configure-windows 'pipe))
(defun gnus-summary-save-article-mail (&optional arg)
"Append the current article to an mail file.
(put 'gnus-article-mode 'mode-class 'special)
-(defvar gnus-boogaboo nil)
+(defvar gnus-bugaboo nil)
(if gnus-article-mode-map
nil
;; "Of" "Oh" "Ov" "Op" "Vu" "V\C-s" "V\C-r" "Vr" "V&" "VT" "Ve"
;; "VD" "Vk" "VK" "Vsn" "Vsa" "Vss" "Vsd" "Vsi"
)))
- (while (and gnus-boogaboo commands) ; disabled
+ (while (and gnus-bugaboo commands) ; disabled
(define-key gnus-article-mode-map (car commands)
'gnus-article-summary-command)
(setq commands (cdr commands))))
(let ((commands (list "q" "Q" "c" "r" "R" "\C-c\C-f" "m" "a" "f" "F"
;; "Zc" "ZC" "ZE" "ZQ" "ZZ" "Zn" "ZR" "ZG" "ZN" "ZP"
"=" "n" "^" "\M-^")))
- (while (and gnus-boogaboo commands) ; disabled
+ (while (and gnus-bugaboo commands) ; disabled
(define-key gnus-article-mode-map (car commands)
'gnus-article-summary-command-nosave)
(setq commands (cdr commands)))))
(interactive)
(if gnus-visual (gnus-article-make-menu-bar))
(kill-all-local-variables)
- (setq mode-line-modified "-- ")
- (make-local-variable 'mode-line-format)
- (setq mode-line-format (copy-sequence mode-line-format))
- (and (equal (nth 3 mode-line-format) " ")
- (setcar (nthcdr 3 mode-line-format) ""))
+ (gnus-simplify-mode-line)
(setq mode-name "Article")
(setq major-mode 'gnus-article-mode)
(make-local-variable 'minor-mode-alist)
(defun gnus-article-hide-headers-if-wanted ()
"Hide unwanted headers if `gnus-have-all-headers' is nil.
-Provided for backwards compatability."
+Provided for backwards compatibility."
(or (save-excursion (set-buffer gnus-summary-buffer) gnus-have-all-headers)
(gnus-article-hide-headers)))
((eq type 'lapsed)
;; If the date is seriously mangled, the timezone
;; functions are liable to bug out, so we condition-case
- ;; the entire thing.
- (let* ((real-sec (condition-case ()
+ ;; the entire thing. We call (current-time) once, rather than
+ ;; letting current-time-string and current-time-zone default to
+ ;; it, because that avoids a rare race condition when the time
+ ;; zone changes between those two calls.
+ (let* ((now (current-time))
+ (real-sec (condition-case ()
(- (gnus-seconds-since-epoch
(timezone-make-date-arpa-standard
- (current-time-string)
- (current-time-zone) "UT"))
+ (current-time-string now)
+ (current-time-zone now) "UT"))
(gnus-seconds-since-epoch
(timezone-make-date-arpa-standard
date nil "UT")))
(delete-region (match-beginning 1) (match-end 1))
(insert
(timezone-make-date-arpa-standard
- date nil (current-time-zone))))))))
+ date)))))))
;; Article mode commands
(or gnus-kill-files-directory "~/News")))
((gnus-use-long-file-name 'not-kill)
;; Append ".KILL" to newsgroup name.
- (expand-file-name (concat (gnus-newsgroup-saveable-name newsgroup)
+ (expand-file-name (concat (gnus-newsgroup-savable-name newsgroup)
"." gnus-kill-file-name)
(or gnus-kill-files-directory "~/News")))
(t
(nth 1 method) accept-function last)))
(defun gnus-request-accept-article (group &optional last)
+ (goto-char (point-max))
+ (or (bolp) (insert "\n"))
(let ((func (if (symbolp group) group
(car (gnus-find-method-for-group group)))))
(funcall (intern (format "%s-request-accept-article" func))
(gnus-message 6 "No new newsgroups."))))))
(defun gnus-matches-options-n (group)
- ;; Returns `subscribe' if the group is to be uncoditionally
+ ;; Returns `subscribe' if the group is to be unconditionally
;; subscribed, `ignore' if it is to be ignored, and nil if there is
;; no match for the group.
(while (and dormant (< (car dormant) (car active)))
(setq dormant (cdr dormant)))
(setq unread (sort (append unselected unread) '<))
+ ;; Weed out duplicates.
+ (let ((un unread))
+ (while (cdr un)
+ (if (eq (car un) (car (cdr un)))
+ (setcdr un (cdr (cdr un)))
+ (setq un (cdr un)))))
;; Compute the ranges of read articles by looking at the list of
;; unread articles.
(while unread
((or (eq symbol options-symbol)
(eq symbol Options-symbol))
(setq gnus-newsrc-options
- ;; This concatting is quite inefficient, but since our
+ ;; This concating is quite inefficient, but since our
;; thorough studies show that approx 99.37% of all
;; .newsrc files only contain a single options line, we
;; don't give a damn, frankly, my dear.
gnus-current-startup-file)))
;; Quickly loadable .newsrc.
(set-buffer (get-buffer-create " *Gnus-newsrc*"))
+ (make-local-variable 'version-control)
+ (setq version-control 'never)
(setq buffer-file-name (concat gnus-current-startup-file ".eld"))
(gnus-add-current-to-buffer-list)
(buffer-disable-undo (current-buffer))
(if ranges (insert ","))))))
(insert "\n")))
(setq newsrc (cdr newsrc)))
+ (make-local-variable 'version-control)
+ (setq version-control 'never)
;; It has been reported that sometime the modtime on the .newsrc
;; file seems to be off. We really do want to overwrite it, so
;; we clear the modtime here before saving. It's a bit odd,
(interactive)
(if gnus-visual (gnus-server-make-menu-bar))
(kill-all-local-variables)
- (setq mode-line-modified "-- ")
- (make-local-variable 'mode-line-format)
- (setq mode-line-format (copy-sequence mode-line-format))
- (and (equal (nth 3 mode-line-format) " ")
- (setcar (nthcdr 3 mode-line-format) ""))
+ (gnus-simplify-mode-line)
(setq major-mode 'gnus-server-mode)
(setq mode-name "Server")
; (gnus-group-set-mode-line)
(goto-char (point-min))
(while (re-search-forward "[/:]" nil t)
(replace-match "." t t))
- ;; Cludge to get rid of "nntp+" problems.
+ ;; Kludge to get rid of "nntp+" problems.
(goto-char (point-min))
(and (looking-at "nn[a-z]+\\+")
(progn
(concat gnus-kill-files-directory
(gnus-replace-chars-in-string group ?. ?/ ?: ?/)
"/" gnus-score-file-suffix)))))
- ;; The localest score file might already be there, but it's
+ ;; The local score file might already be there, but it's
;; supposed to be the very last file, so we delete it from the
;; list if it's already there, and add it to the head of the
;; list.
suffix (or gnus-kill-files-directory "~/News")))
((gnus-use-long-file-name 'not-score)
;; Append ".SCORE" to newsgroup name.
- (expand-file-name (concat (gnus-newsgroup-saveable-name newsgroup)
+ (expand-file-name (concat (gnus-newsgroup-savable-name newsgroup)
"." suffix)
(or gnus-kill-files-directory "~/News")))
(t