]> code.delx.au - gnu-emacs-elpa/blobdiff - company-semantic.el
Don't "adjust key" (#422)
[gnu-emacs-elpa] / company-semantic.el
index eacf1c729694e16b00a2ef94cb8dea89a3954e4d..1680a60f90f195b339db290a27ae161bc7ad8250 100644 (file)
@@ -1,6 +1,6 @@
-;;; company-semantic.el --- A company-mode back-end using CEDET Semantic
+;;; company-semantic.el --- company-mode completion backend using Semantic
 
-;; Copyright (C) 2009-2011  Free Software Foundation, Inc.
+;; Copyright (C) 2009-2011, 2013  Free Software Foundation, Inc.
 
 ;; Author: Nikolaj Schumacher
 
 ;;; Code:
 
 (require 'company)
-(or (require 'semantic-analyze nil t)
-    (require 'semantic/analyze))
-(eval-when-compile (require 'cl))
+(require 'cl-lib)
+
+(defvar semantic-idle-summary-function)
+(declare-function semantic-documentation-for-tag "semantic/doc" )
+(declare-function semantic-analyze-current-context "semantic/analyze")
+(declare-function semantic-analyze-possible-completions "semantic/complete")
+(declare-function semantic-analyze-find-tags-by-prefix "semantic/analyze/fcn")
+(declare-function semantic-tag-class "semantic/tag")
+(declare-function semantic-tag-name "semantic/tag")
+(declare-function semantic-tag-start "semantic/tag")
+(declare-function semantic-tag-buffer "semantic/tag")
+(declare-function semantic-active-p "semantic")
+(declare-function semantic-format-tag-prototype "semantic/format")
+
+(defgroup company-semantic nil
+  "Completion backend using Semantic."
+  :group 'company)
 
 (defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc
-  "*The function turning a semantic tag into doc information."
-  :group 'company
+  "The function turning a semantic tag into doc information."
   :type 'function)
 
 (defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode))
 
-(defvar company-semantic--current-tags nil
+(defvar-local company-semantic--current-tags nil
   "Tags for the current context.")
 
+(defun company-semantic-documentation-for-tag (tag)
+  (when (semantic-tag-buffer tag)
+    ;; When TAG's buffer is unknown, the function below raises an error.
+    (semantic-documentation-for-tag tag)))
+
 (defun company-semantic-doc-or-summary (tag)
-  (or (semantic-documentation-for-tag tag)
+  (or (company-semantic-documentation-for-tag tag)
       (and (require 'semantic-idle nil t)
            (require 'semantic/idle nil t)
            (funcall semantic-idle-summary-function tag nil t))))
 
 (defun company-semantic-summary-and-doc (tag)
-  (let ((doc (semantic-documentation-for-tag tag))
+  (let ((doc (company-semantic-documentation-for-tag tag))
         (summary (funcall semantic-idle-summary-function tag nil t)))
     (and (stringp doc)
          (string-match "\n*\\(.*\\)$" doc)
          (setq doc (match-string 1 doc)))
-    (concat (funcall semantic-idle-summary-function tag nil t)
+    (concat summary
             (when doc
                   (if (< (+ (length doc) (length summary) 4) (window-width))
                       " -- "
             doc)))
 
 (defun company-semantic-doc-buffer (tag)
-  (let ((doc (semantic-documentation-for-tag tag)))
+  (let ((doc (company-semantic-documentation-for-tag tag)))
     (when doc
-      (with-current-buffer (company-doc-buffer)
-        (insert (funcall semantic-idle-summary-function tag nil t)
-                "\n"
-                doc)
-        (current-buffer)))))
+      (company-doc-buffer
+       (concat (funcall semantic-idle-summary-function tag nil t)
+               "\n"
+               doc)))))
 
 (defsubst company-semantic-completions (prefix)
   (ignore-errors
       (push tag company-semantic--current-tags)))
   (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
 
+(defun company-semantic-annotation (argument tags)
+  (let* ((tag (assoc argument tags))
+         (kind (when tag (elt tag 1))))
+    (cl-case kind
+      (function (let* ((prototype (semantic-format-tag-prototype tag nil nil))
+                       (par-pos (string-match "(" prototype)))
+                  (when par-pos (substring prototype par-pos)))))))
+
 (defun company-semantic--pre-prefix-length (prefix-length)
   "Sum up the length of all chained symbols before POS.
 Symbols are chained by \".\" or \"->\"."
   (save-excursion
     (let ((pos (point)))
       (goto-char (- (point) prefix-length))
-      (while (looking-back "->\\|\\.")
+      (while (looking-back "->\\|\\." (- (point) 2))
         (goto-char (match-beginning 0))
         (skip-syntax-backward "w_"))
       (- pos (point)))))
@@ -102,20 +127,23 @@ Symbols are chained by \".\" or \"->\"."
 
 ;;;###autoload
 (defun company-semantic (command &optional arg &rest ignored)
-  "A `company-mode' completion back-end using CEDET Semantic."
+  "`company-mode' completion backend using CEDET Semantic."
   (interactive (list 'interactive))
-  (case command
+  (cl-case command
     (interactive (company-begin-backend 'company-semantic))
-    (prefix (and (memq major-mode company-semantic-modes)
+    (prefix (and (featurep 'semantic)
                  (semantic-active-p)
+                 (memq major-mode company-semantic-modes)
                  (not (company-in-string-or-comment))
                  (or (company-semantic--grab) 'stop)))
     (candidates (if (and (equal arg "")
-                         (not (looking-back "->\\|\\.")))
+                         (not (looking-back "->\\|\\." (- (point) 2))))
                     (company-semantic-completions-raw arg)
                   (company-semantic-completions arg)))
     (meta (funcall company-semantic-metadata-function
                    (assoc arg company-semantic--current-tags)))
+    (annotation (company-semantic-annotation arg
+                                             company-semantic--current-tags))
     (doc-buffer (company-semantic-doc-buffer
                  (assoc arg company-semantic--current-tags)))
     ;; Because "" is an empty context and doesn't return local variables.