+1996-11-30 Markus Linnala <maage@cs.tut.fi>
+
+ * gnus-sum.el (gnus-summary-refer-parent-article): Work when there
+ are no references.
+
+1996-11-30 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * message.el (message-fetch-field): Fetch all headers.
+
+ * gnus-sum.el (gnus-cut-thread): Would cut off the wrong
+ children.
+
+ * gnus-score.el (gnus-all-score-files): Take an optional group
+ param.
+
+ * gnus-start.el (gnus-dribble-touch): New function.
+ (gnus-master-read-slave-newsrc): Use it.
+
+ * gnus-salt.el (gnus-generate-vertical-tree): Would bug out on
+ sparse articles.
+
+ * gnus-sum.el (gnus-summary-search-article): Would infloop.
+
+ * gnus-nocem.el: Ignore invalid entries.
+
+ * gnus-sum.el (gnus-data-remove): Wouldn't update properly when
+ treating the first article in the buffer.
+ (gnus-rebuild-thread): Would compute the wrong offset.
+ (gnus-summary-move-article): Don't mark as read.
+
+1996-11-28 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-sum.el (gnus-thread-loop-p): New function.
+ (gnus-make-threads): Avoid inflooped references.
+
+ * gnus-start.el (gnus-gnus-to-quick-newsrc-format): Bind
+ print-length to nil.
+
+Wed Nov 27 02:41:31 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * nnmail.el (nnmail-process-babyl-mail-format): Goto-char placed
+ wrongly.
+
+ * gnus-group.el (gnus-group-select-group-emphemerally): New
+ command and keystroke.
+
+ * gnus-sum.el (gnus-read-header): Fold continuation lines.
+
+Tue Nov 26 18:43:29 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-sum.el (gnus-summary-update-info): Don't change buffer.
+
+Tue Nov 26 17:56:19 1996 Hrvoje Niksic <hniksic@srce.hr>
+
+ * gnus-sum.el (gnus-summary-print-article): Prompt for file name.
+
+Tue Nov 26 17:08:07 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * article.el (article-date-ut): Use original date.
+
+Tue Nov 26 08:36:38 1996 Wes Hardaker <Wesley.Hardaker@sphys.unil.ch>
+
+ * gnus-picon.el: Customize.
+
+ * smiley.el: Customize. Change artist's email address in comments.
+
+Tue Nov 26 04:37:54 1996 Lars Magne Ingebrigtsen <menja.larsi@ifi.uio.no>
+
+ * gnus.el: Red Gnus v0.71 is released.
+
Tue Nov 26 00:58:25 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
* gnus-sum.el (gnus-get-split-value): Expand file names in save
* gnus.el (gnus-article-display-hook): Moved
`gnus-article-treat-overstrike' last.
+Mon Nov 25 11:21:15 1996 Wes Hardaker <Wesley.Hardaker@sphys.unil.ch>
+
+ * gnus-picon.el: (gnus-picons-try-to-find-face): New param: rightp.
+ (gnus-picons-insert-face-if-exists): Use it and own new param.
+ More properly detect location of bar and dots.
+ (gnus-group-display-picons): Use above.
+ (gnus-article-display-picons): ditto.
+
Mon Nov 25 04:17:03 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
* nnfolder.el (nnfolder-read-folder): Make buffer read/write.
If TYPE is `local', convert to local time; if it is `lapsed', output
how much time has lapsed since DATE."
(interactive (list 'ut t))
- (let* ((header (or header (message-fetch-field "date")
+ (let* ((header (or header
(mail-header-date gnus-current-headers)
+ (message-fetch-field "date")
""))
(date (if (vectorp header) (mail-header-date header)
header))
(defalias 'nndb-request-article 'ignore)
(defalias 'efs-re-read-dir 'ignore)
(defalias 'ange-ftp-re-read-dir 'ignore)
+(defalias 'define-mail-user-agent 'ignore)
(eval-and-compile
(unless (string-match "XEmacs" emacs-version)
(defun gnus-summary-insert-cached-articles ()
"Insert all the articles cached for this group into the current buffer."
(interactive)
- (let ((cached gnus-newsgroup-cached))
+ (let ((cached gnus-newsgroup-cached)
+ (gnus-verbose (max 6 gnus-verbose)))
(unless cached
(error "No cached articles for this group"))
(while cached
"=" gnus-group-select-group
"\r" gnus-group-select-group
"\M-\r" gnus-group-quick-select-group
+ [(meta control return)] gnus-group-select-group-ephemerally
"j" gnus-group-jump-to-group
"n" gnus-group-next-unread-group
"p" gnus-group-prev-unread-group
(let ((gnus-inhibit-limiting t))
(gnus-group-read-group all t)))
+(defun gnus-group-select-group-ephemerally ()
+ "Select the current group without doing any processing whatsoever.
+You will actually be entered into a group that's a copy of
+the current group; no changes you make while in this group will
+be permanent."
+ (interactive)
+ (require 'gnus-score)
+ (let* (gnus-visual
+ gnus-score-find-score-files-function gnus-apply-kill-hook
+ gnus-summary-expunge-below gnus-show-threads gnus-suppress-duplicates
+ gnus-summary-mode-hook gnus-select-group-hook
+ (group (gnus-group-group-name))
+ (method (gnus-find-method-for-group group)))
+ (setq method
+ `(,(car method) ,(concat (cadr method) "-ephemeral")
+ (,(intern (format "%s-address" (car method))) ,(cadr method))
+ ,@(cddr method)))
+ (gnus-group-read-ephemeral-group
+ (gnus-group-prefixed-name group method) method)))
+
;;;###autoload
(defun gnus-fetch-group (group)
"Start Gnus if necessary and enter GROUP.
(narrow-to-region b (1+ (match-beginning 0)))
(goto-char (point-min))
(while (search-forward "\t" nil t)
- (if (ignore-errors
- (setq group (let ((obarray gnus-active-hashtb)) (read buf))))
- (if (not (boundp group))
- ;; Make sure all entries in the hashtb are bound.
- (set group nil)
- (when (gnus-gethash (symbol-name group) gnus-newsrc-hashtb)
- ;; Valid group.
- (beginning-of-line)
- (while (= (following-char) ?\t)
- (forward-line -1))
- (setq id (buffer-substring (point) (1- (search-forward "\t"))))
- (unless (gnus-gethash id gnus-nocem-hashtb)
- ;; only store if not already present
- (gnus-sethash id t gnus-nocem-hashtb)
- (push id ncm))
- (forward-line 1)
- (while (= (following-char) ?\t)
- (forward-line 1))))))
+ (cond
+ ((not (ignore-errors
+ (setq group (let ((obarray gnus-active-hashtb)) (read buf)))))
+ ;; An error.
+ )
+ ((not (symbolp group))
+ ;; Ignore invalid entries.
+ )
+ ((not (boundp group))
+ ;; Make sure all entries in the hashtb are bound.
+ (set group nil))
+ (t
+ (when (gnus-gethash (symbol-name group) gnus-newsrc-hashtb)
+ ;; Valid group.
+ (beginning-of-line)
+ (while (= (following-char) ?\t)
+ (forward-line -1))
+ (setq id (buffer-substring (point) (1- (search-forward "\t"))))
+ (unless (gnus-gethash id gnus-nocem-hashtb)
+ ;; only store if not already present
+ (gnus-sethash id t gnus-nocem-hashtb)
+ (push id ncm))
+ (forward-line 1)
+ (while (= (following-char) ?\t)
+ (forward-line 1))))))
(when ncm
(setq gnus-nocem-touched-alist t)
(push (cons (let ((time (current-time))) (setcdr (cdr time) nil) time)
(require 'gnus)
(require 'xpm)
(require 'annotations)
-
-(defvar gnus-picons-buffer "*Icon Buffer*"
- "Buffer name to display the icons in if gnus-picons-display-where is 'picons.")
-
-(defvar gnus-picons-display-where 'picons
- "Where to display the group and article icons.")
-
-(defvar gnus-picons-database "/usr/local/faces"
+(require 'custom)
+
+(defgroup picons nil
+ "Show pictures of people, domains, and newsgroups (XEmacs).
+For this to work, you must add gnus-group-display-picons to the
+gnus-summary-display-hook or to the gnus-article-display-hook
+depending on what gnus-picons-display-where is set to. You must
+also add gnus-article-display-picons to gnus-article-display-hook."
+ :group 'gnus-visual)
+
+(defcustom gnus-picons-buffer "*Icon Buffer*"
+ "Buffer name to display the icons in if gnus-picons-display-where is 'picons."
+ :type 'string
+ :group 'picons)
+
+(defcustom gnus-picons-display-where 'picons
+ "Where to display the group and article icons."
+ :type '(choice symbol string)
+ :group 'picons)
+
+(defcustom gnus-picons-database "/usr/local/faces"
"Defines the location of the faces database.
For information on obtaining this database of pretty pictures, please
-see http://www.cs.indiana.edu/picons/ftp/index.html" )
+see http://www.cs.indiana.edu/picons/ftp/index.html"
+ :type 'directory
+ :group 'picons)
-(defvar gnus-picons-news-directory "news"
+(defcustom gnus-picons-news-directory "news"
"Sub-directory of the faces database containing the icons for newsgroups."
-)
+ :type 'string
+ :group 'picons)
-(defvar gnus-picons-user-directories '("local" "users" "usenix" "misc/MISC")
+(defcustom gnus-picons-user-directories '("local" "users" "usenix" "misc/MISC")
"List of directories to search for user faces."
-)
+ :type '(repeat string)
+ :group 'picons)
-(defvar gnus-picons-domain-directories '("domains")
+(defcustom gnus-picons-domain-directories '("domains")
"List of directories to search for domain faces.
Some people may want to add \"unknown\" to this list."
-)
+ :type '(repeat string)
+ :group 'picons)
-(defvar gnus-picons-refresh-before-display nil
- "If non-nil, display the article buffer before computing the picons.")
+(defcustom gnus-picons-refresh-before-display nil
+ "If non-nil, display the article buffer before computing the picons."
+ :type 'boolean
+ :group 'picons)
-(defvar gnus-picons-x-face-file-name
+(defcustom gnus-picons-x-face-file-name
(format "/tmp/picon-xface.%s.xbm" (user-login-name))
- "The name of the file in which to store the converted X-face header.")
+ "The name of the file in which to store the converted X-face header."
+ :type 'string
+ :group 'picons)
-(defvar gnus-picons-convert-x-face (format "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | pbmtoxbm > %s" gnus-picons-x-face-file-name)
+(defcustom gnus-picons-convert-x-face (format "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | pbmtoxbm > %s" gnus-picons-x-face-file-name)
"Command to convert the x-face header into a xbm file."
-)
+ :type 'string
+ :group 'picons)
-(defvar gnus-picons-display-as-address t
- "*If t display textual email addresses along with pictures.")
+(defcustom gnus-picons-display-as-address t
+ "*If t display textual email addresses along with pictures."
+ :type 'boolean
+ :group 'picons)
-(defvar gnus-picons-file-suffixes
+(defcustom gnus-picons-file-suffixes
(when (featurep 'x)
(let ((types (list "xbm")))
(when (featurep 'gif)
(when (featurep 'xpm)
(push "xpm" types))
types))
- "List of suffixes on picon file names to try.")
+ "List of suffixes on picon file names to try."
+ :type '(repeat string)
+ :group 'picons)
-(defvar gnus-picons-display-article-move-p t
+(defcustom gnus-picons-display-article-move-p t
"*Whether to move point to first empty line when displaying picons.
-This has only an effect if `gnus-picons-display-where' hs value article.")
+This has only an effect if `gnus-picons-display-where' hs value article."
+ :type 'boolean
+ :group 'picons)
(defvar gnus-picons-map (make-sparse-keymap "gnus-picons-keys")
"keymap to hide/show picon glyphs")
(nconc (gnus-picons-insert-face-if-exists
(car databases)
addrs
- "unknown" gnus-article-annotations t)
+ "unknown" (or gnus-picons-display-as-address
+ gnus-article-annotations) t t)
gnus-article-annotations))
(setq databases (cdr databases)))
(setq found
(nconc (gnus-picons-insert-face-if-exists
(car databases) addrs username
- gnus-picons-display-as-address )
+ (or gnus-picons-display-as-address
+ gnus-article-annotations) nil t)
found))
(setq databases (cdr databases)))
;; add their name if no face exists
(gnus-picons-insert-face-if-exists
gnus-picons-news-directory
(message-tokenize-header gnus-newsgroup-name ".")
- "unknown"))
+ "unknown" nil t))
(add-hook 'gnus-summary-exit-hook 'gnus-picons-remove-all))))
(defsubst gnus-picons-try-suffixes (file)
f))
(defun gnus-picons-insert-face-if-exists (database addrs filename &optional
- nobar-p dots)
+ nobar-p dots rightp)
"Inserts a face at point if I can find one"
;; '(gnus-picons-insert-face-if-exists
;; "Database" '("edu" "indiana" "cs") "Name")
;; The special treatment of MISC doesn't conform with the conventions for
;; picon databases, but otherwise we would always see the MISC/unknown face.
(let ((bar (and (not nobar-p)
- (annotations-in-region
- (point) (min (point-max) (1+ (point)))
- (current-buffer))))
+ (or gnus-picons-display-as-address
+ (annotations-in-region
+ (point) (min (point-max) (1+ (point)))
+ (current-buffer)))))
(path (concat (file-name-as-directory gnus-picons-database)
database "/"))
(domainp (and gnus-picons-display-as-address dots))
(if (setq found
(gnus-picons-try-suffixes (concat path filename "/face.")))
(progn
- (when bar
- (setq bar-ann (gnus-picons-try-to-find-face
- (concat gnus-xmas-glyph-directory "bar.xbm")))
- (when bar-ann
- (setq picons (nconc picons bar-ann))
- (setq bar nil)))
- (setq picons (nconc (when (and domainp first)
+ (setq picons (nconc (when (and domainp first rightp)
(list (make-annotation
"." (point) 'text
- nil nil nil t)
+ nil nil nil rightp)
picons))
(gnus-picons-try-to-find-face
- found nil (if domainp cur filename))
+ found nil (if domainp cur filename) rightp)
+ (when (and domainp first (not rightp))
+ (list (make-annotation
+ "." (point) 'text
+ nil nil nil rightp)
+ picons))
picons)))
(when domainp
(setq picons
- (nconc (list (make-annotation (if first (concat cur ".") cur)
- (point) 'text nil nil nil t))
+ (nconc (list (make-annotation
+ (if first (concat (if (not rightp) ".") cur
+ (if rightp ".")) cur)
+ (point) 'text nil nil nil rightp))
picons))))
+ (when (and bar (or domainp found))
+ (setq bar-ann (gnus-picons-try-to-find-face
+ (concat gnus-xmas-glyph-directory "bar.xbm")
+ nil nil t))
+ (when bar-ann
+ (setq picons (nconc picons bar-ann))
+ (setq bar nil)))
(setq first t))
(when (and addrs domainp)
(let ((it (mapconcat 'downcase addrs ".")))
(make-annotation
- (if first (concat it ".") it) (point) 'text nil nil nil t)))
+ (if first (concat (if (not rightp) ".") it (if rightp ".")) it)
+ (point) 'text nil nil nil rightp)))
picons))
(defvar gnus-picons-glyph-alist nil)
-(defun gnus-picons-try-to-find-face (path &optional xface-p part)
+(defun gnus-picons-try-to-find-face (path &optional xface-p part rightp)
"If PATH exists, display it as a bitmap. Returns t if succeeded."
(let ((glyph (and (not xface-p)
(cdr (assoc path gnus-picons-glyph-alist)))))
(unless xface-p
(push (cons path glyph) gnus-picons-glyph-alist))
(set-glyph-face glyph 'default))
- (let ((new (make-annotation glyph (point) 'text nil nil nil t)))
+ (let ((new (make-annotation glyph (point) 'text nil nil nil rightp)))
(nconc
(list new)
(when (and (eq major-mode 'gnus-article-mode)
(not gnus-picons-display-as-address)
(not part))
- (list (make-annotation " " (point) 'text nil nil nil t)))
+ (list (make-annotation " " (point) 'text nil nil nil rightp)))
(when (and part gnus-picons-display-as-address)
- (let ((txt (make-annotation part (point) 'text nil nil nil t)))
+ (let ((txt (make-annotation part (point) 'text nil nil nil rightp)))
(hide-annotation txt)
(set-extent-property txt 'its-partner new)
(set-extent-property txt 'keymap gnus-picons-map)
"Generate a vertical tree."
(let* ((dummy (stringp (car thread)))
(do (or dummy
- (memq (mail-header-number (car thread)) gnus-tmp-limit)))
+ (and (car thread)
+ (memq (mail-header-number (car thread))
+ gnus-tmp-limit))))
beg)
(if (not do)
;; We don't want this article.
(push (cons group score-files) gnus-score-file-alist-cache)
score-files)))
-(defun gnus-all-score-files ()
+(defun gnus-all-score-files (&optional group)
"Return a list of all score files for the current group."
(let ((funcs gnus-score-find-score-files-function)
- (group gnus-newsgroup-name)
+ (group (or group gnus-newsgroup-name))
score-files)
;; Make sure funcs is a list.
(and funcs
(bury-buffer gnus-dribble-buffer)
(set-buffer obuf))))
+(defun gnus-dribble-touch ()
+ "Touch the dribble buffer."
+ (gnus-dribble-enter ""))
+
(defun gnus-dribble-read-file ()
"Read the dribble file from disk."
(let ((dribble-file (gnus-dribble-file-name)))
(gnus-cache-open))
;; Possibly eval the dribble file.
- (and init (or gnus-use-dribble-file gnus-slave) (gnus-dribble-eval-file))
+ (and init
+ (or gnus-use-dribble-file gnus-slave)
+ (gnus-dribble-eval-file))
;; Slave Gnusii should then clear the dribble buffer.
(when (and init gnus-slave)
(push group gnus-killed-list)
(gnus-sethash group group gnus-killed-hashtb))))))
gnus-active-hashtb)
- (gnus-dribble-enter ""))
+ (gnus-dribble-touch))
;; Get the active file(s) from the backend(s).
(defun gnus-read-active-file ()
(delq 'gnus-killed-list (copy-sequence gnus-variable-list))))
;; Peel off the "dummy" group.
(gnus-newsrc-alist (cdr gnus-newsrc-alist))
+ ;; Make sure the printing isn't abbreviated.
+ (print-length nil)
variable)
;; Insert the variables into the file.
(while variables
(ignore-errors
(delete-file file))))
(setq slave-files (cdr slave-files))))
+ (gnus-dribble-touch)
(gnus-message 7 "Reading slave newsrcs...done"))))
\f
(defun gnus-data-remove (article &optional offset)
(let ((data gnus-newsgroup-data))
(if (= (gnus-data-number (car data)) article)
- (setq gnus-newsgroup-data (cdr gnus-newsgroup-data)
- gnus-newsgroup-data-reverse nil)
+ (progn
+ (setq gnus-newsgroup-data (cdr gnus-newsgroup-data)
+ gnus-newsgroup-data-reverse nil)
+ (when offset
+ (gnus-data-update-list gnus-newsgroup-data offset)))
(while (cdr data)
(when (= (gnus-data-number (cadr data)) article)
(setcdr data (cddr data))
(setq threads (cdr threads)))
result))
+(defun gnus-thread-loop-p (root thread)
+ "Say whether ROOT is in THREAD."
+ (let ((th (cdr thread)))
+ (while (and th
+ (not (eq (caar th) root)))
+ (pop th))
+ (if th
+ ;; We have found a loop.
+ (let (ref-dep)
+ (setcdr thread (delq (car th) (cdr thread)))
+ (if (boundp (setq ref-dep (intern "none"
+ gnus-newsgroup-dependencies)))
+ (setcdr (symbol-value ref-dep)
+ (nconc (cdr (symbol-value ref-dep))
+ (list (car th))))
+ (set ref-dep (list nil (car th))))
+ 1)
+ ;; Recurse down into the sub-threads and look for loops.
+ (apply '+
+ (mapcar
+ (lambda (thread) (gnus-thread-loop-p root thread))
+ (cdr thread))))))
+
(defun gnus-make-threads ()
"Go through the dependency hashtb and find the roots. Return all threads."
(let (threads)
- (mapatoms
- (lambda (refs)
- (unless (car (symbol-value refs))
- ;; These threads do not refer back to any other articles,
- ;; so they're roots.
- (setq threads (append (cdr (symbol-value refs)) threads))))
- gnus-newsgroup-dependencies)
+ (while (catch 'infloop
+ (mapatoms
+ (lambda (refs)
+ ;; Deal with self-referencing References loops.
+ (when (and (car (symbol-value refs))
+ (not (zerop
+ (apply
+ '+
+ (mapcar
+ (lambda (thread)
+ (gnus-thread-loop-p
+ (car (symbol-value refs)) thread))
+ (cdr (symbol-value refs)))))))
+ (setq threads nil)
+ (throw 'infloop t))
+ (unless (car (symbol-value refs))
+ ;; These threads do not refer back to any other articles,
+ ;; so they're roots.
+ (setq threads (append (cdr (symbol-value refs)) threads))))
+ gnus-newsgroup-dependencies)))
threads))
(defun gnus-build-sparse-threads ()
(defun gnus-rebuild-thread (id)
"Rebuild the thread containing ID."
(let ((buffer-read-only nil)
- (old-pos (gnus-point-at-bol))
- current thread data)
+ old-pos current thread data)
(if (not gnus-show-threads)
(setq thread (list (car (gnus-id-to-thread id))))
;; Get the thread this article is part of.
(setq thread (gnus-remove-thread id)))
+ (setq old-pos (gnus-point-at-bol))
(setq current (save-excursion
(and (zerop (forward-line -1))
(gnus-summary-article-number))))
;; GROUP is successfully selected.
(or gnus-newsgroup-headers t)))))
-(defun gnus-articles-to-read (group read-all)
+(defun gnus-articles-to-read (group &optional read-all)
;; Find out what articles the user wants to read.
(let* ((articles
;; Select all articles if `read-all' is non-nil, or if there
(gnus-summary-reselect-current-group all t))
(defun gnus-summary-update-info ()
- (let ((group gnus-newsgroup-name))
- (when gnus-newsgroup-kill-headers
- (setq gnus-newsgroup-killed
- (gnus-compress-sequence
- (nconc
- (gnus-set-sorted-intersection
- (gnus-uncompress-range gnus-newsgroup-killed)
- (setq gnus-newsgroup-unselected
- (sort gnus-newsgroup-unselected '<)))
- (setq gnus-newsgroup-unreads
- (sort gnus-newsgroup-unreads '<)))
- t)))
- (unless (listp (cdr gnus-newsgroup-killed))
- (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
- (let ((headers gnus-newsgroup-headers))
- (run-hooks 'gnus-exit-group-hook)
- (unless gnus-save-score
- (setq gnus-newsgroup-scored nil))
- ;; Set the new ranges of read articles.
- (gnus-update-read-articles
- group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
- ;; Set the current article marks.
- (gnus-update-marks)
- ;; Do the cross-ref thing.
- (when gnus-use-cross-reference
- (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
- ;; Do adaptive scoring, and possibly save score files.
- (when gnus-newsgroup-adaptive
- (gnus-score-adaptive))
- (when gnus-use-scoring
- (gnus-score-save))
- ;; Do not switch windows but change the buffer to work.
- (set-buffer gnus-group-buffer)
- (unless (gnus-ephemeral-group-p gnus-newsgroup-name)
- (gnus-group-update-group group)))))
+ (save-excursion
+ (let ((group gnus-newsgroup-name))
+ (when gnus-newsgroup-kill-headers
+ (setq gnus-newsgroup-killed
+ (gnus-compress-sequence
+ (nconc
+ (gnus-set-sorted-intersection
+ (gnus-uncompress-range gnus-newsgroup-killed)
+ (setq gnus-newsgroup-unselected
+ (sort gnus-newsgroup-unselected '<)))
+ (setq gnus-newsgroup-unreads
+ (sort gnus-newsgroup-unreads '<)))
+ t)))
+ (unless (listp (cdr gnus-newsgroup-killed))
+ (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
+ (let ((headers gnus-newsgroup-headers))
+ (run-hooks 'gnus-exit-group-hook)
+ (unless gnus-save-score
+ (setq gnus-newsgroup-scored nil))
+ ;; Set the new ranges of read articles.
+ (gnus-update-read-articles
+ group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
+ ;; Set the current article marks.
+ (gnus-update-marks)
+ ;; Do the cross-ref thing.
+ (when gnus-use-cross-reference
+ (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
+ ;; Do adaptive scoring, and possibly save score files.
+ (when gnus-newsgroup-adaptive
+ (gnus-score-adaptive))
+ (when gnus-use-scoring
+ (gnus-score-save))
+ ;; Do not switch windows but change the buffer to work.
+ (set-buffer gnus-group-buffer)
+ (unless (gnus-ephemeral-group-p gnus-newsgroup-name)
+ (gnus-group-update-group group))))))
(defun gnus-summary-exit (&optional temporary)
"Exit reading current newsgroup, and then return to group selection mode.
(gnus-summary-article-sparse-p (mail-header-number (car thread)))
(gnus-summary-article-ancient-p
(mail-header-number (car thread))))
- (or (<= (length (cdr thread)) 1)
- (gnus-invisible-cut-children (cdr thread))))
- (setq thread (cadr thread))))
+ (progn
+ (if (<= (length (cdr thread)) 1)
+ (setq thread (cadr thread))
+ (when (gnus-invisible-cut-children (cdr thread))
+ (let ((th (cdr thread)))
+ (while th
+ (if (memq (mail-header-number (caar th))
+ gnus-newsgroup-limit)
+ (setq thread (car th)
+ th nil)
+ (setq th (cdr th)))))))))
+ ))
thread)
(defun gnus-cut-threads (threads)
;; If this article is dormant and has absolutely no visible
;; children, then this article isn't visible.
(and (memq number gnus-newsgroup-dormant)
- (= children 0))
- ;; If this is "fetch-old-headered" and there is only one
- ;; visible child (or less), then we don't want this article.
+ (zerop children))
+ ;; If this is "fetch-old-headered" and there is no
+ ;; visible children, then we don't want this article.
(and (eq gnus-fetch-old-headers 'some)
(gnus-summary-article-ancient-p number)
(zerop children))
;; It's not the current article, so we take a bet on
;; the value we got from the server.
(mail-header-references header)))
- (if ref
+ (if (and ref
+ (not (equal ref "")))
(unless (gnus-summary-refer-article (gnus-parent-id ref skip))
(gnus-message 1 "Couldn't find parent"))
(gnus-message 1 "No references in article %d"
(setq point (point)))
;; We didn't find it, so we go to the next article.
(set-buffer sum)
- (while (and (not found)
- (gnus-summary-article-sparse-p
- (gnus-summary-article-number)))
+ (setq found 'not)
+ (while (eq found 'not)
(if (not (if backward (gnus-summary-find-prev)
(gnus-summary-find-next)))
;; No more articles.
;; Select the next article and adjust point.
(unless (gnus-summary-article-sparse-p
(gnus-summary-article-number))
+ (setq found nil)
(gnus-summary-select-article)
(set-buffer gnus-article-buffer)
(widen)
(when gnus-break-pages
(gnus-narrow-to-page))))
-(defun gnus-summary-print-article ()
- "Generate and print a PostScript image of the article buffer."
- (interactive)
+(defun gnus-summary-print-article (&optional filename)
+ "Generate and print a PostScript image of the article buffer.
+
+If the optional argument FILENAME is nil, send the image to the printer.
+If FILENAME is a string, save the PostScript image in a file with that
+name. If FILENAME is a number, prompt the user for the name of the file
+to save in."
+ (interactive (list (ps-print-preprint current-prefix-arg)))
(gnus-summary-select-article)
(gnus-eval-in-buffer-window gnus-article-buffer
(let ((buffer (generate-new-buffer " *print*")))
(copy-to-buffer buffer (point-min) (point-max))
(set-buffer buffer)
(article-delete-invisible-text)
- (ps-print-buffer-with-faces))
+ (ps-print-buffer-with-faces filename))
(kill-buffer buffer)))))
(defun gnus-summary-show-article (&optional arg)
(unless action
(setq action 'move))
(gnus-set-global-variables)
- (save-window-excursion
- (gnus-summary-select-article))
+ ;; Disable marking as read.
+ (let (gnus-mark-article-hook)
+ (save-window-excursion
+ (gnus-summary-select-article)))
;; Check whether the source group supports the required functions.
(cond ((and (eq action 'move)
(not (gnus-check-backend-function
(save-excursion
(set-buffer nntp-server-buffer)
(when (setq where (gnus-request-head id group))
+ (nnheader-fold-continuation-lines)
(goto-char (point-max))
(insert ".\n")
(goto-char (point-min))
"Score and kill file handling."
:group 'gnus )
-(defconst gnus-version-number "0.71"
+(defconst gnus-version-number "0.72"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Red Gnus v%s" gnus-version-number)
("info" Info-goto-node)
("hexl" hexl-hex-string-to-integer)
("pp" pp pp-to-string pp-eval-expression)
+ ("ps-print" ps-print-preprint)
("mail-extr" mail-extract-address-components)
("message" :interactive t
message-send-and-exit message-yank-original)
(defun message-fetch-field (header)
"The same as `mail-fetch-field', only remove all newlines."
- (let ((value (mail-fetch-field header)))
+ (let ((value (mail-fetch-field header nil t)))
(when value
(nnheader-replace-chars-in-string value ?\n ? ))))
(when (file-directory-p inbox)
(setq inbox (expand-file-name (user-login-name) inbox))))
(if (member inbox nnmail-moved-inboxes)
- ;; We don't try to move an already moced inbox.
+ ;; We don't try to move an already moved inbox.
nil
(if popmail
(progn
(defun nnmail-process-babyl-mail-format (func artnum-func)
(let ((case-fold-search t)
start message-id content-length do-search end)
+ (goto-char (point-min))
(while (not (eobp))
- (goto-char (point-min))
(re-search-forward
"\f\n0, *unseen,+\n\\(\\*\\*\\* EOOH \\*\\*\\*\n\\)?" nil t)
(goto-char (match-end 0))
;; (require 'smiley)
;; (add-hook 'gnus-article-display-hook 'gnus-smiley-display t)
-;; The smilies were drawn by Joe Reiss <joe@jreiss.async.vt.edu>.
+;; The smilies were drawn by Joe Reiss <jreiss@vt.edu>.
(require 'annotations)
(require 'messagexmas)
(require 'cl)
+(require 'custom)
-(defvar smiley-data-directory (message-xmas-find-glyph-directory "smilies")
- "Location of the smiley faces files.")
+(defgroup smiley nil
+ "Turn :-)'s into real images (XEmacs)."
+ :group 'gnus-visual)
+
+(defcustom smiley-data-directory (message-xmas-find-glyph-directory "smilies")
+ "Location of the smiley faces files."
+ :type 'directory
+ :group 'smiley)
;; Notice the subtle differences in the regular expressions in the two alists below
-(defvar smiley-deformed-regexp-alist
+(defcustom smiley-deformed-regexp-alist
'(("\\(:-*[<«]+\\)\\W" 1 "FaceAngry.xpm")
("\\(:-+\\]+\\)\\W" 1 "FaceGoofy.xpm")
("\\(:-*D\\)\\W" 1 "FaceGrinning.xpm")
("\\(;-*[>)}»]+\\)\\W" 1 "FaceWinking.xpm")
("\\(:-*[Vvµ]\\)\\W" 1 "FaceWry.xpm")
("\\([:|]-*P\\)\\W" 1 "FaceYukky.xpm"))
- "Normal and deformed faces for smilies.")
+ "Normal and deformed faces for smilies."
+ :type '(repeat (list regexp
+ (integer :tag "Match")
+ (string :tag "Image")))
+ :group 'smiley)
-(defvar smiley-nosey-regexp-alist
+(defcustom smiley-nosey-regexp-alist
'(("\\(:-+[<«]+\\)\\W" 1 "FaceAngry.xpm")
("\\(:-+\\]+\\)\\W" 1 "FaceGoofy.xpm")
("\\(:-+D\\)\\W" 1 "FaceGrinning.xpm")
("\\(:-+[Vvµ]\\)\\W" 1 "FaceWry.xpm")
("\\(][:8B]-[)>]\\)\\W" 1 "FaceDevilish.xpm")
("\\([:|]-+P\\)\\W" 1 "FaceYukky.xpm"))
- "Smileys with noses. These get less false matches.")
+ "Smileys with noses. These get less false matches."
+ :type '(repeat (list regexp
+ (integer :tag "Match")
+ (string :tag "Image")))
+ :group 'smiley)
-(defvar smiley-regexp-alist smiley-deformed-regexp-alist
+(defcustom smiley-regexp-alist smiley-deformed-regexp-alist
"A list of regexps to map smilies to real images.
Defaults to the content of smiley-deformed-regexp-alist.
An alternative smiley-nosey-regexp-alist that
matches less aggressively is available.
-If this is a symbol, take its value.")
-
-(defvar smiley-flesh-color "yellow"
- "Flesh color.")
-
-(defvar smiley-features-color "black"
- "Features color.")
-
-(defvar smiley-tongue-color "red"
- "Tongue color.")
-
-(defvar smiley-circle-color "black"
- "Circle color.")
+If this is a symbol, take its value."
+ :type '(radio (variable-item smiley-deformed-regexp-alist)
+ (variable-item smiley-nosey-regexp-alist)
+ symbol
+ (repeat (list regexp
+ (integer :tag "Match")
+ (string :tag "Image"))))
+ :group 'smiley)
+
+(defcustom smiley-flesh-color "yellow"
+ "Flesh color."
+ :type 'string
+ :group 'smiley)
+
+(defcustom smiley-features-color "black"
+ "Features color."
+ :type 'string
+ :group 'smiley)
+
+(defcustom smiley-tongue-color "red"
+ "Tongue color."
+ :type 'string
+ :group 'smiley)
+
+(defcustom smiley-circle-color "black"
+ "Circle color."
+ :type 'string
+ :group 'smiley)
(defvar smiley-glyph-cache nil)
(defvar smiley-running-xemacs (string-match "XEmacs" emacs-version))
+1996-11-30 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus.texi (Terminology): Addition.
+
+Wed Nov 27 03:13:05 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus.texi (Selecting a Group): Addition.
+
+Tue Nov 26 12:42:47 1996 Martin Buchholz <mrb@eng.sun.com>
+
+ * message.texi: Typo fixes and stuff.
+
Thu Nov 21 17:45:57 1996 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
* gnus.texi (Canceling and Superseding): Fix.
\input texinfo @c -*-texinfo-*-
@setfilename gnus
-@settitle Red Gnus 0.71 Manual
+@settitle Red Gnus 0.72 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Red Gnus 0.71 Manual
+@title Red Gnus 0.72 Manual
@author by Lars Magne Ingebrigtsen
@page
spool or your mbox file. All at the same time, if you want to push your
luck.
-This manual corresponds to Red Gnus 0.71
+This manual corresponds to Red Gnus 0.72
@end ifinfo
command, but this one does it without expunging and hiding dormants
(@code{gnus-group-visible-select-group}).
+@item M-C-RET
+@kindex M-C-RET (Group)
+@findex gnus-group-select-group-ephemerally
+Finally, this command selects the current group ephemerally without
+doing any processing of its contents
+(@code{gnus-group-select-group-ephemerally}). Even threading has been
+turned off. Everything you do in the group after selecting it in this
+manner will have no permanent effects.
+
@end table
@vindex gnus-large-newsgroup
(@pxref{Saving Articles}). You may customize that variable to create
suggestions you find reasonable.
+@lisp
+(setq gnus-move-split-methods
+ '(("^From:.*Lars Magne" "nnml:junk")
+ ("^Subject:.*gnus" "nnfolder:important")
+ (".*" "nnml:misc")))
+@end lisp
+
@node Various Summary Stuff
@section Various Summary Stuff
This is the opposite of ephemeral groups. All groups listed in the
group buffer are solid groups.
+@item sparse articles
+@cindex sparse articles
+These are article placeholders shown in the summary buffer when
+@code{gnus-build-sparse-threads} has been switched on.
+
@end table
@code{message-reply-to-function} (@pxref{Reply}).
@findex rmail-dont-reply-to-names
-Addresses that matches the @code{rmail-dont-reply-to-names} regular
+Addresses that match the @code{rmail-dont-reply-to-names} regular
expression will be removed from the @code{Cc} header.
@vindex message-ignored-supersedes-headers
Headers matching the @code{message-ignored-supersedes-headers} are
-removed before popping up the new message buffer. The default is
-@samp{^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|Return-Path:}.
+removed before popping up the new message buffer. The default is@*
+@samp{^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|@*
+^Received:\\|^X-From-Line:\\|Return-Path:}.
@table @code
@item message-forward-start-separator
@vindex message-forward-start-separator
-Delimiter inserted before forwarded messages. The default is
+Delimiter inserted before forwarded messages. The default is@*
@samp{------- Start of forwarded message -------\n}.
@vindex message-forward-end-separator
@item message-forward-end-separator
@vindex message-forward-end-separator
-Delimiter inserted after forwarded messages. The default is
+Delimiter inserted after forwarded messages. The default is@*
@samp{------- End of forwarded message -------\n}.
@item message-signature-before-forwarded-message
and resend the message in the current buffer to that address.
@vindex message-ignored-resent-headers
-Headers the match the @code{message-ignored-resent-headers} regexp will
+Headers that match the @code{message-ignored-resent-headers} regexp will
be removed before sending the message. The default is
@samp{^Return-receipt}.
characters @samp{-- } on a line by themselves. This is to make it
easier for the recipient to automatically recognize and process the
signature. So don't remove those characters, even though you might feel
-that they ruin you beautiful design, like, totally.
+that they ruin your beautiful design, like, totally.
Also note that no signature should be more than four lines long.
Including ASCII graphics is an efficient way to get everybody to believe
@table @code
@item message-required-mail-headers
@vindex message-required-mail-headers
-See @pxref{News Headers} for the syntax of this variable. It is
+@xref{News Headers}, for the syntax of this variable. It is
@code{(From Date Subject (optional . In-Reply-To) Message-ID Lines
(optional . X-Mailer))} by default.
@findex system-name
@cindex Sun
This required header will be generated by Message. A unique ID will be
-created based on date, time, user name and system name. Message will
+created based on the date, time, user name and system name. Message will
use @code{mail-host-address} as the fully qualified domain name (FQDN)
-of the machine if that variable is define. If not, it will use
+of the machine if that variable is defined. If not, it will use
@code{system-name}, which doesn't report a FQDN on some machines --
notably Suns.
@item In-Reply-To
This optional header is filled out using the @code{Date} and @code{From}
-header of the article being replied.
+header of the article being replied to.
@item Expires
@cindex Expires
@item Path
@cindex path
-This extremely optional header should probably not ever be used.
+This extremely optional header should probably never be used.
However, some @emph{very} old servers require that this header is
present. @code{message-user-path} further controls how this
-@code{Path} header is to look. If is is @code{nil}, the the server name
-as the leaf node. If is is a string, use the string. If it is neither
+@code{Path} header is to look. If it is @code{nil}, use the server name
+as the leaf node. If it is a string, use the string. If it is neither
a string nor @code{nil}, use the user name only. However, it is highly
unlikely that you should need to fiddle with this variable at all.
@end table
@item message-syntax-checks
@vindex message-syntax-checks
-If non-@code{nil}, message will attempt to check the legality of the
+If non-@code{nil}, Message will attempt to check the legality of the
headers, as well as some other stuff, before posting. You can control
the granularity of the check by adding or removing elements from this
list. Legal elements are:
@item empty-headers
Check whether any of the headers are empty.
@item existing-newsgroups
-Check whether the newsgroups mentioned in the Newsgroups and
-Followup-To headers exist.
+Check whether the newsgroups mentioned in the @code{Newsgroups} and
+@code{Followup-To} headers exist.
@item valid-newsgroups
Check whether the @code{Newsgroups} and @code{Followup-to} headers
are valid syntactically.
@item message-ignored-news-headers
@vindex message-ignored-news-headers
-Regexp of headers to be removed before posting. The default is
-@samp{^NNTP-Posting-Host:\\|^Xref:\\|^Bcc:\\|^Gcc:\\|^Fcc:}.
+Regexp of headers to be removed before posting. The default is@*
+@samp{^NNTP-Posting-Host:\\|^Xref:\\|^Bcc:\\|^Gcc:\\|^Fcc:}.
@item message-default-news-headers
@vindex message-default-news-headers
Message will generate new buffers with unique buffer names when you
request a message buffer. When you send the message, the buffer isn't
-normally killed off. It's name is changed and a certain number of old
+normally killed off. Its name is changed and a certain number of old
message buffers are kept alive.
@table @code
This restores the Gnus window configuration when the message buffer is
killed, postponed or exited.
-An @dfn{action} can be either a normal function; or a list where the
-@code{car} is a function and the @code{cdr} is the list of arguments; or
+An @dfn{action} can be either: a normal function, or a list where the
+@code{car} is a function and the @code{cdr} is the list of arguments, or
a form to be @code{eval}ed.
@node Index