unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
       [not found] <87si8qjhca.fsf@vostro.rath.org>
@ 2017-01-26 19:40 ` Lars Ingebrigtsen
  2017-09-05 15:18 ` Nikolaus Rath
  1 sibling, 0 replies; 31+ messages in thread
From: Lars Ingebrigtsen @ 2017-01-26 19:40 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: 21057, ding

Nikolaus Rath <Nikolaus@rath.org> writes:

> This is useful for servers where all personal mailboxes appear is
> subfolders of the user's INBOX. For example, before the patch one would
> have:
>
> nnimap+fm:INBOX
> nnimap+fm:INBOX.Sent Items
> nnimap+fm:INBOX.Drafts
> nnimap+fm:INBOX.Archive
> nnimap+fm:Shared.Bob.INBOX
>
> and afterwards:
>
> nnimap+fm:INBOX
> nnimap+fm:Sent Items
> nnimap+fm:Drafts
> nnimap+fm:Archive
> nnimap+fm:#Shared.Bob.INBOX

What happens if the user has both INBOX.foo and foo mailboxes?

Tiny code style nitpicks:

> +(defvoo nnimap-use-namespaces nil
> +  "Whether to use IMAP namespaces

Should have a "." at the end.

> +    (utf7-encode 

There's a space at the end of the line here, and several other places,
which there shouldn't be.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
       [not found] <87si8qjhca.fsf@vostro.rath.org>
  2017-01-26 19:40 ` bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces Lars Ingebrigtsen
@ 2017-09-05 15:18 ` Nikolaus Rath
  2017-09-05 15:26   ` Nikolaus Rath
  1 sibling, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2017-09-05 15:18 UTC (permalink / raw)
  To: 21057, Lars Ingebrigtsen

Hello,

Sorry for the delayed response!

> What happens if the user has both INBOX.foo and foo mailboxes?

The "foo" mailbox wouldn't be accessible. I don't think this is a
problem in practice, if the server uses namespaces then the user
wouldn't be able to create anything on that level of the hierarchy.

> Tiny code style nitpicks:
>
>> +(defvoo nnimap-use-namespaces nil
>> +  "Whether to use IMAP namespaces
>
> Should have a "." at the end.
>
>> +    (utf7-encode 
>
> There's a space at the end of the line here, and several other places,
> which there shouldn't be.

Will fix and rebase on top of current emacs master, thanks!

Best,
-Nikolaus
-- 
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-05 15:18 ` Nikolaus Rath
@ 2017-09-05 15:26   ` Nikolaus Rath
  2017-09-05 15:36     ` Andreas Schwab
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2017-09-05 15:26 UTC (permalink / raw)
  To: 21057; +Cc: Lars Ingebrigtsen

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

Hi,

Attached is the updated patch. Should apply cleanly on Emacs master.

Best,
Nikolaus
-- 
GPG 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: 0001-nnimap.el-factor-out-nnimap-group-to-imap.patch --]
[-- Type: text/x-diff, Size: 6827 bytes --]

From b21e4eb2e788e83cb5d82b9eac7f7e3ecd0de837 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Sun, 12 Jul 2015 11:10:28 -0700
Subject: [PATCH 1/2] nnimap.el: factor out nnimap-group-to-imap

* lisp/gnus/nnimap.el (nnimap-request-group-scan)
(nnimap-request-create-group, nnimap-request-delete-group)
(nnimap-request-rename-group, nnimap-request-move-article)
(nnimap-process-expiry-targets)
(nnimap-request-update-group-status)
(nnimap-request-accept-article, nnimap-request-list)
(nnimap-retrieve-group-data-early, nnimap-change-group)
(nnimap-split-incoming-mail): use nnimap-group-to-imap.
(nnimap-group-to-imap): new function to map Gnus group names to
IMAP folder names.
---
 lisp/gnus/nnimap.el | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 2943c..17542 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -166,6 +166,10 @@ textual parts.")
 
 (defvar nnimap-inhibit-logging nil)
 
+(defun nnimap-group-to-imap (group)
+  "Convert Gnus group name to IMAP mailbox name"
+  (utf7-encode group t))
+
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
@@ -834,7 +838,7 @@ textual parts.")
       (with-current-buffer (nnimap-buffer)
 	(erase-buffer)
 	(let ((group-sequence
-	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
+	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
 	      (flag-sequence
 	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
 	  (setf (nnimap-group nnimap-object) group)
@@ -867,13 +871,13 @@ textual parts.")
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-delete-group (group &optional _force server)
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -881,7 +885,7 @@ textual parts.")
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
-			   (utf7-encode group t) (utf7-encode new-name t))))))
+			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
 
 (defun nnimap-unselect-group ()
   ;; Make sure we don't have this group open read/write by asking
@@ -941,7 +945,7 @@ textual parts.")
 				"UID COPY %d %S"))
 		     (result (nnimap-command
 			      command article
-			      (utf7-encode internal-move-group t))))
+                              (nnimap-group-to-imap internal-move-group))))
                 (when (and (car result) (not can-move))
                   (nnimap-delete-article article))
                 (cons internal-move-group
@@ -1008,7 +1012,7 @@ textual parts.")
                     "UID MOVE %s %S"
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
-                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
+                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
                (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
       t)
      (t
@@ -1133,7 +1137,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		      (unsubscribe "UNSUBSCRIBE")))))
       (when command
 	(with-current-buffer (nnimap-buffer)
-	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
+	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -1188,7 +1192,7 @@ If LIMIT, first try to limit the search to the N last articles."
 	    (nnimap-unselect-group))
 	  (erase-buffer)
 	  (setq sequence (nnimap-send-command
-			  "APPEND %S {%d}" (utf7-encode group t)
+			  "APPEND %S {%d}" (nnimap-group-to-imap group)
 			  (length message)))
 	  (unless nnimap-streaming
 	    (nnimap-wait-for-connection "^[+]"))
@@ -1316,7 +1320,7 @@ If LIMIT, first try to limit the search to the N last articles."
 	    (dolist (group groups)
 	      (setf (nnimap-examined nnimap-object) group)
 	      (push (list (nnimap-send-command "EXAMINE %S"
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  group)
 		    sequences))
 	    (nnimap-wait-for-response (caar sequences))
@@ -1388,7 +1392,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		   unexist)
 	      (push
 	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
-					  (utf7-encode group t)
+					  (nnimap-group-to-imap group)
 					  (nnimap-quirk "QRESYNC")
 					  uidvalidity modseq)
 		     'qresync
@@ -1410,7 +1414,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		(incf (nnimap-initial-resync nnimap-object))
 		(setq start 1))
 	      (push (list (nnimap-send-command "%s %S" command
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
 			  start group command)
 		    sequences))))
@@ -1842,7 +1846,7 @@ Return the server's response to the SELECT or EXAMINE command."
                                       (if read-only
                                           "EXAMINE"
                                         "SELECT")
-                                      (utf7-encode group t))))
+                                      (nnimap-group-to-imap group))))
           (when (car result)
             (setf (nnimap-group nnimap-object) group
                   (nnimap-select-result nnimap-object) result)
@@ -2098,7 +2102,7 @@ Return the server's response to the SELECT or EXAMINE command."
 	    (dolist (spec specs)
 	      (when (and (not (member (car spec) groups))
 			 (not (eq (car spec) 'junk)))
-		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
+		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
 	    ;; Then copy over all the messages.
 	    (erase-buffer)
 	    (dolist (spec specs)
@@ -2114,7 +2118,7 @@ Return the server's response to the SELECT or EXAMINE command."
 				     "UID MOVE %s %S"
 				   "UID COPY %s %S")
 				 (nnimap-article-ranges ranges)
-				 (utf7-encode group t))
+				(nnimap-group-to-imap group))
 				ranges)
 			  sequences)))))
 	    ;; Wait for the last COPY response...
-- 
2.11.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-nnimap.el-Add-support-for-IMAP-namespaces.patch --]
[-- Type: text/x-diff, Size: 5945 bytes --]

From a1a268af15472905d7fa81347f0d65abc5702b86 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Tue, 14 Jul 2015 19:03:09 -0700
Subject: [PATCH 2/2] nnimap.el: Add support for IMAP namespaces.

* lisp/gnus/nnimap.el (nnimap-use-namespaces): introduced new server variable.
(nnimap-group-to-imap, nnimap-get-groups): transform IMAP group names
to Gnus group name by stripping / prefixing personal namespace prefix.
(nnimap-open-connection-1): ask server for namespaces and store them.
---
 lisp/gnus/nnimap.el | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 53 insertions(+), 13 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 17542..fb382 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -55,6 +55,13 @@
 If nnimap-stream is `ssl', this will default to `imaps'.  If not,
 it will default to `imap'.")
 
+(defvoo nnimap-use-namespaces nil
+  "Whether to use IMAP namespaces.
+If in Gnus your folder names in all start with (e.g.) `INBOX',
+you probably want to set this to t. The effects of this are
+purely cosmetical, but changing this variable will affect the
+names of your nnimap groups. ")
+
 (defvoo nnimap-stream 'undecided
   "How nnimap talks to the IMAP server.
 The value should be either `undecided', `ssl' or `tls',
@@ -116,6 +123,8 @@ some servers.")
 (defun nnimap-encode-gnus-group (group)
   (encode-coding-string group 'utf-8))
 
+(setq nnimap-namespaces nil)
+
 (defvoo nnimap-fetch-partial-articles nil
   "If non-nil, Gnus will fetch partial articles.
 If t, Gnus will fetch only the first part.  If a string, it
@@ -168,7 +177,17 @@ textual parts.")
 
 (defun nnimap-group-to-imap (group)
   "Convert Gnus group name to IMAP mailbox name"
-  (utf7-encode group t))
+  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (inbox (substring prefix 0 -1)))
+    (utf7-encode
+     (cond ((or (not prefix)
+                (string-equal group inbox))
+            group)
+           ((string-prefix-p "#" group)
+            (substring group 1))
+           (t
+            (concat prefix group))) t)))
 
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
@@ -445,7 +464,8 @@ textual parts.")
 	     (props (cdr stream-list))
 	     (greeting (plist-get props :greeting))
 	     (capabilities (plist-get props :capabilities))
-	     (stream-type (plist-get props :type)))
+	     (stream-type (plist-get props :type))
+             (server (nnoo-current-server 'nnimap)))
 	(when (and stream (not (memq (process-status stream) '(open run))))
 	  (setq stream nil))
 
@@ -478,9 +498,7 @@ textual parts.")
                                ;; the virtual server name and the address
                                (nnimap-credentials
 				(gnus-delete-duplicates
-				 (list
-                                  (nnoo-current-server 'nnimap)
-				  nnimap-address))
+				 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
 		  (setq nnimap-object nil)
@@ -499,7 +517,21 @@ textual parts.")
 		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
 			(when (string= "CAPABILITY" (upcase (car response)))
 			  (setf (nnimap-capabilities nnimap-object)
-				(mapcar #'upcase (cdr response))))))
+				(mapcar #'upcase (cdr response)))))
+                      (when (and nnimap-use-namespaces
+                                 (nnimap-capability "NAMESPACE"))
+                        (erase-buffer)
+                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
+                        (let ((response (nnimap-last-response-string)))
+                          (when (string-match
+                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
+                                 response)
+                            (let ((namespace (cons (match-string 1 response)
+                                                   (match-string 2 response)))
+                                  (entry (assoc server nnimap-namespaces)))
+                              (if entry
+                                  (setcdr entry namespace)
+                                (push (cons server namespace) nnimap-namespaces)))))))
 		  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
@@ -1272,8 +1304,12 @@ If LIMIT, first try to limit the search to the N last articles."
 
 (defun nnimap-get-groups ()
   (erase-buffer)
-  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-	groups)
+  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
+         (prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (prefix-len (length prefix))
+         (inbox (substring prefix 0 -1))
+         groups)
     (nnimap-wait-for-response sequence)
     (subst-char-in-region (point-min) (point-max)
 			  ?\\ ?% t)
@@ -1290,11 +1326,15 @@ If LIMIT, first try to limit the search to the N last articles."
 			   (skip-chars-backward " \r\"")
 			   (point)))))
 	(unless (member '%NoSelect flags)
-	  (push (utf7-decode (if (stringp group)
-				 group
-			       (format "%s" group))
-                             t)
-		groups))))
+          (let* ((group (utf7-decode (if (stringp group) group
+                                       (format "%s" group)) t))
+                 (group (cond ((equal inbox group)
+                               group)
+                              ((string-prefix-p prefix group)
+                               (substring group prefix-len))
+                              (t
+                               (concat "#" group)))))
+            (push group groups)))))
     (nreverse groups)))
 
 (defun nnimap-get-responses (sequences)
-- 
2.11.0


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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-05 15:26   ` Nikolaus Rath
@ 2017-09-05 15:36     ` Andreas Schwab
  2017-09-07 16:01       ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Andreas Schwab @ 2017-09-05 15:36 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Lars Ingebrigtsen, 21057

On Sep 05 2017, Nikolaus Rath <Nikolaus@rath.org> wrote:

> diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
> index 2943c..17542 100644
> --- a/lisp/gnus/nnimap.el
> +++ b/lisp/gnus/nnimap.el
> @@ -166,6 +166,10 @@ textual parts.")
>  
>  (defvar nnimap-inhibit-logging nil)
>  
> +(defun nnimap-group-to-imap (group)
> +  "Convert Gnus group name to IMAP mailbox name"

Missing period.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-05 15:36     ` Andreas Schwab
@ 2017-09-07 16:01       ` Nikolaus Rath
  2017-09-13 17:30         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2017-09-07 16:01 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Lars Ingebrigtsen, 21057

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

On Tue, Sep 5, 2017, at 17:36, Andreas Schwab wrote:
> On Sep 05 2017, Nikolaus Rath <Nikolaus@rath.org> wrote:
> 
> > diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
> > index 2943c..17542 100644
> > --- a/lisp/gnus/nnimap.el
> > +++ b/lisp/gnus/nnimap.el
> > @@ -166,6 +166,10 @@ textual parts.")
> >  
> >  (defvar nnimap-inhibit-logging nil)
> >  
> > +(defun nnimap-group-to-imap (group)
> > +  "Convert Gnus group name to IMAP mailbox name"
> 
> Missing period.

Thanks for the review, revised patches attached.

Best,
-Niko

--
GPG 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: 0001-nnimap.el-factor-out-nnimap-group-to-imap.patch --]
[-- Type: text/x-patch; name="0001-nnimap.el-factor-out-nnimap-group-to-imap.patch", Size: 6829 bytes --]

From a358106b91a1da656d23d2da5aee07fcf8947680 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Sun, 12 Jul 2015 11:10:28 -0700
Subject: [PATCH 1/2] nnimap.el: factor out nnimap-group-to-imap

* lisp/gnus/nnimap.el (nnimap-request-group-scan)
(nnimap-request-create-group, nnimap-request-delete-group)
(nnimap-request-rename-group, nnimap-request-move-article)
(nnimap-process-expiry-targets)
(nnimap-request-update-group-status)
(nnimap-request-accept-article, nnimap-request-list)
(nnimap-retrieve-group-data-early, nnimap-change-group)
(nnimap-split-incoming-mail): use nnimap-group-to-imap.
(nnimap-group-to-imap): new function to map Gnus group names to
IMAP folder names.
---
 lisp/gnus/nnimap.el | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 2943c..a942d8 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -166,6 +166,10 @@ textual parts.")
 
 (defvar nnimap-inhibit-logging nil)
 
+(defun nnimap-group-to-imap (group)
+  "Convert Gnus group name to IMAP mailbox name."
+  (utf7-encode group t))
+
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
@@ -834,7 +838,7 @@ textual parts.")
       (with-current-buffer (nnimap-buffer)
 	(erase-buffer)
 	(let ((group-sequence
-	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
+	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
 	      (flag-sequence
 	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
 	  (setf (nnimap-group nnimap-object) group)
@@ -867,13 +871,13 @@ textual parts.")
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-delete-group (group &optional _force server)
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -881,7 +885,7 @@ textual parts.")
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
-			   (utf7-encode group t) (utf7-encode new-name t))))))
+			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
 
 (defun nnimap-unselect-group ()
   ;; Make sure we don't have this group open read/write by asking
@@ -941,7 +945,7 @@ textual parts.")
 				"UID COPY %d %S"))
 		     (result (nnimap-command
 			      command article
-			      (utf7-encode internal-move-group t))))
+                              (nnimap-group-to-imap internal-move-group))))
                 (when (and (car result) (not can-move))
                   (nnimap-delete-article article))
                 (cons internal-move-group
@@ -1008,7 +1012,7 @@ textual parts.")
                     "UID MOVE %s %S"
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
-                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
+                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
                (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
       t)
      (t
@@ -1133,7 +1137,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		      (unsubscribe "UNSUBSCRIBE")))))
       (when command
 	(with-current-buffer (nnimap-buffer)
-	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
+	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -1188,7 +1192,7 @@ If LIMIT, first try to limit the search to the N last articles."
 	    (nnimap-unselect-group))
 	  (erase-buffer)
 	  (setq sequence (nnimap-send-command
-			  "APPEND %S {%d}" (utf7-encode group t)
+			  "APPEND %S {%d}" (nnimap-group-to-imap group)
 			  (length message)))
 	  (unless nnimap-streaming
 	    (nnimap-wait-for-connection "^[+]"))
@@ -1316,7 +1320,7 @@ If LIMIT, first try to limit the search to the N last articles."
 	    (dolist (group groups)
 	      (setf (nnimap-examined nnimap-object) group)
 	      (push (list (nnimap-send-command "EXAMINE %S"
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  group)
 		    sequences))
 	    (nnimap-wait-for-response (caar sequences))
@@ -1388,7 +1392,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		   unexist)
 	      (push
 	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
-					  (utf7-encode group t)
+					  (nnimap-group-to-imap group)
 					  (nnimap-quirk "QRESYNC")
 					  uidvalidity modseq)
 		     'qresync
@@ -1410,7 +1414,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		(incf (nnimap-initial-resync nnimap-object))
 		(setq start 1))
 	      (push (list (nnimap-send-command "%s %S" command
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
 			  start group command)
 		    sequences))))
