*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 02:12:43 +0000 (02:12 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 02:12:43 +0000 (02:12 +0000)
17 files changed:
lisp/ChangeLog
lisp/gnus-ems.el
lisp/gnus-mh.el
lisp/gnus-msg.el
lisp/gnus-score.el
lisp/gnus-uu.el
lisp/gnus-vis.el
lisp/gnus-vm.el
lisp/gnus.el
lisp/nnbabyl.el
lisp/nndigest.el
lisp/nnmail.el
lisp/nnmbox.el
lisp/nnmh.el
lisp/nnml.el
lisp/nnspool.el
lisp/nnvirtual.el

index 972192e..d111a96 100644 (file)
@@ -1,3 +1,147 @@
+Sat May 20 00:11:59 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-msg.el (gnus-mail-reply-using-mail): Don't barf wifout a
+       message-id. 
+
+       * gnus-score.el (gnus-score-load-file): 'eval was not right. 
+
+       * gnus.el (gnus-make-articles-unread): Would deliver wrong
+       results. 
+
+Fri May 19 01:10:34 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * nnbabyl.el (nnbabyl-insert-newsgroup-line): Did not translate
+       "From " lines.
+       (nnbabyl-insert-lines): Wrong number of lines. 
+       (nnbabyl-request-accept-article): Bugged out. 
+
+       * nnmh.el (nnmh-request-accept-article): Would never accept an
+       article. 
+
+       * gnus-vis.el (gnus-article-add-buttons): `Entry' would be nil
+       sometimes. 
+
+       * gnus-ems.el (gnus-ems-redefine): Redefine buffer-display-table. 
+
+       * gnus.el (gnus): Init server buffer, just in case.
+
+       * nnml.el (nnml-request-create-group): string-to-int instead of
+       int-to-string. 
+
+       * gnus.el (gnus-group-use-permament-levels): New variable,
+       supersedes other variables. 
+       (gnus-article-prepare): Let buffer-read-only nil before calling
+       hooks. 
+       (gnus-summary-next-group): Recenter group buffer.
+       (gnus-get-newsgroup-headers): Articles without message-id's
+       fetched in separate batches would be clobbered.
+
+       * gnus-msg.el (gnus-inews-do-fcc): Make sure the fcc dir exists. 
+       (gnus-inews-news): If both mailing and posting, remove the Fcc
+       before posting. 
+
+       * nnvirtual.el (nnvirtual-request-post-buffer): Don't suggest any
+       newsgroups to post in.
+
+       * gnus.el (gnus-list-of-read-articles): Would totally bug out. 
+
+       * gnus-score.el (gnus-score-string): Add tracing.
+       (gnus-score-find-trace): New command and keystroke.
+
+       * nnmbox.el (nnmbox-request-expire-articles): When deleting the
+       last article, would infloop.
+
+       * nnbabyl.el (nnbabyl-article-string): Did not anchor end of
+       number. 
+
+       * gnus-msg.el (gnus-forward-insert-buffer): Don't do double
+       copying of article buffer.
+       (gnus-copy-article-buffer): Would barf when the article buffer
+       didn't exist.
+
+       * gnus.el (gnus-configure-windows): Split the opposite way.
+       (gnus-summary-next-group): Would cycle on 0 on the last group. 
+
+       * gnus-score.el (gnus-summary-increase-score): Give fuller
+       prompts. 
+
+Sun May 14 10:01:49 1995  Per Abrahamsen  <abraham@iesd.auc.dk>
+
+       * gnus.el: Use (point-min) instead if `1'.
+
+       * gnus.el (gnus-hidden-properties): Added.
+       (gnus-summary-toggle-header, gnus-article-show-all-headers,
+       gnus-article-hide-headers): Use it.
+
+       * gnus-cite.el (gnus-article-hide-citation,
+       gnus-article-hide-citation-maybe, gnus-cite-toggle): Use it.
+
+       * gnus-vis.el (gnus-article-hide-signature,
+       gnus-signature-toggle):  use it.
+
+       * gnus.el (gnus-article-hide-signature): Deleted.  Use the version
+       in `gnus-vis.el' instead.
+
+       * gnus-vis.el (gnus-article-next-button): New function and
+       keybinding. 
+
+Thu May 18 03:10:03 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-score.el (gnus-score-edit-alist): Really save winconf.
+
+       * gnus.el (gnus-summary-enter-digest-group): Don't use / in group
+       names. 
+
+       * nnmail.el (nnmail-split-incoming): Use Content-Length header. 
+
+       * gnus-score.el (gnus-score-headers): Let current-score-file. 
+
+       * gnus-ems.el: Don't use intagible before 19.29.
+
+       * nndigest.el (nndigest-narrow-to-article): Stop before that *End
+       of digest* line.
+
+       * gnus-score.el (gnus-score-score-files): Expand the kill-file
+       path before using it.
+       (gnus-summary-increase-score): Double quoting of types.
+
+       * gnus-mh.el (gnus-mail-forward-using-mhe): Use the incoming
+       buffer. 
+
+       * gnus.el (gnus-summary-prepare-threads): False roots would get
+       incorrect number of children.
+
+       * nnspool.el (nnspool-inews-sentinel): condition-case the sending
+       of eof.
+
+       * gnus.el (gnus-summary-mark-article): Always un-hide threads. 
+       (gnus-update-read-articles): Peel off expired article numbers. 
+       (gnus-article-set-window-start): New function.
+       (gnus-summary-refer-article): Would scroll to the end of the
+       buffer. 
+
+       * gnus-uu.el (gnus-uu-save-article): Grabbed one char to many when
+       snarfing headers. 
+
+       * gnus-score.el (gnus-score-add-followups): Don't enter if there
+       already is one.
+
+       * gnus.el (gnus-nov-read-integer): Condition-case the read. 
+
+       * nnvirtual.el (nnvirtual-close-group): Always handle a close. 
+
+       * gnus-vm.el (gnus-mail-forward-using-vm): Accept an argument.
+
+       * gnus-mh.el (gnus-mail-forward-using-mhe): Ditto.
+
+       * gnus.el (gnus-summary-make-display-table): New function.
+
+Thu May 18 00:58:54 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-summary-mode): Display-table would be nil. 
+
+       * gnus.el: 0.72 is released.
+
 Wed May 17 19:38:43 1995  Lars Magne Ingebrigtsen  <larsi@surt.ifi.uio.no>
 
        * gnus.el: 0.71 is released.
index f601239..9501aed 100644 (file)
          (if props
              (put-text-property start end (car props) (cadr props) buffer)
            (remove-text-properties start end ()))))
-  
+    
+    (or (fboundp 'make-overlay (fset 'make-overlay 'make-extent)))
+    (or (fboundp 'over-lay-put (fset 'overlay-put 'set-extent-property)))
+    (or (boundp 'standard-display-table (setq standard-display-table nil)))
+
     (if (not gnus-visual)
        ()
       (setq gnus-group-mode-hook
     (defun gnus-install-mouse-tracker ()
       (require 'mode-motion)
       (setq mode-motion-hook 'mode-motion-highlight-line)))
+
+   ((and (not (string-match "28.9" emacs-version)) 
+        (not (string-match "29" emacs-version)))
+    (setq gnus-hidden-properties '(invisible t)))
+   
+   ))
+
+(eval-and-compile
+  (cond
+   ((not window-system)
+    (defun gnus-dummy-func (&rest args))
+    (let ((funcs '(mouse-set-point make-face set-face-foreground
+                                  set-face-background)))
+      (while funcs
+       (or (fboundp (car funcs))
+           (fset (car funcs) 'gnus-dummy-func))
+       (setq funcs (cdr funcs)))))
    ))
 
 (defun gnus-ems-redefine ()
   (cond 
    ((string-match "XEmacs\\|Lucid" emacs-version)
     ;; XEmacs definitions.
-    (fset 'gnus-set-mouse-face (lambda (string) string)))
+    (fset 'gnus-set-mouse-face (lambda (string) string))
+
+    (defun gnus-summary-make-display-table ()
+      (let* ((table (window-display-table)))
+       (and (not table)
+            (setq table (make-vector 261 ())))
+       (let ((i 32))
+         (while (>= (setq i (1- i)) 0)
+           (aset table i [??])))
+       (aset table ?\n nil)
+       (let ((i 160))
+         (while (>= (setq i (1- i)) 127)
+           (aset table i [??])))
+       (setq gnus-summary-display-table table)))
+
+    )
 
    ))
 
 (provide 'gnus-ems)
 
+;; Local Variables:
+;; byte-compile-warnings: nil
+;; End:
+
 ;;; gnus-ems.el ends here
index bfc0e07..8de37b2 100644 (file)
@@ -145,12 +145,12 @@ The command \\[mh-yank-cur-msg] yank the original message into current buffer."
 ;; gnus-mail-forward-using-mhe is contributed by Jun-ichiro Itoh
 ;; <itojun@ingram.mt.cs.keio.ac.jp>
 
-(defun gnus-mail-forward-using-mhe ()
+(defun gnus-mail-forward-using-mhe (&optional buffer)
   "Forward the current message to another user using mh-e."
   ;; First of all, prepare mhe mail buffer.
   (let ((to (read-string "To: "))
        (cc (read-string "Cc: "))
-       (buffer (current-buffer))
+       (buffer (or buffer gnus-article-buffer))
        subject
        (config (current-window-configuration))) ;; need to add this - erik
     ;;(gnus-article-show-all-headers)
index c7bd001..a719f43 100644 (file)
@@ -200,6 +200,9 @@ the article to a file).")
 The hook is called from the *post-news* buffer, narrowed to the
 headers.")
 
+(defvar gnus-mail-hook nil
+  "*A hook called as the last thing after setting up a mail buffer.")
+
 ;;; Internal variables.
 
 (defvar gnus-post-news-buffer "*post-news*")
@@ -352,12 +355,17 @@ header line with the old Message-ID."
   ;; if ARTICLE-BUFFER is nil, gnus-article-buffer is used
   ;; this buffer should be passed to all mail/news reply/post routines.
   (setq gnus-article-copy (get-buffer-create " *gnus article copy*"))
+  (buffer-disable-undo gnus-article-copy)
   (or (memq gnus-article-copy gnus-buffer-list)
       (setq gnus-buffer-list (cons gnus-article-copy gnus-buffer-list)))
-  (save-excursion
-    (set-buffer (or article-buffer gnus-article-buffer))
-    (copy-to-buffer gnus-article-copy (point-min) (point-max))
-    (set-text-properties (point-min) (point-max) nil gnus-article-copy)))
+  (let ((article-buffer (or article-buffer gnus-article-buffer)))
+    (if (and (get-buffer article-buffer)
+            (buffer-name (get-buffer article-buffer)))
+       (save-excursion
+         (set-buffer article-buffer)
+         (copy-to-buffer gnus-article-copy (point-min) (point-max))
+         (set-text-properties (point-min) (point-max) 
+                              nil gnus-article-copy)))))
 
 (defun gnus-post-news (post &optional group header article-buffer yank subject)
   "Begin editing a new USENET news article to be posted.
@@ -502,7 +510,8 @@ will attempt to use the foreign server to post the article."
         (progn
           (goto-char (point-min))
           (re-search-forward 
-           (concat "^" (regexp-quote mail-header-separator) "$"))))
+           (concat "^" (regexp-quote mail-header-separator) "$"))
+          (match-beginning 0)))
 
        ;; Correct newsgroups field: change sequence of spaces to comma and 
        ;; eliminate spaces around commas.  Eliminate imbedded line breaks.
@@ -560,7 +569,8 @@ will attempt to use the foreign server to post the article."
 
        ;; Mail the message too if To:, Bcc:. or Cc: exists.
        (let* ((types '("to" "bcc" "cc"))
-              (ty types))
+              (ty types)
+              fcc-line)
          (while ty
            (or (mail-fetch-field (car ty) nil t)
                (setq types (delete (car ty) types)))
@@ -576,10 +586,23 @@ will attempt to use the foreign server to post the article."
                   1 "No mailer defined.  To: and/or Cc: fields ignored.")
                  (sit-for 1))
              (save-excursion
+               ;; We want to remove Fcc, because we want to handle
+               ;; that one ourselves...  
+                 
+               (goto-char (point-min))
+               (if (re-search-forward "^Fcc: " nil t)
+                   (progn
+                     (setq fcc-line
+                           (buffer-substring
+                            (progn (beginning-of-line) (point))
+                            (progn (forward-line 1) (point))))
+                     (forward-line -1)
+                     (gnus-delete-line)))
+
                (save-restriction
                  (widen)
                  (gnus-message 5 "Sending via mail...")
-                     
+
                  (if (and gnus-mail-courtesy-message
                           (or (member "to" types)
                               (member "cc" types)))
@@ -609,7 +632,11 @@ will attempt to use the foreign server to post the article."
                   (re-search-forward 
                    (concat "^" (regexp-quote mail-header-separator) "$")))
                  (goto-char (point-min))
-                 (delete-matching-lines "^BCC:")))))))
+                 (delete-matching-lines "^BCC:"))
+               (if fcc-line
+                   (progn
+                     (goto-char (point-max))
+                     (insert fcc-line))))))))
 
       ;; Send to NNTP server. 
       (gnus-message 5 "Posting to USENET...")
@@ -1062,6 +1089,7 @@ a program specified by the rest of the value."
                (t
                 ;; Suggested by hyoko@flab.fujitsu.junet.
                 ;; Save article in Unix mail format by default.
+                (gnus-make-directory fcc-file)
                 (if (and gnus-author-copy-saver
                          (not (eq gnus-author-copy-saver 'rmail-output)))
                     (funcall gnus-author-copy-saver fcc-file)
@@ -1205,9 +1233,6 @@ organization."
              "~/.organization")))
     (and (stringp organization)
         (> (length organization) 0)
-        (or (file-exists-p organization)
-            (string-match " " organization)
-            (not (string-match  "^/[^/]+/" (expand-file-name organization))))
         (save-excursion
           (gnus-set-work-buffer)
           (if (file-exists-p organization)
@@ -1332,8 +1357,9 @@ mailer."
          (setq reply-to (mail-fetch-field "reply-to"))
          (setq references (mail-fetch-field "references"))
          (setq message-id (mail-fetch-field "message-id")))
-       (setq news-reply-yank-from from)
-       (setq news-reply-yank-message-id message-id)
+       (setq news-reply-yank-from (or from "(nobody)"))
+       (setq news-reply-yank-message-id
+             (or message-id "(unknown Message-ID)"))
 
        ;; Gather the "to" addresses out of the follow-to list and remove
        ;; them as we go.
@@ -1392,7 +1418,8 @@ mailer."
                (goto-char end)
                (setq yank (cdr yank))))
            (goto-char last))
-         (gnus-configure-windows 'reply-yank))))))
+         (gnus-configure-windows 'reply-yank))
+       (run-hooks 'gnus-mail-hook)))))
 
 (defun gnus-mail-yank-original ()
   (interactive)
@@ -1429,8 +1456,7 @@ mailer."
 (defun gnus-forward-insert-buffer (buffer)
   (let ((beg (goto-char (point-max))))
     (insert "------- Start of forwarded message -------\n")
-    (gnus-copy-article-buffer buffer)
-    (insert-buffer gnus-article-copy)
+    (insert-buffer buffer)
     (goto-char (point-max))
     (insert "------- End of forwarded message -------\n")
     ;; Suggested by Sudish Joseph <joseph@cis.ohio-state.edu>. 
index 544075b..8870ec2 100644 (file)
@@ -66,6 +66,9 @@ score alists.")
     (gnus-catchup-mark (from -1) (subject -1)))
   "*Alist of marks and scores.")
 
+(defvar gnus-score-mimic-keymap nil
+  "*Have the score entry functions pretend that they are a keymap.")
+
 (defvar gnus-score-exact-adapt-limit nil
   "*Number that says how long a match has to be before using substring matching.
 When doing adaptive scoring, one normally uses substring matching.
@@ -82,9 +85,10 @@ always be used.")
 
 (defvar gnus-internal-global-score-files nil)
 (defvar gnus-score-file-list nil)
-(defvar gnus-current-score-file nil)
 (defvar gnus-adaptive-score-alist gnus-default-adaptive-score-alist)
 
+(defvar gnus-score-trace nil)
+
 (defvar gnus-score-alist nil
   "Alist containing score information.
 The keys can be symbols or strings.  The following symbols are defined. 
@@ -123,6 +127,7 @@ of the last succesful match.")
 (define-key gnus-summary-score-map "x" 'gnus-score-set-expunge-below)
 (define-key gnus-summary-score-map "e" 'gnus-score-edit-alist)
 (define-key gnus-summary-score-map "f" 'gnus-score-edit-file)
+(define-key gnus-summary-score-map "t" 'gnus-score-find-trace)
 
 
 
@@ -137,8 +142,9 @@ of the last succesful match.")
 
 (defun gnus-summary-increase-score (score)
   (interactive "P")
-  (let* ((score (gnus-score-default score))
-        (prefix (if (< score 0) ?L ?I))
+  (let* ((nscore (gnus-score-default score))
+        (prefix (if (< nscore 0) ?L ?I))
+        (increase (> nscore 0))
         (char-to-header 
          '((?a "from")
            (?s "subject")
@@ -151,54 +157,66 @@ of the last succesful match.")
            (?d "date")
            (?f "followup")))
         (char-to-type
-         '((?e 'e)
-           (?f 'f)
-           (?s 's)
-           (?r 'r)
-           (?b 'before)
-           (?a 'at)
-           (?n 'now)
-           (?< '<)
-           (?> '>)
-           (?= '=)))
+         '((?e e) (?f f) (?s nil) (?r r) (?b before)
+           (?a at) (?n now) (?< <) (?> >) (?= =)))
+        (char-to-perm
+         (list (list ?t (current-time-string)) '(?p nil) '(?i now)))
+        (mimic gnus-score-mimic-keymap)
         hchar entry temporary tchar pchar end type)
     ;; First we read the header to score.
-    (message "%c-" prefix)
+    (if mimic
+       (message "%c-" prefix)
+      (message "%s header (%s): " (if increase "Increase" "Lower")
+              (mapconcat (lambda (s) (char-to-string (car s)))
+                         char-to-header "")))
     (setq hchar (read-char))
     (or (setq entry (assq (downcase hchar) char-to-header))
        (progn
          (ding)
          (setq end t)
-         (message "%c %c" prefix hchar)))
+         (if mimic (message "%c %c" prefix hchar) (message ""))))
     (if (or end (/= (downcase hchar) hchar))
        (progn
          ;; This was a majuscle, so we end reading and set the defaults.
-         (message "%c %c" prefix hchar)
-         (setq type 's
-               temporary t))
+         (if mimic (message "%c %c" prefix hchar) (message ""))
+         (setq type nil
+               temporary (current-time-string)))
       ;; We continue reading - the type.
-      (message "%c %c-" prefix hchar)
+      (if mimic
+         (message "%c %c-" prefix hchar)
+       (message "%s header '%s' with match type (%s): "
+                (if increase "Increase" "Lower")
+                (nth 1 entry)
+                (mapconcat (lambda (s) (char-to-string (car s)))
+                           char-to-type "")))
       (setq tchar (read-char))
       (or (setq type (nth 1 (assq (downcase tchar) char-to-type)))
          (progn
            (ding)
-           (message "%c %c" prefix hchar)
+           (if mimic (message "%c %c" prefix hchar) (message ""))
            (setq end t)))
       (if (or end (/= (downcase tchar) tchar))
          (progn
            ;; It was a majuscle, so we end reading and the the default.
-           (message "%c %c %c" prefix hchar tchar)
-           (setq temporary t))
+           (if mimic (message "%c %c %c" prefix hchar tchar)
+             (message ""))
+           (setq temporary (current-time-string)))
        ;; We continue reading.
-       (message "%c %c %c-" prefix hchar tchar)
+       (if mimic
+           (message "%c %c %c-" prefix hchar tchar)
+         (message "%s permanence (%s): " (if increase "Increase" "Lower")
+                  (mapconcat (lambda (s) (char-to-string (car s)))
+                             char-to-perm "")))
        (setq pchar (read-char))
-       (message "%c %c %c" prefix hchar tchar pchar)
-       (cond ((= pchar ?t)
-              (setq temporary t))
-             ((/= pchar ?p)
-              (ding)
-              (setq end t)
-              (message "%c %c %c %c" prefix hchar tchar pchar)))))
+       (if mimic (message "%c %c %c" prefix hchar tchar pchar)
+         (message ""))
+       (if (setq temporary (nth 1 (assq pchar char-to-perm)))
+           ()
+         (ding)
+         (setq end t)
+         (if mimic 
+             (message "%c %c %c %c" prefix hchar tchar pchar)
+           (message "")))))
     ;; We have all the data, so we enter this score.
     (if end
        ()
@@ -206,8 +224,8 @@ of the last succesful match.")
        (nth 1 entry)                   ; Header
        (gnus-summary-header (or (nth 2 entry) (nth 1 entry))) ; Match
        type                            ; Type
-       (gnus-score-default score)              ; Score
-       (and temporary (current-time-string)) ; Temp
+       score                           ; Score
+       temporary                        ; Temp
        (not (nth 3 entry)))            ; Prompt
       )))
 
@@ -408,16 +426,16 @@ SCORE is the score to add."
 (defun gnus-score-edit-alist (file)
   "Edit the current score alist."
   (interactive (list gnus-current-score-file))
-  (and (buffer-name gnus-summary-buffer) (gnus-score-save))
   (let ((winconf (current-window-configuration)))
+    (and (buffer-name gnus-summary-buffer) (gnus-score-save))
     (gnus-configure-windows 'article)
     (pop-to-buffer (find-file-noselect file))
+    (gnus-score-mode)
     (make-local-variable 'gnus-prev-winconf)
     (setq gnus-prev-winconf winconf))
   (gnus-message 
    4 (substitute-command-keys 
-      "\\<gnus-score-mode-map>\\[gnus-score-edit-done] to save edits"))
-  (gnus-score-mode))
+      "\\<gnus-score-mode-map>\\[gnus-score-edit-done] to save edits")))
   
 (defun gnus-score-edit-file (file)
   "Edit a score file."
@@ -427,12 +445,12 @@ SCORE is the score to add."
   (let ((winconf (current-window-configuration)))
     (gnus-configure-windows 'article)
     (pop-to-buffer (find-file-noselect file))
+    (gnus-score-mode)
     (make-local-variable 'gnus-prev-winconf)
     (setq gnus-prev-winconf winconf))
   (gnus-message 
    4 (substitute-command-keys 
-      "\\<gnus-score-mode-map>\\[gnus-score-edit-done] to save edits"))
-  (gnus-score-mode))
+      "\\<gnus-score-mode-map>\\[gnus-score-edit-done] to save edits")))
   
 (defun gnus-score-load-file (file)
   ;; Load score file FILE.  Returns a list a retrieved score-alists.
@@ -477,7 +495,7 @@ SCORE is the score to add."
          (exclude-files (gnus-score-get 'exclude-files alist))
           (orphan (car (gnus-score-get 'orphan alist)))
          (adapt (gnus-score-get 'adapt alist))
-         (eval (gnus-score-get 'eval alist)))
+         (eval (car (gnus-score-get 'eval alist))))
       ;; We do not respect eval and files atoms from global score
       ;; files. 
       (and files (not global)
@@ -634,7 +652,7 @@ SCORE is the score to add."
            (write-region (point-min) (point-max) file nil 'silent))))
       (kill-buffer (current-buffer)))))
   
-(defun gnus-score-headers (score-files)
+(defun gnus-score-headers (score-files &optional trace)
   ;; Score `gnus-newsgroup-headers'.
   (let (scores)
     ;; PLM: probably this is not the best place to clear orphan-score
@@ -668,6 +686,7 @@ SCORE is the score to add."
             (now (gnus-day-number (current-time-string)))
             (expire (- now gnus-score-expiry-days))
             (headers gnus-newsgroup-headers)
+            (gnus-current-score-file gnus-current-score-file)
             entry header)
        (gnus-message 5 "Scoring...")
        ;; Create articles, an alist of the form `(HEADER . SCORE)'.
@@ -701,7 +720,7 @@ SCORE is the score to add."
                                  (lambda (score)
                                    (length (gnus-score-get header score)))
                                  scores)))
-               (funcall (nth 2 entry) scores header now expire)))
+               (funcall (nth 2 entry) scores header now expire trace)))
          ;; Remove the buffer.
          (kill-buffer (current-buffer)))
 
@@ -789,7 +808,7 @@ SCORE is the score to add."
                    (forward-line))))))
              
 
-(defun gnus-score-integer (scores header now expire)
+(defun gnus-score-integer (scores header now expire &optional trace)
   (let ((gnus-score-index (nth 1 (assoc header gnus-header-index)))
        alike last this art entries alist articles)
 
@@ -822,6 +841,9 @@ SCORE is the score to add."
                          (or (aref (car (car articles)) gnus-score-index) 0)
                          match)
                 (progn
+                  (and trace (setq gnus-score-trace 
+                                   (cons (cons (car (car articles)) kill)
+                                         gnus-score-trace)))
                   (setq found t)
                   (setcdr (car articles) (+ score (cdr (car articles))))))
            (setq articles (cdr articles)))
@@ -836,7 +858,7 @@ SCORE is the score to add."
                 (setq rest entries)))
          (setq entries rest))))))
 
-(defun gnus-score-date (scores header now expire)
+(defun gnus-score-date (scores header now expire &optional trace)
   (let ((gnus-score-index (nth 1 (assoc header gnus-header-index)))
        alike last this art entries alist articles)
 
@@ -870,6 +892,9 @@ SCORE is the score to add."
             (setq l (aref (car (car articles)) gnus-score-index))
             (funcall match-func match (timezone-make-date-sortable l))
             (progn
+              (and trace (setq gnus-score-trace 
+                               (cons (cons (car (car articles)) kill)
+                                     gnus-score-trace)))
               (setq found t)
               (setcdr (car articles) (+ score (cdr (car articles))))))
            (setq articles (cdr articles)))
@@ -884,7 +909,7 @@ SCORE is the score to add."
                 (setq rest entries)))
          (setq entries rest))))))
 
-(defun gnus-score-body (scores header now expire)
+(defun gnus-score-body (scores header now expire &optional trace)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (save-restriction
@@ -954,7 +979,10 @@ SCORE is the score to add."
                      ;; Found a match, update scores.
                      (progn
                        (setcdr (car articles) (+ score (cdr (car articles))))
-                       (setq found t)))
+                       (setq found t)
+                       (and trace (setq gnus-score-trace 
+                                        (cons (cons (car (car articles)) kill)
+                                              gnus-score-trace)))))
                  ;; Update expire date
                  (cond ((null date))   ;Permanent entry.
                        (found          ;Match, update date.
@@ -1063,12 +1091,25 @@ SCORE is the score to add."
 (defun gnus-score-add-followups (header score)
   (save-excursion
     (set-buffer gnus-summary-buffer)
-    (gnus-summary-score-entry 
-     "references" (header-id header) 's score 
-     (current-time-string) nil t)))
+    (let ((id (header-id header))
+         (score gnus-score-alist)
+         dont)
+      ;; Don't enter a score if there already is one.
+      (while score
+       (and (equal "references" (car (car score)))
+            (or (null (nth 3 (car score)))
+                (eq 's (nth 3 (car score))))
+            (progn
+              (or (assoc id (car score))
+                  (setq dont t))
+              (setq score nil)))
+       (setq score (cdr score)))
+      (or dont
+         (gnus-summary-score-entry 
+          "references" id 's score (current-time-string) nil t)))))
 
 
-(defun gnus-score-string (score-list header now expire)
+(defun gnus-score-string (score-list header now expire &optional trace)
   ;; Score ARTICLES according to HEADER in SCORE-LIST.
   ;; Update matches entries to NOW and remove unmatched entried older
   ;; than EXPIRE.
@@ -1147,20 +1188,37 @@ SCORE is the score to add."
                         (setq found (setq arts (get-text-property 
                                                 (point) 'articles)))
                         ;; Found a match, update scores.
-                        (while arts
-                          (setq art (car arts)
-                                arts (cdr arts))
-                          (setcdr art (+ score (cdr art))))))
+                        (if trace
+                            (while arts
+                              (setq art (car arts)
+                                    arts (cdr arts))
+                              (setcdr art (+ score (cdr art)))
+                              (setq gnus-score-trace 
+                                    (cons (cons (header-number
+                                                 (car art)) kill)
+                                          gnus-score-trace)))
+                          (while arts
+                            (setq art (car arts)
+                                  arts (cdr arts))
+                            (setcdr art (+ score (cdr art)))))))
                  (forward-line 1))
              (and (string= match "") (setq match "\n"))
              (while (funcall search-func match nil t)
                (end-of-line)
                (setq found (setq arts (get-text-property (point) 'articles)))
                ;; Found a match, update scores.
-               (while arts
-                 (setq art (car arts)
-                       arts (cdr arts))
-                 (setcdr art (+ score (cdr art))))))
+               (if trace
+                   (while arts
+                     (setq art (car arts)
+                           arts (cdr arts))
+                     (setcdr art (+ score (cdr art)))
+                     (setq gnus-score-trace 
+                           (cons (cons (header-number (car art)) kill)
+                                 gnus-score-trace)))
+                 (while arts
+                   (setq art (car arts)
+                         arts (cdr arts))
+                   (setcdr art (+ score (cdr art)))))))
            ;; Update expire date
            (cond ((null date))         ;Permanent entry.
                  (found                ;Match, update date.
@@ -1389,9 +1447,9 @@ This mode is an extended emacs-lisp mode.
        (winconf gnus-prev-winconf))
     (save-buffer)
     (kill-buffer (current-buffer))
-    (and winconf (set-window-configuration winconf))
     (gnus-score-remove-from-cache bufnam)
-    (gnus-score-load-file bufnam)))
+    (gnus-score-load-file bufnam)
+    (and winconf (set-window-configuration winconf))))
 
 ;;; Finding score files. 
 
@@ -1420,7 +1478,7 @@ score files in the \"/ftp.some-where:/pub/score\" directory.
        (file-name-as-directory
         (or gnus-kill-files-directory "~/News/")))
   ;; If er can't read it, there's no score files.
-  (if (not (file-readable-p gnus-kill-files-directory))
+  (if (not (file-readable-p (expand-file-name gnus-kill-files-directory)))
       (setq gnus-score-file-list nil)
     (if (gnus-use-long-file-name 'not-score)
        ;; We want long file names.
@@ -1542,7 +1600,7 @@ This includes the score file for the group and all its parents."
     (setq all (cons group all))
     (mapcar 'gnus-score-file-name (nreverse all))))
 
-(defun gnus-possibly-score-headers ()
+(defun gnus-possibly-score-headers (&optional trace)
   (let ((func gnus-score-find-score-files-function)
        score-files scores)
     (and func (not (listp func))
@@ -1555,7 +1613,7 @@ This includes the score file for the group and all its parents."
           (setq score-files 
                 (nconc score-files (funcall (car func) gnus-newsgroup-name))))
       (setq func (cdr func)))
-    (if score-files (gnus-score-headers score-files))))
+    (if score-files (gnus-score-headers score-files trace))))
 
 (defun gnus-score-file-name (newsgroup &optional suffix)
   "Return the name of a score file for NEWSGROUP."
@@ -1590,6 +1648,28 @@ This includes the score file for the group and all its parents."
       (setq files (cdr files)))
     (setq gnus-internal-global-score-files out)))
 
+(defun gnus-score-find-trace ()
+  "Find all score rules applied to this article."
+  (interactive)
+  (let ((gnus-newsgroup-headers
+        (list (gnus-get-header-by-number (gnus-summary-article-number))))
+       (gnus-newsgroup-scored nil)
+       (buf (current-buffer))
+       trace)
+    (setq gnus-score-trace nil)
+    (gnus-possibly-score-headers 'trace)
+    (pop-to-buffer "*Gnus Scores*")
+    (erase-buffer)
+    (setq trace gnus-score-trace)
+    (or trace
+       (error "No score rules apply to the current article."))
+    (while trace
+      (insert (format "%S\n" (cdr (car trace))))
+      (setq trace (cdr trace)))
+    (goto-char (point-min))
+    (pop-to-buffer buf)))
+  
+
 (provide 'gnus-score)
 
 ;;; gnus-score.el ends here
index 2223fe0..c88d1a0 100644 (file)
@@ -661,7 +661,8 @@ The headers will be included in the sequence they are matched.")
                         (concat sorthead
                                 (buffer-substring 
                                  (match-beginning 0)
-                                 (or (re-search-forward "^[^ \t]" nil t)
+                                 (or (and (re-search-forward "^[^ \t]" nil t)
+                                          (1- (point)))
                                      (progn (forward-line 1) (point))))))))
             (widen)))
         (insert sorthead)(goto-char (point-max))
index 4d25230..7730b4e 100644 (file)
@@ -437,43 +437,8 @@ highlight-headers-follow-url-netscape:
       ["Set mark below" gnus-score-set-mark-below t]
       ["Set expunge below" gnus-score-set-expunge-below t]
       ["Edit current score file" gnus-score-edit-alist t]
-      ["Edit score file" gnus-score-edit-file t])
-     ["Raise score with current subject" 
-      gnus-summary-temporarily-raise-by-subject t]
-     ["Raise score with current author" 
-      gnus-summary-temporarily-raise-by-author t]
-     ["Raise score with current thread" 
-      gnus-summary-temporarily-raise-by-thread t]
-     ["Raise score with current crossposting" 
-      gnus-summary-temporarily-raise-by-xref t]
-     ["Raise score for followups to current author"
-      gnus-summary-temporarily-raise-followups-to-author t]
-     ["Permanently raise score with current subject"
-      gnus-summary-raise-by-subject t]
-     ["Permanently raise score with current author" 
-      gnus-summary-raise-by-author t]
-     ["Permanently raise score with current crossposting" 
-      gnus-summary-raise-by-xref t]
-     ["Permanently raise score for followups to current author"
-      gnus-summary-raise-followups-to-author t]
-     ["Lower score with current subject" 
-      gnus-summary-temporarily-lower-by-subject t]
-     ["Lower score with current author" 
-      gnus-summary-temporarily-lower-by-author t]
-     ["Lower score with current thread" 
-      gnus-summary-temporarily-lower-by-thread t]
-     ["Lower score with current crossposting" 
-      gnus-summary-temporarily-lower-by-xref t]
-     ["Lower score for followups to current author"
-      gnus-summary-temporarily-lower-followups-to-author t]
-     ["Permanently lower score with current subject"
-      gnus-summary-lower-by-subject t]
-     ["Permanently lower score with current author" 
-      gnus-summary-lower-by-author t]
-     ["Permanently lower score with current crossposting" 
-      gnus-summary-lower-by-xref t]
-     ["Permanently lower score for followups to current author"
-      gnus-summary-lower-followups-to-author t]
+      ["Edit score file" gnus-score-edit-file t]
+      ["Trace score" gnus-score-find-trace t])
      ))
   )
  
@@ -519,10 +484,13 @@ highlight-headers-follow-url-netscape:
        (save-excursion
          (let* ((beg (progn (beginning-of-line) (point)))
                 (end (progn (end-of-line) (point)))
-                (to (max 1 (1- (or (previous-single-property-change
-                                    end 'mouse-face nil beg) end))))
-                (from (1+ (or (next-single-property-change 
-                               beg 'mouse-face nil end) beg))))
+                ;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
+                (from (if (get-text-property beg 'mouse-face) 
+                          beg
+                        (next-single-property-change
+                         beg 'mouse-face nil end)))
+                (to (next-single-property-change
+                     from 'mouse-face nil end)))
            (if (< to beg)
                (progn
                  (setq from beg)
@@ -607,6 +575,8 @@ highlight-headers-follow-url-netscape:
     ("fetch parent" . gnus-summary-refer-parent-article)
     "mail"
     ("move" . gnus-summary-move-article)
+    ("copy" . gnus-summary-copy-article)
+    ("respool" . gnus-summary-respool-article)
     "threads"
     ("lower" . gnus-summary-lower-thread)
     ("kill" . gnus-summary-kill-thread)
@@ -646,6 +616,9 @@ highlight-headers-follow-url-netscape:
 (defvar gnus-carpal-button-face 'bold
   "*Face used on carpal buttons.")
 
+(defvar gnus-carpal-header-face 'bold-italic
+  "*Face used on carpal buffer headers.")
+
 (defvar gnus-carpal-mode-map nil)
 (put 'gnus-carpal-mode 'mode-class 'special)
 
@@ -696,14 +669,16 @@ The following commands are available:
            (setq button (car buttons)
                  buttons (cdr buttons))
            (if (stringp button)
-               (insert button " ")
+               (set-text-properties
+                (point)
+                (prog2 (insert button) (point) (insert " "))
+                (list 'face gnus-carpal-header-face))
              (set-text-properties
               (point)
-              (progn (insert (car button)) (point))
+              (prog2 (insert (car button)) (point) (insert " "))
               (list 'gnus-callback (cdr button)
                     'face gnus-carpal-button-face
-                    'mouse-face 'highlight))
-             (insert " ")))
+                    'mouse-face 'highlight))))
          (let ((fill-column (- (window-width) 2)))
            (fill-region (point-min) (point-max)))
          (set-window-point (get-buffer-window (current-buffer)) 
@@ -892,15 +867,17 @@ External references are things like message-ids and URLs, as specified by
        (goto-char (match-beginning 0))
        (let* ((from (point))
               (entry (gnus-button-entry))
-              (start (match-beginning (nth 1 entry)))
-              (end (match-end (nth 1 entry)))
+              (start (and entry (match-beginning (nth 1 entry))))
+              (end (and entry (match-end (nth 1 entry))))
               (form (nth 2 entry))
               marker)
-         (goto-char (match-end 0))
-         (if (eval form)
-             (gnus-article-add-button start end 'gnus-button-push
-                                      (set-marker (make-marker)
-                                                  from))))))))
+         (if (not entry)
+             ()
+           (goto-char (match-end 0))
+           (if (eval form)
+               (gnus-article-add-button start end 'gnus-button-push
+                                        (set-marker (make-marker)
+                                                    from)))))))))
 
 ;;; External functions:
 
index 1f34fba..a50d2ac 100644 (file)
@@ -100,9 +100,9 @@ Has to be set before gnus-vm is loaded.")
     ;; Remember the directory name to save articles.
     (setq gnus-newsgroup-last-mail folder)))
   
-(defun gnus-mail-forward-using-vm ()
+(defun gnus-mail-forward-using-vm (&optional buffer)
   "Forward the current message to another user using vm."
-  (let ((gnus-buffer (current-buffer))
+  (let ((gnus-buffer (or buffer (current-buffer)))
        (subject (concat "[" gnus-newsgroup-name "] "
                         (or (gnus-fetch-field "Subject") ""))))
     (or (featurep 'win-vm)
index c776489..0fc38a8 100644 (file)
@@ -36,7 +36,6 @@
 (require 'mail-utils)
 (require 'timezone)
 (require 'nnheader)
-(require 'gnus-ems)
 
 ;; Site dependent variables. These variables should be defined in
 ;; paths.el.
@@ -65,6 +64,7 @@ The ORGANIZATION environment variable is used instead if it is defined.
 If this variable contains a function, this function will be called
 with the current newsgroup name as the argument. The function should
 return a string.
+
 In any case, if the string (either in the variable, in the environment
 variable, or returned by the function) is a file name, the contents of
 this file will be used as the organization.")
@@ -491,9 +491,8 @@ If this variable is nil, scoring will be disabled.")
 (defvar gnus-group-default-list-level gnus-level-subscribed
   "*Default listing level.")
 
-(defvar gnus-group-always-list-unread gnus-level-subscribed
-  "*Always list groups less than this variable with unread articles. 
-If nil, use parameter to specify.")
+(defvar gnus-group-use-permanent-levels nil
+  "*If non-nil, once you set a level, Gnus will use this level.")
 
 (defvar gnus-show-mime nil
   "*If non-ni, do mime processing of articles.
@@ -1113,6 +1112,7 @@ automatically when it is selected.")
 (defvar gnus-override-method nil)
 (defvar gnus-article-check-size nil)
 
+(defvar gnus-current-score-file nil)
 (defvar gnus-current-move-group nil)
 
 (defvar gnus-newsgroup-dependencies nil)
@@ -1122,6 +1122,8 @@ automatically when it is selected.")
 
 (defvar gnus-newsgroup-adaptive nil)
 
+(defvar gnus-summary-display-table nil)
+
 (defconst gnus-group-line-format-alist
   (list (list ?M 'marked ?c)
        (list ?S 'subscribed ?c)
@@ -1168,7 +1170,8 @@ automatically when it is selected.")
        (list ?z 'score-char ?c)
        (list ?U 'unread ?c)
        (list ?t '(gnus-summary-number-of-articles-in-thread 
-                  (or gnus-tmp-adopt-thread 
+                  (or (prog1 gnus-tmp-adopt-thread 
+                        (setq gnus-tmp-adopt-thread nil))
                       (if (boundp 'thread) (symbol-value 'thread)
                         thread nil)))
                   ?d)
@@ -1209,7 +1212,7 @@ variable (string, integer, character, etc).")
 (defconst gnus-maintainer "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls & Boys)"
   "The mail address of the Gnus maintainer.")
 
-(defconst gnus-version "(ding) Gnus v0.72"
+(defconst gnus-version "(ding) Gnus v0.73"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -1514,6 +1517,7 @@ Thank you for your help in stamping out bugs.
   (autoload 'gnus-score-adaptive "gnus-score")
   (autoload 'gnus-score-remove-lines-adaptive "gnus-score")
   (autoload 'gnus-possibly-score-headers "gnus-score")
+  (autoload 'gnus-score-find-trace "gnus-score")
 
   ;; gnus-uu
   (autoload 'gnus-uu-extract-map "gnus-uu" nil nil 'keymap)
@@ -1636,6 +1640,10 @@ Thank you for your help in stamping out bugs.
        (point)
       (goto-char p))))
 
+;;; Load the compatability functions. 
+
+(require 'gnus-ems)
+
 \f
 ;;;
 ;;; Gnus Utility Functions
@@ -2239,7 +2247,9 @@ If optional argument RE-ONLY is non-nil, strip `Re:' only."
       (if (and (listp (car hor)) 
               (eq (car (car hor)) 'horizontal))
          (progn
-           (split-window nil (floor (* (frame-width) (nth 1 (car hor)))) t)
+           (split-window nil (- (frame-width) 
+                                (floor (* (frame-width) (nth 1 (car hor)))))
+                         t)
            (setq hor (cdr hor))))
 
       ;; Go through the rules and eval the elements that are to be
@@ -2367,7 +2377,7 @@ If optional argument RE-ONLY is non-nil, strip `Re:' only."
     (pop-to-buffer "*Gnus Bug*")
     (erase-buffer)
     (mail-mode)
-    (mail-setup gnus-maintainer "[Gnus Bug Report] " nil nil nil nil)
+    (mail-setup gnus-maintainer nil nil nil nil nil)
     (make-local-variable 'gnus-prev-winconf)
     (setq gnus-prev-winconf winconf)
     (goto-char (point-min))
@@ -2959,6 +2969,7 @@ prompt the user for the name of an NNTP server to use."
        (switch-to-buffer gnus-group-buffer)
        (gnus-group-get-new-news))
     (gnus-clear-system)
+    (nnheader-init-server-buffer)
     (gnus-read-init-file)
     (let ((level (and arg (numberp arg) (> arg 0) arg))
          did-connect)
@@ -2974,6 +2985,7 @@ prompt the user for the name of an NNTP server to use."
          (run-hooks 'gnus-startup-hook)
          ;; NNTP server is successfully open. 
          (gnus-update-format-specifications)
+         (gnus-summary-make-display-table)
          (let ((buffer-read-only nil))
            (erase-buffer)
            (if (not gnus-inhibit-startup-message)
@@ -3026,7 +3038,13 @@ 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))))
-  (setq level (or level gnus-group-default-list-level gnus-level-subscribed))
+  (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)))
   (gnus-group-setup-buffer)    ;May call from out of group buffer
   (let ((case-fold-search nil)
        (group (gnus-group-group-name)))
@@ -3936,7 +3954,7 @@ or nil if no action could be taken."
         ticked)
     (if (not (numberp (car entry)))
        (gnus-message 1 "Can't catch up; non-active group")
-      ;; Do the updating only if the newsgroup isn't killed
+      ;; Do the updating only if the newsgroup isn't killed.
       (if entry
          (progn
            (setq ticked (if all nil (cdr (assq 'tick marked))))
@@ -4166,15 +4184,21 @@ specify which levels you are interested in re-scanning."
   (interactive "P")
   (run-hooks 'gnus-get-new-news-hook)
   (let ((level arg))
+    (if gnus-group-use-permanent-levels
+       (progn
+         (if level
+             (setq gnus-group-default-list-level level)
+           (setq level (or gnus-group-default-list-level 
+                           gnus-level-subscribed)))))
     (if (and gnus-read-active-file (not level))
        (progn
          (gnus-read-active-file)
          (gnus-get-unread-articles (or level (1+ gnus-level-subscribed))))
       (let ((gnus-read-active-file nil))
        (gnus-get-unread-articles (or level (1+ gnus-level-subscribed)))))
-    (gnus-group-list-groups 
-     (or gnus-group-always-list-unread level gnus-level-subscribed)
-     gnus-have-all-newsgroups)))
+    (gnus-group-list-groups (or (and gnus-group-use-permanent-levels level)
+                               gnus-level-subscribed)
+                           gnus-have-all-newsgroups)))
 
 (defun gnus-group-get-new-news-this-group (n)
   "Check for newly arrived news in the current group (and the N-1 next groups).
@@ -5016,19 +5040,30 @@ The following commands are available:
   (setq truncate-lines t)
   (setq selective-display t)
   (setq selective-display-ellipses t)  ;Display `...'
+  (setq buffer-display-table gnus-summary-display-table)
+  (run-hooks 'gnus-summary-mode-hook))
+
+(defun gnus-summary-make-display-table ()
   ;; Change the display table.  Odd characters have a tendency to mess
-  ;; up nicely formatted displays.
-  (setq buffer-display-table (if (vectorp standard-display-table)
-                                (copy-sequence standard-display-table)
-                              (make-vector 261 nil)))
+  ;; up nicely formatted displays - we make all possible glyphs
+  ;; display only a single character.
+
+  ;; We start from the standard display table, if any.
+  (setq gnus-summary-display-table 
+       (or (copy-sequence standard-display-table)
+           (make-display-table)))
+  ;; Nix out all the control chars...
   (let ((i 32))
     (while (>= (setq i (1- i)) 0)
-      (aset buffer-display-table i [??])))
-  (aset buffer-display-table ?\n nil)
-  (let ((i 160))
+      (aset gnus-summary-display-table i [??])))
+  ;; ... but not newline, of course.
+  (aset gnus-summary-display-table ?\n nil)
+  ;; We nix out any glyphs over 126 that are not set already.  
+  (let ((i 256))
     (while (>= (setq i (1- i)) 127)
-      (aset buffer-display-table i [??])))
-  (run-hooks 'gnus-summary-mode-hook))
+      ;; Only modify if the entry is nil.
+      (or (aref gnus-summary-display-table i) 
+         (aset gnus-summary-display-table i [??])))))
 
 (defun gnus-summary-clear-local-variables ()
   (let ((locals gnus-summary-local-variables))
@@ -5070,13 +5105,15 @@ The following commands are available:
        (let ((name gnus-newsgroup-name)
              (marked gnus-newsgroup-marked)
              (unread gnus-newsgroup-unreads)
-             (headers gnus-current-headers))
+             (headers gnus-current-headers)
+             (score-file gnus-current-score-file))
          (save-excursion
            (set-buffer gnus-group-buffer)
            (setq gnus-newsgroup-name name)
            (setq gnus-newsgroup-marked marked)
            (setq gnus-newsgroup-unreads unread)
-           (setq gnus-current-headers headers))))))
+           (setq gnus-current-headers headers)
+           (setq gnus-current-score-file score-file))))))
 
 (defun gnus-summary-insert-dummy-line (sformat subject number)
   (if (not sformat) 
@@ -5197,6 +5234,7 @@ If NO-ARTICLE is non-nil, no article is selected initially."
             (kill-buffer (current-buffer))
             (set-buffer gnus-group-buffer)
             (gnus-group-next-unread-group 1)))
