IMAP command logging improvement
[gnus] / lisp / nnml.el
index 6d676bb..b865260 100644 (file)
@@ -1,7 +1,7 @@
 ;;; nnml.el --- mail spool access for Gnus
 
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1995-2012 Free Software
+;;   Foundation, Inc.
 
 ;; Authors: Didier Verna <didier@xemacs.org> (adding compaction)
 ;;     Simon Josefsson <simon@josefsson.org> (adding MARKS)
@@ -160,8 +160,7 @@ non-nil.")
 
 (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old)
   (when (nnml-possibly-change-directory group server)
-    (save-excursion
-      (set-buffer nntp-server-buffer)
+    (with-current-buffer nntp-server-buffer
       (erase-buffer)
       (let* ((file nil)
             (number (length sequence))
@@ -236,7 +235,11 @@ non-nil.")
                          (nnheader-article-to-file-alist
                           (setq gpath (nnml-group-pathname (car group-num)
                                                            nil server))))))
-         (setq path (concat gpath (int-to-string (cdr group-num)))))
+         (nnml-update-file-alist)
+         (setq path (concat gpath (if nnml-use-compressed-files
+                                      (cdr (assq (cdr group-num)
+                                                 nnml-article-file-alist))
+                                    (number-to-string (cdr group-num))))))
       (setq path (nnml-article-to-file id)))
     (cond
      ((not path)
@@ -255,7 +258,7 @@ non-nil.")
       (cons (if group-num (car group-num) group)
            (string-to-number (file-name-nondirectory path)))))))
 