@@ -1842,7 +1846,7 @@ Return the server's response to the SELECT or EXAMINE command."
                                       (if read-only
                                           "EXAMINE"
                                         "SELECT")
-                                      (utf7-encode group t))))
+                                      (nnimap-group-to-imap group))))
           (when (car result)
             (setf (nnimap-group nnimap-object) group
                   (nnimap-select-result nnimap-object) result)
@@ -2098,7 +2102,7 @@ Return the server's response to the SELECT or EXAMINE command."
 	    (dolist (spec specs)
 	      (when (and (not (member (car spec) groups))
 			 (not (eq (car spec) 'junk)))
-		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
+		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
 	    ;; Then copy over all the messages.
 	    (erase-buffer)
 	    (dolist (spec specs)
@@ -2114,7 +2118,7 @@ Return the server's response to the SELECT or EXAMINE command."
 				     "UID MOVE %s %S"
 				   "UID COPY %s %S")
 				 (nnimap-article-ranges ranges)
-				 (utf7-encode group t))
+				(nnimap-group-to-imap group))
 				ranges)
 			  sequences)))))
 	    ;; Wait for the last COPY response...
-- 
2.11.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-nnimap.el-Add-support-for-IMAP-namespaces.patch --]
[-- Type: text/x-patch; name="0002-nnimap.el-Add-support-for-IMAP-namespaces.patch", Size: 5948 bytes --]

From 7c3cec13b87404a985dc8f821f8ef6af3d072073 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Tue, 14 Jul 2015 19:03:09 -0700
Subject: [PATCH 2/2] nnimap.el: Add support for IMAP namespaces.

* lisp/gnus/nnimap.el (nnimap-use-namespaces): introduced new server variable.
(nnimap-group-to-imap, nnimap-get-groups): transform IMAP group names
to Gnus group name by stripping / prefixing personal namespace prefix.
(nnimap-open-connection-1): ask server for namespaces and store them.
---
 lisp/gnus/nnimap.el | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 53 insertions(+), 13 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index a942d8..3ede4d 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -55,6 +55,13 @@
 If nnimap-stream is `ssl', this will default to `imaps'.  If not,
 it will default to `imap'.")
 
+(defvoo nnimap-use-namespaces nil
+  "Whether to use IMAP namespaces.
+If in Gnus your folder names in all start with (e.g.) `INBOX',
+you probably want to set this to t. The effects of this are
+purely cosmetical, but changing this variable will affect the
+names of your nnimap groups. ")
+
 (defvoo nnimap-stream 'undecided
   "How nnimap talks to the IMAP server.
 The value should be either `undecided', `ssl' or `tls',
@@ -116,6 +123,8 @@ some servers.")
 (defun nnimap-encode-gnus-group (group)
   (encode-coding-string group 'utf-8))
 
+(setq nnimap-namespaces nil)
+
 (defvoo nnimap-fetch-partial-articles nil
   "If non-nil, Gnus will fetch partial articles.
 If t, Gnus will fetch only the first part.  If a string, it
@@ -168,7 +177,17 @@ textual parts.")
 
 (defun nnimap-group-to-imap (group)
   "Convert Gnus group name to IMAP mailbox name."
-  (utf7-encode group t))
+  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (inbox (substring prefix 0 -1)))
+    (utf7-encode
+     (cond ((or (not prefix)
+                (string-equal group inbox))
+            group)
+           ((string-prefix-p "#" group)
+            (substring group 1))
+           (t
+            (concat prefix group))) t)))
 
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
@@ -445,7 +464,8 @@ textual parts.")
 	     (props (cdr stream-list))
 	     (greeting (plist-get props :greeting))
 	     (capabilities (plist-get props :capabilities))
-	     (stream-type (plist-get props :type)))
+	     (stream-type (plist-get props :type))
+             (server (nnoo-current-server 'nnimap)))
 	(when (and stream (not (memq (process-status stream) '(open run))))
 	  (setq stream nil))
 
@@ -478,9 +498,7 @@ textual parts.")
                                ;; the virtual server name and the address
                                (nnimap-credentials
 				(gnus-delete-duplicates
-				 (list
-                                  (nnoo-current-server 'nnimap)
-				  nnimap-address))
+				 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
 		  (setq nnimap-object nil)
@@ -499,7 +517,21 @@ textual parts.")
 		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
 			(when (string= "CAPABILITY" (upcase (car response)))
 			  (setf (nnimap-capabilities nnimap-object)
-				(mapcar #'upcase (cdr response))))))
+				(mapcar #'upcase (cdr response)))))
+                      (when (and nnimap-use-namespaces
+                                 (nnimap-capability "NAMESPACE"))
+                        (erase-buffer)
+                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
+                        (let ((response (nnimap-last-response-string)))
+                          (when (string-match
+                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
+                                 response)
+                            (let ((namespace (cons (match-string 1 response)
+                                                   (match-string 2 response)))
+                                  (entry (assoc server nnimap-namespaces)))
+                              (if entry
+                                  (setcdr entry namespace)
+                                (push (cons server namespace) nnimap-namespaces)))))))
 		  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
@@ -1272,8 +1304,12 @@ If LIMIT, first try to limit the search to the N last articles."
 
 (defun nnimap-get-groups ()
   (erase-buffer)
-  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-	groups)
+  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
+         (prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (prefix-len (length prefix))
+         (inbox (substring prefix 0 -1))
+         groups)
     (nnimap-wait-for-response sequence)
     (subst-char-in-region (point-min) (point-max)
 			  ?\\ ?% t)
@@ -1290,11 +1326,15 @@ If LIMIT, first try to limit the search to the N last articles."
 			   (skip-chars-backward " \r\"")
 			   (point)))))
 	(unless (member '%NoSelect flags)
-	  (push (utf7-decode (if (stringp group)
-				 group
-			       (format "%s" group))
-                             t)
-		groups))))
+          (let* ((group (utf7-decode (if (stringp group) group
+                                       (format "%s" group)) t))
+                 (group (cond ((equal inbox group)
+                               group)
+                              ((string-prefix-p prefix group)
+                               (substring group prefix-len))
+                              (t
+                               (concat "#" group)))))
+            (push group groups)))))
     (nreverse groups)))
 
 (defun nnimap-get-responses (sequences)
-- 
2.11.0


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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-07 16:01       ` Nikolaus Rath
@ 2017-09-13 17:30         ` Lars Ingebrigtsen
  2017-09-17  8:16           ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Lars Ingebrigtsen @ 2017-09-13 17:30 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Andreas Schwab, 21057

Nikolaus Rath <nikolaus@rath.org> writes:

> Thanks for the review, revised patches attached.

Looks good to me.  It needs to be documented in the manual, though, and
perhaps a NEWS entry...

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-13 17:30         ` Lars Ingebrigtsen
@ 2017-09-17  8:16           ` Nikolaus Rath
  2017-12-06 14:25             ` Nikolaus Rath
  2017-12-27 21:10             ` Lars Ingebrigtsen
  0 siblings, 2 replies; 31+ messages in thread
From: Nikolaus Rath @ 2017-09-17  8:16 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Andreas Schwab, 21057

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

On Sep 13 2017, Lars Ingebrigtsen <larsi@gnus.org> wrote:
> Nikolaus Rath <nikolaus@rath.org> writes:
>
>> Thanks for the review, revised patches attached.
>
> Looks good to me.  It needs to be documented in the manual, though, and
> perhaps a NEWS entry...

Updated patch is attached.

Best,
-Nikolaus

-- 
GPG 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: 0001-nnimap.el-factor-out-nnimap-group-to-imap.patch --]
[-- Type: text/x-diff, Size: 6589 bytes --]

From 2c1c2ccaeb0c19649d125b64fe3f917c7a3fbb76 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Sun, 12 Jul 2015 11:10:28 -0700
Subject: [PATCH 1/2] nnimap.el: factor out nnimap-group-to-imap

* lisp/gnus/nnimap.el (nnimap-request-group-scan)
(nnimap-request-create-group, nnimap-request-delete-group)
(nnimap-request-rename-group, nnimap-request-move-article)
(nnimap-process-expiry-targets)
(nnimap-request-update-group-status)
(nnimap-request-accept-article, nnimap-request-list)
(nnimap-retrieve-group-data-early, nnimap-change-group)
(nnimap-split-incoming-mail): use nnimap-group-to-imap.
(nnimap-group-to-imap): new function to map Gnus group names to
IMAP folder names.
---
 lisp/gnus/nnimap.el | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 6e2a7..a646f4 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -166,6 +166,10 @@ nnimap-quirks
 
 (defvar nnimap-inhibit-logging nil)
 
