Gnus development mailing list
 help / color / mirror / Atom feed
* [PATCH] nnimap: enable additional expunge options
@ 2015-05-27  2:20 Nikolaus Rath
  2015-08-03  9:24 ` Eric Abrahamsen
  0 siblings, 1 reply; 4+ messages in thread
From: Nikolaus Rath @ 2015-05-27  2:20 UTC (permalink / raw)
  To: ding, bugs

[-- Attachment #1: Type: text/plain, Size: 1719 bytes --]

Hello,

If the IMAP server supports the UID EXPUNGE command, the nnimap backend
currently always expunges deleted articles.

If the IMAP server does not support this command, articles are either
not expunged at all (nnimap-expunge is nil), or ALL articles that are
currently flagged as deleted will be expunged when any one article is
deleted in Gnus.

The attached patch introduces three new settings for nnimap-expunge:

 * If nnimap-expunge is 'never, deleted articles are marked with the
   IMAP \\Delete flag but not automatically expunged.

 * If nnimap-expunge is 'immediately, deleted articles are immediately
   expunged (this requires the server to support the UID EXPUNGE
   command).

 * If nnimap-expunge is 'on-exit, deleted articles are flagged, and all
   flagged articles are expunged when the group is closed.

Note that none of these behaviors is available with the current settings
(nil / non-nil).

The 'on-exit setting is mostly useful as a safe-guard: as long as the
group is not closed, article deletions are reversal (either by using a
different IMAP client, or by exiting Gnus without updating the summary
buffer).

The 'never setting is not (yet) very useful because Gnus does not
distinguish between deleted articles and regular articles in the summary
buffer. However, this will be addressed by a separate patch.

I hope these patches will improve interoperability of Gnus with other
IMAP mail clients.

Thanks for considering.

Best,
-Nikolaus

-- 
GPG encrypted emails preferred. Key id: 0xD113FCAC3C4E599F
Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

             »Time flies like an arrow, fruit flies like a Banana.«

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: nnimap_expunge.diff --]
[-- Type: text/x-diff, Size: 5008 bytes --]

--- nnimap.el.bak	2015-05-25 11:04:15.671769838 -0700
+++ nnimap.el	2015-05-26 19:03:11.563602488 -0700
@@ -103,10 +103,20 @@
 Possible choices are nil (use default methods), `anonymous',
 `login', `plain' and `cram-md5'.")
 
