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