+(defun nnimap-group-to-imap (group)
+  "Convert Gnus group name to IMAP mailbox name."
+  (utf7-encode group t))
+
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
@@ -834,7 +838,7 @@ nnimap-request-group-scan
       (with-current-buffer (nnimap-buffer)
 	(erase-buffer)
 	(let ((group-sequence
-	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
+	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
 	      (flag-sequence
 	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
 	  (setf (nnimap-group nnimap-object) group)
@@ -867,13 +871,13 @@ nnimap-request-create-group
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-delete-group (group &optional _force server)
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -881,7 +885,7 @@ nnimap-request-rename-group
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
-			   (utf7-encode group t) (utf7-encode new-name t))))))
+			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
 
 (defun nnimap-unselect-group ()
   ;; Make sure we don't have this group open read/write by asking
@@ -941,7 +945,7 @@ nnimap-request-move-article
 				"UID COPY %d %S"))
 		     (result (nnimap-command
 			      command article
-			      (utf7-encode internal-move-group t))))
+                              (nnimap-group-to-imap internal-move-group))))
                 (when (and (car result) (not can-move))
                   (nnimap-delete-article article))
                 (cons internal-move-group
@@ -1008,7 +1012,7 @@ nnimap-process-expiry-targets
                     "UID MOVE %s %S"
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
-                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
+                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
                (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
       t)
      (t
@@ -1133,7 +1137,7 @@ nnimap-request-update-group-status
 		      (unsubscribe "UNSUBSCRIBE")))))
       (when command
 	(with-current-buffer (nnimap-buffer)
-	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
+	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -1188,7 +1192,7 @@ nnimap-request-accept-article
 	    (nnimap-unselect-group))
 	  (erase-buffer)
 	  (setq sequence (nnimap-send-command
-			  "APPEND %S {%d}" (utf7-encode group t)
+			  "APPEND %S {%d}" (nnimap-group-to-imap group)
 			  (length message)))
 	  (unless nnimap-streaming
 	    (nnimap-wait-for-connection "^[+]"))
@@ -1316,7 +1320,7 @@ nnimap-request-list
 	    (dolist (group groups)
 	      (setf (nnimap-examined nnimap-object) group)
 	      (push (list (nnimap-send-command "EXAMINE %S"
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  group)
 		    sequences))
 	    (nnimap-wait-for-response (caar sequences))
@@ -1388,7 +1392,7 @@ nnimap-retrieve-group-data-early
 		   unexist)
 	      (push
 	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
-					  (utf7-encode group t)
+					  (nnimap-group-to-imap group)
 					  (nnimap-quirk "QRESYNC")
 					  uidvalidity modseq)
 		     'qresync
@@ -1410,7 +1414,7 @@ nnimap-retrieve-group-data-early
 		(incf (nnimap-initial-resync nnimap-object))
 		(setq start 1))
 	      (push (list (nnimap-send-command "%s %S" command
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
 			  start group command)
 		    sequences))))
@@ -1842,7 +1846,7 @@ nnimap-change-group
                                       (if read-only
                                           "EXAMINE"
                                         "SELECT")
-                                      (utf7-encode group t))))
+                                      (nnimap-group-to-imap group))))
           (when (car result)
             (setf (nnimap-group nnimap-object) group
                   (nnimap-select-result nnimap-object) result)
@@ -2098,7 +2102,7 @@ nnimap-split-incoming-mail
 	    (dolist (spec specs)
 	      (when (and (not (member (car spec) groups))
 			 (not (eq (car spec) 'junk)))
-		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
+		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
 	    ;; Then copy over all the messages.
 	    (erase-buffer)
 	    (dolist (spec specs)
@@ -2114,7 +2118,7 @@ nnimap-split-incoming-mail
 				     "UID MOVE %s %S"
 				   "UID COPY %s %S")
 				 (nnimap-article-ranges ranges)
-				 (utf7-encode group t))
+				(nnimap-group-to-imap group))
 				ranges)
 			  sequences)))))
 	    ;; Wait for the last COPY response...
-- 
2.11.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-nnimap.el-Add-support-for-IMAP-namespaces.patch --]
[-- Type: text/x-diff, Size: 6955 bytes --]

From f5079a11c20944027465ea21291a8fc9e7ad3be1 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Tue, 14 Jul 2015 19:03:09 -0700
Subject: [PATCH 2/2] nnimap.el: Add support for IMAP namespaces.

* lisp/gnus/nnimap.el (nnimap-use-namespaces): introduced new server variable.
(nnimap-group-to-imap, nnimap-get-groups): transform IMAP group names
to Gnus group name by stripping / prefixing personal namespace prefix.
(nnimap-open-connection-1): ask server for namespaces and store them.
---
 doc/misc/gnus.texi  |  6 +++++
 etc/NEWS            |  5 ++++
 lisp/gnus/nnimap.el | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 88e121..4b33e 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -14301,6 +14301,12 @@ Customizing the IMAP Connection
 If non-@code{nil}, record all @acronym{IMAP} commands in the
 @samp{"*imap log*"} buffer.
 
+@item nnimap-use-namespaces
+If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
+names. If your IMAP mailboxes are called something like @samp{INBOX}
+and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
+be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
+
 @end table
 
 
diff --git a/etc/NEWS b/etc/NEWS
index 371cd..1f905d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -37,6 +37,11 @@ When you add a new item, use the appropriate mark if you are sure it applies,
 \f
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
+** Gnus
+
++++
+*** The nnimap backend now has support for IMAP namespaces.
+
 \f
 * New Modes and Packages in Emacs 27.1
 
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index a646f4..7ad54a 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -55,6 +55,13 @@ nnimap-server-port
 If nnimap-stream is `ssl', this will default to `imaps'.  If not,
 it will default to `imap'.")
 
+(defvoo nnimap-use-namespaces nil
+  "Whether to use IMAP namespaces.
+If in Gnus your folder names in all start with (e.g.) `INBOX',
+you probably want to set this to t. The effects of this are
+purely cosmetical, but changing this variable will affect the
+names of your nnimap groups. ")
+
 (defvoo nnimap-stream 'undecided
   "How nnimap talks to the IMAP server.
 The value should be either `undecided', `ssl' or `tls',
@@ -116,6 +123,8 @@ nnimap-decode-gnus-group
 (defun nnimap-encode-gnus-group (group)
   (encode-coding-string group 'utf-8))
 
+(setq nnimap-namespaces nil)
+
 (defvoo nnimap-fetch-partial-articles nil
   "If non-nil, Gnus will fetch partial articles.
 If t, Gnus will fetch only the first part.  If a string, it
@@ -168,7 +177,17 @@ nnimap-inhibit-logging
 
 (defun nnimap-group-to-imap (group)
   "Convert Gnus group name to IMAP mailbox name."
-  (utf7-encode group t))
+  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (inbox (substring prefix 0 -1)))
+    (utf7-encode
+     (cond ((or (not prefix)
+                (string-equal group inbox))
+            group)
+           ((string-prefix-p "#" group)
+            (substring group 1))
+           (t
+            (concat prefix group))) t)))
 
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
@@ -445,7 +464,8 @@ nnimap-open-connection-1
 	     (props (cdr stream-list))
 	     (greeting (plist-get props :greeting))
 	     (capabilities (plist-get props :capabilities))
-	     (stream-type (plist-get props :type)))
+	     (stream-type (plist-get props :type))
+             (server (nnoo-current-server 'nnimap)))
 	(when (and stream (not (memq (process-status stream) '(open run))))
 	  (setq stream nil))
 
@@ -478,9 +498,7 @@ nnimap-open-connection-1
                                ;; the virtual server name and the address
                                (nnimap-credentials
 				(gnus-delete-duplicates
-				 (list
-                                  (nnoo-current-server 'nnimap)
-				  nnimap-address))
+				 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
 		  (setq nnimap-object nil)
@@ -499,7 +517,21 @@ nnimap-open-connection-1
 		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
 			(when (string= "CAPABILITY" (upcase (car response)))
 			  (setf (nnimap-capabilities nnimap-object)
-				(mapcar #'upcase (cdr response))))))
+				(mapcar #'upcase (cdr response)))))
+                      (when (and nnimap-use-namespaces
+                                 (nnimap-capability "NAMESPACE"))
+                        (erase-buffer)
+                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
+                        (let ((response (nnimap-last-response-string)))
+                          (when (string-match
+                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
+                                 response)
+                            (let ((namespace (cons (match-string 1 response)
+                                                   (match-string 2 response)))
+                                  (entry (assoc server nnimap-namespaces)))
+                              (if entry
+                                  (setcdr entry namespace)
+                                (push (cons server namespace) nnimap-namespaces)))))))
 		  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
@@ -1272,8 +1304,12 @@ nnimap-add-cr
 
 (defun nnimap-get-groups ()
   (erase-buffer)
-  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-	groups)
+  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
+         (prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (prefix-len (length prefix))
+         (inbox (substring prefix 0 -1))
+         groups)
     (nnimap-wait-for-response sequence)
     (subst-char-in-region (point-min) (point-max)
 			  ?\\ ?% t)
@@ -1290,11 +1326,15 @@ nnimap-get-groups
 			   (skip-chars-backward " \r\"")
 			   (point)))))
 	(unless (member '%NoSelect flags)
-	  (push (utf7-decode (if (stringp group)
-				 group
-			       (format "%s" group))
-                             t)
-		groups))))
+          (let* ((group (utf7-decode (if (stringp group) group
+                                       (format "%s" group)) t))
+                 (group (cond ((equal inbox group)
+                               group)
+                              ((string-prefix-p prefix group)
+                               (substring group prefix-len))
+                              (t
+                               (concat "#" group)))))
+            (push group groups)))))
     (nreverse groups)))
 
 (defun nnimap-get-responses (sequences)
-- 
2.11.0


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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-17  8:16           ` Nikolaus Rath
@ 2017-12-06 14:25             ` Nikolaus Rath
  2017-12-27 21:10             ` Lars Ingebrigtsen
  1 sibling, 0 replies; 31+ messages in thread
From: Nikolaus Rath @ 2017-12-06 14:25 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Andreas Schwab, 21057

*ping*

It's been 80 days. Any chance someone could take a look? If I understand
correctly, the only thing that needs review are the added manual and
NEWS entries.

Best,
-Nikolaus

On Sep 17 2017, Nikolaus Rath <Nikolaus@rath.org> wrote:
> On Sep 13 2017, Lars Ingebrigtsen <larsi@gnus.org> wrote:
>> Nikolaus Rath <nikolaus@rath.org> writes:
>>
>>> Thanks for the review, revised patches attached.
>>
>> Looks good to me.  It needs to be documented in the manual, though, and
>> perhaps a NEWS entry...
>
> Updated patch is attached.
>
> Best,
> -Nikolaus
>
> -- 
> GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F
>
>              »Time flies like an arrow, fruit flies like a Banana.«
>
> From 2c1c2ccaeb0c19649d125b64fe3f917c7a3fbb76 Mon Sep 17 00:00:00 2001
> From: Nikolaus Rath <Nikolaus@rath.org>
> Date: Sun, 12 Jul 2015 11:10:28 -0700
> Subject: [PATCH 1/2] nnimap.el: factor out nnimap-group-to-imap
>
> * lisp/gnus/nnimap.el (nnimap-request-group-scan)
> (nnimap-request-create-group, nnimap-request-delete-group)
> (nnimap-request-rename-group, nnimap-request-move-article)
> (nnimap-process-expiry-targets)
> (nnimap-request-update-group-status)
> (nnimap-request-accept-article, nnimap-request-list)
> (nnimap-retrieve-group-data-early, nnimap-change-group)
> (nnimap-split-incoming-mail): use nnimap-group-to-imap.
> (nnimap-group-to-imap): new function to map Gnus group names to
> IMAP folder names.
> ---
>  lisp/gnus/nnimap.el | 32 ++++++++++++++++++--------------
>  1 file changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
> index 6e2a7..a646f4 100644
> --- a/lisp/gnus/nnimap.el
> +++ b/lisp/gnus/nnimap.el
> @@ -166,6 +166,10 @@ nnimap-quirks
>  
>  (defvar nnimap-inhibit-logging nil)
>  
> +(defun nnimap-group-to-imap (group)
> +  "Convert Gnus group name to IMAP mailbox name."
> +  (utf7-encode group t))
> +
>  (defun nnimap-buffer ()
>    (nnimap-find-process-buffer nntp-server-buffer))
>  
> @@ -834,7 +838,7 @@ nnimap-request-group-scan
>        (with-current-buffer (nnimap-buffer)
>  	(erase-buffer)
>  	(let ((group-sequence
> -	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
> +	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
>  	      (flag-sequence
>  	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
>  	  (setf (nnimap-group nnimap-object) group)
> @@ -867,13 +871,13 @@ nnimap-request-create-group
>    (setq group (nnimap-decode-gnus-group group))
>    (when (nnimap-change-group nil server)
>      (with-current-buffer (nnimap-buffer)
> -      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
> +      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
>  
>  (deffoo nnimap-request-delete-group (group &optional _force server)
>    (setq group (nnimap-decode-gnus-group group))
>    (when (nnimap-change-group nil server)
>      (with-current-buffer (nnimap-buffer)
> -      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
> +      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
>  
>  (deffoo nnimap-request-rename-group (group new-name &optional server)
>    (setq group (nnimap-decode-gnus-group group))
> @@ -881,7 +885,7 @@ nnimap-request-rename-group
>      (with-current-buffer (nnimap-buffer)
>        (nnimap-unselect-group)
>        (car (nnimap-command "RENAME %S %S"
> -			   (utf7-encode group t) (utf7-encode new-name t))))))
> +			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
>  
>  (defun nnimap-unselect-group ()
>    ;; Make sure we don't have this group open read/write by asking
> @@ -941,7 +945,7 @@ nnimap-request-move-article
>  				"UID COPY %d %S"))
>  		     (result (nnimap-command
>  			      command article
> -			      (utf7-encode internal-move-group t))))
> +                              (nnimap-group-to-imap internal-move-group))))
>                  (when (and (car result) (not can-move))
>                    (nnimap-delete-article article))
>                  (cons internal-move-group
> @@ -1008,7 +1012,7 @@ nnimap-process-expiry-targets
>                      "UID MOVE %s %S"
>                    "UID COPY %s %S")
>                  (nnimap-article-ranges (gnus-compress-sequence articles))
> -                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
> +                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
>                 (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
>        t)
>       (t
> @@ -1133,7 +1137,7 @@ nnimap-request-update-group-status
>  		      (unsubscribe "UNSUBSCRIBE")))))
>        (when command
>  	(with-current-buffer (nnimap-buffer)
> -	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
> +	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
>  
>  (deffoo nnimap-request-set-mark (group actions &optional server)
>    (setq group (nnimap-decode-gnus-group group))
> @@ -1188,7 +1192,7 @@ nnimap-request-accept-article
>  	    (nnimap-unselect-group))
>  	  (erase-buffer)
>  	  (setq sequence (nnimap-send-command
> -			  "APPEND %S {%d}" (utf7-encode group t)
> +			  "APPEND %S {%d}" (nnimap-group-to-imap group)
>  			  (length message)))
>  	  (unless nnimap-streaming
>  	    (nnimap-wait-for-connection "^[+]"))
> @@ -1316,7 +1320,7 @@ nnimap-request-list
>  	    (dolist (group groups)
>  	      (setf (nnimap-examined nnimap-object) group)
>  	      (push (list (nnimap-send-command "EXAMINE %S"
> -					       (utf7-encode group t))
> +					       (nnimap-group-to-imap group))
>  			  group)
>  		    sequences))
>  	    (nnimap-wait-for-response (caar sequences))
> @@ -1388,7 +1392,7 @@ nnimap-retrieve-group-data-early
>  		   unexist)
>  	      (push
>  	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
> -					  (utf7-encode group t)
> +					  (nnimap-group-to-imap group)
>  					  (nnimap-quirk "QRESYNC")
>  					  uidvalidity modseq)
>  		     'qresync
> @@ -1410,7 +1414,7 @@ nnimap-retrieve-group-data-early
>  		(incf (nnimap-initial-resync nnimap-object))
>  		(setq start 1))
>  	      (push (list (nnimap-send-command "%s %S" command
> -					       (utf7-encode group t))
> +					       (nnimap-group-to-imap group))
>  			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
>  			  start group command)
>  		    sequences))))
> @@ -1842,7 +1846,7 @@ nnimap-change-group
>                                        (if read-only
>                                            "EXAMINE"
>                                          "SELECT")
> -                                      (utf7-encode group t))))
> +                                      (nnimap-group-to-imap group))))
>            (when (car result)
>              (setf (nnimap-group nnimap-object) group
>                    (nnimap-select-result nnimap-object) result)
> @@ -2098,7 +2102,7 @@ nnimap-split-incoming-mail
>  	    (dolist (spec specs)
>  	      (when (and (not (member (car spec) groups))
>  			 (not (eq (car spec) 'junk)))
> -		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
> +		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
>  	    ;; Then copy over all the messages.
>  	    (erase-buffer)
>  	    (dolist (spec specs)
> @@ -2114,7 +2118,7 @@ nnimap-split-incoming-mail
>  				     "UID MOVE %s %S"
>  				   "UID COPY %s %S")
>  				 (nnimap-article-ranges ranges)
> -				 (utf7-encode group t))
> +				(nnimap-group-to-imap group))
>  				ranges)
>  			  sequences)))))
>  	    ;; Wait for the last COPY response...
> -- 
> 2.11.0
>
> From f5079a11c20944027465ea21291a8fc9e7ad3be1 Mon Sep 17 00:00:00 2001
> From: Nikolaus Rath <Nikolaus@rath.org>
> Date: Tue, 14 Jul 2015 19:03:09 -0700
> Subject: [PATCH 2/2] nnimap.el: Add support for IMAP namespaces.
>
> * lisp/gnus/nnimap.el (nnimap-use-namespaces): introduced new server variable.
> (nnimap-group-to-imap, nnimap-get-groups): transform IMAP group names
> to Gnus group name by stripping / prefixing personal namespace prefix.
> (nnimap-open-connection-1): ask server for namespaces and store them.
> ---
>  doc/misc/gnus.texi  |  6 +++++
>  etc/NEWS            |  5 ++++
>  lisp/gnus/nnimap.el | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
>  3 files changed, 64 insertions(+), 13 deletions(-)
>
> diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
> index 88e121..4b33e 100644
> --- a/doc/misc/gnus.texi
> +++ b/doc/misc/gnus.texi
> @@ -14301,6 +14301,12 @@ Customizing the IMAP Connection
>  If non-@code{nil}, record all @acronym{IMAP} commands in the
>  @samp{"*imap log*"} buffer.
>  
> +@item nnimap-use-namespaces
> +If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
> +names. If your IMAP mailboxes are called something like @samp{INBOX}
> +and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
> +be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
> +
>  @end table
>  
>  
> diff --git a/etc/NEWS b/etc/NEWS
> index 371cd..1f905d 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -37,6 +37,11 @@ When you add a new item, use the appropriate mark if you are sure it applies,
>  \f
>  * Changes in Specialized Modes and Packages in Emacs 27.1
>  
> +** Gnus
> +
> ++++
> +*** The nnimap backend now has support for IMAP namespaces.
> +
>  \f
>  * New Modes and Packages in Emacs 27.1
>  
> diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
> index a646f4..7ad54a 100644
> --- a/lisp/gnus/nnimap.el
> +++ b/lisp/gnus/nnimap.el
> @@ -55,6 +55,13 @@ nnimap-server-port
>  If nnimap-stream is `ssl', this will default to `imaps'.  If not,
>  it will default to `imap'.")
>  
> +(defvoo nnimap-use-namespaces nil
> +  "Whether to use IMAP namespaces.
> +If in Gnus your folder names in all start with (e.g.) `INBOX',
> +you probably want to set this to t. The effects of this are
> +purely cosmetical, but changing this variable will affect the
> +names of your nnimap groups. ")
> +
>  (defvoo nnimap-stream 'undecided
>    "How nnimap talks to the IMAP server.
>  The value should be either `undecided', `ssl' or `tls',
> @@ -116,6 +123,8 @@ nnimap-decode-gnus-group
>  (defun nnimap-encode-gnus-group (group)
>    (encode-coding-string group 'utf-8))
>  
> +(setq nnimap-namespaces nil)
> +
>  (defvoo nnimap-fetch-partial-articles nil
>    "If non-nil, Gnus will fetch partial articles.
>  If t, Gnus will fetch only the first part.  If a string, it
> @@ -168,7 +177,17 @@ nnimap-inhibit-logging
>  
>  (defun nnimap-group-to-imap (group)
>    "Convert Gnus group name to IMAP mailbox name."
> -  (utf7-encode group t))
> +  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
> +                              nnimap-namespaces)))
> +         (inbox (substring prefix 0 -1)))
> +    (utf7-encode
> +     (cond ((or (not prefix)
> +                (string-equal group inbox))
> +            group)
> +           ((string-prefix-p "#" group)
> +            (substring group 1))
> +           (t
> +            (concat prefix group))) t)))
>  
>  (defun nnimap-buffer ()
>    (nnimap-find-process-buffer nntp-server-buffer))
> @@ -445,7 +464,8 @@ nnimap-open-connection-1
>  	     (props (cdr stream-list))
>  	     (greeting (plist-get props :greeting))
>  	     (capabilities (plist-get props :capabilities))
> -	     (stream-type (plist-get props :type)))
> +	     (stream-type (plist-get props :type))
> +             (server (nnoo-current-server 'nnimap)))
>  	(when (and stream (not (memq (process-status stream) '(open run))))
>  	  (setq stream nil))
>  
> @@ -478,9 +498,7 @@ nnimap-open-connection-1
>                                 ;; the virtual server name and the address
>                                 (nnimap-credentials
>  				(gnus-delete-duplicates
> -				 (list
> -                                  (nnoo-current-server 'nnimap)
> -				  nnimap-address))
> +				 (list server nnimap-address))
>                                  ports
>                                  nnimap-user))))
>  		  (setq nnimap-object nil)
> @@ -499,7 +517,21 @@ nnimap-open-connection-1
>  		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
>  			(when (string= "CAPABILITY" (upcase (car response)))
>  			  (setf (nnimap-capabilities nnimap-object)
> -				(mapcar #'upcase (cdr response))))))
> +				(mapcar #'upcase (cdr response)))))
> +                      (when (and nnimap-use-namespaces
> +                                 (nnimap-capability "NAMESPACE"))
> +                        (erase-buffer)
> +                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
> +                        (let ((response (nnimap-last-response-string)))
> +                          (when (string-match
> +                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
> +                                 response)
> +                            (let ((namespace (cons (match-string 1 response)
> +                                                   (match-string 2 response)))
> +                                  (entry (assoc server nnimap-namespaces)))
> +                              (if entry
> +                                  (setcdr entry namespace)
> +                                (push (cons server namespace) nnimap-namespaces)))))))
>  		  ;; If the login failed, then forget the credentials
>  		  ;; that are now possibly cached.
>  		  (dolist (host (list (nnoo-current-server 'nnimap)
> @@ -1272,8 +1304,12 @@ nnimap-add-cr
>  
>  (defun nnimap-get-groups ()
>    (erase-buffer)
> -  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
> -	groups)
> +  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
> +         (prefix (cadr (assoc (nnoo-current-server 'nnimap)
> +                              nnimap-namespaces)))
> +         (prefix-len (length prefix))
> +         (inbox (substring prefix 0 -1))
> +         groups)
>      (nnimap-wait-for-response sequence)
>      (subst-char-in-region (point-min) (point-max)
>  			  ?\\ ?% t)
> @@ -1290,11 +1326,15 @@ nnimap-get-groups
>  			   (skip-chars-backward " \r\"")
>  			   (point)))))
>  	(unless (member '%NoSelect flags)
> -	  (push (utf7-decode (if (stringp group)
> -				 group
> -			       (format "%s" group))
> -                             t)
> -		groups))))
> +          (let* ((group (utf7-decode (if (stringp group) group
> +                                       (format "%s" group)) t))
> +                 (group (cond ((equal inbox group)
> +                               group)
> +                              ((string-prefix-p prefix group)
> +                               (substring group prefix-len))
> +                              (t
> +                               (concat "#" group)))))
> +            (push group groups)))))
>      (nreverse groups)))
>  
>  (defun nnimap-get-responses (sequences)
> -- 
> 2.11.0
>


-- 
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-09-17  8:16           ` Nikolaus Rath
  2017-12-06 14:25             ` Nikolaus Rath
@ 2017-12-27 21:10             ` Lars Ingebrigtsen
  2018-05-31 11:38               ` Nikolaus Rath
  1 sibling, 1 reply; 31+ messages in thread
From: Lars Ingebrigtsen @ 2017-12-27 21:10 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Andreas Schwab, 21057

Nikolaus Rath <Nikolaus@rath.org> writes:

>> Looks good to me.  It needs to be documented in the manual, though, and
>> perhaps a NEWS entry...
>
> Updated patch is attached.

Looks good, but a couple of niggles:

> +(setq nnimap-namespaces nil)

This should be a defvar, or rather, a defvoo.

[...]

> +  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
> +                              nnimap-namespaces)))
> +         (inbox (substring prefix 0 -1)))

