-;;; 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
(require 'cl-lib)
(defgroup company-clang nil
- "Completion back-end for Clang."
+ "Completion backend for Clang."
:group 'company)
(defcustom company-clang-executable
"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."
"Major modes which clang may complete.")
(defcustom company-clang-insert-arguments t
- "When non-nil, insert function arguments as a template after completion.")
+ "When non-nil, insert function arguments as a template after completion."
+ :type 'boolean
+ :package-version '(company . "0.8.0"))
;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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
(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
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)
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
(post-completion (let ((anno (company-clang--annotation arg)))
(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