+      (message "Can't select group")
       nil)
      ((eq did-select 'quit)
       (and (eq major-mode 'gnus-summary-mode)
@@ -5232,7 +5270,8 @@ If NO-ARTICLE is non-nil, no article is selected initially."
            ;; This newsgroup is empty.
            (gnus-summary-catchup-and-exit nil t) ;Without confirmations.
            (gnus-message 6 "No unread news")
-           (gnus-kill-buffer kill-buffer))
+           (gnus-kill-buffer kill-buffer)
+           nil)
        (save-excursion
          (if kill-buffer
              (let ((gnus-summary-buffer kill-buffer))
@@ -5262,7 +5301,8 @@ If NO-ARTICLE is non-nil, no article is selected initially."
                  (funcall gnus-asynchronous-article-function
                           gnus-newsgroup-threads)
                gnus-newsgroup-threads)))
-       (gnus-kill-buffer kill-buffer))))))
+       (gnus-kill-buffer kill-buffer))
+      t))))
 
 (defun gnus-summary-prepare ()
   ;; Generate the summary buffer.
@@ -5272,7 +5312,8 @@ If NO-ARTICLE is non-nil, no article is selected initially."
      (if gnus-show-threads
         (gnus-gather-threads 
          (gnus-sort-threads 
-          (if gnus-summary-expunge-below
+          (if (and gnus-summary-expunge-below
+                   (not gnus-fetch-old-headers))
               (gnus-make-threads-and-expunge)
             (gnus-make-threads))))
        gnus-newsgroup-headers)
@@ -5280,6 +5321,9 @@ If NO-ARTICLE is non-nil, no article is selected initially."
     ;; Erase header retrieval message.
     (gnus-summary-update-lines)
     (message "")
+    ;; Remove the final newline.
+    ;;(goto-char (point-max))
+    ;;(delete-char -1)
     ;; Call hooks for modifying summary buffer.
     ;; Suggested by sven@tde.LTH.Se (Sven Mattisson).
     (goto-char (point-min))
@@ -5292,22 +5336,21 @@ If NO-ARTICLE is non-nil, no article is selected initially."
     (let ((hashtb (gnus-make-hashtable 1023))
          (prev threads)
          (result threads)
-         thread subject hthread unre-subject whole-subject)
+         thread subject hthread whole-subject)
       (while threads
-       (setq subject (header-subject (car (car threads)))
-             whole-subject subject)
-       (and gnus-summary-gather-subject-limit
-            (or (and (numberp gnus-summary-gather-subject-limit)
-                     (> (length subject) gnus-summary-gather-subject-limit)
-                     (setq subject
-                           (substring subject 0 
-                                      gnus-summary-gather-subject-limit)))
-                (and (eq 'fuzzy gnus-summary-gather-subject-limit)
-                     (setq subject (gnus-simplify-subject-fuzzy subject)))))
+       (setq whole-subject 
+             (setq subject (header-subject (car (car threads)))))
+       (if gnus-summary-gather-subject-limit
+           (or (and (numberp gnus-summary-gather-subject-limit)
+                    (> (length subject) gnus-summary-gather-subject-limit)
+                    (setq subject
+                          (substring subject 0 
+                                     gnus-summary-gather-subject-limit)))
+               (and (eq 'fuzzy gnus-summary-gather-subject-limit)
+                    (setq subject (gnus-simplify-subject-fuzzy subject))))
+         (setq subject (gnus-simplify-subject-re subject)))
        (if (setq hthread 
-                 (gnus-gethash 
-                  (setq unre-subject (gnus-simplify-subject-re subject))
-                  hashtb))
+                 (gnus-gethash subject hashtb))
            (progn
              (or (stringp (car (car hthread)))
                  (setcar hthread (list whole-subject (car hthread))))
@@ -5315,7 +5358,7 @@ If NO-ARTICLE is non-nil, no article is selected initially."
                                           (list (car threads))))
              (setcdr prev (cdr threads))
              (setq threads prev))
-         (gnus-sethash unre-subject threads hashtb))
+         (gnus-sethash subject threads hashtb))
        (setq prev threads)
        (setq threads (cdr threads)))
       result)))