And then you could just set nnimap-namespaces without maintaining a
per-server alist, since that's what the voo machinery does for you
(switching out variables on a per-server basis).

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2017-12-27 21:10             ` Lars Ingebrigtsen
@ 2018-05-31 11:38               ` Nikolaus Rath
  2018-07-03  7:40                 ` Nikolaus Rath
  2018-07-22 13:31                 ` Lars Ingebrigtsen
  0 siblings, 2 replies; 31+ messages in thread
From: Nikolaus Rath @ 2018-05-31 11:38 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Andreas Schwab, 21057

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

Hi,

On Wed, 27 Dec 2017, at 22:10, Lars Ingebrigtsen wrote:
> Looks good, but a couple of niggles:
> 
> > +(setq nnimap-namespaces nil)
> 
> This should be a defvar, or rather, a defvoo.
> 
> [...]
> 
> > +  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
> > +                              nnimap-namespaces)))
> > +         (inbox (substring prefix 0 -1)))
> 
> And then you could just set nnimap-namespaces without maintaining a
> per-server alist, since that's what the voo machinery does for you
> (switching out variables on a per-server basis).

Updated patches attached (and rebased onto current master).

Best,
-Nikolaus

--
GPG 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: 0001-nnimap.el-factor-out-nnimap-group-to-imap.patch --]
[-- Type: text/x-patch; name="0001-nnimap.el-factor-out-nnimap-group-to-imap.patch", Size: 6589 bytes --]

From 2c1c2ccaeb0c19649d125b64fe3f917c7a3fbb76 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Sun, 12 Jul 2015 11:10:28 -0700
Subject: [PATCH 1/3] nnimap.el: factor out nnimap-group-to-imap

* lisp/gnus/nnimap.el (nnimap-request-group-scan)
(nnimap-request-create-group, nnimap-request-delete-group)
(nnimap-request-rename-group, nnimap-request-move-article)
(nnimap-process-expiry-targets)
(nnimap-request-update-group-status)
(nnimap-request-accept-article, nnimap-request-list)
(nnimap-retrieve-group-data-early, nnimap-change-group)
(nnimap-split-incoming-mail): use nnimap-group-to-imap.
(nnimap-group-to-imap): new function to map Gnus group names to
IMAP folder names.
---
 lisp/gnus/nnimap.el | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 6e2a7..a646f4 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -166,6 +166,10 @@ nnimap-quirks
 
 (defvar nnimap-inhibit-logging nil)
 
+(defun nnimap-group-to-imap (group)
+  "Convert Gnus group name to IMAP mailbox name."
+  (utf7-encode group t))
+
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
@@ -834,7 +838,7 @@ nnimap-request-group-scan
       (with-current-buffer (nnimap-buffer)
 	(erase-buffer)
 	(let ((group-sequence
-	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
+	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
 	      (flag-sequence
 	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
 	  (setf (nnimap-group nnimap-object) group)
@@ -867,13 +871,13 @@ nnimap-request-create-group
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-delete-group (group &optional _force server)
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -881,7 +885,7 @@ nnimap-request-rename-group
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
-			   (utf7-encode group t) (utf7-encode new-name t))))))
+			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
 
 (defun nnimap-unselect-group ()
   ;; Make sure we don't have this group open read/write by asking
@@ -941,7 +945,7 @@ nnimap-request-move-article
 				"UID COPY %d %S"))
 		     (result (nnimap-command
 			      command article
-			      (utf7-encode internal-move-group t))))
+                              (nnimap-group-to-imap internal-move-group))))
                 (when (and (car result) (not can-move))
                   (nnimap-delete-article article))
                 (cons internal-move-group
@@ -1008,7 +1012,7 @@ nnimap-process-expiry-targets
                     "UID MOVE %s %S"
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
-                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
+                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
                (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
       t)
      (t
@@ -1133,7 +1137,7 @@ nnimap-request-update-group-status
 		      (unsubscribe "UNSUBSCRIBE")))))
       (when command
 	(with-current-buffer (nnimap-buffer)
-	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
+	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -1188,7 +1192,7 @@ nnimap-request-accept-article
 	    (nnimap-unselect-group))
 	  (erase-buffer)
 	  (setq sequence (nnimap-send-command
-			  "APPEND %S {%d}" (utf7-encode group t)
+			  "APPEND %S {%d}" (nnimap-group-to-imap group)
 			  (length message)))
 	  (unless nnimap-streaming
 	    (nnimap-wait-for-connection "^[+]"))
@@ -1316,7 +1320,7 @@ nnimap-request-list
 	    (dolist (group groups)
 	      (setf (nnimap-examined nnimap-object) group)
 	      (push (list (nnimap-send-command "EXAMINE %S"
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  group)
 		    sequences))
 	    (nnimap-wait-for-response (caar sequences))
@@ -1388,7 +1392,7 @@ nnimap-retrieve-group-data-early
 		   unexist)
 	      (push
 	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
-					  (utf7-encode group t)
+					  (nnimap-group-to-imap group)
 					  (nnimap-quirk "QRESYNC")
 					  uidvalidity modseq)
 		     'qresync
@@ -1410,7 +1414,7 @@ nnimap-retrieve-group-data-early
 		(incf (nnimap-initial-resync nnimap-object))
 		(setq start 1))
 	      (push (list (nnimap-send-command "%s %S" command
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
 			  start group command)
 		    sequences))))
