From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Nikolaus Rath Newsgroups: gmane.emacs.bugs Subject: bug#21057: [PATCH] nnimap.el: add support for IMAP namespaces Date: Sun, 17 Sep 2017 09:16:49 +0100 Message-ID: <877ewxoi32.fsf@vostro.rath.org> References: <87efrlfa20.fsf@thinkpad.rath.org> <87a829f9pc.fsf@thinkpad.rath.org> <1504800077.365137.1098530944.678C4105@webmail.messagingengine.com> <87k212zetg.fsf@mouse.gnus.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1505636295 6834 195.159.176.226 (17 Sep 2017 08:18:15 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 17 Sep 2017 08:18:15 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) Cc: Andreas Schwab , 21057@debbugs.gnu.org To: Lars Ingebrigtsen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Sep 17 10:18:09 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dtUmF-0001W7-It for geb-bug-gnu-emacs@m.gmane.org; Sun, 17 Sep 2017 10:18:07 +0200 Original-Received: from localhost ([::1]:59723 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dtUmN-0002Jq-0M for geb-bug-gnu-emacs@m.gmane.org; Sun, 17 Sep 2017 04:18:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:48583) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dtUmE-0002JI-GT for bug-gnu-emacs@gnu.org; Sun, 17 Sep 2017 04:18:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dtUmA-0007VP-PU for bug-gnu-emacs@gnu.org; Sun, 17 Sep 2017 04:18:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:35747) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dtUmA-0007VD-FW for bug-gnu-emacs@gnu.org; Sun, 17 Sep 2017 04:18:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dtUm9-00054V-Lw; Sun, 17 Sep 2017 04:18:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Nikolaus Rath Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bugs@gnus.org Resent-Date: Sun, 17 Sep 2017 08:18:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21057 X-GNU-PR-Package: emacs,gnus X-GNU-PR-Keywords: patch Original-Received: via spool by 21057-submit@debbugs.gnu.org id=B21057.150563622119425 (code B ref 21057); Sun, 17 Sep 2017 08:18:01 +0000 Original-Received: (at 21057) by debbugs.gnu.org; 17 Sep 2017 08:17:01 +0000 Original-Received: from localhost ([127.0.0.1]:44428 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dtUl8-00052r-3c for submit@debbugs.gnu.org; Sun, 17 Sep 2017 04:17:01 -0400 Original-Received: from out1-smtp.messagingengine.com ([66.111.4.25]:53581) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dtUl3-00052f-2w for 21057@debbugs.gnu.org; Sun, 17 Sep 2017 04:16:57 -0400 Original-Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 6219B21130; Sun, 17 Sep 2017 04:16:52 -0400 (EDT) Original-Received: from frontend1 ([10.202.2.160]) by compute1.internal (MEProxy); Sun, 17 Sep 2017 04:16:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc:x-sasl-enc; s=fm1; bh=WF04wdoebm+Tw7G4iY V3Yl7cg4/zJgs0xB2l9Dd/Hb8=; b=c4HCSKhYbF5ZACzpw+ONjzpt00h4kPXzeT KqduPl9JnJYuBEr1FsGAWam0rM8u+p/dNPKzVdM2Z7COHnTL31Mfky8BUfKadIhX LxyeQbwdcc4zAeBt4xs4uW6wA1fmH8XIrrW2Gf8DXsvuORIFrx1kpw4Ufgkkxd7x D8OCKQ94C4Y+jMIsojcb/ZNft8IeDrcMdsUtCC2tHcSKpe1B0dg38JsNg2pqZ0oo gJAH28GyoWOeuQMsWOWfVoWdoqUsI7tZfPMCkovm7BreVpQLZLYic7lfGMjZ4obU 8gX+zNywwo6LAACu0kCx3L/ZUX7UHXTgqzLZphYGQqIQzDCagXKQ== X-ME-Sender: X-Sasl-enc: PyXAT2Y6+W4a6wL2Y5pDKL+TgNDXhtVuABPbGnLK8/H+ 1505636212 Original-Received: from ebox.rath.org (ebox.rath.org [45.79.69.51]) by mail.messagingengine.com (Postfix) with ESMTPA id 10C497F955; Sun, 17 Sep 2017 04:16:52 -0400 (EDT) Original-Received: from vostro.rath.org (vostro [192.168.12.4]) by ebox.rath.org (Postfix) with ESMTPS id 02AED195; Sun, 17 Sep 2017 08:16:51 +0000 (UTC) Original-Received: by vostro.rath.org (Postfix, from userid 1000) id 94AE91023AF; Sun, 17 Sep 2017 09:16:49 +0100 (BST) In-Reply-To: <87k212zetg.fsf@mouse.gnus.org> (Lars Ingebrigtsen's message of "Wed, 13 Sep 2017 19:30:35 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:137023 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sep 13 2017, Lars Ingebrigtsen wrote: > Nikolaus Rath 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 --=20 GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F =C2=BBTime flies like an arrow, fruit flies like a Banana.=C2= =AB --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-nnimap.el-factor-out-nnimap-group-to-imap.patch >From 2c1c2ccaeb0c19649d125b64fe3f917c7a3fbb76 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath 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 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0002-nnimap.el-Add-support-for-IMAP-namespaces.patch >From f5079a11c20944027465ea21291a8fc9e7ad3be1 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath 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, * Changes in Specialized Modes and Packages in Emacs 27.1 +** Gnus + ++++ +*** The nnimap backend now has support for IMAP namespaces. + * 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 --=-=-=--