*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 23:34:30 +0000 (23:34 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 23:34:30 +0000 (23:34 +0000)
18 files changed:
lisp/ChangeLog
lisp/custom-edit.el
lisp/custom.el
lisp/gnus-art.el
lisp/gnus-group.el
lisp/gnus-int.el
lisp/gnus-score.el
lisp/gnus-setup.el
lisp/gnus-start.el
lisp/gnus-sum.el
lisp/gnus-util.el
lisp/gnus.el
lisp/message.el
lisp/nnweb.el
lisp/widget-edit.el
lisp/widget.el
texi/ChangeLog
texi/gnus.texi

index 609eb7e..bbedff7 100644 (file)
@@ -1,3 +1,30 @@
+Thu Oct  3 02:04:37 1996  Lars Magne Ingebrigtsen  <larsi@ylfing.ifi.uio.no>
+
+       * gnus-int.el (gnus-request-head): Use the cache.
+
+Wed Oct  2 00:57:22 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * message.el (message-resend): Message.
+
+       * gnus-group.el (gnus-group-timestamp-string): New function.
+
+       * gnus-util.el (gnus-time-iso8601): New function.
+
+       * gnus-group.el (gnus-group-set-timestamp): New function.
+       (gnus-group-timestamp): New subst.
+
+       * gnus-start.el (gnus-subscribe-hierarchical-interactive): Accept
+       RET as default. 
+
+Tue Oct  1 05:13:57 1996  Martin Buchholz  <mrb@eng.sun.com>
+
+       * gnus-sum.el (gnus-summary-insert-pseudos): Error takes a format
+       string. 
+
+Tue Oct  1 05:12:29 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus.el: Red Gnus v0.46 is released.
+
 Tue Oct  1 03:41:17 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
 
        * gnus-picon.el (gnus-picons-glyph-hashtb): Made into hashtb.
index 1145a05..f76b135 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, faces
-;; Version: 0.98
+;; Version: 0.991
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
       sexp
     (list 'quote sexp)))
 
-(defun custom-unimplemented (&rest ignore)
-  "Apologize for my laziness."
-  (error "Sorry, not implemented"))
-
 ;;; Modification of Basic Widgets.
 ;;
 ;; We add extra properties to the basic widgets needed here.  This is
@@ -135,15 +131,15 @@ MAGIC is a string used to present that state.
 FACE is a face used to present the state.
 
 The list should be sorted most significant first."
-  :type '(repeat (list (choice (item nil)
-                              (item unknown)
-                              (item hidden)
-                              (item invalid)
-                              (item modified)
-                              (item applied)
-                              (item saved)
-                              (item rogue)
-                              (item factory))
+  :type '(repeat (list (choice (const nil)
+                              (const unknown)
+                              (const hidden)
+                              (const invalid)
+                              (const modified)
+                              (const applied)
+                              (const saved)
+                              (const rogue)
+                              (const factory))
                       string face))
   :group 'customize)
 