@@ -1842,7 +1846,7 @@ nnimap-change-group
                                       (if read-only
                                           "EXAMINE"
                                         "SELECT")
-                                      (utf7-encode group t))))
+                                      (nnimap-group-to-imap group))))
           (when (car result)
             (setf (nnimap-group nnimap-object) group
                   (nnimap-select-result nnimap-object) result)
@@ -2098,7 +2102,7 @@ nnimap-split-incoming-mail
 	    (dolist (spec specs)
 	      (when (and (not (member (car spec) groups))
 			 (not (eq (car spec) 'junk)))
-		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
+		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
 	    ;; Then copy over all the messages.
 	    (erase-buffer)
 	    (dolist (spec specs)
@@ -2114,7 +2118,7 @@ nnimap-split-incoming-mail
 				     "UID MOVE %s %S"
 				   "UID COPY %s %S")
 				 (nnimap-article-ranges ranges)
-				 (utf7-encode group t))
+				(nnimap-group-to-imap group))
 				ranges)
 			  sequences)))))
 	    ;; Wait for the last COPY response...
-- 
2.11.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-nnimap.el-Add-support-for-IMAP-namespaces.patch --]
[-- Type: text/x-patch; name="0002-nnimap.el-Add-support-for-IMAP-namespaces.patch", Size: 6955 bytes --]

From f5079a11c20944027465ea21291a8fc9e7ad3be1 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Tue, 14 Jul 2015 19:03:09 -0700
Subject: [PATCH 2/3] nnimap.el: Add support for IMAP namespaces.

* lisp/gnus/nnimap.el (nnimap-use-namespaces): introduced new server variable.
(nnimap-group-to-imap, nnimap-get-groups): transform IMAP group names
to Gnus group name by stripping / prefixing personal namespace prefix.
(nnimap-open-connection-1): ask server for namespaces and store them.
---
 doc/misc/gnus.texi  |  6 +++++
 etc/NEWS            |  5 ++++
 lisp/gnus/nnimap.el | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 88e121..4b33e 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -14301,6 +14301,12 @@ Customizing the IMAP Connection
 If non-@code{nil}, record all @acronym{IMAP} commands in the
 @samp{"*imap log*"} buffer.
 
+@item nnimap-use-namespaces
+If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
+names. If your IMAP mailboxes are called something like @samp{INBOX}
+and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
+be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
+
 @end table
 
 
diff --git a/etc/NEWS b/etc/NEWS
index 371cd..1f905d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -37,6 +37,11 @@ When you add a new item, use the appropriate mark if you are sure it applies,
 \f
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
+** Gnus
+
++++
+*** The nnimap backend now has support for IMAP namespaces.
+
 \f
 * New Modes and Packages in Emacs 27.1
 
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index a646f4..7ad54a 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -55,6 +55,13 @@ nnimap-server-port
 If nnimap-stream is `ssl', this will default to `imaps'.  If not,
 it will default to `imap'.")
 
+(defvoo nnimap-use-namespaces nil
+  "Whether to use IMAP namespaces.
+If in Gnus your folder names in all start with (e.g.) `INBOX',
+you probably want to set this to t. The effects of this are
+purely cosmetical, but changing this variable will affect the
+names of your nnimap groups. ")
+
 (defvoo nnimap-stream 'undecided
   "How nnimap talks to the IMAP server.
 The value should be either `undecided', `ssl' or `tls',
@@ -116,6 +123,8 @@ nnimap-decode-gnus-group
 (defun nnimap-encode-gnus-group (group)
   (encode-coding-string group 'utf-8))
 
+(setq nnimap-namespaces nil)
+
 (defvoo nnimap-fetch-partial-articles nil
   "If non-nil, Gnus will fetch partial articles.
 If t, Gnus will fetch only the first part.  If a string, it
@@ -168,7 +177,17 @@ nnimap-inhibit-logging
 
 (defun nnimap-group-to-imap (group)
   "Convert Gnus group name to IMAP mailbox name."
-  (utf7-encode group t))
+  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (inbox (substring prefix 0 -1)))
+    (utf7-encode
+     (cond ((or (not prefix)
+                (string-equal group inbox))
+            group)
+           ((string-prefix-p "#" group)
+            (substring group 1))
+           (t
+            (concat prefix group))) t)))
 
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
@@ -445,7 +464,8 @@ nnimap-open-connection-1
 	     (props (cdr stream-list))
 	     (greeting (plist-get props :greeting))
 	     (capabilities (plist-get props :capabilities))
-	     (stream-type (plist-get props :type)))
+	     (stream-type (plist-get props :type))
+             (server (nnoo-current-server 'nnimap)))
 	(when (and stream (not (memq (process-status stream) '(open run))))
 	  (setq stream nil))
 
@@ -478,9 +498,7 @@ nnimap-open-connection-1
                                ;; the virtual server name and the address
                                (nnimap-credentials
 				(gnus-delete-duplicates
-				 (list
-                                  (nnoo-current-server 'nnimap)
-				  nnimap-address))
+				 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
 		  (setq nnimap-object nil)
@@ -499,7 +517,21 @@ nnimap-open-connection-1
 		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
 			(when (string= "CAPABILITY" (upcase (car response)))
 			  (setf (nnimap-capabilities nnimap-object)
-				(mapcar #'upcase (cdr response))))))
+				(mapcar #'upcase (cdr response)))))
+                      (when (and nnimap-use-namespaces
+                                 (nnimap-capability "NAMESPACE"))
+                        (erase-buffer)
+                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
+                        (let ((response (nnimap-last-response-string)))
+                          (when (string-match
+                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
+                                 response)
+                            (let ((namespace (cons (match-string 1 response)
+                                                   (match-string 2 response)))
+                                  (entry (assoc server nnimap-namespaces)))
+                              (if entry
+                                  (setcdr entry namespace)
+                                (push (cons server namespace) nnimap-namespaces)))))))
 		  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
@@ -1272,8 +1304,12 @@ nnimap-add-cr
 
 (defun nnimap-get-groups ()
   (erase-buffer)
-  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-	groups)
+  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
+         (prefix (cadr (assoc (nnoo-current-server 'nnimap)
+                              nnimap-namespaces)))
+         (prefix-len (length prefix))
+         (inbox (substring prefix 0 -1))
+         groups)
     (nnimap-wait-for-response sequence)
     (subst-char-in-region (point-min) (point-max)
 			  ?\\ ?% t)
@@ -1290,11 +1326,15 @@ nnimap-get-groups
 			   (skip-chars-backward " \r\"")
 			   (point)))))
 	(unless (member '%NoSelect flags)
-	  (push (utf7-decode (if (stringp group)
-				 group
-			       (format "%s" group))
-                             t)
-		groups))))
+          (let* ((group (utf7-decode (if (stringp group) group
+                                       (format "%s" group)) t))
+                 (group (cond ((equal inbox group)
+                               group)
+                              ((string-prefix-p prefix group)
+                               (substring group prefix-len))
+                              (t
+                               (concat "#" group)))))
+            (push group groups)))))
     (nreverse groups)))
 
 (defun nnimap-get-responses (sequences)
-- 
2.11.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Turn-nnimap-namespaces-into-a-defvoo-to-make-it-per-.patch --]
[-- Type: text/x-patch; name="0003-Turn-nnimap-namespaces-into-a-defvoo-to-make-it-per-.patch", Size: 3099 bytes --]

From 40fa6ff0052818fd778f4f88eb46213ee9629732 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Thu, 31 May 2018 12:13:28 +0100
Subject: [PATCH 3/3] Turn nnimap-namespaces into a defvoo to make it
 per-server.

---
 lisp/gnus/nnimap.el | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 7ad54a..3c95f1 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -117,14 +117,14 @@ nnimap-connection-alist
 
 (defvoo nnimap-current-infos nil)
 
+(defvoo nnimap-namespace nil)
+
 (defun nnimap-decode-gnus-group (group)
   (decode-coding-string group 'utf-8))
 
 (defun nnimap-encode-gnus-group (group)
   (encode-coding-string group 'utf-8))
 
-(setq nnimap-namespaces nil)
-
 (defvoo nnimap-fetch-partial-articles nil
   "If non-nil, Gnus will fetch partial articles.
 If t, Gnus will fetch only the first part.  If a string, it
@@ -177,17 +177,15 @@ nnimap-inhibit-logging
 
 (defun nnimap-group-to-imap (group)
   "Convert Gnus group name to IMAP mailbox name."
-  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
-                              nnimap-namespaces)))
-         (inbox (substring prefix 0 -1)))
+  (let* ((inbox (substring nnimap-namespace 0 -1)))
     (utf7-encode
-     (cond ((or (not prefix)
+     (cond ((or (not nnimap-namespace)
                 (string-equal group inbox))
             group)
            ((string-prefix-p "#" group)
             (substring group 1))
            (t
-            (concat prefix group))) t)))
+            (concat nnimap-namespace group))) t)))
 
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
@@ -526,13 +524,8 @@ nnimap-open-connection-1
                           (when (string-match
                                  "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
                                  response)
-                            (let ((namespace (cons (match-string 1 response)
-                                                   (match-string 2 response)))
-                                  (entry (assoc server nnimap-namespaces)))
-                              (if entry
-                                  (setcdr entry namespace)
-                                (push (cons server namespace) nnimap-namespaces)))))))
-		  ;; If the login failed, then forget the credentials
+                            (setq nnimap-namespace (match-string 1 response))))))
+                  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
 				      nnimap-address))