@@ -5363,26 +5406,29 @@ If NO-ARTICLE is non-nil, no article is selected initially."
   ;; `gnus-get-newsgroup-headers' and builds the trees. First we go
   ;; through the dependecies in the hash table and finds all the
   ;; roots. Roots do not refer back to any valid articles.
-  (let (roots)
+  (let ((default (or gnus-summary-default-score 0))
+       (below gnus-summary-expunge-below)
+       roots article)
     (and gnus-fetch-old-headers (eq gnus-headers-retrieved-by 'nov)
         (gnus-build-old-threads))
     (mapatoms
      (lambda (refs)
        (if (not (car (symbol-value refs)))
-          (if (and gnus-summary-expunge-below
-                   (not gnus-fetch-old-headers))
-              (let ((headers (cdr (symbol-value refs))))
-                (while headers
-                 (if (not (< (or (cdr (assq (header-number (car headers))
-                                            gnus-newsgroup-scored))
-                                 gnus-summary-default-score 0)
-                             gnus-summary-expunge-below))
-                     (setq roots (cons (car headers) roots))
-                   (setq gnus-newsgroup-unreads
-                         (delq (header-number (car headers))
-                               gnus-newsgroup-unreads)))
-                 (setq headers (cdr headers))))
-            (setq roots (append (cdr (symbol-value refs)) roots)))
+          ;; These articles do not refer back to any other articles -
+          ;; they are roots.
+          (let ((headers (cdr (symbol-value refs))))
+            ;; We weed out the low-scored articles.
+            (while headers
+              (if (not (< (or (cdr (assq (header-number (car headers))
+                                         gnus-newsgroup-scored)) default)
+                          below))
+                  ;; It is over.
+                  (setq roots (cons (car headers) roots))
+                ;; It is below, so we mark it as read.
+                (setq gnus-newsgroup-unreads
+                      (delq (header-number (car headers))
+                            gnus-newsgroup-unreads)))
+              (setq headers (cdr headers))))
         ;; Ok, these refer back to valid articles, but if
         ;; `gnus-thread-ignore-subject' is nil, we have to check that
         ;; the root has the same subject as its children. The children
