From 433fee565a134ed119c13ad0ae9e987a44ff2d19 Mon Sep 17 00:00:00 2001 From: Mark Walters Date: Tue, 27 Oct 2015 09:05:28 +0000 Subject: [PATCH] [PATCH (draft)] company model for external programs --- 62/3b7e266e5ed120f8b52c891970f549cfbdd3ca | 191 ++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 62/3b7e266e5ed120f8b52c891970f549cfbdd3ca diff --git a/62/3b7e266e5ed120f8b52c891970f549cfbdd3ca b/62/3b7e266e5ed120f8b52c891970f549cfbdd3ca new file mode 100644 index 000000000..6c5465803 --- /dev/null +++ b/62/3b7e266e5ed120f8b52c891970f549cfbdd3ca @@ -0,0 +1,191 @@ +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 393086DE1733 + for ; Tue, 27 Oct 2015 02:05:37 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at cworth.org +X-Spam-Flag: NO +X-Spam-Score: -0.124 +X-Spam-Level: +X-Spam-Status: No, score=-0.124 tagged_above=-999 required=5 tests=[AWL=0.446, + 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] + 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 53f91SiiWBEI for ; + Tue, 27 Oct 2015 02:05:35 -0700 (PDT) +Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com + [209.85.212.173]) + by arlo.cworth.org (Postfix) with ESMTPS id E2FCA6DE13EF + for ; Tue, 27 Oct 2015 02:05:34 -0700 (PDT) +Received: by wicll6 with SMTP id ll6so149967543wic.1 + for ; Tue, 27 Oct 2015 02:05:31 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; + h=from:to:cc:subject:date:message-id; + bh=6YOP8beHAArwmZTj4i+0EcVohWzQRKcyC01X5S9uqI4=; + b=W2disYO3WsNJZoB7UPcDZw6uGWbx26LJkky8OJco3Y7irMQJmrzGZhaf1a0+7x1DFI + uQVRgkZcMCGngQoHJhUJhOIyzoVDL7p532uXeSY4hHVKp7GagPdOYtxoRhl+akB77IEH + QUr+eaNEz5kbd/5Wgw6kmpE6kIGAgS/WqgvM3JX150c4veu3uDVbbvyMUJj88iSJZAF6 + E0SjUtaNwVIxhfcxidzW50cldr7fTzDANieHvvd+LQfUcP9pOlc6w378KgqXJrozE6P+ + Twl1Ua30QkDIB845BQRzxjKYUOnV0QdxeXU2urNiQXwen5TAoj9zb6Gw9bK0k2HER3wS + SoDA== +X-Received: by 10.194.59.137 with SMTP id z9mr25820928wjq.28.1445936731562; + Tue, 27 Oct 2015 02:05:31 -0700 (PDT) +Received: from localhost (5751dfa2.skybroadband.com. [87.81.223.162]) + by smtp.gmail.com with ESMTPSA id q8sm16965563wiz.23.2015.10.27.02.05.30 + (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); + Tue, 27 Oct 2015 02:05:31 -0700 (PDT) +From: Mark Walters +To: notmuch@notmuchmail.org +Subject: [PATCH (draft)] company model for external programs +Date: Tue, 27 Oct 2015 09:05:28 +0000 +Message-Id: <1445936728-30840-1-git-send-email-markwalters1009@gmail.com> +X-Mailer: git-send-email 2.1.4 +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: Tue, 27 Oct 2015 09:05:37 -0000 + +--- + +This is an attempt to make company mode work for external address +completion programs. We need to be able to run the address completion +asynchronously. + +The changes are three fold: separate out the internal completion code +into its own function, allow the external program to be called +asynchronously, and copy the relevant code from the emacs function +process-lines into our function as it doesn't appear to be available +as a separate function. + +It seems to work in light testing but asynchronous emacs is always a +little fragile/tricky. + +Best wishes + +Mark + + + +emacs/notmuch-address.el | 2 +- + emacs/notmuch-company.el | 65 +++++++++++++++++++++++++++++++++++++----------- + 2 files changed, 51 insertions(+), 16 deletions(-) + +diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el +index 49e2402..65d04ce 100644 +--- a/emacs/notmuch-address.el ++++ b/emacs/notmuch-address.el +@@ -81,7 +81,7 @@ (defcustom notmuch-address-use-company t + + (defun notmuch-address-setup () + (let* ((use-company (and notmuch-address-use-company +- (eq notmuch-address-command 'internal) ++ ;; (eq notmuch-address-command 'internal) + (require 'company nil t))) + (pair (cons notmuch-address-completion-headers-regexp + (if use-company +diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el +index add3161..dc3d018 100644 +--- a/emacs/notmuch-company.el ++++ b/emacs/notmuch-company.el +@@ -42,6 +42,7 @@ (defvar company-backends) + (declare-function notmuch-address-matching "notmuch-address") + (defvar notmuch-address-full-harvest-finished) + (defvar notmuch-address-completion-headers-regexp) ++(defvar notmuch-address-command) + + ;;;###autoload + (defun notmuch-company-setup () +@@ -49,6 +50,54 @@ (defun notmuch-company-setup () + (make-local-variable 'company-backends) + (setq company-backends '(notmuch-company))) + ++(defun notmuch-company-address-internal (arg) ++ (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 start the (potentially long-running) full asynchronous harvest if necessary ++ (notmuch-address-harvest-trigger)))))))) ++ ++(defun notmuch-company-external-sentinel (callback proc _event) ++ (let (lines) ++ (with-current-buffer (process-buffer proc) ++ ;; Copied verbatim from the process-lines function in subr.el in ++ ;; the standard emacs distribution. ++ (goto-char (point-min)) ++ (while (not (eobp)) ++ (setq lines (cons (buffer-substring-no-properties ++ (line-beginning-position) ++ (line-end-position)) ++ lines)) ++ (forward-line 1)) ++ (message "lines %s" lines)) ++ (kill-buffer (process-buffer proc)) ++ (funcall callback (nreverse lines)))) ++ ++(defun notmuch-company-address-external (arg) ++ (cons :async ++ (lambda (callback) ++ (let* ((buf (generate-new-buffer " *notmuch-external-address*")) ++ (proc (start-process "notmuch-external-address" buf ++ notmuch-address-command arg))) ++ (set-process-sentinel proc (apply-partially ++ 'notmuch-company-external-sentinel ++ callback)))))) ++ ++(defun notmuch-company-address (arg) ++ (if (eq notmuch-address-command 'internal) ++ (notmuch-company-address-internal arg) ++ (notmuch-company-address-external arg))) ++ + ;;;###autoload + (defun notmuch-company (command &optional arg &rest _ignore) + "`company-mode' completion back-end for `notmuch'." +@@ -62,21 +111,7 @@ (defun notmuch-company (command &optional arg &rest _ignore) + (looking-back (concat notmuch-address-completion-headers-regexp ".*") + (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 start the (potentially long-running) full asynchronous harvest if necessary +- (notmuch-address-harvest-trigger)))))))) ++ (candidates (notmuch-company-address arg)) + (match (if (string-match notmuch-company-last-prefix arg) + (match-end 0) + 0)) +-- +2.1.4 + -- 2.26.2