-(defvoo nnimap-expunge t
-  "If non-nil, expunge articles after deleting them.
-This is always done if the server supports UID EXPUNGE, but it's
-not done by default on servers that doesn't support that command.")
+(defvoo nnimap-expunge 'on-exit
+  "If 'never, deleted articles are marked with the IMAP \\Delete
+flag but not automatically expunged. If 'immediately, deleted
+articles are immediately expunged (this requires the server to
+support the UID EXPUNGE command). If 'on-exit, deleted articles
+are flagged, and all flagged articles are expunged when the
+group is closed.
+
+For backwards compatibility, this variable may also be set to t
+or nil. If the server supports UID EXPUNGE, both t and nil are
+equivalent to 'immediately. If the server does not support UID
+EXPUNGE nil is equivalent to 'never, while t will immediately
+expunge ALL articles that are currently flagged as deleted
+(i.e., potentially not only the article that was just deleted).")
 
 (defvoo nnimap-streaming t
   "If non-nil, try to use streaming commands with IMAP servers.
@@ -864,7 +875,11 @@
     (nreverse articles)))
 
 (deffoo nnimap-close-group (group &optional server)
-  t)
+  (if (eq nnimap-expunge 'on-exit)
+      (with-current-buffer (nnimap-buffer)
+        (nnimap-wait-for-response
+         (nnimap-send-command "EXPUNGE")))
+    t))
 
 (deffoo nnimap-request-move-article (article group server accept-form
 					     &optional last internal-move-group)
@@ -909,8 +926,7 @@
     articles)
    ((and force
 	 (eq nnmail-expiry-target 'delete))
-    (unless (nnimap-delete-article (gnus-compress-sequence articles))
-      (nnheader-message 7 "Article marked for deletion, but not expunged."))
+    (nnimap-delete-article (gnus-compress-sequence articles))
     nil)
    (t
     (let ((deletable-articles
@@ -1026,21 +1042,36 @@
             (when (and limit number-of-article)
               (nnimap-find-article-by-message-id group server message-id))))))))
 
-(defun nnimap-delete-article (articles)
+(defun nnimap-delete-article (articles &optional sync)
+  "Delete ARTICLES.
+
+If sync is non-nil, wait for server response."
   (with-current-buffer (nnimap-buffer)
     (nnimap-command "UID STORE %s +FLAGS.SILENT (\\Deleted)"
 		    (nnimap-article-ranges articles))
+    (let ((sequence
     (cond
-     ((nnimap-capability "UIDPLUS")
+            ((eq nnimap-expunge 'immediately)
+             (if (nnimap-capability "UIDPLUS")
       (nnimap-command "UID EXPUNGE %s"
 		      (nnimap-article-ranges articles))
-      t)
+               (nnheader-message 3 (concat "nnimap-expunge set to 'immediately, but "
+                                           "server doesn't support UIDPLUS"))))
+
+            ((memq nnimap-expunge '(on-exit never)) nil)
+
+            ((nnimap-capability "UIDPLUS")
+             (nnimap-command "UID EXPUNGE %s"
+                             (nnimap-article-ranges articles)))
+
      (nnimap-expunge
-      (nnimap-command "EXPUNGE")
-      t)
-     (t (gnus-message 7 (concat "nnimap: nnimap-expunge is not set and the "
-                                "server doesn't support UIDPLUS, so we won't "
-                                "delete this article now"))))))
+             (nnimap-command "EXPUNGE"))
+
+            (t
+             (nnheader-message 7 "Article marked for deletion, but not expunged.")))))
+
+      (if (and sync sequence)
+          (nnimap-wait-for-response sequence)))))
 
 (deffoo nnimap-request-scan (&optional group server)
   (when group
@@ -2042,27 +2073,9 @@
 	      (nnimap-wait-for-response (caar sequences))
 	      ;; And then mark the successful copy actions as deleted,
 	      ;; and possibly expunge them.
-	      (nnimap-mark-and-expunge-incoming
-	       (nnimap-parse-copied-articles sequences)))
-            (nnimap-mark-and-expunge-incoming junk-articles)))))))
-
-(defun nnimap-mark-and-expunge-incoming (range)
-  (when range
-    (setq range (nnimap-article-ranges range))
-    (erase-buffer)
-    (let ((sequence
-	   (nnimap-send-command
-	    "UID STORE %s +FLAGS.SILENT (\\Deleted)" range)))
-      (cond
-       ;; If the server supports it, we now delete the message we have
-       ;; just copied over.
-       ((nnimap-capability "UIDPLUS")
-	(setq sequence (nnimap-send-command "UID EXPUNGE %s" range)))
-       ;; If it doesn't support UID EXPUNGE, then we only expunge if the
-       ;; user has configured it.
-       (nnimap-expunge
-	(setq sequence (nnimap-send-command "EXPUNGE"))))
-      (nnimap-wait-for-response sequence))))
+              (nnimap-delete-article
+               (nnimap-parse-copied-articles sequences) t))
+            (nnimap-delete-article junk-articles t)))))))
 
 (defun nnimap-parse-copied-articles (sequences)
   (let (sequence copied range)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] nnimap: enable additional expunge options
  2015-05-27  2:20 [PATCH] nnimap: enable additional expunge options Nikolaus Rath
@ 2015-08-03  9:24 ` Eric Abrahamsen
  2015-08-03 17:21   ` Nikolaus Rath
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Abrahamsen @ 2015-08-03  9:24 UTC (permalink / raw)
  To: ding

Nikolaus Rath <Nikolaus@rath.org> writes:

> Hello,
>
> If the IMAP server supports the UID EXPUNGE command, the nnimap backend
> currently always expunges deleted articles.
>
> If the IMAP server does not support this command, articles are either
> not expunged at all (nnimap-expunge is nil), or ALL articles that are
> currently flagged as deleted will be expunged when any one article is
> deleted in Gnus.
>
> The attached patch introduces three new settings for nnimap-expunge:
>
>  * If nnimap-expunge is 'never, deleted articles are marked with the
>    IMAP \\Delete flag but not automatically expunged.
>
>  * If nnimap-expunge is 'immediately, deleted articles are immediately
>    expunged (this requires the server to support the UID EXPUNGE
>    command).
>
>  * If nnimap-expunge is 'on-exit, deleted articles are flagged, and all
>    flagged articles are expunged when the group is closed.
>
> Note that none of these behaviors is available with the current settings
> (nil / non-nil).
>
> The 'on-exit setting is mostly useful as a safe-guard: as long as the
> group is not closed, article deletions are reversal (either by using a
> different IMAP client, or by exiting Gnus without updating the summary
> buffer).
>
> The 'never setting is not (yet) very useful because Gnus does not
> distinguish between deleted articles and regular articles in the summary
> buffer. However, this will be addressed by a separate patch.

Hey, I'm trying out the rest of these patches -- I set `nnimap-expunge'
to 'never on an outlook imap account, and the messages still get
(completely) deleted when I use `gnus-summary-delete-article' -- I can
see them vanishing from the webmail interface. This is a little odd
because, with this patch applied, the EXPUNGE command never seems to be
issued, yet away the messages go. Is this perhaps a quirk of outlook?
I'll try it on a local dovecot as well...

E




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] nnimap: enable additional expunge options
  2015-08-03  9:24 ` Eric Abrahamsen
@ 2015-08-03 17:21   ` Nikolaus Rath
  0 siblings, 0 replies; 4+ messages in thread
From: Nikolaus Rath @ 2015-08-03 17:21 UTC (permalink / raw)
  To: ding

On Aug 03 2015, Eric Abrahamsen <eric@ericabrahamsen.net> wrote:
>> If the IMAP server supports the UID EXPUNGE command, the nnimap backend
>> currently always expunges deleted articles.
>>
>> If the IMAP server does not support this command, articles are either
>> not expunged at all (nnimap-expunge is nil), or ALL articles that are
>> currently flagged as deleted will be expunged when any one article is
>> deleted in Gnus.
>>
>> The attached patch introduces three new settings for nnimap-expunge:
>>
>>  * If nnimap-expunge is 'never, deleted articles are marked with the
>>    IMAP \\Delete flag but not automatically expunged.
>>
>>  * If nnimap-expunge is 'immediately, deleted articles are immediately
>>    expunged (this requires the server to support the UID EXPUNGE
>>    command).
>>
>>  * If nnimap-expunge is 'on-exit, deleted articles are flagged, and all
>>    flagged articles are expunged when the group is closed.
>>
>> Note that none of these behaviors is available with the current settings
>> (nil / non-nil).
>>
>> The 'on-exit setting is mostly useful as a safe-guard: as long as the
>> group is not closed, article deletions are reversal (either by using a
>> different IMAP client, or by exiting Gnus without updating the summary
>> buffer).
>>
>> The 'never setting is not (yet) very useful because Gnus does not
>> distinguish between deleted articles and regular articles in the summary
>> buffer. However, this will be addressed by a separate patch.
>
> Hey, I'm trying out the rest of these patches -- I set `nnimap-expunge'
> to 'never on an outlook imap account, and the messages still get
> (completely) deleted when I use `gnus-summary-delete-article' -- I can
> see them vanishing from the webmail interface. This is a little odd
> because, with this patch applied, the EXPUNGE command never seems to be
> issued, yet away the messages go. Is this perhaps a quirk of outlook?
> I'll try it on a local dovecot as well...

Some webmail interface automatically issue an EXPUNGE command when you
look at a folder. Typically the argument is that it "eliminates
potential confusion of the user".

Try looking at the mailbox with Thunderbird (it shows deleted messages
as crossed-out), or with Gnus and nnimap-hide-expunged set to false (you
can't distinguish between deleted and not-deleted in this case, but you
can confirm that the ones that you deleted are still there).


Best,
-Nikolaus

-- 
GPG encrypted emails preferred. Key id: 0xD113FCAC3C4E599F
Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

             »Time flies like an arrow, fruit flies like a Banana.«



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] nnimap: enable additional expunge options
@ 2015-07-03  2:10 Nikolaus Rath
  0 siblings, 0 replies; 4+ messages in thread
From: Nikolaus Rath @ 2015-07-03  2:10 UTC (permalink / raw)
  To: 20670, ding

[-- Attachment #1: Type: text/plain, Size: 1698 bytes --]

Hello,

If the IMAP server supports the UID EXPUNGE command, the nnimap backend
currently always expunges deleted articles.

If the IMAP server does not support this command, articles are either
not expunged at all (nnimap-expunge is nil), or ALL articles that are
currently flagged as deleted will be expunged when any one article is
deleted in Gnus.

The attached patch introduces three new settings for nnimap-expunge:

 * If nnimap-expunge is 'never, deleted articles are marked with the
   IMAP \\Delete flag but not automatically expunged.

 * If nnimap-expunge is 'immediately, deleted articles are immediately
   expunged (this requires the server to support the UID EXPUNGE
   command).

 * If nnimap-expunge is 'on-exit, deleted articles are flagged, and all
   flagged articles are expunged when the group is closed.

Note that none of these behaviors is available with the current settings
(nil / non-nil).

The 'on-exit setting is mostly useful as a safe-guard: as long as the
group is not closed, article deletions are reversal (either by using a
different IMAP client, or by exiting Gnus without updating the summary
buffer).

The 'never setting is not (yet) very useful because Gnus does not
distinguish between deleted articles and regular articles in the summary
buffer. However, this will be addressed by a separate patch.


Changes since v1:

 * Made first line of docstring a complete sentence.


Thanks for considering,
-Nikolaus

-- 
GPG encrypted emails preferred. Key id: 0xD113FCAC3C4E599F
Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

             »Time flies like an arrow, fruit flies like a Banana.«

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: nnimap_expunge_v2.diff --]
[-- Type: text/x-diff, Size: 5006 bytes --]

diff --git a/nnimap.el b/nnimap.el
--- a/nnimap.el
+++ b/nnimap.el
@@ -103,10 +103,21 @@
 Possible choices are nil (use default methods), `anonymous',
 `login', `plain' and `cram-md5'.")
 
-(defvoo nnimap-expunge t
-  "If non-nil, expunge articles after deleting them.
-This is always done if the server supports UID EXPUNGE, but it's
-not done by default on servers that doesn't support that command.")
+(defvoo nnimap-expunge 'on-exit
+  "When to expunge deleted messages.
+If 'never, deleted articles are marked with the IMAP \\Delete
+flag but not automatically expunged. If 'immediately, deleted
+articles are immediately expunged (this requires the server to
+support the UID EXPUNGE command). If 'on-exit, deleted articles
+are flagged, and all flagged articles are expunged when the
+group is closed.
+
+For backwards compatibility, this variable may also be set to t
+or nil. If the server supports UID EXPUNGE, both t and nil are
+equivalent to 'immediately. If the server does not support UID
+EXPUNGE nil is equivalent to 'never, while t will immediately
+expunge ALL articles that are currently flagged as deleted
+(i.e., potentially not only the article that was just deleted).")
 
 (defvoo nnimap-streaming t
   "If non-nil, try to use streaming commands with IMAP servers.
@@ -865,7 +876,11 @@
     (nreverse articles)))
 
 (deffoo nnimap-close-group (group &optional server)
-  t)
+  (if (eq nnimap-expunge 'on-exit)
+      (with-current-buffer (nnimap-buffer)
+        (nnimap-wait-for-response
+         (nnimap-send-command "EXPUNGE")))
+    t))
 
 (deffoo nnimap-request-move-article (article group server accept-form
 					     &optional last internal-move-group)
@@ -910,8 +925,7 @@
     articles)
    ((and force
 	 (eq nnmail-expiry-target 'delete))
-    (unless (nnimap-delete-article (gnus-compress-sequence articles))
-      (nnheader-message 7 "Article marked for deletion, but not expunged."))
+    (nnimap-delete-article (gnus-compress-sequence articles))
     nil)
    (t
     (let ((deletable-articles
@@ -1027,21 +1041,36 @@
             (when (and limit number-of-article)
               (nnimap-find-article-by-message-id group server message-id))))))))
 
-(defun nnimap-delete-article (articles)
+(defun nnimap-delete-article (articles &optional sync)
+  "Delete ARTICLES.
+
+If sync is non-nil, wait for server response."
   (with-current-buffer (nnimap-buffer)
     (nnimap-command "UID STORE %s +FLAGS.SILENT (\\Deleted)"
 		    (nnimap-article-ranges articles))
+    (let ((sequence
     (cond
-     ((nnimap-capability "UIDPLUS")
+            ((eq nnimap-expunge 'immediately)
+             (if (nnimap-capability "UIDPLUS")
       (nnimap-command "UID EXPUNGE %s"
 		      (nnimap-article-ranges articles))
-      t)
+               (nnheader-message 3 (concat "nnimap-expunge set to 'immediately, but "
+                                           "server doesn't support UIDPLUS"))))
+
+            ((memq nnimap-expunge '(on-exit never)) nil)
+
+            ((nnimap-capability "UIDPLUS")
+             (nnimap-command "UID EXPUNGE %s"
+                             (nnimap-article-ranges articles)))
+
      (nnimap-expunge
-      (nnimap-command "EXPUNGE")
-      t)
-     (t (gnus-message 7 (concat "nnimap: nnimap-expunge is not set and the "
-                                "server doesn't support UIDPLUS, so we won't "
-                                "delete this article now"))))))
+             (nnimap-command "EXPUNGE"))
+
+            (t
+             (nnheader-message 7 "Article marked for deletion, but not expunged.")))))
+
+      (if (and sync sequence)
+          (nnimap-wait-for-response sequence)))))
 
 (deffoo nnimap-request-scan (&optional group server)
   (when group
@@ -2043,27 +2072,9 @@
 	      (nnimap-wait-for-response (caar sequences))
 	      ;; And then mark the successful copy actions as deleted,
 	      ;; and possibly expunge them.
-	      (nnimap-mark-and-expunge-incoming
-	       (nnimap-parse-copied-articles sequences)))
-            (nnimap-mark-and-expunge-incoming junk-articles)))))))
-
-(defun nnimap-mark-and-expunge-incoming (range)
-  (when range
-    (setq range (nnimap-article-ranges range))
-    (erase-buffer)
-    (let ((sequence
-	   (nnimap-send-command
-	    "UID STORE %s +FLAGS.SILENT (\\Deleted)" range)))
-      (cond
-       ;; If the server supports it, we now delete the message we have
-       ;; just copied over.
-       ((nnimap-capability "UIDPLUS")
-	(setq sequence (nnimap-send-command "UID EXPUNGE %s" range)))
-       ;; If it doesn't support UID EXPUNGE, then we only expunge if the
-       ;; user has configured it.
-       (nnimap-expunge
-	(setq sequence (nnimap-send-command "EXPUNGE"))))
-      (nnimap-wait-for-response sequence))))
+              (nnimap-delete-article
+               (nnimap-parse-copied-articles sequences) t))
+            (nnimap-delete-article junk-articles t)))))))
 
 (defun nnimap-parse-copied-articles (sequences)
   (let (sequence copied range)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-08-03 17:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-27  2:20 [PATCH] nnimap: enable additional expunge options Nikolaus Rath
2015-08-03  9:24 ` Eric Abrahamsen
2015-08-03 17:21   ` Nikolaus Rath
2015-07-03  2:10 Nikolaus Rath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).