From 5cef93597739782b9be4b9ffdae686cffc0c7946 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Tue, 1 Apr 2014 08:07:51 +0300 Subject: [PATCH] Make company-clang work asynchronously #62 --- company-clang.el | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/company-clang.el b/company-clang.el index 787ecef6e..42a548784 100644 --- a/company-clang.el +++ b/company-clang.el @@ -1,6 +1,6 @@ -;;; company-clang.el --- company-mode completion back-end for Clang +;;; company-clang.el --- company-mode completion back-end for Clang -*- lexical-binding: t -*- -;; Copyright (C) 2009, 2011, 2013 Free Software Foundation, Inc. +;; Copyright (C) 2009, 2011, 2013-2014 Free Software Foundation, Inc. ;; Author: Nikolaj Schumacher @@ -107,7 +107,7 @@ or automatically through a custom `company-clang-prefix-guesser'." (defconst company-clang--completion-pattern "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$") -(defconst company-clang--error-buffer-name "*clang error*") +(defconst company-clang--error-buffer-name "*clang-error*") (defun company-clang--lang-option () (if (eq major-mode 'objc-mode) @@ -175,20 +175,30 @@ or automatically through a custom `company-clang-prefix-guesser'." (setq buffer-read-only t) (goto-char (point-min)))))) -(defun company-clang--call-process (prefix &rest args) +(defun company-clang--start-process (prefix callback &rest args) (let ((objc (derived-mode-p 'objc-mode)) - (buf (get-buffer-create "*clang-output*")) - res) + (buf (get-buffer-create "*clang-output*"))) (with-current-buffer buf (erase-buffer)) - (setq res (if (company-clang--auto-save-p) - (apply 'call-process company-clang-executable nil buf nil args) - (apply 'call-process-region (point-min) (point-max) - company-clang-executable nil buf nil args))) - (with-current-buffer buf - (unless (eq 0 res) - (company-clang--handle-error res args)) - ;; Still try to get any useful input. - (company-clang--parse-output prefix objc)))) + (if (get-buffer-process buf) + (funcall callback nil) + (let ((process (apply #'start-process "company-clang" buf + company-clang-executable args))) + (set-process-sentinel + process + (lambda (proc status) + (unless (string-match-p "hangup" status) + (funcall + callback + (let ((res (process-exit-status proc))) + (with-current-buffer buf + (unless (eq 0 res) + (company-clang--handle-error res args)) + ;; Still try to get any useful input. + (company-clang--parse-output prefix objc))))))) + (unless (company-clang--auto-save-p) + (send-region process (point-min) (point-max)) + (send-string process "\n") + (process-send-eof process)))))) (defsubst company-clang--build-location (pos) (save-excursion @@ -214,15 +224,16 @@ or automatically through a custom `company-clang-prefix-guesser'." (list (company-clang--build-location pos)) (list (if (company-clang--auto-save-p) buffer-file-name "-")))) -(defun company-clang--candidates (prefix) +(defun company-clang--candidates (prefix callback) (and (company-clang--auto-save-p) (buffer-modified-p) (basic-save-buffer)) (when (null company-clang--prefix) (company-clang-set-prefix (or (funcall company-clang-prefix-guesser) 'none))) - (apply 'company-clang--call-process + (apply 'company-clang--start-process prefix + callback (company-clang--build-complete-args (- (point) (length prefix))))) (defun company-clang--prefix () @@ -301,7 +312,8 @@ passed via standard input." company-clang-executable (not (company-in-string-or-comment)) (company-clang--prefix))) - (candidates (company-clang--candidates arg)) + (candidates (cons :async + (lambda (cb) (company-clang--candidates arg cb)))) (meta (company-clang--meta arg)) (annotation (company-clang--annotation arg)) (post-completion (let ((anno (company-clang--annotation arg))) -- 2.39.2