-(deffoo nnml-request-group (group &optional server dont-check)
+(deffoo nnml-request-group (group &optional server dont-check info)
   (let ((file-name-coding-system nnmail-pathname-coding-system)
        (decoded (nnml-decoded-group-name group server)))
     (cond
@@ -405,8 +408,7 @@ non-nil.")
      (let (nnml-current-directory
           nnml-current-group
           nnml-article-file-alist)
-       (save-excursion
-        (set-buffer buf)
+       (with-current-buffer buf
         (insert-buffer-substring nntp-server-buffer)
         (setq result (eval accept-form))
         (kill-buffer (current-buffer))
@@ -462,8 +464,7 @@ non-nil.")
 
 (deffoo nnml-request-replace-article (article group buffer)
   (nnml-possibly-change-directory group)
-  (save-excursion
-    (set-buffer buffer)
+  (with-current-buffer buffer
     (nnml-possibly-create-directory group)
     (let ((chars (nnmail-insert-lines))
          (art (concat (int-to-string article) "\t"))
@@ -478,8 +479,7 @@ non-nil.")
              t)
        (setq headers (nnml-parse-head chars article))
        ;; Replace the NOV line in the NOV file.
-       (save-excursion
-         (set-buffer (nnml-open-nov group))
+       (with-current-buffer (nnml-open-nov group)
          (goto-char (point-min))
          (if (or (looking-at art)
                  (search-forward (concat "\n" art) nil t))
@@ -614,8 +614,7 @@ non-nil.")
 
 ;; Find an article number in the current group given the Message-ID.
 (defun nnml-find-group-number (id server)
-  (save-excursion
-    (set-buffer (get-buffer-create " *nnml id*"))
+  (with-current-buffer (get-buffer-create " *nnml id*")
     (let ((alist nnml-group-alist)
          number)
       ;; We want to look through all .overview files, but we want to
@@ -657,8 +656,7 @@ non-nil.")
       nil
     (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory)))
       (when (file-exists-p nov)
-       (save-excursion
-         (set-buffer nntp-server-buffer)
+       (with-current-buffer nntp-server-buffer
          (erase-buffer)
          (nnheader-insert-file-contents nov)
          (if (and fetch-old
@@ -804,16 +802,14 @@ article number.  This function is called narrowed to an article."
 
 (defun nnml-add-incremental-nov (group article headers)
   "Add a nov line for the GROUP nov headers, incrementally."
-  (save-excursion
-    (set-buffer (nnml-open-incremental-nov group))
+  (with-current-buffer (nnml-open-incremental-nov group)
     (goto-char (point-max))
     (mail-header-set-number headers article)
     (nnheader-insert-nov headers)))
 
 (defun nnml-add-nov (group article headers)
   "Add a nov line for the GROUP base."
-  (save-excursion
-    (set-buffer (nnml-open-nov group))
+  (with-current-buffer (nnml-open-nov group)
     (goto-char (point-max))
     (mail-header-set-number headers article)
     (nnheader-insert-nov headers)))
@@ -844,8 +840,7 @@ article number.  This function is called narrowed to an article."
                                              "")
                                            decoded)))
         (file-name-coding-system nnmail-pathname-coding-system))
-    (save-excursion
-      (set-buffer buffer)
+    (with-current-buffer buffer
       (set (make-local-variable 'nnml-nov-buffer-file-name)
           (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name))
       (erase-buffer)
@@ -855,7 +850,9 @@ article number.  This function is called narrowed to an article."
     buffer))
 
 (defun nnml-open-nov (group)
-  (or (cdr (assoc group nnml-nov-buffer-alist))
+  (or (let ((buffer (cdr (assoc group nnml-nov-buffer-alist))))
+       (and (buffer-name buffer)
+            buffer))
       (let ((buffer (nnml-get-nov-buffer group)))
        (push (cons group buffer) nnml-nov-buffer-alist)
        buffer)))
@@ -887,6 +884,7 @@ article number.  This function is called narrowed to an article."
   ;; Save the active file.
   (nnmail-save-active nnml-group-alist nnml-active-file))
 
+(defvar nnml-files)
 (defun nnml-generate-nov-databases-directory (dir &optional seen no-active)
   "Regenerate the NOV database in DIR.
 
@@ -906,9 +904,9 @@ Unless no-active is non-nil, update the active file too."
                   (file-directory-p dir))
          (nnml-generate-nov-databases-directory dir seen)))
       ;; Do this directory.
-      (let ((files (sort (nnheader-article-to-file-alist dir)
+      (let ((nnml-files (sort (nnheader-article-to-file-alist dir)
                         'car-less-than-car)))
-       (if (not files)
+       (if (not nnml-files)
            (let* ((group (nnheader-file-to-group
                           (directory-file-name dir) nnml-directory))
                   (info (cadr (assoc group nnml-group-alist))))
@@ -916,11 +914,10 @@ Unless no-active is non-nil, update the active file too."
                (setcar info (1+ (cdr info)))))
          (funcall nnml-generate-active-function dir)
          ;; Generate the nov file.
-         (nnml-generate-nov-file dir files)
+         (nnml-generate-nov-file dir nnml-files)
          (unless no-active
            (nnmail-save-active nnml-group-alist nnml-active-file)))))))
 
-(defvar files)
 (defun nnml-generate-active-info (dir)
   ;; Update the active info for this group.
   (let ((group (directory-file-name dir))
@@ -931,9 +928,9 @@ Unless no-active is non-nil, update the active file too."
          last (or (caadr entry) 0)
          nnml-group-alist (delq entry nnml-group-alist))
     (push (list group
-               (cons (or (caar files) (1+ last))
+               (cons (or (caar nnml-files) (1+ last))
                      (max last
-                          (or (caar (last files))
+                          (or (caar (last nnml-files))
                               0))))
          nnml-group-alist)))
 
@@ -942,42 +939,38 @@ Unless no-active is non-nil, update the active file too."
         (nov (concat dir nnml-nov-file-name))
         (nov-buffer (get-buffer-create " *nov*"))
         chars file headers)
-    (save-excursion
+    (with-current-buffer nov-buffer
       ;; Init the nov buffer.
-      (set-buffer nov-buffer)
       (buffer-disable-undo)
       (erase-buffer)
       (set-buffer nntp-server-buffer)
       ;; Delete the old NOV file.
       (when (file-exists-p nov)
        (funcall nnmail-delete-file-function nov))
-      (while files
-       (unless (file-directory-p (setq file (concat dir (cdar files))))
-         (erase-buffer)
-         (nnheader-insert-file-contents file)
-         (narrow-to-region
-          (goto-char (point-min))
-          (progn
-            (re-search-forward "\n\r?\n" nil t)
-            (setq chars (- (point-max) (point)))
-            (max (point-min) (1- (point)))))
-         (unless (zerop (buffer-size))
-           (goto-char (point-min))
-           (setq headers (nnml-parse-head chars (caar files)))
-           (save-excursion
-             (set-buffer nov-buffer)
-             (goto-char (point-max))
-             (nnheader-insert-nov headers)))
-         (widen))
-       (setq files (cdr files)))
-      (save-excursion
-       (set-buffer nov-buffer)
+      (dolist (file files)
+       (let ((path (concat dir (cdr file))))
+         (unless (file-directory-p path)
+           (erase-buffer)
+           (nnheader-insert-file-contents path)
+           (narrow-to-region
+            (goto-char (point-min))
+            (progn
+              (re-search-forward "\n\r?\n" nil t)
+              (setq chars (- (point-max) (point)))
+              (max (point-min) (1- (point)))))
+           (unless (zerop (buffer-size))
+             (goto-char (point-min))
+             (setq headers (nnml-parse-head chars (car file)))
+             (with-current-buffer nov-buffer
+               (goto-char (point-max))
+               (nnheader-insert-nov headers)))
+           (widen))))
+      (with-current-buffer nov-buffer
        (nnmail-write-region (point-min) (point-max) nov nil 'nomesg)
        (kill-buffer (current-buffer))))))
 
 (defun nnml-nov-delete-article (group article)
-  (save-excursion
-    (set-buffer (nnml-open-nov group))
+  (with-current-buffer (nnml-open-nov group)
     (when (nnheader-find-nov-line article)
       (delete-region (point) (progn (forward-line 1) (point)))
       (when (bobp)
@@ -1008,11 +1001,9 @@ Use the nov database for that directory if available."
     ;; build list from .overview if available
     ;; We would use nnml-open-nov, except that nnml-nov-buffer-alist is
     ;; defvoo'd, and we might get called when it hasn't been swapped in.
-    (save-excursion
+    (with-current-buffer (nnml-get-nov-buffer nnml-current-group)
       (let ((list nil)
-           art
-           (buffer (nnml-get-nov-buffer nnml-current-group)))
-       (set-buffer buffer)
+           art)
        (goto-char (point-min))
        (while (not (eobp))
          (setq art (read (current-buffer)))
@@ -1031,11 +1022,9 @@ Use the nov database for the current group if available."
                                  nnml-current-directory))))
       (nnheader-article-to-file-alist nnml-current-directory)
     ;; build list from .overview if available
-    (save-excursion
+    (with-current-buffer (nnml-get-nov-buffer nnml-current-group)
       (let ((alist nil)
-           (buffer (nnml-get-nov-buffer nnml-current-group))
            art)
-       (set-buffer buffer)
        (goto-char (point-min))
        (while (not (eobp))
          (setq art (read (current-buffer)))
@@ -1048,23 +1037,11 @@ Use the nov database for the current group if available."
   (nnml-possibly-change-directory group server)
   (unless nnml-marks-is-evil
     (nnml-open-marks group server)
-    (dolist (action actions)
-      (let ((range (nth 0 action))
-           (what  (nth 1 action))
-           (marks (nth 2 action)))
-       (assert (or (eq what 'add) (eq what 'del)) nil
-               "Unknown request-set-mark action: %s" what)
-       (dolist (mark marks)
-         (setq nnml-marks (gnus-update-alist-soft
-                           mark
-                           (funcall (if (eq what 'add) 'gnus-range-add
-                                      'gnus-remove-from-range)
-                                    (cdr (assoc mark nnml-marks)) range)
-                           nnml-marks)))))
+    (setq nnml-marks (nnheader-update-marks-actions nnml-marks actions))
     (nnml-save-marks group server))
   nil)
 
-(deffoo nnml-request-update-info (group info &optional server)
+(deffoo nnml-request-marks (group info &optional server)
   (nnml-possibly-change-directory group server)
   (when (and (not nnml-marks-is-evil) (nnml-marks-changed-p group server))
     (nnheader-message 8 "Updating marks for %s..." group)
@@ -1236,7 +1213,7 @@ Use the nov database for the current group if available."
                ;; #### already belongs to a range, whereas the corresponding
                ;; #### article doesn't exist (for example, if you delete an
                ;; #### article). For that reason, it is important to update
-               ;; #### the ranges (meaning remove inexistent articles) before
+               ;; #### the ranges (meaning remove nonexistent articles) before
                ;; #### doing anything on them.
                ;; 2 a/ read articles:
                (let ((read (gnus-info-read info)))
@@ -1260,8 +1237,7 @@ Use the nov database for the current group if available."
                  (gnus-info-set-marks info newmarks))
                ;; 3/ Update the NOV entry for this article:
                (unless nnml-nov-is-evil
-                 (save-excursion
-                   (set-buffer (nnml-open-nov group))
+                 (with-current-buffer (nnml-open-nov group)
                    (when (nnheader-find-nov-line old-number)
                      ;; Replace the article number:
                      (looking-at old-number-string)
@@ -1322,6 +1298,9 @@ Use the nov database for the current group if available."
          (nnml-save-nov)
          ;; b/ Save the active file:
          (nnmail-save-active nnml-group-alist nnml-active-file)
+         (let ((marks (nnml-group-pathname group nnml-marks-file-name server)))
+           (when (file-exists-p marks)
+             (delete-file marks)))
          t)))))
 
 (defun nnml-request-compact (&optional server)