Re: [PATCH 3/3] Emacs: Add address completion based on company-mode
authorMark Walters <markwalters1009@gmail.com>
Sat, 24 Oct 2015 23:34:17 +0000 (00:34 +0100)
committerW. Trevor King <wking@tremily.us>
Sat, 20 Aug 2016 21:49:55 +0000 (14:49 -0700)
83/7f799c5cdaad7ecf47240eb55974b822da935b [new file with mode: 0644]

diff --git a/83/7f799c5cdaad7ecf47240eb55974b822da935b b/83/7f799c5cdaad7ecf47240eb55974b822da935b
new file mode 100644 (file)
index 0000000..e6dd0e2
--- /dev/null
@@ -0,0 +1,244 @@
+Return-Path: <markwalters1009@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 4E2406DE17EF\r
+ for <notmuch@notmuchmail.org>; Sat, 24 Oct 2015 16:34:26 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at cworth.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0.276\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0.276 tagged_above=-999 required=5 tests=[AWL=0.102, \r
+ DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+ FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,\r
+ RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01,\r
+ RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, URIBL_SBL=0.644,\r
+ URIBL_SBL_A=0.1] autolearn=disabled\r
+Received: from arlo.cworth.org ([127.0.0.1])\r
+ by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id 2q5jFyltyGhn for <notmuch@notmuchmail.org>;\r
+ Sat, 24 Oct 2015 16:34:23 -0700 (PDT)\r
+Received: from mail-wi0-f172.google.com (mail-wi0-f172.google.com\r
+ [209.85.212.172])\r
+ by arlo.cworth.org (Postfix) with ESMTPS id 26D466DE17A4\r
+ for <notmuch@notmuchmail.org>; Sat, 24 Oct 2015 16:34:23 -0700 (PDT)\r
+Received: by wicfx6 with SMTP id fx6so71410167wic.1\r
+ for <notmuch@notmuchmail.org>; Sat, 24 Oct 2015 16:34:21 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r
+ h=from:to:cc:subject:in-reply-to:references:user-agent:date\r
+ :message-id:mime-version:content-type;\r
+ bh=p0YTSE7RHIKMS8J/L6g7+MJBON+FTorskSWp4HNMYs0=;\r
+ b=XcFIdFKAFU/WYJgmPzp+Ty2e9FXNFgOLqMA7eFTO8Ls4ZjL+3bagkX6wYtRp0G/U8n\r
+ e5/KjVGm4Bi88f+jZju/iBQ4se72KEEwH20dwu1qDjERwdKs9Zmx3o5GFd3uGo4L775p\r
+ SzMEXsyyC7ybbYibnZR3vKAUcwhxQJ5htzfHi9/3N/g5fQ79FY3vdXDPXJZ2Q7SvvLSt\r
+ NNQR08unZfDwho6hYHg+MHwaIyIqmQ6muG+MkGYKU9mxmhSFnXK/D3+kBtOd9pE/xyJc\r
+ y+oTgoyS85d5fSN4nQneZDKGqxuB8Pfc1vrr+EpLbS0opnocn1DIyxvZPtx8ps05R21q\r
+ sZDQ==\r
+X-Received: by 10.194.48.113 with SMTP id k17mr12132347wjn.62.1445729661356;\r
+ Sat, 24 Oct 2015 16:34:21 -0700 (PDT)\r
+Received: from localhost (5751dfa2.skybroadband.com. [87.81.223.162])\r
+ by smtp.gmail.com with ESMTPSA id hk5sm30494962wjb.6.2015.10.24.16.34.19\r
+ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\r
+ Sat, 24 Oct 2015 16:34:20 -0700 (PDT)\r
+From: Mark Walters <markwalters1009@gmail.com>\r
+To: David Bremner <david@tethera.net>, notmuch@notmuchmail.org\r
+Subject: Re: [PATCH 3/3] Emacs: Add address completion based on company-mode\r
+In-Reply-To: <1445708484-32189-4-git-send-email-david@tethera.net>\r
+References: <1445702019-10638-1-git-send-email-markwalters1009@gmail.com>\r
+ <1445708484-32189-1-git-send-email-david@tethera.net>\r
+ <1445708484-32189-4-git-send-email-david@tethera.net>\r
+User-Agent: Notmuch/0.21~rc1+29~g057f24d (http://notmuchmail.org) Emacs/23.4.1\r
+ (x86_64-pc-linux-gnu)\r
+Date: Sun, 25 Oct 2015 00:34:17 +0100\r
+Message-ID: <87lhardeo6.fsf@qmul.ac.uk>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.20\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sat, 24 Oct 2015 23:34:26 -0000\r
+\r
+On Sat, 24 Oct 2015, David Bremner <david@tethera.net> wrote:\r
+> From: Michal Sojka <sojkam1@fel.cvut.cz>\r
+>\r
+> With this patch, address completion candidates are shown automatically\r
+> after short typing delay in a nice popup box. This requires company-mode\r
+> to be installed and it works only on Emacs >= 24. The completion is\r
+> based entirely on the asynchronous address harvesting from\r
+> notmuch-address.el so the GUI is theoretically not blocked for long\r
+> time.\r
+>\r
+> The completion works similarly as the TAB-initiated completion from\r
+> notmuch-address.el, i.e. quick harvest based on user input is executed\r
+> first and only after full harvesting is finished, in-memory cached data\r
+> is used.\r
+> ---\r
+>  emacs/Makefile.local     |  1 +\r
+>  emacs/notmuch-company.el | 73 ++++++++++++++++++++++++++++++++++++++++++++++++\r
+>  emacs/notmuch-mua.el     | 13 ++++++++-\r
+>  3 files changed, 86 insertions(+), 1 deletion(-)\r
+>  create mode 100644 emacs/notmuch-company.el\r
+>\r
+> diff --git a/emacs/Makefile.local b/emacs/Makefile.local\r
+> index 1109cfa..4c06c52 100644\r
+> --- a/emacs/Makefile.local\r
+> +++ b/emacs/Makefile.local\r
+> @@ -20,6 +20,7 @@ emacs_sources := \\r
+>      $(dir)/notmuch-print.el \\r
+>      $(dir)/notmuch-version.el \\r
+>      $(dir)/notmuch-jump.el \\r
+> +    $(dir)/notmuch-company.el\r
+>  \r
+>  $(dir)/notmuch-version.el: $(dir)/Makefile.local version.stamp\r
+>  $(dir)/notmuch-version.el: $(srcdir)/$(dir)/notmuch-version.el.tmpl\r
+> diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el\r
+> new file mode 100644\r
+> index 0000000..03c492f\r
+> --- /dev/null\r
+> +++ b/emacs/notmuch-company.el\r
+> @@ -0,0 +1,73 @@\r
+> +;; notmuch-company.el --- Mail address completion for notmuch via company-mode  -*- lexical-binding: t -*-\r
+> +\r
+> +\r
+> +;; Authors: Trevor Jim <tjim@mac.com>\r
+> +;;      Michal Sojka <sojkam1@fel.cvut.cz>\r
+> +;;\r
+> +;; Keywords: mail, completion\r
+> +\r
+> +;; This program is free software; you can redistribute it and/or modify\r
+> +;; it under the terms of the GNU General Public License as published by\r
+> +;; the Free Software Foundation, either version 3 of the License, or\r
+> +;; (at your option) any later version.\r
+> +\r
+> +;; This program is distributed in the hope that it will be useful,\r
+> +;; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+> +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+> +;; GNU General Public License for more details.\r
+> +\r
+> +;; You should have received a copy of the GNU General Public License\r
+> +;; along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+> +\r
+> +;;; Commentary:\r
+> +\r
+> +;; To enable this, install company mode (https://company-mode.github.io/)\r
+> +;; and customize notmuch-message-use-company\r
+> +;;\r
+> +;; NB company-minimum-prefix-length defaults to 3 so you don't get\r
+> +;; completion unless you type 3 characters\r
+> +\r
+> +;;; Code:\r
+> +\r
+> +(require 'notmuch-address)\r
+> +(require 'cl-lib)\r
+> +\r
+> +(defvar-local notmuch-company-last-prefix nil)\r
+> +(declare-function company-begin-backend "company")\r
+> +(declare-function company-grab "company")\r
+> +\r
+> +;;;###autoload\r
+> +(defun notmuch-company (command &optional arg &rest _ignore)\r
+> +  "`company-mode' completion back-end for `notmuch'."\r
+> +  (interactive (list 'interactive))\r
+> +  (require 'company)\r
+> +  (let ((case-fold-search t)\r
+> +    (completion-ignore-case t))\r
+> +    (cl-case command\r
+> +      (interactive (company-begin-backend 'notmuch-company))\r
+> +      (prefix (and (derived-mode-p 'message-mode)\r
+> +               (looking-back "^\\(To\\|Cc\\|Bcc\\):.*"\r
+> +                             (line-beginning-position))\r
+> +               (setq notmuch-company-last-prefix (company-grab "[:,][ \t]*\\(.*\\)" 1 (point-at-bol)))))\r
+> +      (candidates (cond\r
+> +               (notmuch-address-full-harvest-finished\r
+> +                ;; Update harvested addressed from time to time\r
+> +                (notmuch-address-harvest-trigger)\r
+> +                (notmuch-address-matching arg))\r
+> +               (t\r
+> +                (cons :async\r
+> +                      (lambda (callback)\r
+> +                        ;; First run quick asynchronous harvest based on what the user entered so far\r
+> +                        (notmuch-address-harvest\r
+> +                         (format "to:%s*" arg) nil\r
+> +                         (lambda (_proc _event)\r
+> +                           (funcall callback (notmuch-address-matching arg))\r
+> +                           ;; Then (re)start potentially long-running full asynchronous harvesting\r
+> +                           (notmuch-address-harvest-trigger))))))))\r
+\r
+I have found a bug in this but I don't know the best way to fix it.\r
+\r
+If you start notmuch in emacs, start composing a message, type 3 letters\r
+(say) in the to line and press tab then you get the "quick" address\r
+completion, and it starts the full harvest. However if you don't select\r
+one of the addresses and just type another character and pause then\r
+notmuch-company starts and it sees that you haven't got a full harvest\r
+so it asynchronously gets the quick completions. But this kills the main\r
+harvest (the "; this also kills the process" line in\r
+notmuch-address.el). The sentinel for the full harvest then marks the\r
+full harvest complete.\r
+\r
+Since it is marked complete the full harvest won't ever get done (or\r
+not until the completion timeouts in 24 hours). \r
+\r
+The first part of the fix is probably to only mark the harvest complete\r
+if the sentinel returns normally. But it may need more, perhaps to run\r
+the async quick case in a separate buffer from the full harvest.\r
+\r
+Best wishes\r
+\r
+Mark\r
+\r
+\r
+> +      (match (if (string-match notmuch-company-last-prefix arg)\r
+> +             (match-end 0)\r
+> +           0))\r
+> +      (no-cache t))))\r
+> +\r
+> +\r
+> +(provide 'notmuch-company)\r
+> diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el\r
+> index 6cc9656..c90381d 100644\r
+> --- a/emacs/notmuch-mua.el\r
+> +++ b/emacs/notmuch-mua.el\r
+> @@ -25,6 +25,7 @@\r
+>  \r
+>  (require 'notmuch-lib)\r
+>  (require 'notmuch-address)\r
+> +(require 'notmuch-company)\r
+>  \r
+>  (eval-when-compile (require 'cl))\r
+>  \r
+> @@ -268,12 +269,22 @@ Note that these functions use `mail-citation-hook' if that is non-nil."\r
+>    (message-goto-body)\r
+>    (set-buffer-modified-p nil))\r
+>  \r
+> +(defcustom notmuch-message-use-company t\r
+> +  "If available, use company mode for completion in notmuch-message-mode"\r
+> +  :type 'boolean\r
+> +  :group 'notmuch-send)\r
+> +\r
+>  (define-derived-mode notmuch-message-mode message-mode "Message[Notmuch]"\r
+>    "Notmuch message composition mode. Mostly like `message-mode'"\r
+>    (when notmuch-address-command\r
+>      (unless (memq notmuch-address-message-alist-member message-completion-alist)\r
+>        (setq message-completion-alist\r
+> -        (push notmuch-address-message-alist-member message-completion-alist)))))\r
+> +        (push notmuch-address-message-alist-member message-completion-alist))))\r
+> +  (when (and notmuch-message-use-company\r
+> +         (require 'company nil t))\r
+> +    (company-mode)\r
+> +    (make-local-variable 'company-backends)\r
+> +    (setq company-backends '(notmuch-company))))\r
+>  \r
+>  (define-key notmuch-message-mode-map (kbd "C-c C-c") #'notmuch-mua-send-and-exit)\r
+>  (define-key notmuch-message-mode-map (kbd "C-c C-s") #'notmuch-mua-send)\r
+> -- \r
+> 2.6.1\r