@@ -1305,8 +1298,7 @@ nnimap-add-cr
 (defun nnimap-get-groups ()
   (erase-buffer)
   (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-         (prefix (cadr (assoc (nnoo-current-server 'nnimap)
-                              nnimap-namespaces)))
+         (prefix nnimap-namespace)
          (prefix-len (length prefix))
          (inbox (substring prefix 0 -1))
          groups)
-- 
2.11.0


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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-05-31 11:38               ` Nikolaus Rath
@ 2018-07-03  7:40                 ` Nikolaus Rath
  2018-07-07  9:12                   ` Eli Zaretskii
  2018-07-22 13:31                 ` Lars Ingebrigtsen
  1 sibling, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-03  7:40 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Andreas Schwab, 21057

*ping*

Could someone take a look at the revised patch?

Thanks!
-Nikolaus

--
GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

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

On Thu, 31 May 2018, at 12:38, Nikolaus Rath wrote:
> Hi,
> 
> On Wed, 27 Dec 2017, at 22:10, Lars Ingebrigtsen wrote:
> > Looks good, but a couple of niggles:
> > 
> > > +(setq nnimap-namespaces nil)
> > 
> > This should be a defvar, or rather, a defvoo.
> > 
> > [...]
> > 
> > > +  (let* ((prefix (cadr (assoc (nnoo-current-server 'nnimap)
> > > +                              nnimap-namespaces)))
> > > +         (inbox (substring prefix 0 -1)))
> > 
> > And then you could just set nnimap-namespaces without maintaining a
> > per-server alist, since that's what the voo machinery does for you
> > (switching out variables on a per-server basis).
> 
> Updated patches attached (and rebased onto current master).
> 
> Best,
> -Nikolaus
> 
> --
> GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F
> 
>              »Time flies like an arrow, fruit flies like a Banana.«
> Email had 3 attachments:
> + 0001-nnimap.el-factor-out-nnimap-group-to-imap.patch
>   9k (text/x-patch)
> + 0002-nnimap.el-Add-support-for-IMAP-namespaces.patch
>   10k (text/x-patch)
> + 0003-Turn-nnimap-namespaces-into-a-defvoo-to-make-it-per-.patch
>   4k (text/x-patch)





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-03  7:40                 ` Nikolaus Rath
@ 2018-07-07  9:12                   ` Eli Zaretskii
  2018-07-17 19:43                     ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2018-07-07  9:12 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: schwab, larsi, 21057

> From: Nikolaus Rath <nikolaus@rath.org>
> Date: Tue, 03 Jul 2018 08:40:59 +0100
> Cc: Andreas Schwab <schwab@suse.de>, 21057@debbugs.gnu.org
> 
> *ping*
> 
> Could someone take a look at the revised patch?

Sorry it takes us this long to review your contribution.

Lars, any further comments?  If not, I'd like to push this to the
master branch.





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-07  9:12                   ` Eli Zaretskii
@ 2018-07-17 19:43                     ` Nikolaus Rath
  2018-07-20  9:43                       ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-17 19:43 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: schwab, larsi, 21057

On Sat, 7 Jul 2018, at 10:12, Eli Zaretskii wrote:
> > From: Nikolaus Rath <nikolaus@rath.org>
> > Date: Tue, 03 Jul 2018 08:40:59 +0100
> > Cc: Andreas Schwab <schwab@suse.de>, 21057@debbugs.gnu.org
> > 
> > *ping*
> > 
> > Could someone take a look at the revised patch?
> 
> Sorry it takes us this long to review your contribution.
> 
> Lars, any further comments?  If not, I'd like to push this to the
> master branch.

Anything I can do to help?


Best,
-Nikolaus

--
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-17 19:43                     ` Nikolaus Rath
@ 2018-07-20  9:43                       ` Eli Zaretskii
  2018-07-20 19:16                         ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2018-07-20  9:43 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: schwab, larsi, 21057

> From: Nikolaus Rath <nikolaus@rath.org>
> Cc: larsi@gnus.org, schwab@suse.de, 21057@debbugs.gnu.org
> Date: Tue, 17 Jul 2018 20:43:35 +0100
> 
> On Sat, 7 Jul 2018, at 10:12, Eli Zaretskii wrote:
> > > From: Nikolaus Rath <nikolaus@rath.org>
> > > Date: Tue, 03 Jul 2018 08:40:59 +0100
> > > Cc: Andreas Schwab <schwab@suse.de>, 21057@debbugs.gnu.org
> > > 
> > > *ping*
> > > 
> > > Could someone take a look at the revised patch?
> > 
> > Sorry it takes us this long to review your contribution.
> > 
> > Lars, any further comments?  If not, I'd like to push this to the
> > master branch.
> 
> Anything I can do to help?

I was going to just apply your changes, but that failed: first, the
patch includes changes to lisp/ChangeLog, which we no longer have; and
second, nnimap.el is not in lisp, it's in lisp/gnus/.  I tried to edit
the patch to fix these issues, but then "git am" still failed claiming
that the patch wouldn't apply.

So please rebase your patch on the current master branch and resubmit.

Thanks.





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-20  9:43                       ` Eli Zaretskii
@ 2018-07-20 19:16                         ` Nikolaus Rath
  2018-07-20 19:50                           ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-20 19:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: schwab, larsi, 21057

On Jul 20 2018, Eli Zaretskii <eliz@gnu.org> wrote:
>> From: Nikolaus Rath <nikolaus@rath.org>
>> Cc: larsi@gnus.org, schwab@suse.de, 21057@debbugs.gnu.org
>> Date: Tue, 17 Jul 2018 20:43:35 +0100
>> 
>> On Sat, 7 Jul 2018, at 10:12, Eli Zaretskii wrote:
>> > > From: Nikolaus Rath <nikolaus@rath.org>
>> > > Date: Tue, 03 Jul 2018 08:40:59 +0100
>> > > Cc: Andreas Schwab <schwab@suse.de>, 21057@debbugs.gnu.org
>> > > 
>> > > *ping*
>> > > 
>> > > Could someone take a look at the revised patch?
>> > 
>> > Sorry it takes us this long to review your contribution.
>> > 
>> > Lars, any further comments?  If not, I'd like to push this to the
>> > master branch.
>> 
>> Anything I can do to help?
>
> I was going to just apply your changes, but that failed: first, the
> patch includes changes to lisp/ChangeLog, which we no longer have; and
> second, nnimap.el is not in lisp, it's in lisp/gnus/.  I tried to edit
> the patch to fix these issues, but then "git am" still failed claiming
> that the patch wouldn't apply.

Are you sure that you tried to apply the right patch? The patches in
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21057#37 all refer to
lisp/gnus/nnimap.el and do not contain any ChangeLog file:

$ grep diff *.patch
0001-nnimap.el-factor-out-nnimap-group-to-imap.patch:diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
0002-nnimap.el-Add-support-for-IMAP-namespaces.patch:diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
0002-nnimap.el-Add-support-for-IMAP-namespaces.patch:diff --git a/etc/NEWS b/etc/NEWS
0002-nnimap.el-Add-support-for-IMAP-namespaces.patch:diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
0003-Turn-nnimap-namespaces-into-a-defvoo-to-make-it-per-.patch:diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el


Best,
-Nikolaus

-- 
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-20 19:16                         ` Nikolaus Rath
@ 2018-07-20 19:50                           ` Eli Zaretskii
  0 siblings, 0 replies; 31+ messages in thread
From: Eli Zaretskii @ 2018-07-20 19:50 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: schwab, larsi, 21057

> From: Nikolaus Rath <Nikolaus@rath.org>
> Cc: larsi@gnus.org,  schwab@suse.de,  21057@debbugs.gnu.org
> Date: Fri, 20 Jul 2018 20:16:38 +0100
> 
> > I was going to just apply your changes, but that failed: first, the
> > patch includes changes to lisp/ChangeLog, which we no longer have; and
> > second, nnimap.el is not in lisp, it's in lisp/gnus/.  I tried to edit
> > the patch to fix these issues, but then "git am" still failed claiming
> > that the patch wouldn't apply.
> 
> Are you sure that you tried to apply the right patch? The patches in
> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21057#37 all refer to
> lisp/gnus/nnimap.el and do not contain any ChangeLog file:

Oops, no, I tried to use the original patches.  Sorry.





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-05-31 11:38               ` Nikolaus Rath
  2018-07-03  7:40                 ` Nikolaus Rath
@ 2018-07-22 13:31                 ` Lars Ingebrigtsen
  2018-07-23  6:00                   ` Eric Abrahamsen
  1 sibling, 1 reply; 31+ messages in thread
From: Lars Ingebrigtsen @ 2018-07-22 13:31 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Andreas Schwab, 21057

Nikolaus Rath <nikolaus@rath.org> writes:

> Updated patches attached (and rebased onto current master).

Sorry for the delays; I've now applied your patches to Emacs master.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-22 13:31                 ` Lars Ingebrigtsen
@ 2018-07-23  6:00                   ` Eric Abrahamsen
  2018-07-23  7:03                     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 31+ messages in thread
From: Eric Abrahamsen @ 2018-07-23  6:00 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Andreas Schwab, Nikolaus Rath, 21057

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Nikolaus Rath <nikolaus@rath.org> writes:
>
>> Updated patches attached (and rebased onto current master).
>
> Sorry for the delays; I've now applied your patches to Emacs master.

This raises an error for me when Gnus starts.

`nnimap-retrieve-group-data-early' calls `nnimap-group-to-imap', which
does:

(substring nnimap-namespace 0 -1)

`nnimap-namespace' is nil, so an error is raised.

What's supposed to happen?

Eric





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  6:00                   ` Eric Abrahamsen
@ 2018-07-23  7:03                     ` Lars Ingebrigtsen
  2018-07-23  7:22                       ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Lars Ingebrigtsen @ 2018-07-23  7:03 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: Andreas Schwab, Nikolaus Rath, 21057

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> This raises an error for me when Gnus starts.
>
> `nnimap-retrieve-group-data-early' calls `nnimap-group-to-imap', which
> does:
>
> (substring nnimap-namespace 0 -1)
>
> `nnimap-namespace' is nil, so an error is raised.

I've now reverted the patch.  It seems like if you're not using
namespaces, it'll bug out in several places that assumes that namespaces
are in use.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  7:03                     ` Lars Ingebrigtsen
@ 2018-07-23  7:22                       ` Nikolaus Rath
  2018-07-23  7:39                         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-23  7:22 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

On Jul 23 2018, Lars Ingebrigtsen <larsi@gnus.org> wrote:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> This raises an error for me when Gnus starts.
>>
>> `nnimap-retrieve-group-data-early' calls `nnimap-group-to-imap', which
>> does:
>>
>> (substring nnimap-namespace 0 -1)
>>
>> `nnimap-namespace' is nil, so an error is raised.
>
> I've now reverted the patch.  It seems like if you're not using
> namespaces, it'll bug out in several places that assumes that namespaces
> are in use.

I think the problem is just the default value for nnimap-namespace
provided to defvoo, it should be the empty string rather than nil.

Am I missing something?

Best,
-Nikolaus

-- 
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  7:22                       ` Nikolaus Rath
@ 2018-07-23  7:39                         ` Lars Ingebrigtsen
  2018-07-23  8:58                           ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Lars Ingebrigtsen @ 2018-07-23  7:39 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

Nikolaus Rath <Nikolaus@rath.org> writes:

> I think the problem is just the default value for nnimap-namespace
> provided to defvoo, it should be the empty string rather than nil.
>
> Am I missing something?

The procedure when things don't work is to revert the patch so that
people can use Emacs while we try to figure out what the problem is.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  7:39                         ` Lars Ingebrigtsen
@ 2018-07-23  8:58                           ` Nikolaus Rath
  2018-07-23  9:00                             ` Lars Ingebrigtsen
  2018-07-23  9:01                             ` Lars Ingebrigtsen
  0 siblings, 2 replies; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-23  8:58 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

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

Hi,

That's fine. I really just wanted to ask if my understanding is correct, to avoid creating a wrong patch for the patch.

Cheers,
Niko



On 23 July 2018 08:39:36 BST, Lars Ingebrigtsen <larsi@gnus.org> wrote:
>Nikolaus Rath <Nikolaus@rath.org> writes:
>
>> I think the problem is just the default value for nnimap-namespace
>> provided to defvoo, it should be the empty string rather than nil.
>>
>> Am I missing something?
>
>The procedure when things don't work is to revert the patch so that
>people can use Emacs while we try to figure out what the problem is.
>
>-- 
>(domestic pets only, the antidote for overdose, milk.)
>   bloggy blog: http://lars.ingebrigtsen.no

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

[-- Attachment #2: Type: text/html, Size: 1094 bytes --]

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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  8:58                           ` Nikolaus Rath
@ 2018-07-23  9:00                             ` Lars Ingebrigtsen
  2018-07-23  9:01                             ` Lars Ingebrigtsen
  1 sibling, 0 replies; 31+ messages in thread
From: Lars Ingebrigtsen @ 2018-07-23  9:00 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

Nikolaus Rath <Nikolaus@rath.org> writes:

> That's fine. I really just wanted to ask if my understanding is
> correct, to avoid creating a wrong patch for the patch.

I think that sounds likely, but I haven't tested.  :-)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  8:58                           ` Nikolaus Rath
  2018-07-23  9:00                             ` Lars Ingebrigtsen
@ 2018-07-23  9:01                             ` Lars Ingebrigtsen
  2018-07-23  9:53                               ` Nikolaus Rath
  1 sibling, 1 reply; 31+ messages in thread
From: Lars Ingebrigtsen @ 2018-07-23  9:01 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

(That is, there are checks for whether nnimap-namespace is nil here and
there, so those seem invalid if nil isn't a valid value for that variable.)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no






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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  9:01                             ` Lars Ingebrigtsen
@ 2018-07-23  9:53                               ` Nikolaus Rath
  2018-07-23 11:28                                 ` Robert Pluim
  2018-07-23 16:47                                 ` Eric Abrahamsen
  0 siblings, 2 replies; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-23  9:53 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

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

Hi,

Reworked patch is attached.

I tested with and and without nnimap-use-namespaces on Emacs 25.1.1.

Best,
Nikolaus

-- 
GPG 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: 0001-Make-nnimap-support-IMAP-namespaces.patch --]
[-- Type: text/x-diff, Size: 12786 bytes --]

From ff88c4969617ede5742e039136159fe3650ac693 Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Mon, 23 Jul 2018 10:21:46 +0100
Subject: [PATCH] Make nnimap support IMAP namespaces

* lisp/gnus/nnimap.el (nnimap-use-namespaces): Introduce new
server variable.
(nnimap-group-to-imap, nnimap-get-groups): Transform IMAP group
names to Gnus group name by stripping / prefixing personal
namespace prefix.
(nnimap-open-connection-1): Ask server for namespaces and store them.

* lisp/gnus/nnimap.el (nnimap-request-group-scan)
(nnimap-request-create-group, nnimap-request-delete-group)
(nnimap-request-rename-group, nnimap-request-move-article)
(nnimap-process-expiry-targets)
(nnimap-request-update-group-status)
(nnimap-request-accept-article, nnimap-request-list)
(nnimap-retrieve-group-data-early, nnimap-change-group)
(nnimap-split-incoming-mail): Use nnimap-group-to-imap.
(nnimap-group-to-imap): New function to map Gnus group names to
IMAP folder names.
---
 doc/misc/gnus.texi  |  6 ++++
 etc/NEWS            |  5 +++
 lisp/gnus/nnimap.el | 93 +++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 6793ed..cd97cf 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -14320,6 +14320,12 @@ fetch all textual parts, while leaving the rest on the server.
 If non-@code{nil}, record all @acronym{IMAP} commands in the
 @samp{"*imap log*"} buffer.
 
+@item nnimap-use-namespaces
+If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
+names. If your IMAP mailboxes are called something like @samp{INBOX}
+and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
+be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
+
 @end table
 
 
diff --git a/etc/NEWS b/etc/NEWS
index fc2a5..57b51 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -46,6 +46,11 @@ option --enable-check-lisp-object-type is therefore no longer as
 useful and so is no longer enabled by default in developer builds,
 to reduce differences between developer and production builds.
 
+** Gnus
+
++++
+*** The nnimap backend now has support for IMAP namespaces.
+
 \f
 * Startup Changes in Emacs 27.1
 
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 3b397..efcb68 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -55,6 +55,13 @@
 If nnimap-stream is `ssl', this will default to `imaps'.  If not,
 it will default to `imap'.")
 
+(defvoo nnimap-use-namespaces nil
+  "Whether to use IMAP namespaces.
+If in Gnus your folder names in all start with (e.g.) `INBOX',
+you probably want to set this to t. The effects of this are
+purely cosmetical, but changing this variable will affect the
+names of your nnimap groups. ")
+
 (defvoo nnimap-stream 'undecided
   "How nnimap talks to the IMAP server.
 The value should be either `undecided', `ssl' or `tls',
@@ -110,6 +117,8 @@ some servers.")
 
 (defvoo nnimap-current-infos nil)
 
+(defvoo nnimap-namespace nil)
+
 (defun nnimap-decode-gnus-group (group)
   (decode-coding-string group 'utf-8))
 
@@ -166,6 +175,19 @@ textual parts.")
 
 (defvar nnimap-inhibit-logging nil)
 
+(defun nnimap-group-to-imap (group)
+  "Convert Gnus group name to IMAP mailbox name."
+  (let* ((inbox (if nnimap-namespace
+                    (substring nnimap-namespace 0 -1) nil)))
+    (utf7-encode
+     (cond ((or (not inbox)
+                (string-equal group inbox))
+            group)
+           ((string-prefix-p "#" group)
+            (substring group 1))
+           (t
+            (concat nnimap-namespace group))) t)))
+
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
@@ -442,7 +464,8 @@ textual parts.")
 	     (props (cdr stream-list))
 	     (greeting (plist-get props :greeting))
 	     (capabilities (plist-get props :capabilities))
-	     (stream-type (plist-get props :type)))
+	     (stream-type (plist-get props :type))
+             (server (nnoo-current-server 'nnimap)))
 	(when (and stream (not (memq (process-status stream) '(open run))))
 	  (setq stream nil))
 
@@ -475,9 +498,7 @@ textual parts.")
                                ;; the virtual server name and the address
                                (nnimap-credentials
 				(gnus-delete-duplicates
-				 (list
-                                  (nnoo-current-server 'nnimap)
-				  nnimap-address))
+				 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
 		  (setq nnimap-object nil)
@@ -496,8 +517,17 @@ textual parts.")
 		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
 			(when (string= "CAPABILITY" (upcase (car response)))
 			  (setf (nnimap-capabilities nnimap-object)
-				(mapcar #'upcase (cdr response))))))
-		  ;; If the login failed, then forget the credentials
+				(mapcar #'upcase (cdr response)))))
+                      (when (and nnimap-use-namespaces
+                                 (nnimap-capability "NAMESPACE"))
+                        (erase-buffer)
+                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
+                        (let ((response (nnimap-last-response-string)))
+                          (when (string-match
+                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
+                                 response)
+                            (setq nnimap-namespace (match-string 1 response))))))
+                  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
 				      nnimap-address))
@@ -837,7 +867,7 @@ textual parts.")
       (with-current-buffer (nnimap-buffer)
 	(erase-buffer)
 	(let ((group-sequence
-	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
+	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
 	      (flag-sequence
 	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
 	  (setf (nnimap-group nnimap-object) group)
@@ -870,13 +900,13 @@ textual parts.")
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-delete-group (group &optional _force server)
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -884,7 +914,7 @@ textual parts.")
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
-			   (utf7-encode group t) (utf7-encode new-name t))))))
+			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
 
 (defun nnimap-unselect-group ()
   ;; Make sure we don't have this group open read/write by asking
@@ -944,7 +974,7 @@ textual parts.")
 				"UID COPY %d %S"))
 		     (result (nnimap-command
 			      command article
-			      (utf7-encode internal-move-group t))))
+                              (nnimap-group-to-imap internal-move-group))))
                 (when (and (car result) (not can-move))
                   (nnimap-delete-article article))
                 (cons internal-move-group
@@ -1011,7 +1041,7 @@ textual parts.")
                     "UID MOVE %s %S"
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
-                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
+                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
                (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
       t)
      (t
@@ -1136,7 +1166,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		      (unsubscribe "UNSUBSCRIBE")))))
       (when command
 	(with-current-buffer (nnimap-buffer)
-	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
+	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -1191,7 +1221,7 @@ If LIMIT, first try to limit the search to the N last articles."
 	    (nnimap-unselect-group))
 	  (erase-buffer)
 	  (setq sequence (nnimap-send-command
-			  "APPEND %S {%d}" (utf7-encode group t)
+			  "APPEND %S {%d}" (nnimap-group-to-imap group)
 			  (length message)))
 	  (unless nnimap-streaming
 	    (nnimap-wait-for-connection "^[+]"))
@@ -1271,8 +1301,12 @@ If LIMIT, first try to limit the search to the N last articles."
 
 (defun nnimap-get-groups ()
   (erase-buffer)
-  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-	groups)
+  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
+         (prefix nnimap-namespace)
+         (prefix-len (if prefix (length prefix) nil))
+         (inbox (if prefix
+                    (substring prefix 0 -1) nil))
+         groups)
     (nnimap-wait-for-response sequence)
     (subst-char-in-region (point-min) (point-max)
 			  ?\\ ?% t)
@@ -1289,11 +1323,16 @@ If LIMIT, first try to limit the search to the N last articles."
 			   (skip-chars-backward " \r\"")
 			   (point)))))
 	(unless (member '%NoSelect flags)
-	  (push (utf7-decode (if (stringp group)
-				 group
-			       (format "%s" group))
-                             t)
-		groups))))
+          (let* ((group (utf7-decode (if (stringp group) group
+                                       (format "%s" group)) t))
+                 (group (cond ((or (not prefix)
+                                   (equal inbox group))
+                               group)
+                              ((string-prefix-p prefix group)
+                               (substring group prefix-len))
+                              (t
+                               (concat "#" group)))))
+            (push group groups)))))
     (nreverse groups)))
 
 (defun nnimap-get-responses (sequences)
@@ -1319,7 +1358,7 @@ If LIMIT, first try to limit the search to the N last articles."
 	    (dolist (group groups)
 	      (setf (nnimap-examined nnimap-object) group)
 	      (push (list (nnimap-send-command "EXAMINE %S"
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  group)
 		    sequences))
 	    (nnimap-wait-for-response (caar sequences))
@@ -1391,7 +1430,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		   unexist)
 	      (push
 	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
-					  (utf7-encode group t)
+					  (nnimap-group-to-imap group)
 					  (nnimap-quirk "QRESYNC")
 					  uidvalidity modseq)
 		     'qresync
@@ -1413,7 +1452,7 @@ If LIMIT, first try to limit the search to the N last articles."
 		(cl-incf (nnimap-initial-resync nnimap-object))
 		(setq start 1))
 	      (push (list (nnimap-send-command "%s %S" command
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
 			  start group command)
 		    sequences))))
