X-Git-Url: https://code.delx.au/gnu-emacs-elpa/blobdiff_plain/1de79de6691409bbc044c614991a0c01bb72521f..212c8fc3101781a2f1c55ca61772eb75a2046e87:/company-clang.el diff --git a/company-clang.el b/company-clang.el index 14b6753e6..54d4b9b9c 100644 --- a/company-clang.el +++ b/company-clang.el @@ -1,6 +1,6 @@ -;;; company-clang.el --- company-mode completion back-end for Clang -*- lexical-binding: t -*- +;;; company-clang.el --- company-mode completion backend for Clang -*- lexical-binding: t -*- -;; Copyright (C) 2009, 2011, 2013-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009, 2011, 2013-2016 Free Software Foundation, Inc. ;; Author: Nikolaj Schumacher @@ -30,7 +30,7 @@ (require 'cl-lib) (defgroup company-clang nil - "Completion back-end for Clang." + "Completion backend for Clang." :group 'company) (defcustom company-clang-executable @@ -51,7 +51,7 @@ and `c-electric-colon', for automatic completion right after \">\" and "Additional arguments to pass to clang when completing. Prefix files (-include ...) can be selected with `company-clang-set-prefix' or automatically through a custom `company-clang-prefix-guesser'." - :type '(repeat (string :tag "Argument" nil))) + :type '(repeat (string :tag "Argument"))) (defcustom company-clang-prefix-guesser 'company-clang-guess-prefix "A function to determine the prefix file for the current buffer." @@ -60,6 +60,11 @@ or automatically through a custom `company-clang-prefix-guesser'." (defvar company-clang-modes '(c-mode c++-mode objc-mode) "Major modes which clang may complete.") +(defcustom company-clang-insert-arguments t + "When non-nil, insert function arguments as a template after completion." + :type 'boolean + :package-version '(company . "0.8.0")) + ;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar company-clang--prefix nil) @@ -139,13 +144,31 @@ or automatically through a custom `company-clang-prefix-guesser'." (get-text-property 0 'meta candidate)) (defun company-clang--annotation (candidate) + (let ((ann (company-clang--annotation-1 candidate))) + (if (not (and ann (string-prefix-p "(*)" ann))) + ann + (with-temp-buffer + (insert ann) + (search-backward ")") + (let ((pt (1+ (point)))) + (re-search-forward ".\\_>" nil t) + (delete-region pt (point))) + (buffer-string))))) + +(defun company-clang--annotation-1 (candidate) (let ((meta (company-clang--meta candidate))) (cond ((null meta) nil) - ((string-match ":" meta) - (substring meta (match-beginning 0))) - ((string-match "\\((.*)\\'\\)" meta) - (match-string 1 meta))))) + ((string-match "[^:]:[^:]" meta) + (substring meta (1+ (match-beginning 0)))) + ((string-match "\\((.*)[ a-z]*\\'\\)" meta) + (let ((paren (match-beginning 1))) + (if (not (eq (aref meta (1- paren)) ?>)) + (match-string 1 meta) + (with-temp-buffer + (insert meta) + (goto-char paren) + (substring meta (1- (search-backward "<")))))))))) (defun company-clang--strip-formatting (text) (replace-regexp-in-string @@ -177,10 +200,14 @@ or automatically through a custom `company-clang-prefix-guesser'." (defun company-clang--start-process (prefix callback &rest args) (let ((objc (derived-mode-p 'objc-mode)) - (buf (get-buffer-create "*clang-output*"))) - (with-current-buffer buf (erase-buffer)) + (buf (get-buffer-create "*clang-output*")) + ;; Looks unnecessary in Emacs 25.1 and later. + (process-adaptive-read-buffering nil)) (if (get-buffer-process buf) (funcall callback nil) + (with-current-buffer buf + (erase-buffer) + (setq buffer-undo-list t)) (let ((process (apply #'start-process "company-clang" buf company-clang-executable args))) (set-process-sentinel @@ -214,14 +241,14 @@ or automatically through a custom `company-clang-prefix-guesser'." t)))))) (defsubst company-clang--build-complete-args (pos) - (append '("-cc1" "-fsyntax-only" "-code-completion-macros") + (append '("-fsyntax-only" "-Xclang" "-code-completion-macros") (unless (company-clang--auto-save-p) (list "-x" (company-clang--lang-option))) company-clang-arguments (when (stringp company-clang--prefix) (list "-include" (expand-file-name company-clang--prefix))) - '("-code-completion-at") - (list (company-clang--build-location pos)) + (list "-Xclang" (format "-code-completion-at=%s" + (company-clang--build-location pos))) (list (if (company-clang--auto-save-p) buffer-file-name "-")))) (defun company-clang--candidates (prefix callback) @@ -262,26 +289,8 @@ or automatically through a custom `company-clang-prefix-guesser'." ver)) 0))) -(defun company-clang-objc-templatify (selector) - (let* ((end (point-marker)) - (beg (- (point) (length selector) 1)) - (templ (company-template-declare-template beg end)) - (cnt 0)) - (save-excursion - (goto-char beg) - (catch 'stop - (while (search-forward ":" end t) - (when (looking-at "([^)]*) ?") - (delete-region (match-beginning 0) (match-end 0))) - (company-template-add-field templ (point) (format "arg%d" cnt)) - (if (< (point) end) - (insert " ") - (throw 'stop t)) - (cl-incf cnt)))) - (company-template-move-to-first templ))) - (defun company-clang (command &optional arg &rest ignored) - "`company-mode' completion back-end for Clang. + "`company-mode' completion backend for Clang. Clang is a parser for C and ObjC. Clang version 1.1 or newer is required. Additional command line arguments can be specified in @@ -311,11 +320,12 @@ passed via standard input." (meta (company-clang--meta arg)) (annotation (company-clang--annotation arg)) (post-completion (let ((anno (company-clang--annotation arg))) - (when anno + (when (and company-clang-insert-arguments anno) (insert anno) - (if (string-match ":" anno) - (company-clang-objc-templatify anno) - (company-template-c-like-templatify anno))))))) + (if (string-match "\\`:[^:]" anno) + (company-template-objc-templatify anno) + (company-template-c-like-templatify + (concat arg anno)))))))) (provide 'company-clang) ;;; company-clang.el ends here