X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lisp%2Fnnfolder.el;h=94ebe1abb4f7be7a292147bf9511aa00658aadec;hb=41fb7027bd9100cf7a76b88761ed42317e11cfa8;hp=84d6cc680b6a9ee0ea2f06a1e7d5b00251110f3d;hpb=77c2b3c6707324bdf2d5376e1c97cdfff7014c74;p=elisp%2Fgnus.git- diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el index 84d6cc6..94ebe1a 100644 --- a/lisp/nnfolder.el +++ b/lisp/nnfolder.el @@ -1,8 +1,8 @@ ;;; nnfolder.el --- mail folder access for Gnus -;; Copyright (C) 1995,96,97 Free Software Foundation, Inc. +;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc. ;; Author: Scott Byer -;; Lars Magne Ingebrigtsen +;; Lars Magne Ingebrigtsen ;; Masanobu UMEDA ;; Keywords: mail @@ -31,7 +31,7 @@ (require 'message) (require 'nnmail) (require 'nnoo) -(require 'cl) +(eval-when-compile (require 'cl)) (require 'gnus-util) (nnoo-declare nnfolder) @@ -90,6 +90,7 @@ time saver for large mailboxes.") (defvoo nnfolder-buffer-alist nil) (defvoo nnfolder-scantime-alist nil) (defvoo nnfolder-active-timestamp nil) +(defvoo nnfolder-file-coding-system nnmail-file-coding-system-1) @@ -101,24 +102,16 @@ time saver for large mailboxes.") (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) - (let (article art-string start stop) + (let (article start stop) (nnfolder-possibly-change-group group server) (when nnfolder-current-buffer (set-buffer nnfolder-current-buffer) (goto-char (point-min)) (if (stringp (car articles)) 'headers - (while articles - (setq article (car articles)) - (setq art-string (nnfolder-article-string article)) + (while (setq article (pop articles)) (set-buffer nnfolder-current-buffer) - (when (or (search-forward art-string nil t) - ;; Don't search the whole file twice! Also, articles - ;; probably have some locality by number, so searching - ;; backwards will be faster. Especially if we're at the - ;; beginning of the buffer :-). -SLB - (search-backward art-string nil t)) - (nnmail-search-unix-mail-delim-backward) + (when (nnfolder-goto-article article) (setq start (point)) (search-forward "\n\n" nil t) (setq stop (1- (point))) @@ -126,8 +119,7 @@ time saver for large mailboxes.") (insert (format "221 %d Article retrieved.\n" article)) (insert-buffer-substring nnfolder-current-buffer start stop) (goto-char (point-max)) - (insert ".\n")) - (setq articles (cdr articles))) + (insert ".\n"))) (set-buffer nntp-server-buffer) (nnheader-fold-continuation-lines) @@ -165,9 +157,8 @@ time saver for large mailboxes.") (save-excursion (set-buffer nnfolder-current-buffer) (goto-char (point-min)) - (when (search-forward (nnfolder-article-string article) nil t) + (when (nnfolder-goto-article article) (let (start stop) - (nnmail-search-unix-mail-delim-backward) (setq start (point)) (forward-line 1) (unless (and (nnmail-search-unix-mail-delim) @@ -309,7 +300,10 @@ time saver for large mailboxes.") (set-buffer nnfolder-current-buffer) (while (and articles is-old) (goto-char (point-min)) - (when (search-forward (nnfolder-article-string (car articles)) nil t) + (when (and (nnfolder-goto-article (car articles)) + (search-forward (concat "\n" nnfolder-article-marker) + nil t)) + (forward-sexp) (if (setq is-old (nnmail-expired-article-p newsgroup @@ -329,87 +323,98 @@ time saver for large mailboxes.") (nnmail-save-active nnfolder-group-alist nnfolder-active-file) (nconc rest articles)))) -(deffoo nnfolder-request-move-article - (article group server accept-form &optional last) - (let ((buf (get-buffer-create " *nnfolder move*")) - result) - (and - (nnfolder-request-article article group server) - (save-excursion - (set-buffer buf) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert-buffer-substring nntp-server-buffer) - (goto-char (point-min)) - (while (re-search-forward - (concat "^" nnfolder-article-marker) - (save-excursion (search-forward "\n\n" nil t) (point)) t) - (delete-region (progn (beginning-of-line) (point)) - (progn (forward-line 1) (point)))) - (setq result (eval accept-form)) - (kill-buffer buf) - result) - (save-excursion - (nnfolder-possibly-change-group group server) - (set-buffer nnfolder-current-buffer) - (goto-char (point-min)) - (when (search-forward (nnfolder-article-string article) nil t) - (nnfolder-delete-mail)) - (when last - (nnfolder-save-buffer) - (nnfolder-adjust-min-active group) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file)))) - result)) +(deffoo nnfolder-request-move-article (article group server + accept-form &optional last) + (save-excursion + (let ((buf (get-buffer-create " *nnfolder move*")) + result) + (and + (nnfolder-request-article article group server) + (save-excursion + (set-buffer buf) + (erase-buffer) + (insert-buffer-substring nntp-server-buffer) + (goto-char (point-min)) + (while (re-search-forward + (concat "^" nnfolder-article-marker) + (save-excursion (search-forward "\n\n" nil t) (point)) t) + (delete-region (progn (beginning-of-line) (point)) + (progn (forward-line 1) (point)))) + (setq result (eval accept-form)) + (kill-buffer buf) + result) + (save-excursion + (nnfolder-possibly-change-group group server) + (set-buffer nnfolder-current-buffer) + (goto-char (point-min)) + (when (nnfolder-goto-article article) + (nnfolder-delete-mail)) + (when last + (nnfolder-save-buffer) + (nnfolder-adjust-min-active group) + (nnmail-save-active nnfolder-group-alist nnfolder-active-file)))) + result))) (deffoo nnfolder-request-accept-article (group &optional server last) - (nnfolder-possibly-change-group group server) - (nnmail-check-syntax) - (let ((buf (current-buffer)) - result art-group) - (goto-char (point-min)) - (when (looking-at "X-From-Line: ") - (replace-match "From ")) - (and - (nnfolder-request-list) - (save-excursion - (set-buffer buf) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (forward-line -1) - (while (re-search-backward (concat "^" nnfolder-article-marker) nil t) - (delete-region (point) (progn (forward-line 1) (point)))) - (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id"))) - (setq result (if (stringp group) - (list (cons group (nnfolder-active-number group))) - (setq art-group - (nnmail-article-group 'nnfolder-active-number)))) - (if (and (null result) - (yes-or-no-p "Moved to `junk' group; delete article? ")) - (setq result 'junk) - (setq result - (car (nnfolder-save-mail result))))) - (when last + (save-excursion + (nnfolder-possibly-change-group group server) + (nnmail-check-syntax) + (let ((buf (current-buffer)) + result art-group) + (goto-char (point-min)) + (when (looking-at "X-From-Line: ") + (replace-match "From ")) + (and + (nnfolder-request-list) (save-excursion - (nnfolder-possibly-change-folder (or (caar art-group) group)) - (nnfolder-save-buffer) + (set-buffer buf) + (goto-char (point-min)) + (search-forward "\n\n" nil t) + (forward-line -1) + (while (re-search-backward (concat "^" nnfolder-article-marker) nil t) + (delete-region (point) (progn (forward-line 1) (point)))) (when nnmail-cache-accepted-message-ids - (nnmail-cache-close))))) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - (unless result - (nnheader-report 'nnfolder "Couldn't store article")) - result)) + (nnmail-cache-insert (nnmail-fetch-field "message-id"))) + (setq result (if (stringp group) + (list (cons group (nnfolder-active-number group))) + (setq art-group + (nnmail-article-group 'nnfolder-active-number)))) + (if (and (null result) + (yes-or-no-p "Moved to `junk' group; delete article? ")) + (setq result 'junk) + (setq result + (car (nnfolder-save-mail result))))) + (when last + (save-excursion + (nnfolder-possibly-change-folder (or (caar art-group) group)) + (nnfolder-save-buffer) + (when nnmail-cache-accepted-message-ids + (nnmail-cache-close))))) + (nnmail-save-active nnfolder-group-alist nnfolder-active-file) + (unless result + (nnheader-report 'nnfolder "Couldn't store article")) + result))) (deffoo nnfolder-request-replace-article (article group buffer) (nnfolder-possibly-change-group group) (save-excursion (set-buffer buffer) + (goto-char (point-min)) + (let (xfrom) + (while (re-search-forward "^X-From-Line: \\(.*\\)$" nil t) + (setq xfrom (match-string 1)) + (gnus-delete-line)) + (goto-char (point-min)) + (if xfrom + (insert "From " xfrom "\n") + (unless (looking-at message-unix-mail-delimiter) + (insert "From nobody " (current-time-string) "\n")))) (nnfolder-normalize-buffer) (set-buffer nnfolder-current-buffer) (goto-char (point-min)) - (if (not (search-forward (nnfolder-article-string article) nil t)) + (if (not (nnfolder-goto-article article)) nil - (nnfolder-delete-mail t t) + (nnfolder-delete-mail) (insert-buffer-substring buffer) (nnfolder-save-buffer) t))) @@ -471,10 +476,9 @@ time saver for large mailboxes.") (goto-char (point-min)) (while (and (search-forward marker nil t) (re-search-forward number nil t)) - (setq activemin (min activemin - (string-to-number (buffer-substring - (match-beginning 0) - (match-end 0)))))) + (let ((newnum (string-to-number (match-string 0)))) + (if (nnmail-within-headers-p) + (setq activemin (min activemin newnum))))) (setcar active activemin)))) (defun nnfolder-article-string (article) @@ -482,11 +486,38 @@ time saver for large mailboxes.") (concat "\n" nnfolder-article-marker (int-to-string article) " ") (concat "\nMessage-ID: " article))) -(defun nnfolder-delete-mail (&optional force leave-delim) - "Delete the message that point is in." - (save-excursion - (delete-region +(defun nnfolder-goto-article (article) + "Place point at the start of the headers of ARTICLE. +ARTICLE can be an article number or a Message-ID. +Returns t if successful, nil otherwise." + (let ((art-string (nnfolder-article-string article)) + start found) + ;; It is likely that we are at or before the delimiter line. + ;; We therefore go to the end of the previous line, and start + ;; searching from there. + (beginning-of-line) + (unless (bobp) + (forward-char -1)) + (setq start (point)) + ;; First search forward. + (while (and (setq found (search-forward art-string nil t)) + (not (nnmail-within-headers-p)))) + ;; If unsuccessful, search backward from where we started, + (unless found + (goto-char start) + (while (and (setq found (search-backward art-string nil t)) + (not (nnmail-within-headers-p))))) + (when found + (nnmail-search-unix-mail-delim-backward)))) + +(defun nnfolder-delete-mail (&optional leave-delim) + "Delete the message that point is in. +If optional argument LEAVE-DELIM is t, then mailbox delimiter is not +deleted. Point is left where the deleted region was." + (save-restriction + (narrow-to-region (save-excursion + (forward-line 1) ; in case point is at beginning of message already (nnmail-search-unix-mail-delim-backward) (if leave-delim (progn (forward-line 1) (point)) (point))) @@ -494,7 +525,9 @@ time saver for large mailboxes.") (forward-line 1) (if (nnmail-search-unix-mail-delim) (point) - (point-max)))))) + (point-max)))) + (run-hooks 'nnfolder-delete-mail-hook) + (delete-region (point-min) (point-max)))) (defun nnfolder-possibly-change-group (group &optional server dont-check) ;; Change servers. @@ -537,7 +570,8 @@ time saver for large mailboxes.") (setq nnfolder-current-group group) (when (or (not nnfolder-current-buffer) - (not (verify-visited-file-modtime nnfolder-current-buffer))) + (not (verify-visited-file-modtime + nnfolder-current-buffer))) (save-excursion (setq file (nnfolder-group-pathname group)) ;; See whether we need to create the new file. @@ -652,7 +686,10 @@ time saver for large mailboxes.") (defun nnfolder-read-folder (group) (let* ((file (nnfolder-group-pathname group)) - (buffer (set-buffer (nnheader-find-file-noselect file)))) + (buffer (set-buffer + (let ((nnmail-file-coding-system + nnfolder-file-coding-system)) + (nnheader-find-file-noselect file))))) (if (equal (cadr (assoc group nnfolder-scantime-alist)) (nth 5 (file-attributes file))) ;; This looks up-to-date, so we don't do any scanning. @@ -674,7 +711,7 @@ time saver for large mailboxes.") (minid (lsh -1 -1)) maxid start end newscantime buffer-read-only) - (buffer-disable-undo (current-buffer)) + (buffer-disable-undo) (setq maxid (cdr active)) (goto-char (point-min)) @@ -689,8 +726,9 @@ time saver for large mailboxes.") (while (and (search-forward marker nil t) (re-search-forward number nil t)) (let ((newnum (string-to-number (match-string 0)))) - (setq maxid (max maxid newnum)) - (setq minid (min minid newnum)))) + (if (nnmail-within-headers-p) + (setq maxid (max maxid newnum) + minid (min minid newnum))))) (setcar active (max 1 (min minid maxid))) (setcdr active (max maxid (cdr active))) (goto-char (point-min))) @@ -764,11 +802,12 @@ time saver for large mailboxes.") (nnfolder-possibly-change-folder file) (nnfolder-possibly-change-group file) (nnfolder-close-group file)))) - (message ""))) + (nnheader-message 5 ""))) (defun nnfolder-group-pathname (group) "Make pathname for GROUP." - (setq group (gnus-encode-coding-string group nnmail-pathname-coding-system)) + (setq group + (encode-coding-string group nnmail-pathname-coding-system)) (let ((dir (file-name-as-directory (expand-file-name nnfolder-directory)))) ;; If this file exists, we use it directly. (if (or nnmail-use-long-file-names