@@ -1847,7 +1886,7 @@ Return the server's response to the SELECT or EXAMINE command."
                                       (if read-only
                                           "EXAMINE"
                                         "SELECT")
-                                      (utf7-encode group t))))
+                                      (nnimap-group-to-imap group))))
           (when (car result)
             (setf (nnimap-group nnimap-object) group
                   (nnimap-select-result nnimap-object) result)
@@ -2105,7 +2144,7 @@ Return the server's response to the SELECT or EXAMINE command."
 	    (dolist (spec specs)
 	      (when (and (not (member (car spec) groups))
 			 (not (eq (car spec) 'junk)))
-		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
+		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
 	    ;; Then copy over all the messages.
 	    (erase-buffer)
 	    (dolist (spec specs)
@@ -2121,7 +2160,7 @@ Return the server's response to the SELECT or EXAMINE command."
 				     "UID MOVE %s %S"
 				   "UID COPY %s %S")
 				 (nnimap-article-ranges ranges)
-				 (utf7-encode group t))
+				(nnimap-group-to-imap group))
 				ranges)
 			  sequences)))))
 	    ;; Wait for the last COPY response...
-- 
2.11.0


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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  9:53                               ` Nikolaus Rath
@ 2018-07-23 11:28                                 ` Robert Pluim
  2018-07-23 18:00                                   ` Nikolaus Rath
  2018-07-23 16:47                                 ` Eric Abrahamsen
  1 sibling, 1 reply; 31+ messages in thread
From: Robert Pluim @ 2018-07-23 11:28 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Eric Abrahamsen, Andreas Schwab, Lars Ingebrigtsen, 21057

Nikolaus Rath <Nikolaus@rath.org> writes:

Nitpicks below.

> Hi,
>
> Reworked patch is attached.
>
> I tested with and and without nnimap-use-namespaces on Emacs 25.1.1.
>
> Best,
> Nikolaus
>
> -- 
> GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F
>
>              »Time flies like an arrow, fruit flies like a Banana.«
>
> From ff88c4969617ede5742e039136159fe3650ac693 Mon Sep 17 00:00:00 2001
> From: Nikolaus Rath <Nikolaus@rath.org>
> Date: Mon, 23 Jul 2018 10:21:46 +0100
> Subject: [PATCH] Make nnimap support IMAP namespaces
>
> * lisp/gnus/nnimap.el (nnimap-use-namespaces): Introduce new
> server variable.
> (nnimap-group-to-imap, nnimap-get-groups): Transform IMAP group
> names to Gnus group name by stripping / prefixing personal
> namespace prefix.
> (nnimap-open-connection-1): Ask server for namespaces and store them.
>
> * lisp/gnus/nnimap.el (nnimap-request-group-scan)
> (nnimap-request-create-group, nnimap-request-delete-group)
> (nnimap-request-rename-group, nnimap-request-move-article)
> (nnimap-process-expiry-targets)
> (nnimap-request-update-group-status)
> (nnimap-request-accept-article, nnimap-request-list)
> (nnimap-retrieve-group-data-early, nnimap-change-group)
> (nnimap-split-incoming-mail): Use nnimap-group-to-imap.
> (nnimap-group-to-imap): New function to map Gnus group names to
> IMAP folder names.
> ---
>  doc/misc/gnus.texi  |  6 ++++
>  etc/NEWS            |  5 +++
>  lisp/gnus/nnimap.el | 93 +++++++++++++++++++++++++++++++++++++----------------
>  3 files changed, 77 insertions(+), 27 deletions(-)
>
> diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
> index 6793ed..cd97cf 100644
> --- a/doc/misc/gnus.texi
> +++ b/doc/misc/gnus.texi
> @@ -14320,6 +14320,12 @@ fetch all textual parts, while leaving the rest on the server.
>  If non-@code{nil}, record all @acronym{IMAP} commands in the
>  @samp{"*imap log*"} buffer.
>  
> +@item nnimap-use-namespaces
> +If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
> +names. If your IMAP mailboxes are called something like @samp{INBOX}
> +and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
> +be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
> +
>  @end table
>

Does this also work for secondary servers? I imagine it does.

>  
> diff --git a/etc/NEWS b/etc/NEWS
> index fc2a5..57b51 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -46,6 +46,11 @@ option --enable-check-lisp-object-type is therefore no longer as
>  useful and so is no longer enabled by default in developer builds,
>  to reduce differences between developer and production builds.
>  
> +** Gnus
> +
> ++++
> +*** The nnimap backend now has support for IMAP namespaces.
> +

This should mention the 'nnimap-use-namespaces' variable.

>  \f
>  * Startup Changes in Emacs 27.1
>  
> diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
> index 3b397..efcb68 100644
> --- a/lisp/gnus/nnimap.el
> +++ b/lisp/gnus/nnimap.el
> @@ -55,6 +55,13 @@
>  If nnimap-stream is `ssl', this will default to `imaps'.  If not,
>  it will default to `imap'.")
>  
> +(defvoo nnimap-use-namespaces nil
> +  "Whether to use IMAP namespaces.
> +If in Gnus your folder names in all start with (e.g.) `INBOX',
> +you probably want to set this to t. The effects of this are
> +purely cosmetical, but changing this variable will affect the

cosmetical⇒cosmetic

Thanks

Robert





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23  9:53                               ` Nikolaus Rath
  2018-07-23 11:28                                 ` Robert Pluim