@@ -5400,8 +5446,7 @@ If NO-ARTICLE is non-nil, no article is selected initially."
                     (progn
                       (if (not (< (or (cdr (assq (header-number (car headers))
                                                  gnus-newsgroup-scored))
-                                      gnus-summary-default-score 0)
-                                  gnus-summary-expunge-below))
+                                      default) below))
                           (setq roots (cons (car headers) roots))
                         (setq gnus-newsgroup-unreads
                               (delq (header-number (car headers))
@@ -5409,34 +5454,38 @@ If NO-ARTICLE is non-nil, no article is selected initially."
                       (setcdr prev (cdr headers)))
                   (setq prev headers))
                 (setq headers (cdr headers)))))
-        (and gnus-summary-expunge-below
-             (not gnus-fetch-old-headers)
-             (let* ((prev (symbol-value refs))
-                    (headers (cdr prev))
-                    id)
-               (while headers
-                 (if (not (< (or (cdr (assq (header-number (car headers))
-                                            gnus-newsgroup-scored))
-                                 gnus-summary-default-score 0)
-                             gnus-summary-expunge-below))
-                     (setq prev (cdr prev))
-                   (setq gnus-newsgroup-unreads 
-                         (delq (header-number (car headers))
-                               gnus-newsgroup-unreads))
-                   (setcdr prev (cdr headers))
-                   (setq id (gnus-gethash (header-id (car headers))
-                                          gnus-newsgroup-dependencies))
-                   (let ((h (cdr id)))
-                     (while h
-                       (if (not (< (or (cdr (assq (header-number (car h))
-                                                  gnus-newsgroup-scored))
-                                       gnus-summary-default-score 0)
-                                   gnus-summary-expunge-below))
-                           (setq roots (cons (car h) roots)))
-                       (setq h (cdr h)))))
-                 (setq headers (cdr headers)))))))
+        ;; If this article is expunged, some of the children might be
+        ;; roots.  
+        (if (< (or (cdr (assq (header-number (car (symbol-value refs)))
+                              gnus-newsgroup-scored)) default)
+               below)
+            (let* ((prev (symbol-value refs))
+                   (headers (cdr prev)))
+              (while headers
+                (setq article (header-number (car headers)))
+                (if (not (< (or (cdr (assq article gnus-newsgroup-scored))
+                                default) below))
+                    (progn (setq roots (cons (car headers) roots))
+                           (setq prev headers))
+                  (setq gnus-newsgroup-unreads 
+                        (delq article gnus-newsgroup-unreads))
+                  (setcdr prev (cdr headers)))
+                (setq headers (cdr headers))))
+          ;; It was not expunged, but we look at expunged children.
+          (let* ((prev (symbol-value refs))
+                 (headers (cdr prev))
+                 article id)
+            (while headers
+              (setq article (header-number (car headers)))
+              (if (not (< (or (cdr (assq article gnus-newsgroup-scored))
+                              default) below))
+                  (setq prev headers)
+                (setq gnus-newsgroup-unreads 
+                      (delq article gnus-newsgroup-unreads))
+                (setcdr prev (cdr headers)))
+              (setq headers (cdr headers)))))))
      gnus-newsgroup-dependencies)