@@ -186,6 +182,16 @@ The list should be sorted most significant first."
 
 ;;; The `custom' Widget.
 
+(defvar custom-save-needed-p nil
+  "Non-nil if any customizations need to be saved.")
+
+(add-hook 'kill-emacs-hook 'custom-save-maybe)
+
+(defun custom-save-maybe ()
+  (and custom-save-needed-p
+       (y-or-n-p "You have unsaved customizations, save them now? ")
+       (custom-save)))
+
 (define-widget 'custom 'default
   "Customize a user option."
   :convert-widget 'widget-item-convert-widget
@@ -203,8 +209,7 @@ The list should be sorted most significant first."
 
 (defun custom-format-handler (widget escape)
   ;; We recognize extra escape sequences.
-  (let* ((symbol (widget-get widget :value))
-        (buttons (widget-get widget :buttons))
+  (let* ((buttons (widget-get widget :buttons))
         (level (widget-get widget :custom-level)))
     (cond ((eq escape ?l)
           (when level 
@@ -403,7 +408,7 @@ Optional EVENT is the location for the menu."
     (cond ((eq state 'hidden)
           (error "Cannot apply hidden variable."))
          ((setq val (widget-apply child :validate))
-          (error "Invalid %S"))
+          (error "Invalid %S" val))
          ((eq form 'lisp)
           (set symbol (eval (widget-value child))))
          (t
@@ -421,11 +426,13 @@ Optional EVENT is the location for the menu."
     (cond ((eq state 'hidden)
           (error "Cannot apply hidden variable."))
          ((setq val (widget-apply child :validate))
-          (error "Invalid %S"))
+          (error "Invalid %S" val))
          ((eq form 'lisp)
+          (setq custom-save-needed-p (cons symbol custom-save-needed-p))
           (put symbol 'saved-value (list (widget-value child)))
           (set symbol (eval (widget-value child))))
          (t
+          (setq custom-save-needed-p (cons symbol custom-save-needed-p))
           (put symbol
                'saved-value (list (custom-quote (widget-value
                                                  child))))
@@ -446,9 +453,10 @@ Optional EVENT is the location for the menu."
   "Restore the factory setting for the variable being edited by WIDGET."
   (let ((symbol (widget-value widget)))
     (if (get symbol 'factory-value)
-       (set symbol (car (get symbol 'factory-value)))
+       (set symbol (eval (car (get symbol 'factory-value))))
       (error "No factory default for %S" symbol))
     (when (get symbol 'saved-value)
+      (setq custom-save-needed-p (cons symbol custom-save-needed-p))
       (put symbol 'saved-value nil))
     (widget-put widget :custom-state 'unknown)
     (custom-redraw widget)))
@@ -607,7 +615,7 @@ Optional EVENT is the location for the menu."
         (child (car (widget-get widget :children))))
     (unless (get symbol 'saved-face)
       (error "No saved value for this face")
-      (widget-value-set child (get symbol 'saved-face)))))
+    (widget-value-set child (get symbol 'saved-face)))))
 
 (defun custom-face-factory (widget)
   "Restore WIDGET to the face's factory settings."
@@ -624,7 +632,8 @@ Optional EVENT is the location for the menu."
 (define-widget 'face 'default
   "Select and customize a face."
   :convert-widget 'widget-item-convert-widget
-  :format "%[%t%]%v"
+  :format "%[%t%]: %v"
+  :tag "Face"
   :value 'default
   :value-create 'widget-face-value-create
   :value-delete 'widget-radio-value-delete
@@ -638,8 +647,8 @@ Optional EVENT is the location for the menu."
   (let* ((symbol (widget-value widget))
         (child (widget-create-child-and-convert
                 widget 'custom-face
+                :format "%t %s%m %h%v"
                 :custom-level nil
-                :tag ""
                 :value symbol)))
     (custom-magic-reset child)
     (widget-put widget :children (list child))))
@@ -657,6 +666,7 @@ Optional EVENT is the location for the menu."
                                 'face-history)))
     (unless (zerop (length answer))
       (widget-value-set widget (intern answer))
+      (widget-apply widget :notify widget event)
       (widget-setup))))
 
 ;;; The `custom-group' Widget.
@@ -825,6 +835,7 @@ Leave point at the location of the call, or after the last expression."
   (interactive)
   (custom-save-variables)
   (custom-save-faces)
+  (setq custom-save-needed-p nil)
   (save-excursion
     (set-buffer (find-file-noselect custom-file))
     (save-buffer)))
index f8258fa..45b4028 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, faces
-;; Version: 0.98
+;; Version: 0.991
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
index 5c46531..f075cb6 100644 (file)
@@ -628,6 +628,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
     "\C-c\C-b" gnus-bug
 
     "\C-d" gnus-article-read-summary-keys