@ 2018-07-23 16:47                                 ` Eric Abrahamsen
  1 sibling, 0 replies; 31+ messages in thread
From: Eric Abrahamsen @ 2018-07-23 16:47 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: Andreas Schwab, Lars Ingebrigtsen, 21057


On 07/23/18 10:53 AM, Nikolaus Rath wrote:
> Hi,
>
> Reworked patch is attached.
>
> I tested with and and without nnimap-use-namespaces on Emacs 25.1.1.

Works for me on master, with nnimap-use-namespaces nil.  





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

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23 11:28                                 ` Robert Pluim
@ 2018-07-23 18:00                                   ` Nikolaus Rath
  2018-07-27  7:54                                     ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-23 18:00 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

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

On Jul 23 2018, Robert Pluim <rpluim@gmail.com> wrote:
> Nikolaus Rath <Nikolaus@rath.org> writes:
>
> Nitpicks below.

Fixed, updated patch attached.

> Does this also work for secondary servers? I imagine it does.

Yes, it should.

Best,
-Nikolaus

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Make-nnimap-support-IMAP-namespaces.patch --]
[-- Type: text/x-diff, Size: 12568 bytes --]

From 90b4930ec9004caaa39615edb1bd271bc14aeecb Mon Sep 17 00:00:00 2001
From: Nikolaus Rath <Nikolaus@rath.org>
Date: Mon, 23 Jul 2018 10:21:46 +0100
Subject: [PATCH] Make nnimap support IMAP namespaces

* lisp/gnus/nnimap.el (nnimap-use-namespaces): Introduce new
server variable.
(nnimap-group-to-imap, nnimap-get-groups): Transform IMAP group
names to Gnus group name by stripping / prefixing personal
namespace prefix.
(nnimap-open-connection-1): Ask server for namespaces and store them.

* lisp/gnus/nnimap.el (nnimap-request-group-scan)
(nnimap-request-create-group, nnimap-request-delete-group)
(nnimap-request-rename-group, nnimap-request-move-article)
(nnimap-process-expiry-targets)
(nnimap-request-update-group-status)
(nnimap-request-accept-article, nnimap-request-list)
(nnimap-retrieve-group-data-early, nnimap-change-group)
(nnimap-split-incoming-mail): Use nnimap-group-to-imap.
(nnimap-group-to-imap): New function to map Gnus group names to
IMAP folder names.
---
 doc/misc/gnus.texi  |  6 ++++
 etc/NEWS            |  7 ++++
 lisp/gnus/nnimap.el | 93 +++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 6793ed..cd97cf 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -14320,6 +14320,12 @@ Customizing the IMAP Connection
 If non-@code{nil}, record all @acronym{IMAP} commands in the
 @samp{"*imap log*"} buffer.
 
+@item nnimap-use-namespaces
+If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
+names. If your IMAP mailboxes are called something like @samp{INBOX}
+and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
+be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
+
 @end table
 
 
diff --git a/etc/NEWS b/etc/NEWS
index fc2a5..04b4a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -46,6 +46,13 @@ option --enable-check-lisp-object-type is therefore no longer as
 useful and so is no longer enabled by default in developer builds,
 to reduce differences between developer and production builds.
 
+** Gnus
+
++++
+*** The nnimap backend now has support for IMAP namespaces.
+This feature can be enabled by setting the new 'nnimap-use-namespaces'
+server variable to non-nil.
+
 \f
 * Startup Changes in Emacs 27.1
 
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 3b397..1736f8 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -55,6 +55,13 @@ nnimap-server-port
 If nnimap-stream is `ssl', this will default to `imaps'.  If not,
 it will default to `imap'.")
 
+(defvoo nnimap-use-namespaces nil
+  "Whether to use IMAP namespaces.
+If in Gnus your folder names in all start with (e.g.) `INBOX',
+you probably want to set this to t. The effects of this are
+purely cosmetic, but changing this variable will affect the
+names of your nnimap groups. ")
+
 (defvoo nnimap-stream 'undecided
   "How nnimap talks to the IMAP server.
 The value should be either `undecided', `ssl' or `tls',
@@ -110,6 +117,8 @@ nnimap-connection-alist
 
 (defvoo nnimap-current-infos nil)
 
+(defvoo nnimap-namespace nil)
+
 (defun nnimap-decode-gnus-group (group)
   (decode-coding-string group 'utf-8))
 
@@ -166,6 +175,19 @@ nnimap-quirks
 
 (defvar nnimap-inhibit-logging nil)
 
+(defun nnimap-group-to-imap (group)
+  "Convert Gnus group name to IMAP mailbox name."
+  (let* ((inbox (if nnimap-namespace
+                    (substring nnimap-namespace 0 -1) nil)))
+    (utf7-encode
+     (cond ((or (not inbox)
+                (string-equal group inbox))
+            group)
+           ((string-prefix-p "#" group)
+            (substring group 1))
+           (t
+            (concat nnimap-namespace group))) t)))
+
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
@@ -442,7 +464,8 @@ nnimap-open-connection-1
 	     (props (cdr stream-list))
 	     (greeting (plist-get props :greeting))
 	     (capabilities (plist-get props :capabilities))
-	     (stream-type (plist-get props :type)))
+	     (stream-type (plist-get props :type))
+             (server (nnoo-current-server 'nnimap)))
 	(when (and stream (not (memq (process-status stream) '(open run))))
 	  (setq stream nil))
 
@@ -475,9 +498,7 @@ nnimap-open-connection-1
                                ;; the virtual server name and the address
                                (nnimap-credentials
 				(gnus-delete-duplicates
-				 (list
-                                  (nnoo-current-server 'nnimap)
-				  nnimap-address))
+				 (list server nnimap-address))
                                 ports
                                 nnimap-user))))
 		  (setq nnimap-object nil)
@@ -496,8 +517,17 @@ nnimap-open-connection-1
 		      (dolist (response (cddr (nnimap-command "CAPABILITY")))
 			(when (string= "CAPABILITY" (upcase (car response)))
 			  (setf (nnimap-capabilities nnimap-object)
-				(mapcar #'upcase (cdr response))))))
-		  ;; If the login failed, then forget the credentials
+				(mapcar #'upcase (cdr response)))))
+                      (when (and nnimap-use-namespaces
+                                 (nnimap-capability "NAMESPACE"))
+                        (erase-buffer)
+                        (nnimap-wait-for-response (nnimap-send-command "NAMESPACE"))
+                        (let ((response (nnimap-last-response-string)))
+                          (when (string-match
+                                 "^\\*\\W+NAMESPACE\\W+((\"\\([^\"\n]+\\)\"\\W+\"\\(.\\)\"))\\W+"
+                                 response)
+                            (setq nnimap-namespace (match-string 1 response))))))
+                  ;; If the login failed, then forget the credentials
 		  ;; that are now possibly cached.
 		  (dolist (host (list (nnoo-current-server 'nnimap)
 				      nnimap-address))
@@ -837,7 +867,7 @@ nnimap-request-group-scan
       (with-current-buffer (nnimap-buffer)
 	(erase-buffer)
 	(let ((group-sequence
-	       (nnimap-send-command "SELECT %S" (utf7-encode group t)))
+	       (nnimap-send-command "SELECT %S" (nnimap-group-to-imap group)))
 	      (flag-sequence
 	       (nnimap-send-command "UID FETCH 1:* FLAGS")))
 	  (setf (nnimap-group nnimap-object) group)
@@ -870,13 +900,13 @@ nnimap-request-create-group
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
+      (car (nnimap-command "CREATE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-delete-group (group &optional _force server)
   (setq group (nnimap-decode-gnus-group group))
   (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
-      (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
+      (car (nnimap-command "DELETE %S" (nnimap-group-to-imap group))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -884,7 +914,7 @@ nnimap-request-rename-group
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
-			   (utf7-encode group t) (utf7-encode new-name t))))))
+			   (nnimap-group-to-imap group) (nnimap-group-to-imap new-name))))))
 
 (defun nnimap-unselect-group ()
   ;; Make sure we don't have this group open read/write by asking
@@ -944,7 +974,7 @@ nnimap-request-move-article
 				"UID COPY %d %S"))
 		     (result (nnimap-command
 			      command article
-			      (utf7-encode internal-move-group t))))
+                              (nnimap-group-to-imap internal-move-group))))
                 (when (and (car result) (not can-move))
                   (nnimap-delete-article article))
                 (cons internal-move-group
@@ -1011,7 +1041,7 @@ nnimap-process-expiry-targets
                     "UID MOVE %s %S"
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
-                (utf7-encode (gnus-group-real-name nnmail-expiry-target) t))
+                (nnimap-group-to-imap (gnus-group-real-name nnmail-expiry-target)))
                (set (if can-move 'deleted-articles 'articles-to-delete) articles))))
       t)
      (t
@@ -1136,7 +1166,7 @@ nnimap-request-update-group-status
 		      (unsubscribe "UNSUBSCRIBE")))))
       (when command
 	(with-current-buffer (nnimap-buffer)
-	  (nnimap-command "%s %S" (cadr command) (utf7-encode group t)))))))
+	  (nnimap-command "%s %S" (cadr command) (nnimap-group-to-imap group)))))))
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
@@ -1191,7 +1221,7 @@ nnimap-request-accept-article
 	    (nnimap-unselect-group))
 	  (erase-buffer)
 	  (setq sequence (nnimap-send-command
-			  "APPEND %S {%d}" (utf7-encode group t)
+			  "APPEND %S {%d}" (nnimap-group-to-imap group)
 			  (length message)))
 	  (unless nnimap-streaming
 	    (nnimap-wait-for-connection "^[+]"))
@@ -1271,8 +1301,12 @@ nnimap-add-cr
 
 (defun nnimap-get-groups ()
   (erase-buffer)
-  (let ((sequence (nnimap-send-command "LIST \"\" \"*\""))
-	groups)
+  (let* ((sequence (nnimap-send-command "LIST \"\" \"*\""))
+         (prefix nnimap-namespace)
+         (prefix-len (if prefix (length prefix) nil))
+         (inbox (if prefix
+                    (substring prefix 0 -1) nil))
+         groups)
     (nnimap-wait-for-response sequence)
     (subst-char-in-region (point-min) (point-max)
 			  ?\\ ?% t)
@@ -1289,11 +1323,16 @@ nnimap-get-groups
 			   (skip-chars-backward " \r\"")
 			   (point)))))
 	(unless (member '%NoSelect flags)
-	  (push (utf7-decode (if (stringp group)
-				 group
-			       (format "%s" group))
-                             t)
-		groups))))
+          (let* ((group (utf7-decode (if (stringp group) group
+                                       (format "%s" group)) t))
+                 (group (cond ((or (not prefix)
+                                   (equal inbox group))
+                               group)
+                              ((string-prefix-p prefix group)
+                               (substring group prefix-len))
+                              (t
+                               (concat "#" group)))))
+            (push group groups)))))
     (nreverse groups)))
 
 (defun nnimap-get-responses (sequences)
@@ -1319,7 +1358,7 @@ nnimap-request-list
 	    (dolist (group groups)
 	      (setf (nnimap-examined nnimap-object) group)
 	      (push (list (nnimap-send-command "EXAMINE %S"
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  group)
 		    sequences))
 	    (nnimap-wait-for-response (caar sequences))
@@ -1391,7 +1430,7 @@ nnimap-retrieve-group-data-early
 		   unexist)
 	      (push
 	       (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
-					  (utf7-encode group t)
+					  (nnimap-group-to-imap group)
 					  (nnimap-quirk "QRESYNC")
 					  uidvalidity modseq)
 		     'qresync
@@ -1413,7 +1452,7 @@ nnimap-retrieve-group-data-early
 		(cl-incf (nnimap-initial-resync nnimap-object))
 		(setq start 1))
 	      (push (list (nnimap-send-command "%s %S" command
-					       (utf7-encode group t))
+					       (nnimap-group-to-imap group))
 			  (nnimap-send-command "UID FETCH %d:* FLAGS" start)
 			  start group command)
 		    sequences))))
@@ -1847,7 +1886,7 @@ nnimap-change-group
                                       (if read-only
                                           "EXAMINE"
                                         "SELECT")
-                                      (utf7-encode group t))))
+                                      (nnimap-group-to-imap group))))
           (when (car result)
             (setf (nnimap-group nnimap-object) group
                   (nnimap-select-result nnimap-object) result)
@@ -2105,7 +2144,7 @@ nnimap-split-incoming-mail
 	    (dolist (spec specs)
 	      (when (and (not (member (car spec) groups))
 			 (not (eq (car spec) 'junk)))
-		(nnimap-command "CREATE %S" (utf7-encode (car spec) t))))
+		(nnimap-command "CREATE %S" (nnimap-group-to-imap (car spec)))))
 	    ;; Then copy over all the messages.
 	    (erase-buffer)
 	    (dolist (spec specs)
@@ -2121,7 +2160,7 @@ nnimap-split-incoming-mail
 				     "UID MOVE %s %S"
 				   "UID COPY %s %S")
 				 (nnimap-article-ranges ranges)
-				 (utf7-encode group t))
+				(nnimap-group-to-imap group))
 				ranges)
 			  sequences)))))
 	    ;; Wait for the last COPY response...
-- 
2.11.0


[-- Attachment #3: Type: text/plain, Size: 150 bytes --]



-- 
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-23 18:00                                   ` Nikolaus Rath
@ 2018-07-27  7:54                                     ` Nikolaus Rath
  2018-08-05  9:54                                       ` Nikolaus Rath
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-07-27  7:54 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

*ping*

Can we re-apply? Sounds like the issue is fixed.

Best,
Nikolaus


-- 
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-07-27  7:54                                     ` Nikolaus Rath
@ 2018-08-05  9:54                                       ` Nikolaus Rath
  2018-08-11  7:49                                         ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Nikolaus Rath @ 2018-08-05  9:54 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Eric Abrahamsen, Andreas Schwab, 21057

Friendly ping.. is there anything that blocks applying this?

Best,
-Nikolaus

--
GPG 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] 31+ messages in thread

* bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
  2018-08-05  9:54                                       ` Nikolaus Rath
@ 2018-08-11  7:49                                         ` Eli Zaretskii
  0 siblings, 0 replies; 31+ messages in thread
From: Eli Zaretskii @ 2018-08-11  7:49 UTC (permalink / raw)
  To: Nikolaus Rath; +Cc: eric, schwab, larsi, 21057-done

> From: Nikolaus Rath <nikolaus@rath.org>
> Date: Sun, 05 Aug 2018 10:54:27 +0100
> Cc: Eric Abrahamsen <eric@ericabrahamsen.net>, Andreas Schwab <schwab@suse.de>,
> 	21057@debbugs.gnu.org
> 
> Friendly ping.. is there anything that blocks applying this?

Pushed to the master branch.

In the future, please observe 2 spaces between sentences in
documentation and comments, and also mention the bug number in the
commit log message.





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

end of thread, other threads:[~2018-08-11  7:49 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <87si8qjhca.fsf@vostro.rath.org>
2017-01-26 19:40 ` bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces Lars Ingebrigtsen
2017-09-05 15:18 ` Nikolaus Rath
2017-09-05 15:26   ` Nikolaus Rath
2017-09-05 15:36     ` Andreas Schwab
2017-09-07 16:01       ` Nikolaus Rath
2017-09-13 17:30         ` Lars Ingebrigtsen
2017-09-17  8:16           ` Nikolaus Rath
2017-12-06 14:25             ` Nikolaus Rath
2017-12-27 21:10             ` Lars Ingebrigtsen
2018-05-31 11:38               ` Nikolaus Rath
2018-07-03  7:40                 ` Nikolaus Rath
2018-07-07  9:12                   ` Eli Zaretskii
2018-07-17 19:43                     ` Nikolaus Rath
2018-07-20  9:43                       ` Eli Zaretskii
2018-07-20 19:16                         ` Nikolaus Rath
2018-07-20 19:50                           ` Eli Zaretskii
2018-07-22 13:31                 ` Lars Ingebrigtsen
2018-07-23  6:00                   ` Eric Abrahamsen
2018-07-23  7:03                     ` Lars Ingebrigtsen
2018-07-23  7:22                       ` Nikolaus Rath
2018-07-23  7:39                         ` Lars Ingebrigtsen
2018-07-23  8:58                           ` Nikolaus Rath
2018-07-23  9:00                             ` Lars Ingebrigtsen
2018-07-23  9:01                             ` Lars Ingebrigtsen
2018-07-23  9:53                               ` Nikolaus Rath
2018-07-23 11:28                                 ` Robert Pluim
2018-07-23 18:00                                   ` Nikolaus Rath
2018-07-27  7:54                                     ` Nikolaus Rath
2018-08-05  9:54                                       ` Nikolaus Rath
2018-08-11  7:49                                         ` Eli Zaretskii
2018-07-23 16:47                                 ` Eric Abrahamsen

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).