-    
+
     (mapcar 'gnus-trim-thread
            (apply 'append
                   (mapcar 'gnus-cut-thread
@@ -5672,7 +5721,7 @@ or a straight list of headers."
        ;; The header is a dummy root.
        (cond ((eq gnus-summary-make-false-root 'adopt)
               ;; We let the first article adopt the rest.
-              (let ((gnus-tmp-adopt-thread thread))
+              (let ((gnus-tmp-adopt-thread (list (cdr thread))))
                 (gnus-summary-prepare-threads (list (car (cdr thread))) 0))
               (setq thread (cdr (cdr thread)))
               (while thread
@@ -5685,7 +5734,7 @@ or a straight list of headers."
               (setq clevel 1))
              ((eq gnus-summary-make-false-root 'empty)
               ;; We print the articles with empty subject fields. 
-              (let ((gnus-tmp-adopt-thread thread))
+              (let ((gnus-tmp-adopt-thread (list (cdr thread))))
                 (gnus-summary-prepare-threads (list (car (cdr thread))) 0))
               (setq thread (cdr (cdr thread)))
               (while thread
@@ -6152,7 +6201,8 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                             (setq ids (cdr ids)))))
                     ;; Update expirable articles.
                     (gnus-add-marked-articles nil 'expirable exps info)
-                    (and (null (nth 2 info))
+                    (and active
+                         (null (nth 2 info))
                          (> (car active) 1)
                          (setcar (nthcdr 2 info) (cons 1 (1- (car active)))))
                     (setcar (nthcdr 2 info)
@@ -6201,11 +6251,12 @@ The resulting hash table is returned, or nil if no Xrefs were found."
 (defsubst gnus-header-value ()
   (buffer-substring (match-end 0) (gnus-point-at-eol)))
 
+(defvar gnus-newsgroup-none-id 0)
+
 (defun gnus-get-newsgroup-headers ()
   (setq gnus-article-internal-prepare-hook nil)
   (let ((cur nntp-server-buffer)
        (dependencies gnus-newsgroup-dependencies)
-       (none-id 0)
        headers char article id dep end)
     (save-excursion
       (set-buffer nntp-server-buffer)
@@ -6257,8 +6308,10 @@ The resulting hash table is returned, or nil if no Xrefs were found."
              ;; subsequent routines simpler.
              (header-set-id 
               header 
-              (setq id (concat "none+" (int-to-string 
-                                        (setq none-id (1+ none-id)))))))
+              (setq id (concat "none+" 
+                               (int-to-string 
+                                (setq gnus-newsgroup-none-id 
+                                      (1+ gnus-newsgroup-none-id)))))))
            (goto-char p)
            (if (search-forward "\nreferences: " nil t)
                (progn
@@ -6324,7 +6377,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
   '(prog1
        (if (= (following-char) ?\t)
           0
-        (let ((num (read buffer)))
+        (let ((num (condition-case nil (read buffer) (error nil))))
           (if (numberp num) num 0)))
      (or (eobp) (forward-char 1))))
 
@@ -6760,7 +6813,7 @@ displayed, no centering will be performed."
     (and info active
         (gnus-sorted-complement 
          (gnus-uncompress-range active) 
-         (gnus-list-of-unread-articles (nth 2 info))))))
+         (gnus-list-of-unread-articles group)))))
 
 ;; Various summary commands
 
@@ -6989,12 +7042,22 @@ If BACKWARD, go to previous group instead."
                   (progn
                     (set-buffer (setq gnus-summary-buffer sumbuf))
                     (gnus-summary-exit-no-update t))))
-         (gnus-summary-read-group group nil no-article buf)
-         (while (and (string= gnus-newsgroup-name ingroup)
-                     (bufferp sumbuf) (buffer-name sumbuf))
-           (set-buffer gnus-group-buffer)
-           (gnus-summary-read-group 
-            (gnus-group-group-name) nil no-article buf)))))))
+         (let ((prevgroup group))
+           (gnus-summary-read-group group nil no-article buf)
+           (while (and (string= gnus-newsgroup-name ingroup)
+                       (bufferp sumbuf) 
+                       (buffer-name sumbuf)
+                       (not (string= prevgroup (gnus-group-group-name))))
+             (set-buffer gnus-group-buffer)
+             (gnus-summary-read-group 
+              (setq prevgroup (gnus-group-group-name)) 
+              nil no-article buf))
+           (and (string= prevgroup (gnus-group-group-name))
+                ;; We have reached the final group in the group
+                ;; buffer.
+                (progn
+                  (set-buffer sumbuf)
+                  (gnus-summary-exit)))))))))
 
 (defun gnus-summary-prev-group (no-article)
   "Exit current newsgroup and then select previous unread newsgroup.
@@ -7078,6 +7141,7 @@ If optional argument UNREAD is non-nil, only unread article is selected."
     (goto-char (point-min))
     (while (and (not (eq (car (get-text-property (point) 'gnus)) article))
                (zerop (forward-line 1))))
+    (gnus-summary-show-thread)
     ;; Skip dummy articles. 
     (if (eq (gnus-summary-article-mark) ?Z)
        (forward-line 1))
@@ -7102,6 +7166,7 @@ If optional argument UNREAD is non-nil, only unread article is selected."
   (if (null article)
       nil
     (gnus-article-prepare article all-header)
+    (gnus-summary-show-thread)
     (if (eq (gnus-summary-article-mark) ?Z)
        (progn
          (forward-line 1)
@@ -7113,19 +7178,8 @@ If optional argument UNREAD is non-nil, only unread article is selected."
     (gnus-summary-goto-subject article)
     ;; Successfully display article.
     (gnus-summary-update-line)
-    (let ((bookmark (cdr (assq article gnus-newsgroup-bookmarks))))
-      (set-window-start 
-       (get-buffer-window gnus-article-buffer)
-       (save-excursion
-        (set-buffer gnus-article-buffer)
-        (goto-char (point-min))
-        (cond (bookmark
-               (gnus-message 6 "Moved to bookmark")
-               (search-forward "\n\n" nil t)
-               (forward-line bookmark)
-               (point))
-              (t
-               (point-min))))))
+    (gnus-article-set-window-start 
+     (cdr (assq article gnus-newsgroup-bookmarks)))
     t))
 
 (defun gnus-summary-select-article (&optional all-headers force pseudo article)
@@ -7155,21 +7209,8 @@ be displayed."
            (if all-headers (gnus-article-show-all-headers))
            (gnus-configure-windows 'article)
            nil))
-      (if (not did)
-         ()
-       (let ((bookmark (cdr (assq article gnus-newsgroup-bookmarks))))
-         (set-window-start 
-          (get-buffer-window gnus-article-buffer)
-          (save-excursion
-            (set-buffer gnus-article-buffer)
-            (goto-char (point-min))
-            (cond (bookmark
-                   (gnus-message 6 "Moved to bookmark")
-                   (search-forward "\n\n" nil t)
-                   (forward-line bookmark)
-                   (point))
-                  (t
-                   (point-min))))))))))
+      (if did (gnus-article-set-window-start 
+              (cdr (assq article gnus-newsgroup-bookmarks)))))))
 
 (defun gnus-summary-set-current-mark (&optional current-mark)
   "Obsolete function."
@@ -7309,6 +7350,7 @@ current article."
   "Show previous page of selected article.
 Argument LINES specifies lines to be scrolled down."
   (interactive "P")
+  (gnus-set-global-variables)
   (let ((article (gnus-summary-article-number)))
     (if (or (null gnus-current-article)
            (null gnus-article-current)
@@ -7325,6 +7367,7 @@ Argument LINES specifies lines to be scrolled down."
   "Scroll up (or down) one line current article.
 Argument LINES specifies lines to be scrolled up (or down if negative)."
   (interactive "p")
+  (gnus-set-global-variables)
   (or (gnus-summary-select-article nil nil 'pseudo)
       (gnus-eval-in-buffer-window 
        gnus-article-buffer
@@ -7338,27 +7381,32 @@ Argument LINES specifies lines to be scrolled up (or down if negative)."
 (defun gnus-summary-next-same-subject ()
   "Select next article which has the same subject as current one."
   (interactive)
+  (gnus-set-global-variables)
   (gnus-summary-next-article nil (gnus-summary-subject-string)))
 
 (defun gnus-summary-prev-same-subject ()
   "Select previous article which has the same subject as current one."
   (interactive)
+  (gnus-set-global-variables)
   (gnus-summary-prev-article nil (gnus-summary-subject-string)))
 
 (defun gnus-summary-next-unread-same-subject ()
   "Select next unread article which has the same subject as current one."
   (interactive)
+  (gnus-set-global-variables)
   (gnus-summary-next-article t (gnus-summary-subject-string)))
 
 (defun gnus-summary-prev-unread-same-subject ()
   "Select previous unread article which has the same subject as current one."
   (interactive)
+  (gnus-set-global-variables)
   (gnus-summary-prev-article t (gnus-summary-subject-string)))
 
 (defun gnus-summary-first-unread-article ()
   "Select the first unread article. 
 Return nil if there are no unread articles."
   (interactive)
+  (gnus-set-global-variables)
   (prog1
       (if (gnus-summary-first-subject t)
          (gnus-summary-display-article (gnus-summary-article-number)))
@@ -7481,6 +7529,8 @@ NOTE: This command only works with newsgroup that use NNTP."
                (setq number (header-number gnus-current-headers))
                (gnus-rebuild-thread message-id)
                (gnus-summary-goto-subject number)
+               (gnus-article-set-window-start 
+                (cdr (assq number gnus-newsgroup-bookmarks)))
                message-id)
            (gnus-message 1 "No such references")
            nil))))))
@@ -7492,7 +7542,7 @@ NOTE: This command only works with newsgroup that use NNTP."
   (gnus-summary-select-article)
   ;; We do not want a narrowed article.
   (gnus-summary-stop-page-breaking)
-  (let ((name (format "%s/%d" 
+  (let ((name (format "%s-%d" 
                      (gnus-group-prefixed-name 
                       gnus-newsgroup-name (list 'nndigest "")) 
                      gnus-current-article))
@@ -8052,6 +8102,7 @@ This will have permanent effect only in mail groups."
   (interactive "p")
   ;; Skip dummy header line.
   (save-excursion
+    (gnus-summary-show-thread)
     (if (eq (gnus-summary-article-mark) ?Z)
        (forward-line 1))
     (let ((buffer-read-only nil))
@@ -8298,6 +8349,7 @@ the actual number of articles marked is returned."
   (let ((buffer-read-only nil))
     (if (gnus-summary-goto-subject article)
        (progn
+         (gnus-summary-show-thread)
          (and (eq (gnus-summary-article-mark) ?Z)
               (forward-line 1))
          (gnus-summary-update-mark gnus-process-mark 'replied)
@@ -8309,6 +8361,7 @@ the actual number of articles marked is returned."
   (let ((buffer-read-only nil))
     (if (gnus-summary-goto-subject article)
        (progn
+         (gnus-summary-show-thread)
          (and (eq (gnus-summary-article-mark) ?Z)
               (forward-line 1))
          (gnus-summary-update-mark ?  'replied)
@@ -8377,7 +8430,6 @@ marked."
     (if (gnus-summary-goto-subject article)
        (let ((buffer-read-only nil))
          (gnus-summary-show-thread)
-         (beginning-of-line)
          (and (eq (gnus-summary-article-mark) ?Z)
               (forward-line 1))
          ;; Fix the mark.
@@ -9467,6 +9519,21 @@ The following commands are available:
        (gnus-add-current-to-buffer-list)
        (gnus-article-mode))))
 
+;; Set article window start at LINE, where LINE is the number of lines
+;; from the head of the article.
+(defun gnus-article-set-window-start (&optional line)
+  (set-window-start 
+   (get-buffer-window gnus-article-buffer)
+   (save-excursion
+     (set-buffer gnus-article-buffer)
+     (goto-char (point-min))
+     (if (not line)
+        (point-min)
+       (gnus-message 6 "Moved to bookmark")
+       (search-forward "\n\n" nil t)
+       (forward-line line)
+       (point)))))
+
 (defun gnus-request-article-this-buffer (article group)
   "Get an article and insert it into this buffer."
   (setq group (or group gnus-newsgroup-name))
@@ -9629,14 +9696,15 @@ If ALL-HEADERS is non-nil, no headers are hidden."
                  (not (not (or all-headers gnus-show-all-headers))))
            ;; Hooks for getting information from the article.
            ;; This hook must be called before being narrowed.
-           (run-hooks 'internal-hook)
-           (run-hooks 'gnus-article-prepare-hook)
+           (let (buffer-read-only)
+             (run-hooks 'internal-hook)
+             (run-hooks 'gnus-article-prepare-hook))
            ;; Decode MIME message.
            (if (and gnus-show-mime
                     (gnus-fetch-field "Mime-Version"))
                (funcall gnus-show-mime-method))
            ;; Perform the article display hooks.
-           (let ((buffer-read-only nil))
+           (let (buffer-read-only)
              (run-hooks 'gnus-article-display-hook))
            ;; Do page break.
            (goto-char (point-min))
@@ -11392,6 +11460,13 @@ Returns whether the updating was successful."
       ;; Remove any negative articles numbers.
       (while (and unread (< (car unread) 0))
        (setq unread (cdr unread)))
+      ;; Remove any expired article numbers
+      (while (and unread (< (car unread) (car active)))
+       (setq unread (cdr unread)))
+      (while (and ticked (< (car ticked) (car active)))
+       (setq ticked (cdr ticked)))
+      (while (and dormant (< (car dormant) (car active)))
+       (setq dormant (cdr dormant)))
       (setq unread (sort (append unselected unread) '<))
       ;; Set the number of unread articles in gnus-newsrc-hashtb.
       (setcar entry (max 0 (- (length unread) (length ticked) 
@@ -11422,12 +11497,20 @@ Returns whether the updating was successful."
 
 (defun gnus-make-articles-unread (group articles)
   "Mark ARTICLES in GROUP as unread."
-  (let ((info (nth 2 (or (gnus-gethash group gnus-newsrc-hashtb)
-                        (gnus-gethash (gnus-group-real-name group)
-                                      gnus-newsrc-hashtb)))))
-    (setcar (nthcdr 2 info)
-           (gnus-remove-from-range (nth 2 info) articles))
-    (gnus-group-update-group group t)))
+  (let* ((info (nth 2 (or (gnus-gethash group gnus-newsrc-hashtb)
+                         (gnus-gethash (gnus-group-real-name group)
+                                       gnus-newsrc-hashtb))))
+        (ranges (nth 2 info))
+        news)
+    (while articles
+      (and (gnus-member-of-range (car articles) ranges)
+          (setq news (cons (car articles) news)))
+      (setq articles (cdr articles)))
+    (if (not news)
+       ()
+      (setcar (nthcdr 2 info)
+             (gnus-remove-from-range (nth 2 info) (nreverse news)))
+      (gnus-group-update-group group t))))
 
 (defun gnus-read-active-file ()
   "Get active file from NNTP server."
index 9daa71e..2dbc0e0 100644 (file)
        (let ((nnmail-split-methods
              (if (stringp group) (list (list group "")) 
                nnmail-split-methods)))
-        (setq result (nnbabyl-save-mail)))
+        (setq result (car (nnbabyl-save-mail))))
        (set-buffer nnbabyl-mbox-buffer)
        (goto-char (point-max))
        (search-backward "\n\^_")
 
 (defun nnbabyl-article-string (article)
   (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":" 
-         (int-to-string article)))
+         (int-to-string article) " "))
+
+(defun nnbabyl-insert-lines ()
+  "Insert how many lines and chars there are in the body of the mail."
+  (let (lines chars)
+    (save-excursion
+      (goto-char (point-min))
+      (if (search-forward "\n\n" nil t) 
+         (progn
+           ;; There may be an EOOH line here...
+           (if (looking-at "\\*\\*\\* EOOH \\*\\*\\*")
+               (search-forward "\n\n" nil t))
+           (setq chars (- (point-max) (point)))
+           (setq lines (- (count-lines (point) (point-max)) 1))
+           ;; Move back to the end of the headers. 
+           (goto-char (point-min))
+           (search-forward "\n\n" nil t)
+           (forward-char -1)
+           (save-excursion
+             (if (re-search-backward "^Lines: " nil t)
+                 (delete-region (point) (progn (forward-line 1) (point)))))
+           (insert (format "Lines: %d\n" lines))
+           chars)))))
 
 (defun nnbabyl-save-mail ()
   ;; Called narrowed to an article.
   (let ((group-art (nreverse (nnmail-article-group 'nnbabyl-active-number))))
-    (nnmail-insert-lines)
+    (nnbabyl-insert-lines)
     (nnmail-insert-xref group-art)
     (nnbabyl-insert-newsgroup-line group-art)
     (run-hooks 'nnbabyl-prepare-save-mail-hook)
     (goto-char (point-min))
     ;; If there is a C-l at the beginning of the narrowed region, this
     ;; isn't really a "save", but rather a "scan".
+    (while (looking-at "From ")
+      (replace-match "Mail-from: From " t t)
+      (forward-line 1))
+    (goto-char (point-min))
     (or (looking-at "\^L")
        (save-excursion
          (insert "\^L\n0, unseen,,\n*** EOOH ***\n")
          (goto-char (point-max))
          (insert "\^_\n")))
-    (while (looking-at "From ")
-      (replace-match "Mail-from: " t t)
-      (forward-line 1))
     (if (search-forward "\n\n" nil t)
        (progn
          (forward-char -1)
index 3c4baf3..f255d09 100644 (file)
           (point)
           (or (and (re-search-forward nndigest-separator nil t)
                    (match-beginning 0))
+              (and (re-search-forward "^------------------------------" nil t)
+                   (match-beginning 0))
               (point-max)))
          (cons (point-min) (point-max)))
       nil)))
index 6d01fea..6d6023c 100644 (file)
@@ -437,7 +437,7 @@ nn*-request-list should have been called before calling this function."
   "Go through the entire INCOMING file and pick out each individual mail.
 FUNC will be called with the buffer narrowed to each mail."
   (let ((delim (concat "^" rmail-unix-mail-delimiter))
-       start end)
+       start end content-length do-search)
     (save-excursion
       (set-buffer (get-buffer-create " *nnmail incoming*"))
       (buffer-disable-undo (current-buffer))
@@ -454,11 +454,33 @@ FUNC will be called with the buffer narrowed to each mail."
            ;; Skip all the headers in case there are more "From "s...
            (if (not (search-forward "\n\n" nil t))
                (forward-line 1))
+           ;; Look for a Content-Length header.
+           (if (not (save-excursion
+                      (and (re-search-backward 
+                            "^Content-Length: \\([0-9]+\\)" nil t)
+                           (setq content-length (int-to-string
+                                                 (buffer-substring 
+                                                  (match-beginning 1)
+                                                  (match-end 1))))
+                           ;; We destroy the header, since none of
+                           ;; the backends ever use it, and we do not
+                           ;; want to confuse other mailers by having
+                           ;; a (possibly) faulty header.
+                           (progn (insert "X-") t))))
+               (setq do-search t)
+             (if (save-excursion
+                   (forward-char content-length)
+                   (looking-at delim))
+                 (progn
+                   (forward-char content-length)
+                   (setq do-search nil))
+               (setq do-search t)))
            ;; Go to the beginning of the next article - or to the end
            ;; of the buffer.  
-           (if (re-search-forward delim nil t)
-               (goto-char (match-beginning 0))
-             (goto-char (point-max)))
+           (if do-search
+               (if (re-search-forward delim nil t)
+                   (goto-char (match-beginning 0))
+                 (goto-char (point-max))))
            (save-excursion
              (save-restriction
                (narrow-to-region start (point))
index 7204bdc..958fe0b 100644 (file)
       ;; Find the lowest active article in this group.
       (let ((active (nth 1 (assoc newsgroup nnmbox-group-alist))))
        (goto-char (point-min))
-       (while (not (search-forward
-                    (nnmbox-article-string (car active)) nil t))
+       (while (and (not (search-forward
+                         (nnmbox-article-string (car active)) nil t))
+                   (<= (car active) (cdr active)))
          (setcar active (1+ (car active)))
          (goto-char (point-min))))
       (nnmail-save-active nnmbox-group-alist nnmbox-active-file)
index 29f8290..648915c 100644 (file)
        (setq nnmh-group-alist (nnmail-get-active))
        ;; We trick the choosing function into believing that only one
        ;; group is availiable.  
-       (let ((nnmail-split-methods '(group "")))
-        (cons group (nnmh-save-mail))))
+       (let ((nnmail-split-methods (list (list group ""))))
+        (car (nnmh-save-mail))))
     (and
      (nnmh-request-list)
      (setq nnmh-group-alist (nnmail-get-active))
-     (nnmh-save-mail))))
+     (car (nnmh-save-mail)))))
 
 (defun nnmh-request-replace-article (article group buffer)
   (nnmh-possibly-change-directory group)
index 34e4219..5e0924d 100644 (file)
@@ -227,7 +227,7 @@ all. This may very well take some time.")
        (nnml-possibly-change-directory group)
        (let ((articles (mapcar
                         (lambda (file)
-                          (int-to-string file))
+                          (string-to-int file))
                         (directory-files 
                          nnml-current-directory nil "^[0-9]+$"))))
          (and articles
index 5065555..bab17e6 100644 (file)
@@ -321,7 +321,11 @@ Newsgroup must be selected before calling this function."
                        nnspool-inews-program nnspool-inews-switches)))
       (set-process-sentinel proc 'nnspool-inews-sentinel)
       (process-send-region proc (point-min) (point-max))
-      (process-send-eof proc)
+      ;; We slap a condition-case around this, because the process may
+      ;; have exited already...
+      (condition-case nil
+         (process-send-eof proc)
+       (error nil))
       t)))
 
 (defun nnspool-inews-sentinel (proc status)
@@ -397,9 +401,10 @@ Newsgroup must be selected before calling this function."
   (let ((first (car articles))
        (last (progn (while (cdr articles) (setq articles (cdr articles)))
                     (car articles))))
-    (call-process "sed" nil t nil "-e" 
-                 (format "1,/^%d\t/d\n/^%d\t/,$d"
-                         (1- first) (1+ last)) file)))
+    (call-process "awk" nil t nil 
+                 (format "BEGIN {firstmsg=%d; lastmsg=%d;}\n $1 >= firstmsg && $1 <= lastmsg {print;}"
+                         (1- first) (1+ last))
+                 file)))
 
 (defun nnspool-find-article-by-message-id (id)
   "Return full pathname of an article identified by message-ID."
index e7ad24e..16094dd 100644 (file)
@@ -180,13 +180,15 @@ If the stream is opened, return T, otherwise return NIL."
        nil))))
     
 (defun nnvirtual-close-group (group &optional server)
-  (nnvirtual-possibly-change-newsgroups group server t)
-  (nnvirtual-update-marked)
-  (setq nnvirtual-current-group nil
-       nnvirtual-current-groups nil
-       nnvirtual-current-mapping nil)
-  (setq nnvirtual-group-alist 
-       (delq (assoc group nnvirtual-group-alist) nnvirtual-group-alist)))
+  (if (not nnvirtual-current-group)
+      ()
+    (nnvirtual-possibly-change-newsgroups group server t)
+    (nnvirtual-update-marked)
+    (setq nnvirtual-current-group nil
+         nnvirtual-current-groups nil
+         nnvirtual-current-mapping nil)
+    (setq nnvirtual-group-alist 
+         (delq (assoc group nnvirtual-group-alist) nnvirtual-group-alist))))
 
 (defun nnvirtual-request-list (&optional server) 
   (setq nnvirtual-status-string "nnvirtual: LIST is not implemented.")
@@ -204,7 +206,10 @@ If the stream is opened, return T, otherwise return NIL."
 
 (fset 'nnvirtual-request-post 'nntp-request-post)
 
-(fset 'nnvirtual-request-post-buffer 'nntp-request-post-buffer)
+(defun nnvirtual-request-post-buffer 
+  (post group subject header article-buffer info follow-to respect-poster)
+  (nntp-request-post-buffer post "" subject header article-buffer
+                           info follow-to respect-poster))
 
 \f
 ;;; Internal functions.