+Mon Aug 7 02:32:03 1995 Lars Magne Ingebrigtsen <lingebri@sunsci4.cern.ch>
+
+ * gnus.el (gnus-group-list-mode): New variable.
+ (gnus-have-all-newsgroups): Obsolete variable.
+ (gnus-group-list-groups): Use new variable.
+
+Sun Aug 6 06:34:37 1995 Lars Magne Ingebrigtsen <lingebri@sunsci4.cern.ch>
+
+ * gnus.el (gnus-group-check-bogus-groups): Would list all groups.
+
+Thu Jul 20 05:19:06 1995 Sudish Joseph <joseph@cis.ohio-state.edu>
+
+ * gnus-score.el (gnus-score-insert-help): Now displays help in
+ shrink-wrapped window at bottom of frame with items aligned in
+ columns.
+
+Sun Aug 6 02:25:31 1995 Lars Magne Ingebrigtsen <lingebri@sunsci4.cern.ch>
+
+ * gnus-score.el (gnus-score-adaptive): Use fuzzy matches.
+
+ * gnus-uu.el (gnus-uu-mark-thread): Move cursor.
+
+ * nnvirtual.el (nnvirtual-retrieve-headers): Did not properly open
+ methods.
+ (nnvirtual-possibly-change-newsgroups): Would refuse to include
+ component groups with similar names to itself.
+
+ * nnmail.el (nnmail-activate): Did not set timestamp properly.
+
+ * gnus.el (gnus-group-default-level): New function.
+ (gnus-group-get-new-news): Use it.
+ (gnus-group-list-groups): Ditto.
+ (gnus-setup-news): Would not activate groups for `gnus-no-server'.
+
Sat Aug 5 00:12:33 1995 Lars Magne Ingebrigtsen <lingebri@sunsci4.cern.ch>
+ * gnus.el: 0.99.6 is released.
+
* gnus.el (gnus-summary-next-article): Don't bug out on the end of
the group buffer.
(defvar gnus-score-mimic-keymap nil
"*Have the score entry functions pretend that they are a keymap.")
-(defvar gnus-score-exact-adapt-limit nil
+(defvar gnus-score-exact-adapt-limit 10
"*Number that says how long a match has to be before using substring matching.
-When doing adaptive scoring, one normally uses substring matching.
-However, if the header one matches is short, the possibility for false
-positives is great, so if the length of the match is less than this
-variable, exact matching will be used.
+When doing adaptive scoring, one normally uses fuzzy or substring
+matching. However, if the header one matches is short, the possibility
+for false positives is great, so if the length of the match is less
+than this variable, exact matching will be used.
-If this variable is nil, which it is by default, exact matching will
-always be used.")
+If this variable is nil, exact matching will always be used.")
\f
(defvar gnus-header-index nil)
(defvar gnus-score-index nil)
-(autoload 'gnus-uu-ctl-map "gnus-uu" nil nil 'keymap)
+(eval-and-compile
+ (autoload 'gnus-uu-ctl-map "gnus-uu" nil nil 'keymap)
+ (autoload 'appt-select-lowest-window "appt.el"))
;;; Summary mode score maps.
(if (eq 'perm temporary) ; Temp
nil
temporary)
- (not (nth 3 entry))) ; Prompt
- )))
-
+ (not (nth 3 entry))) ; Prompt
+ )))
+
(defun gnus-score-insert-help (string alist idx)
(setq gnus-score-help-winconf (current-window-configuration))
(save-excursion
- (pop-to-buffer "*Score Help*")
+ (set-buffer (get-buffer-create "*Score Help*"))
(buffer-disable-undo (current-buffer))
(erase-buffer)
(insert string ":\n\n")
- (while alist
- (insert (format " %c: %s\n" (car (car alist)) (nth idx (car alist))))
- (setq alist (cdr alist))))
- (select-window (get-buffer-window gnus-summary-buffer)))
-
+ (let ((max -1)
+ (list alist)
+ (i 0)
+ n width pad format)
+ ;; find the longest string to display
+ (while list
+ (setq n (length (nth idx (car list))))
+ (or (> max n)
+ (setq max n))
+ (setq list (cdr list)))
+ (setq max (+ max 4)) ; %c, `:', SPACE, a SPACE at end
+ (setq n (/ (window-width) max)) ; items per line
+ (setq width (/ (window-width) n)) ; width of each item
+ ;; insert `n' items, each in a field of width `width'
+ (while alist
+ (if (< i n)
+ ()
+ (setq i 0)
+ (delete-char -1) ; the `\n' takes a char
+ (insert "\n"))
+ (setq pad (- width 3))
+ (setq format (concat "%c: %-" (int-to-string pad) "s"))
+ (insert (format format (car (car alist)) (nth idx (car alist))))
+ (setq alist (cdr alist))
+ (setq i (1+ i))))
+ ;; display ourselves in a small window at the bottom
+ (appt-select-lowest-window)
+ (split-window)
+ (pop-to-buffer "*Score Help*")
+ (shrink-window-if-larger-than-buffer)
+ (select-window (get-buffer-window gnus-summary-buffer))))
+
(defun gnus-summary-header (header &optional no-err)
;; Return HEADER for current articles, or error.
(let ((article (gnus-summary-article-number))
;; here.
(if (or (not gnus-score-exact-adapt-limit)
(< (length match) gnus-score-exact-adapt-limit))
- 'e 's)
+ 'e
+ (if (equal (nth 1 (car elem)) "subject")
+ 'f 's))
(nth 2 (car elem)) date nil t)
(setq elem (cdr elem))))
(forward-line 1)))))
"Marks all articles downwards in this thread."
(interactive)
(gnus-set-global-variables)
- (save-excursion
- (let ((level (gnus-summary-thread-level)))
+ (let ((level (gnus-summary-thread-level)))
(while (and (gnus-summary-set-process-mark (gnus-summary-article-number))
(zerop (gnus-summary-next-subject 1))
- (> (gnus-summary-thread-level) level)))))
+ (> (gnus-summary-thread-level) level))))
(gnus-summary-position-cursor))
(defun gnus-uu-mark-sparse ()
(defconst gnus-maintainer "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
"The mail address of the Gnus maintainers.")
-(defconst gnus-version "(ding) Gnus v0.99.6"
+(defconst gnus-version "(ding) Gnus v0.99.7"
"Version number for this version of Gnus.")
(defvar gnus-info-nodes
(defvar gnus-current-select-method nil
"The current method for selecting a newsgroup.")
-(defvar gnus-have-all-newsgroups nil)
+(defvar gnus-group-list-mode nil)
(defvar gnus-article-internal-prepare-hook nil)
(mouse-set-point e)
(gnus-group-read-group nil))
+;; Look at LEVEL and find out what the level is really supposed to be.
+;; If LEVEL is non-nil, LEVEL will be returned, if not, what happens
+;; will depend on whether `gnus-group-use-permanent-levels' is used.
+(defun gnus-group-default-level (&optional level number-or-nil)
+ (cond
+ (gnus-group-use-permanent-levels
+ (setq gnus-group-default-list-level
+ (or level gnus-group-default-list-level))
+ (or gnus-group-default-list-level gnus-level-subscribed))
+ (number-or-nil
+ level)
+ (t
+ (or level gnus-group-default-list-level gnus-level-subscribed))))
+
+
;;;###autoload
(defun gnus-no-server (&optional arg)
"Read network news.
(gnus-group-mode)
(and gnus-carpal (gnus-carpal-setup-buffer 'group)))))
-(defun gnus-group-list-groups (level &optional unread)
+(defun gnus-group-list-groups (&optional level unread)
"List newsgroups with level LEVEL or lower that have unread articles.
Default is all subscribed groups.
-If argument UNREAD is non-nil, groups with no unread articles are also listed."
- (interactive (list (and current-prefix-arg
- (prefix-numeric-value current-prefix-arg))))
- (if gnus-group-use-permanent-levels
- (progn
- (setq gnus-group-default-list-level
- (or level gnus-group-default-list-level))
- (setq level (or gnus-group-default-list-level gnus-level-subscribed)))
- (setq level (or level gnus-group-default-list-level
- gnus-level-subscribed)))
+If argument UNREAD is non-nil, groups with no unread articles are also
+listed."
+ (interactive (list (if current-prefix-arg
+ (prefix-numeric-value current-prefix-arg)
+ gnus-level-subscribed)))
+ (or level
+ (setq level (car gnus-group-list-mode)
+ unread (cdr gnus-group-list-mode)))
+ (setq level (gnus-group-default-level level))
(gnus-group-setup-buffer) ;May call from out of group buffer
(let ((case-fold-search nil)
(group (gnus-group-group-name)))
gnus-level-killed ?K regexp))
(gnus-group-set-mode-line)
- (setq gnus-have-all-newsgroups all)
+ (setq gnus-group-list-mode (cons level all))
(run-hooks 'gnus-group-prepare-hook)))
(defun gnus-group-prepare-flat-list-dead (groups level mark regexp)
(setq gnus-newsrc-alist
(sort (cdr gnus-newsrc-alist) gnus-group-sort-function))
(gnus-make-hashtable-from-newsrc-alist)
- (gnus-group-list-groups (if gnus-have-all-newsgroups gnus-level-unsubscribed)
- gnus-have-all-newsgroups))
+ (gnus-group-list-groups))
(defun gnus-group-sort-by-alphabet (info1 info2)
(string< (car info1) (car info2)))
unsubscribed groups."
(interactive "P")
(setq arg (or arg gnus-level-unsubscribed))
- (gnus-group-list-groups arg t))
+ (gnus-group-list-groups gnus-level-unsubscribed t))
(defun gnus-group-list-killed ()
"List all killed newsgroups in the group buffer."
specify which levels you are interested in re-scanning."
(interactive "P")
(run-hooks 'gnus-get-new-news-hook)
- (if gnus-group-use-permanent-levels
- (setq arg
- (setq gnus-group-default-list-level
- (or arg gnus-group-default-list-level
- gnus-level-subscribed))))
+ (setq arg (gnus-group-default-level arg t))
(if (and gnus-read-active-file (not arg))
(progn
(gnus-read-active-file)
(gnus-have-read-active-file
(and (not arg) gnus-have-read-active-file)))
(gnus-get-unread-articles (or arg (1+ gnus-level-subscribed)))))
- (gnus-group-list-groups (or (and gnus-group-use-permanent-levels arg)
- gnus-group-default-list-level
- gnus-level-subscribed)
- gnus-have-all-newsgroups))
+ (gnus-group-list-groups arg))
(defun gnus-group-get-new-news-this-group (&optional n)
"Check for newly arrived news in the current group (and the N-1 next groups).
(interactive "P")
(gnus-save-newsrc-file)
(gnus-setup-news 'force)
- (gnus-group-list-groups arg gnus-have-all-newsgroups))
+ (gnus-group-list-groups arg))
(defun gnus-group-read-init-file ()
"Read the Gnus elisp init file."
group."
(interactive "P")
(gnus-check-bogus-newsgroups (and (not silent) (not gnus-expert-user)))
- (gnus-group-list-groups nil gnus-have-all-newsgroups))
+ (gnus-group-list-groups))
(defun gnus-group-edit-global-kill (&optional article group)
"Edit the global kill file.
(use-local-map gnus-article-mode-map)
(setq buffer-read-only t)
(buffer-disable-undo (current-buffer))
+ (run-hooks 'gnus-visual-mark-article-hook)
(gnus-configure-windows 'summary))))
+(defun gnus-summary-edit-article-abort ()
+ "Abort changes to the current article."
+ (interactive)
+ (gnus-article-mode)
+ (use-local-map gnus-article-mode-map)
+ (setq buffer-read-only t)
+ (buffer-disable-undo (current-buffer))
+ (run-hooks 'gnus-visual-mark-article-hook)
+ (gnus-configure-windows 'summary))
+
(defun gnus-summary-fancy-query ()
"Query where the fancy respool algorithm would put this article."
(interactive)
(and init gnus-use-dribble-file (gnus-dribble-eval-file))
;; Find the number of unread articles in each non-dead group.
- (gnus-get-unread-articles (or level (1+ gnus-level-subscribed)))
+ (let ((gnus-read-active-file (and (not level) gnus-read-active-file)))
+ (gnus-get-unread-articles (or level (1+ gnus-level-subscribed))))
;; Find new newsgroups and treat them.
(if (and init gnus-check-new-newsgroups gnus-read-active-file (not level)
(gnus-server-opened gnus-select-method))
;; and add it if it isn't.
;;(if (not (assoc nnfoler-current-group nnfolder-group-alist)
(set-buffer (setq nnfolder-current-buffer
- (nnheader-find-file-noselect file)))
+ (nnheader-find-file-noselect file nil 'raw)))
(buffer-disable-undo (current-buffer))
(let ((delim (concat "^" rmail-unix-mail-delimiter))
(marker (concat "\n" nnfolder-article-marker))
(defun nnheader-insert-head (file)
(let ((beg 0)
(chop 1024))
- (while (and (eq chop (nth 1 (insert-file-contents
+ (while (and (eq chop (nth 1 (nnheader-insert-file-contents-literally
file nil beg (setq beg (+ chop beg)))))
(prog1 (not (search-backward "\n\n" nil t))
(goto-char (point-max)))))))
(eobp)
(widen))))
-(defun nnheader-find-file-noselect (file)
- "Basically does the same as `find-file-noselect', but avoids that function."
- (save-excursion
- (or
- (get-file-buffer file)
- (prog1
- (set-buffer (get-buffer-create (create-file-buffer file)))
- (and (file-exists-p file)
- (not (file-directory-p file))
- (insert-file-contents file))
- (set-visited-file-name file)
- (set-buffer-modified-p nil)))))
+;; Written by Erik Naggum <erik@naggum.no>.
+(defun nnheader-insert-file-contents-literally (filename &optional visit beg end replace)
+ "Like `insert-file-contents', q.v., but only reads in the file.
+A buffer may be modified in several ways after reading into the buffer due
+to advanced Emacs features, such as file-name-handlers, format decoding,
+find-file-hooks, etc.
+ This function ensures that none of these modifications will take place."
+ (let ((file-name-handler-alist nil)
+ (format-alist nil)
+ (after-insert-file-functions nil)
+ (find-buffer-file-type-function
+ (if (fboundp 'find-buffer-file-type)
+ (symbol-function 'find-buffer-file-type)
+ nil)))
+ (unwind-protect
+ (progn
+ (fset 'find-buffer-file-type (lambda (filename) t))
+ (insert-file-contents filename visit beg end replace))
+ (if find-buffer-file-type-function
+ (fset 'find-buffer-file-type find-buffer-file-type-function)
+ (fmakunbound 'find-buffer-file-type)))))
+
+(defun nnheader-find-file-noselect (filename &optional nowarn rawfile)
+ "Read file FILENAME into a buffer and return the buffer.
+If a buffer exists visiting FILENAME, return that one, but
+verify that the file has not changed since visited or saved.
+The buffer is not selected, just returned to the caller."
+ (setq filename
+ (abbreviate-file-name
+ (expand-file-name filename)))
+ (if (file-directory-p filename)
+ (if find-file-run-dired
+ (dired-noselect filename)
+ (error "%s is a directory." filename))
+ (let* ((buf (get-file-buffer filename))
+ (truename (abbreviate-file-name (file-truename filename)))
+ (number (nthcdr 10 (file-attributes truename)))
+ ;; Find any buffer for a file which has same truename.
+ (other (and (not buf) (find-buffer-visiting filename)))
+ error)
+ ;; Let user know if there is a buffer with the same truename.
+ (if other
+ (progn
+ (or nowarn
+ (string-equal filename (buffer-file-name other))
+ (message "%s and %s are the same file"
+ filename (buffer-file-name other)))
+ ;; Optionally also find that buffer.
+ (if (or find-file-existing-other-name find-file-visit-truename)
+ (setq buf other))))
+ (if buf
+ (or nowarn
+ (verify-visited-file-modtime buf)
+ (cond ((not (file-exists-p filename))
+ (error "File %s no longer exists!" filename))
+ ((yes-or-no-p
+ (if (string= (file-name-nondirectory filename)
+ (buffer-name buf))
+ (format
+ (if (buffer-modified-p buf)
+ "File %s changed on disk. Discard your edits? "
+ "File %s changed on disk. Reread from disk? ")
+ (file-name-nondirectory filename))
+ (format
+ (if (buffer-modified-p buf)
+ "File %s changed on disk. Discard your edits in %s? "
+ "File %s changed on disk. Reread from disk into %s? ")
+ (file-name-nondirectory filename)
+ (buffer-name buf))))
+ (save-excursion
+ (set-buffer buf)
+ (revert-buffer t t)))))
+ (save-excursion
+;;; The truename stuff makes this obsolete.
+;;; (let* ((link-name (car (file-attributes filename)))
+;;; (linked-buf (and (stringp link-name)
+;;; (get-file-buffer link-name))))
+;;; (if (bufferp linked-buf)
+;;; (message "Symbolic link to file in buffer %s"
+;;; (buffer-name linked-buf))))
+ (setq buf (create-file-buffer filename))
+;; (set-buffer-major-mode buf)
+ (set-buffer buf)
+ (erase-buffer)
+ (if rawfile
+ (condition-case ()
+ (nnheader-insert-file-contents-literally filename t)
+ (file-error
+ ;; Unconditionally set error
+ (setq error t)))
+ (condition-case ()
+ (insert-file-contents filename t)
+ (file-error
+ ;; Run find-file-not-found-hooks until one returns non-nil.
+ (or t; (run-hook-with-args-until-success 'find-file-not-found-hooks)
+ ;; If they fail too, set error.
+ (setq error t)))))
+ ;; Find the file's truename, and maybe use that as visited name.
+ (setq buffer-file-truename truename)
+ (setq buffer-file-number number)
+ ;; On VMS, we may want to remember which directory in a search list
+ ;; the file was found in.
+ (and (eq system-type 'vax-vms)
+ (let (logical)
+ (if (string-match ":" (file-name-directory filename))
+ (setq logical (substring (file-name-directory filename)
+ 0 (match-beginning 0))))
+ (not (member logical find-file-not-true-dirname-list)))
+ (setq buffer-file-name buffer-file-truename))
+ (if find-file-visit-truename
+ (setq buffer-file-name
+ (setq filename
+ (expand-file-name buffer-file-truename))))
+ ;; Set buffer's default directory to that of the file.
+ (setq default-directory (file-name-directory filename))
+ ;; Turn off backup files for certain file names. Since
+ ;; this is a permanent local, the major mode won't eliminate it.
+ (and (not (funcall backup-enable-predicate buffer-file-name))
+ (progn
+ (make-local-variable 'backup-inhibited)
+ (setq backup-inhibited t)))
+ (if rawfile
+ nil
+ (after-find-file error (not nowarn)))))
+ buf)))
+
(provide 'nnheader)
(> (nth 1 file-time) (nth 1 timestamp))))))
(save-excursion
(or (eq timestamp 'none)
- (set (intern (format "%s-active-timestamp" backend)) file-time))
+ (set (intern (format "%s-active-timestamp" backend))
+ (current-time)))
(funcall (intern (format "%s-request-list" backend)))
(set (intern (format "%s-group-alist" backend))
(nnmail-get-active))))
(not (buffer-name nnmbox-mbox-buffer)))
(save-excursion
(set-buffer (setq nnmbox-mbox-buffer
- (nnheader-find-file-noselect nnmbox-mbox-file)))
+ (nnheader-find-file-noselect
+ nnmbox-mbox-file nil 'raw)))
(buffer-disable-undo (current-buffer))))
(if (not nnmbox-group-alist)
(nnmail-activate 'nnmbox))
(let ((delim (concat "^" rmail-unix-mail-delimiter))
start end)
(set-buffer (setq nnmbox-mbox-buffer
- (nnheader-find-file-noselect nnmbox-mbox-file)))
+ (nnheader-find-file-noselect
+ nnmbox-mbox-file nil 'raw)))
(buffer-disable-undo (current-buffer))
(goto-char (point-min))
(while (re-search-forward delim nil t)
(let ((map nnvirtual-current-mapping)
(offset 0)
articles beg group active top article result prefix
- fetched-articles)
+ fetched-articles group-method)
(while sequence
(while (< (car (car map)) (car sequence))
(setq offset (car (car map)))
(setq sequence (cdr sequence)))
(setq articles (nreverse articles))
(if (and articles
- (setq result (gnus-retrieve-headers articles group)))
+ (setq result
+ (progn
+ (setq group-method
+ (gnus-find-method-for-group group))
+ (and (or (gnus-server-opened group-method)
+ (gnus-open-server group-method))
+ (gnus-retrieve-headers articles group)))))
(save-excursion
(set-buffer nntp-server-buffer)
;; If we got HEAD headers, we convert them into NOV
(nnvirtual-possibly-change-newsgroups newsgroup server t)
(and (numberp article)
(let ((map nnvirtual-current-mapping)
- (offset 0))
+ (offset 0)
+ group-method)
(while (< (car (car map)) article)
(setq offset (car (car map)))
(setq map (cdr map)))
+ (setq group-method (gnus-find-method-for-group (nth 1 (car map))))
+ (or (gnus-server-opened group-method)
+ (gnus-open-server group-method))
(gnus-request-group (nth 1 (car map)) t)
(gnus-request-article (- (+ (nth 2 (car map)) article) offset)
(nth 1 (car map)) buffer))))
(delq inf nnvirtual-group-alist)))
(setq nnvirtual-current-mapping nil)
(setq nnvirtual-current-group group)
- (let ((newsrc gnus-newsrc-alist))
+ (let ((newsrc gnus-newsrc-alist)
+ (virt-group (gnus-group-prefixed-name
+ nnvirtual-current-group '(nnvirtual ""))))
(setq nnvirtual-current-groups nil)
(while newsrc
(and (string-match regexp (car (car newsrc)))
- (not (string= (gnus-group-real-name (car (car newsrc)))
- nnvirtual-current-group))
+ (not (string= (car (car newsrc)) virt-group))
(setq nnvirtual-current-groups
(cons (car (car newsrc)) nnvirtual-current-groups)))
(setq newsrc (cdr newsrc))))
group name with @code{gnus-adaptive-file-suffix} appended.
@vindex gnus-score-exact-adapt-limit
-When doing adaptive scoring, substring matching would probably give you
-the best results in most cases. However, if the header one matches is
-short, the possibility for false positives is great, so if the length of
-the match is less than @code{gnus-score-exact-adapt-limit}, exact
-matching will be used. If this variable is @code{nil}, which it is by
-default, exact matching will always be used to avoid this problem.
+When doing adaptive scoring, substring or fuzzy matching would probably
+give you the best results in most cases. However, if the header one
+matches is short, the possibility for false positives is great, so if
+the length of the match is less than
+@code{gnus-score-exact-adapt-limit}, exact matching will be used. If
+this variable is @code{nil}, exact matching will always be used to avoid
+this problem.
@node Scoring Tips
@subsection Scoring Tips