Only delete articles immediately if the target is 'delete.
[gnus] / lisp / nnimap.el
index 8324d99..82c9976 100644 (file)
@@ -137,7 +137,7 @@ textual parts.")
 
 (defun nnimap-transform-headers ()
   (goto-char (point-min))
-  (let (article bytes lines)
+  (let (article bytes lines size)
     (block nil
       (while (not (eobp))
        (while (not (looking-at "^\\* [0-9]+ FETCH.*UID \\([0-9]+\\)"))
@@ -148,6 +148,12 @@ textual parts.")
              bytes (nnimap-get-length)
              lines nil)
        (beginning-of-line)
+       (setq size
+             (and (re-search-forward "RFC822.SIZE \\([0-9]+\\)"
+                                     (line-end-position)
+                                     t)
+                  (match-string 1)))
+       (beginning-of-line)
        (when (search-forward "BODYSTRUCTURE" (line-end-position) t)
          (let ((structure (ignore-errors (read (current-buffer)))))
            (while (and (consp structure)
@@ -157,7 +163,8 @@ textual parts.")
        (delete-region (line-beginning-position) (line-end-position))
        (insert (format "211 %s Article retrieved." article))
        (forward-line 1)
-       (insert (format "Chars: %d\n" bytes))
+       (when size
+         (insert (format "Chars: %s\n" size)))
        (when lines
          (insert (format "Lines: %s\n" lines)))
        (re-search-forward "^\r$")
@@ -268,7 +275,11 @@ textual parts.")
                           (if (eq nnimap-authenticator 'anonymous)
                               (list "anonymous"
                                     (message-make-address))
-                            (nnimap-credentials nnimap-address ports))))
+                            (nnimap-credentials
+                             nnimap-address
+                             (if nnimap-server-port
+                                 (cons (format "%s" nnimap-server-port) ports)
+                               ports)))))
                (setq nnimap-object nil)
              (setq login-result (nnimap-command "LOGIN %S %S"
                                                 (car credentials)
@@ -354,28 +365,35 @@ textual parts.")
                (goto-char (+ (point) bytes))
                (delete-region (point) (point-max))
                (nnheader-ms-strip-cr))
-             t)))))))
+             (cons group article))))))))
 
 (defun nnimap-find-wanted-parts (structure)
-  (let ((nnimap-level 1))
-    (message-flatten-list (nnimap-find-wanted-parts-1 structure))))
+  (message-flatten-list (nnimap-find-wanted-parts-1 structure "")))
 
-(defun nnimap-find-wanted-parts-1 (structure)
-  (let (levels)
+(defun nnimap-find-wanted-parts-1 (structure prefix)
+  (let ((num 1)
+       parts)
     (while (consp (car structure))
       (let ((sub (pop structure)))
        (if (consp (car sub))
-           (push (nnimap-find-wanted-parts-1 sub) levels)
+           (push (nnimap-find-wanted-parts-1
+                  sub (if (string= prefix "")
+                          (number-to-string num)
+                        (format "%s.%s" prefix num)))
+                 parts)
          (let ((type (format "%s/%s" (nth 0 sub) (nth 1 sub))))
            (when (string-match nnimap-fetch-partial-articles type)
-             (push nnimap-level levels)))
-         (incf nnimap-level))))
-    (nreverse levels)))
+             (push (if (string= prefix "")
+                       (number-to-string num)
+                     (format "%s.%s" prefix num))
+                   parts)))
+         (incf num))))
+    (nreverse parts)))
 
 (deffoo nnimap-request-group (group &optional server dont-check info)
-  (with-current-buffer nntp-server-buffer
-    (let ((result (nnimap-possibly-change-group group server))
-         articles active marks high low)
+  (let ((result (nnimap-possibly-change-group group server))
+       articles active marks high low)
+    (with-current-buffer nntp-server-buffer
       (when result
        (if (and dont-check
                 (setq active (nth 2 (assoc group nnimap-current-infos))))
@@ -387,7 +405,7 @@ textual parts.")
          (with-current-buffer (nnimap-buffer)
            (erase-buffer)
            (let ((group-sequence
-                  (nnimap-send-command "SELECT %S" (utf7-encode group)))
+                  (nnimap-send-command "SELECT %S" (utf7-encode group t)))
                  (flag-sequence
                   (nnimap-send-command "UID FETCH 1:* FLAGS")))
              (nnimap-wait-for-response flag-sequence)
@@ -403,16 +421,29 @@ textual parts.")
                (setq high (nth 3 (car marks))
                      low (nth 4 (car marks))))
               ((re-search-backward "UIDNEXT \\([0-9]+\\)" nil t)
-               (setq high (string-to-number (match-string 1))
+               (setq high (1- (string-to-number (match-string 1)))
                      low 1)))))
          (erase-buffer)
          (insert
           (format
-           "211 %d %d %d %S\n"
-           (1+ (- high low))
-           low high group))))
+           "211 %d %d %d %S\n" (1+ (- high low)) low high group))))
       t)))
 