+    "\M-*" gnus-article-read-summary-keys
     "\M-g" gnus-article-read-summary-keys)
 
   (substitute-key-definition
@@ -1195,7 +1196,8 @@ If given a prefix, show the hidden text instead."
 
          ;; We only request an article by message-id when we do not have the
          ;; headers for it, so we'll have to get those.
-         (when (stringp article)
+         (when (and (not gnus-doing-request-article)
+                    (stringp article))
            (let ((gnus-override-method gnus-refer-article-method))
              (gnus-read-header article)))
 
index d368cce..d033b76 100644 (file)
@@ -121,6 +121,7 @@ with some simple extensions.
 %l    Whether there are GroupLens predictions for this group (string)
 %n    Select from where (string)
 %z    A string that look like `<%s:%n>' if a foreign select method is used
+?d    The date the group was last entered.
 %u    User defined specifier.  The next character in the format string should
       be a letter.  Gnus will call the function gnus-user-format-function-X,
       where X is the letter following %u.  The function will be passed the
@@ -324,6 +325,7 @@ ticked: The number of ticked articles.")
     (?l gnus-tmp-grouplens ?s)
     (?z gnus-tmp-news-method-string ?s)
     (?m (gnus-group-new-mail gnus-tmp-group) ?c)
+    (?d (gnus-group-timestamp-string gnus-tmp-group) ?s)
     (?u gnus-tmp-user-defined ?s)))
 
 (defvar gnus-group-mode-line-format-alist
@@ -3127,6 +3129,28 @@ and the second element is the address."
                     (sort (nconc (gnus-uncompress-range (cdr m))
                                  (copy-sequence articles)) '<) t))))))
 
+;;;
+;;; Group timestamps
+;;;
+
+(defun gnus-group-set-timestamp ()
+  "Change the timestamp of the current group to the current time.
+This function can be used in hooks like `gnus-select-group-hook'."
+  (let ((time (current-time)))
+    (setcdr (cdr time) nil)
+    (gnus-group-set-parameter gnus-newsgroup-name 'timestamp time)))
+
+(defsubst gnus-group-timestamp (group)
+  "Return the timestamp for GROUP."
+  (gnus-group-get-parameter group 'timestamp))
+
+(defun gnus-group-timestamp-string (group)
+  "Return a string of the timestamp for GROUP."
+  (let ((time (gnus-group-timestamp group)))
+    (if (not time)
+       ""
+      (gnus-time-iso8601 time))))
+
 (provide 'gnus-group)
 
 ;;; gnus-group.el ends here
index 5b2da01..67db32f 100644 (file)
@@ -283,18 +283,31 @@ If BUFFER, insert the article in that group."
 (defun gnus-request-head (article group)
   "Request the head of ARTICLE in GROUP."
   (let* ((method (gnus-find-method-for-group group))
-        (head (gnus-get-function method 'request-head t)))
-    (if (fboundp head)
-       (funcall head article (gnus-group-real-name group) (nth 1 method))
-      (let ((res (gnus-request-article article group)))
-       (when res
-         (save-excursion
-           (set-buffer nntp-server-buffer)
-           (goto-char (point-min))
-           (when (search-forward "\n\n" nil t)
-             (delete-region (1- (point)) (point-max)))
-           (nnheader-fold-continuation-lines)))
-       res))))
+        (head (gnus-get-function method 'request-head t))
+        res clean-up)
+    (cond
+     ;; Check the cache.
+     ((and gnus-use-cache
+          (numberp article)
+          (gnus-cache-request-article article group))
+      (setq res (cons group article)
+           clean-up t))
+     ;; Use `head' function.
+     ((fboundp head)
+      (setq res (funcall head article (gnus-group-real-name group)
+                        (nth 1 method))))
+     ;; Use `article' function.
+     (t
+      (setq res (gnus-request-article article group)
+           clean-up t)))
+    (when clean-up
+      (save-excursion
+       (set-buffer nntp-server-buffer)
+       (goto-char (point-min))
+       (when (search-forward "\n\n" nil t)
+         (delete-region (1- (point)) (point-max)))
+       (nnheader-fold-continuation-lines)))
+    res))
 
 (defun gnus-request-body (article group)
   "Request the body of ARTICLE in GROUP."
index 5ee09d3..658dcaf 100644 (file)
@@ -182,9 +182,7 @@ This variable allows the same syntax as `gnus-home-score-file'.")
     "right" "before" "our" "without" "too" "those" "why" "must" "part"
     "being" "current" "back" "still" "go" "point" "value" "each" "did"
     "both" "true" "off" "say" "another" "state" "might" "under" "start"
-    "try"
-
-    "re")
+    "try" "re")
   "Default list of words to be ignored when doing adaptive word scoring.")
 
 (defvar gnus-default-adaptive-word-score-alist  
index b84f35e..bb240d9 100644 (file)
@@ -31,6 +31,8 @@
 
 ;;; Code:
 
+(require 'cl)
+
 (defvar running-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
 
 (defvar gnus-emacs-lisp-directory (if running-xemacs
index 287746b..a885aec 100644 (file)
@@ -336,7 +336,7 @@ Can be used to turn version control on or off.")
              (push prefix prefixes)
              (message "Descend hierarchy %s? ([y]nsq): "
                       (substring prefix 1 (1- (length prefix))))
-             (while (not (memq (setq ans (read-char)) '(?y ?\n ?n ?s ?q)))
+             (while (not (memq (setq ans (read-char)) '(?y ?\n ?\r ?n ?s ?q)))
                (ding)
                (message "Descend hierarchy %s? ([y]nsq): "
                         (substring prefix 1 (1- (length prefix)))))
@@ -364,7 +364,7 @@ Can be used to turn version control on or off.")
                       (setq groups (cdr groups))))
                    (t nil)))
          (message "Subscribe %s? ([n]yq)" (car groups))
-         (while (not (memq (setq ans (read-char)) '(?y ?\n ?q ?n)))
+         (while (not (memq (setq ans (read-char)) '(?y ?\n ?\r ?q ?n)))
            (ding)
            (message "Subscribe %s? ([n]yq)" (car groups)))
          (setq group (car groups))
index 8b0ef0c..f19a952 100644 (file)
@@ -7786,7 +7786,7 @@ save those articles instead."
        (article (gnus-summary-article-number))
        after-article b e)
     (unless (gnus-summary-goto-subject article)
-      (error (format "No such article: %d" article)))
+      (error "No such article: %d" article))
     (gnus-summary-position-point)
     ;; If all commands are to be bunched up on one line, we collect
     ;; them here.
@@ -7912,10 +7912,8 @@ save those articles instead."
       ;; We have to really fetch the header to this article.
       (save-excursion
        (set-buffer nntp-server-buffer)
-       (when (setq where (gnus-request-article-this-buffer id group))
-         (goto-char (point-min))
-         (when (search-forward "\n\n" nil t)
-           (delete-region (1- (point)) (point-max)))
+       (when (setq where (gnus-request-head id group))
+         (goto-char (point-max))
          (insert ".\n")
          (goto-char (point-min))
          (insert "211 ")
index e9c06fb..2030703 100644 (file)
                         timezone-months-assoc))
                   "???"))))))
 
+(defun gnus-time-iso8601 (time)
+  "Return a string of TIME in YYMMDDTHHMMSS format."
+  (format-time-string "%Y%m%dT%H%M%S" time))
+  
 (defun gnus-date-iso8601 (header)
   "Convert the date field in HEADER to YYMMDDTHHMMSS"
   (condition-case ()
-      (format-time-string "%Y%m%dT%H%M%S"
-                         (nnmail-date-to-time (mail-header-date header)))
+      (gnus-time-iso8601 (nnmail-date-to-time (mail-header-date header)))
     (error "")))
 
 (defun gnus-mode-string-quote (string)
index bbe72c3..27fa7a7 100644 (file)
@@ -42,7 +42,7 @@
   "Score and kill file handling."
   :group 'gnus )
 
-(defconst gnus-version-number "0.46"
+(defconst gnus-version-number "0.47"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Red Gnus v%s" gnus-version-number)
index 416dd5b..519a7b9 100644 (file)
@@ -2869,6 +2869,7 @@ Optional NEWS will use news to forward instead of mail."
 (defun message-resend (address)
   "Resend the current article to ADDRESS."
   (interactive "sResend message to: ")
+  (message "Resending message to %s..." address)
   (save-excursion
     (let ((cur (current-buffer))
          beg)
@@ -2904,7 +2905,8 @@ Optional NEWS will use news to forward instead of mail."
        (insert "Also-"))
       ;; Send it.
       (message-send-mail)
-      (kill-buffer (current-buffer)))))
+      (kill-buffer (current-buffer)))
+    (message "Resending message to %s...done" address)))
 
 ;;;###autoload
 (defun message-bounce ()
index c51d450..9f08176 100644 (file)
 
 (deffoo nnweb-request-group (group &optional server dont-check)
   (nnweb-possibly-change-server nil server)
-  (when (and (not (equal group nnweb-group))
+  (when (and group 
+            (not (equal group nnweb-group))
             (not nnweb-ephemeral-p))
     (let ((info (assoc group nnweb-group-alist)))
       (setq nnweb-group group)
index 5a07f3f..2b6ae2d 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: extensions
-;; Version: 0.98
+;; Version: 0.991
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
@@ -760,7 +760,7 @@ With optional ARG, move across that many fields."
   :match 'widget-item-match
   :match-inline 'widget-item-match-inline
   :action 'widget-item-action
-  :format "%t")
+  :format "%t\n")
 
 (defun widget-item-convert-widget (widget)
   ;; Initialize :value and :tag from :args in WIDGET.
@@ -861,6 +861,7 @@ With optional ARG, move across that many fields."
                                                  :value-to-internal
                                                  (widget-value widget))
                                                 'widget-field-history)))
+    (widget-apply widget :notify widget event)
     (widget-setup)))
 
 (defun widget-field-value-create (widget)
@@ -904,6 +905,7 @@ With optional ARG, move across that many fields."
          (setq from (1+ from)
                to (1- to))
          (while (and size
+                     (not (zerop size))
                      (> to from)
                      (eq (char-after (1- to)) ?\ ))
            (setq to (1- to)))
@@ -926,6 +928,7 @@ With optional ARG, move across that many fields."
   "A menu of options."
   :convert-widget  'widget-choice-convert-widget
   :format "%[%t%]: %v"
+  :case-fold t
   :tag "choice"
   :void '(item :format "invalid (%t)\n")
   :value-create 'widget-choice-value-create
@@ -940,12 +943,12 @@ With optional ARG, move across that many fields."
 
 (defun widget-choice-convert-widget (widget)
   ;; Expand type args into widget objects.
-                                       ;  (widget-put widget :args (mapcar (lambda (child)
-                                       ;                                    (if (widget-get child ':converted)
-                                       ;                                        child
-                                       ;                                      (widget-put child ':converted t)
-                                       ;                                      (widget-convert child)))
-                                       ;                                  (widget-get widget :args)))
+;  (widget-put widget :args (mapcar (lambda (child)
+;                                   (if (widget-get child ':converted)
+;                                       child
+;                                     (widget-put child ':converted t)
+;                                     (widget-convert child)))
+;                                 (widget-get widget :args)))
   (widget-put widget :args (mapcar 'widget-convert (widget-get widget :args)))
   widget)
 
@@ -982,6 +985,7 @@ With optional ARG, move across that many fields."
   (let ((args (widget-get widget :args))
        (old (widget-get widget :choice))
        (tag (widget-apply widget :menu-tag-get))
+       (completion-ignore-case (widget-get widget :case-fold))
        current choices)
     ;; Remember old value.
     (if (and old (not (widget-apply widget :validate)))
@@ -1012,7 +1016,8 @@ With optional ARG, move across that many fields."
       (widget-value-set widget 
                        (widget-apply current :value-to-external
                                      (widget-get current :value)))
-      (widget-setup)))
+    (widget-apply widget :notify widget event)
+    (widget-setup)))
   ;; Notify parent.
   (widget-apply widget :notify widget event)
   (widget-clear-undo))
@@ -1460,7 +1465,7 @@ With optional ARG, move across that many fields."
        (t 
         (widget-default-format-handler widget escape))))
 
-                                       ;(defun widget-editable-list-format-handler (widget escape)
+;(defun widget-editable-list-format-handler (widget escape)
 ;  ;; We recognize the insert button.
 ;  (cond ((eq escape ?i)
 ;       (insert " ")                   
@@ -1726,8 +1731,9 @@ With optional ARG, move across that many fields."
   :format "%[%t%]: %v")
 
 (define-widget 'regexp 'string
+  "A regular expression."
   ;; Should do validation.
-  "A regular expression.")
+  :tag "Regexp")
 
 (define-widget 'file 'string
   "A file widget.  
@@ -1746,6 +1752,7 @@ It will read a file name from the minibuffer when activated."
         (answer (read-file-name (concat menu-tag ": (defalt `" value "') ")
                                 dir nil must-match file)))
     (widget-value-set widget (abbreviate-file-name answer))
+    (widget-apply widget :notify widget event)
     (widget-setup)))
 
 (define-widget 'directory 'file
@@ -1968,13 +1975,15 @@ It will read a directory name from the minibuffer when activated."
                       (t
                        (read-string prompt (widget-value widget))))))
     (unless (zerop (length answer))
-      (widget-value-set widget answer))))
+      (widget-value-set widget answer)
+      (widget-apply widget :notify widget event)
+      (widget-setup))))
 
 ;;; The Help Echo
 
 (defun widget-echo-help-mouse ()
   "Display the help message for the widget under the mouse.
-Enable with (run-with-idle-timer 2 t 'widget-echo-help-mouse)"
+Enable with (run-with-idle-timer 1 t 'widget-echo-help-mouse)"
   (let* ((pos (mouse-position))
         (frame (car pos))
         (x (car (cdr pos)))
index bde0b98..25b7ce2 100644 (file)
@@ -4,7 +4,7 @@
 ;;
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: help, extensions, faces, hypermedia
-;; Version: 0.98
+;; Version: 0.991
 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
 
 ;;; Commentary:
@@ -26,7 +26,7 @@
             (set (car keywords) (car keywords)))
         (setq keywords (cdr keywords))))))
 
