From: Nikolaus Rath <Nikolaus@rath.org>
To: 21057@debbugs.gnu.org
Cc: Lars Ingebrigtsen <larsi@gnus.org>
Subject: bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces
Date: Tue, 05 Sep 2017 17:26:23 +0200 [thread overview]
Message-ID: <87a829f9pc.fsf@thinkpad.rath.org> (raw)
In-Reply-To: <87efrlfa20.fsf@thinkpad.rath.org> (Nikolaus Rath's message of "Tue, 05 Sep 2017 17:18:47 +0200")
[-- 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
next prev parent reply other threads:[~2017-09-05 15:26 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-13 1:52 bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces Nikolaus Rath
2017-01-26 19:40 ` Lars Ingebrigtsen
2017-09-05 15:18 ` Nikolaus Rath
2017-09-05 15:26 ` Nikolaus Rath [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87a829f9pc.fsf@thinkpad.rath.org \
--to=nikolaus@rath.org \
--cc=21057@debbugs.gnu.org \
--cc=larsi@gnus.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.