+(deffoo nnimap-request-create-group (group &optional server args)
+  (when (nnimap-possibly-change-group nil server)
+    (with-current-buffer (nnimap-buffer)
+      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+
+(deffoo nnimap-request-delete-group (group &optional force server)
+  (when (nnimap-possibly-change-group nil server)
+    (with-current-buffer (nnimap-buffer)
+      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+
+(deffoo nnimap-request-expunge-group (group &optional server)
+  (when (nnimap-possibly-change-group group server)
+    (with-current-buffer (nnimap-buffer)
+      (car (nnimap-command "EXPUNGE")))))
+
 (defun nnimap-get-flags (spec)
   (let ((articles nil)
        elems)
@@ -449,16 +480,18 @@ textual parts.")
                    (nnimap-find-article-by-message-id
                     internal-move-group message-id))))
        (with-temp-buffer
-         (let ((result (eval accept-form)))
-           (when result
-             (nnimap-delete-article article)
-             result)))))))
+         (when (nnimap-request-article article group server (current-buffer))
+           (let ((result (eval accept-form)))
+             (when result
+               (nnimap-delete-article article)
+               result))))))))
 
 (deffoo nnimap-request-expire-articles (articles group &optional server force)
   (cond
    ((not (nnimap-possibly-change-group group server))
     articles)
-   (force
+   ((and force
+        (eq nnmail-expiry-target 'delete))
     (unless (nnimap-delete-article articles)
       (message "Article marked for deletion, but not expunged."))
     nil)
@@ -519,7 +552,8 @@ textual parts.")
                                (mapconcat #'identity flags " ")))))))
        ;; Wait for the last command to complete to avoid later
        ;; syncronisation problems with the stream.
-       (nnimap-wait-for-response sequence)))))
+       (when sequence
+         (nnimap-wait-for-response sequence))))))
 
 (deffoo nnimap-request-accept-article (group &optional server last)
   (when (nnimap-possibly-change-group nil server)
@@ -852,7 +886,9 @@ textual parts.")
     (if (equal (caar response) "OK")
        (cons t response)
       (nnheader-report 'nnimap "%s"
-                      (mapconcat #'identity (car response) " "))
+                      (mapconcat (lambda (a)
+                                   (format "%s" a))
+                                 (car response) " "))
       nil)))
 
 (defun nnimap-get-response (sequence)
@@ -864,11 +900,12 @@ textual parts.")
     (goto-char (point-min))
     (while (and (memq (process-status process)
                      '(open run))
-               (not (re-search-forward "^\\* " nil t)))
+               (not (re-search-forward "^\\* .*\n" nil t)))
       (nnheader-accept-process-output process)
       (goto-char (point-min)))
-    (and (looking-at "[A-Z0-9]+")
-        (match-string 0))))
+    (forward-line -1)
+    (and (looking-at "\\* \\([A-Z0-9]+\\)")
+        (match-string 1))))
 
 (defun nnimap-wait-for-response (sequence &optional messagep)
   (let ((process (get-buffer-process (current-buffer))))
@@ -960,7 +997,7 @@ textual parts.")
                 "BODY.PEEK[HEADER] BODY.PEEK"
               "RFC822.PEEK"))
            (if nnimap-split-download-body-default
-               ""
+               "[]"
              "[1]")))
    t))