]> code.delx.au - gnu-emacs-elpa/blobdiff - company-clang.el
company-clang: Only initialize in supported major modes
[gnu-emacs-elpa] / company-clang.el
index 7613e317a12e6d009e7d416306b7c9ba52df19de..6b80ef02f77fb4b324a2ef50deeea11017392a07 100644 (file)
@@ -1,6 +1,6 @@
 ;;; company-clang.el --- A company-mode completion back-end for clang
 
-;; Copyright (C) 2009, 2011  Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011, 2013  Free Software Foundation, Inc.
 
 ;; Author: Nikolaj Schumacher
 
@@ -77,7 +77,7 @@ Prefix files (-include ...) can be selected with
   ;; Prefixes seem to be called .pch.  Pre-compiled headers do, too.
   ;; So we look at the magic number to rule them out.
   (let* ((file (company-clang--guess-pch-file buffer-file-name))
-         (magic-number (company-clang--file-substring file 0 4)))
+         (magic-number (and file (company-clang--file-substring file 0 4))))
     (unless (member magic-number '("CPCH" "gpch"))
       file)))
 
@@ -101,18 +101,24 @@ Prefix files (-include ...) can be selected with
 
 ;; TODO: How to handle OVERLOAD and Pattern?
 (defconst company-clang--completion-pattern
-  "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)")
+  "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?")
 
 (defconst company-clang--error-buffer-name "*clang error*")
 
+(defvar company-clang--meta-cache nil)
+
 (defun company-clang--parse-output (prefix)
   (goto-char (point-min))
   (let ((pattern (format company-clang--completion-pattern
                          (regexp-quote prefix)))
         (case-fold-search nil)
         lines match)
+    (setq company-clang--meta-cache (make-hash-table :test 'equal))
     (while (re-search-forward pattern nil t)
       (setq match (match-string-no-properties 1))
+      (let ((meta (match-string-no-properties 2)))
+        (when (and meta (not (string= match meta)))
+          (puthash match meta company-clang--meta-cache)))
       (unless (equal match "Pattern")
         (push match lines)))
     lines))
@@ -175,17 +181,19 @@ Prefix files (-include ...) can be selected with
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defconst company-clang-required-version "1.1")
+(defconst company-clang-required-version 1.1)
 
 (defsubst company-clang-version ()
   "Return the version of `company-clang-executable'."
   (with-temp-buffer
-    (switch-to-buffer (current-buffer))
     (call-process company-clang-executable nil t nil "--version")
     (goto-char (point-min))
-    (if (re-search-forward "\\clang version \\([0-9.]+\\)" nil t)
-        (match-string-no-properties 1)
-      "0")))
+    (if (re-search-forward "clang\\(?: version \\|-\\)\\([0-9.]+\\)" nil t)
+        (let ((ver (string-to-number (match-string-no-properties 1))))
+          (if (> ver 100)
+              (/ ver 100)
+            ver))
+      0)))
 
 (defun company-clang-objc-templatify (selector)
   (let* ((end (point))
@@ -202,8 +210,7 @@ Prefix files (-include ...) can be selected with
 
 (defun company-clang (command &optional arg &rest ignored)
   "A `company-mode' completion back-end for clang.
-Clang is a parser for C and ObjC.  The unreleased development version of
-clang (1.1) is required.
+Clang is a parser for C and ObjC.  Clang version 1.1 or newer is required.
 
 Additional command line arguments can be specified in
 `company-clang-arguments'.  Prefix files (-include ...) can be selected
@@ -215,17 +222,23 @@ Completions only work correctly when the buffer has been saved.
   (interactive (list 'interactive))
   (case command
     (interactive (company-begin-backend 'company-clang))
-    (init (unless company-clang-executable
-            (error "Company found no clang executable"))
-          (when (version< (company-clang-version)
-                          company-clang-required-version)
-            (error "Company requires clang version 1.1")))
+    (init (when (memq major-mode company-clang-modes)
+            (unless company-clang-executable
+              (error "Company found no clang executable"))
+            (when (< (company-clang-version) company-clang-required-version)
+              (error "Company requires clang version 1.1"))))
     (prefix (and (memq major-mode company-clang-modes)
                  buffer-file-name
                  company-clang-executable
                  (not (company-in-string-or-comment))
                  (or (company-grab-symbol) 'stop)))
     (candidates (company-clang--candidates arg))
+    (meta (let ((meta (gethash arg company-clang--meta-cache)))
+            (when meta
+              (replace-regexp-in-string
+               "#]" " "
+               (replace-regexp-in-string "[<{[]#\\|#[>}]" "" meta t)
+               t))))
     (post-completion (and (derived-mode-p 'objc-mode)
                           (string-match ":" arg)
                           (company-clang-objc-templatify arg)))))