-(define-widget-keywords :widget-doc
+(define-widget-keywords :case-fold :widget-doc
   :create :convert-widget :format :value-create :offset :extra-offset
   :tag :doc :from :to :args :value :value-from :value-to :action
   :value-set :value-delete :match :parent :delete :menu-tag-get
index 59e0e5c..920ae63 100644 (file)
@@ -1,3 +1,7 @@
+Wed Oct  2 01:32:49 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Group Timestamps): New.
+
 Tue Oct  1 01:34:45 1996  Lars Magne Ingebrigtsen  <larsi@hrym.ifi.uio.no>
 
        * gnus.texi (Expiring Mail): Addition.
index 8ef8d1b..74c0623 100644 (file)
@@ -1,7 +1,7 @@
 \input texinfo                  @c -*-texinfo-*-
 
 @setfilename gnus
-@settitle Red Gnus 0.46 Manual
+@settitle Red Gnus 0.47 Manual
 @synindex fn cp
 @synindex vr cp
 @synindex pg cp
@@ -287,7 +287,7 @@ into another language, under the above conditions for modified versions.
 @tex
 
 @titlepage
-@title Red Gnus 0.46 Manual
+@title Red Gnus 0.47 Manual
 
 @author by Lars Magne Ingebrigtsen
 @page
@@ -1125,6 +1125,10 @@ The default is 1---this will mean that group names like
 @samp{%} (@code{gnus-new-mail-mark}) if there has arrived new mail to
 the group lately.
 
+@item d
+A string that says when you last read the group (@pxref{Group
+Timestamp}). 
+
 @item u
 User defined specifier.  The next character in the format string should
 be a letter.  @sc{gnus} will call the function
@@ -2705,6 +2709,7 @@ happens.  You just have to be careful if you do stuff like that.
 @menu
 * Scanning New Messages:: Asking Gnus to see whether new messages have arrived.
 * Group Information::     Information and help on groups and Gnus.
+* Group Timestamp::       Making Gnus keep track of when you last read a group.
 * File Commands::         Reading and writing the Gnus files.
 @end menu
 
@@ -2861,6 +2866,46 @@ Go to the Gnus info node (@code{gnus-info-find-node}).
 @end table
 
 
+@node Group Timestamp
+@subsection Group Timestamp
+@cindex timestamps
+@cindex group timestamps
+
+It can be convenient to let Gnus keep track of when you last read a
+group.  To set the ball rolling, you should add
+@code{gnus-group-set-timestamp} to @code{gnus-select-group-hook}:
+
+@lisp
+(add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp)
+@end lisp
+
+After doing this, each time you enter a group, it'll be recorded.
+
+This information can be displayed in various ways---the easiest is to
+use the @samp{%d} spec in the group line format:
+
+@lisp
+(setq gnus-group-line-format 
+      "%M\%S\%p\%P\%5y: %(%-40,40g%) %d\n")
+@end lisp
+
+This will result in lines looking like:
+
+@example
+*        0: mail.ding                                19961002T012943
+         0: custom                                   19961002T012713
+@end example
+
+As you can see, the date is displayed in compact ISO 8601 format.  This
+may be a bit too much, so to just display the date, you could say
+something like:
+
+@lisp
+(setq gnus-group-line-format 
+      "%M\%S\%p\%P\%5y: %(%-40,40g%) %6,6~(cut 2)d\n")
+@end lisp
+
+
 @node File Commands
 @subsection File Commands
 @cindex file commands
@@ -8391,7 +8436,7 @@ password, you can either set @code{nnmail-pop-password-required} to
 @code{t} and be prompted for the password, or set
 @code{nnmail-pop-password} to the password itself.
 
-Your Emacs has to have been configured with @samp{--use-pop} before
+Your Emacs has to have been configured with @samp{--with-pop} before
 compilation.  This is the default, but some installations have it
 switched off.