]> code.delx.au - gnu-emacs-elpa/blobdiff - company-semantic.el
Add company-semantic-begin-after-member-access
[gnu-emacs-elpa] / company-semantic.el
index 1680a60f90f195b339db290a27ae161bc7ad8250..27522da5d95a7c8b2ea1ed3110444faebbdd1c06 100644 (file)
@@ -1,6 +1,6 @@
 ;;; company-semantic.el --- company-mode completion backend using Semantic
 
-;; Copyright (C) 2009-2011, 2013  Free Software Foundation, Inc.
+;; Copyright (C) 2009-2011, 2013-2016  Free Software Foundation, Inc.
 
 ;; Author: Nikolaj Schumacher
 
   "The function turning a semantic tag into doc information."
   :type 'function)
 
+(defcustom company-semantic-begin-after-member-access t
+  "When non-nil, automatic completion will start whenever the current
+symbol is preceded by \".\", \"->\" or \"::\", ignoring
+`company-minimum-prefix-length'.
+
+If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
+and `c-electric-colon', for automatic completion right after \">\" and
+\":\".")
+
 (defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode))
 
 (defvar-local company-semantic--current-tags nil
@@ -90,7 +99,7 @@
     (let ((completion-ignore-case nil)
           (context (semantic-analyze-current-context)))
       (setq company-semantic--current-tags
-            (semantic-analyze-possible-completions context))
+            (semantic-analyze-possible-completions context 'no-unique))
       (all-completions prefix company-semantic--current-tags))))
 
 (defun company-semantic-completions-raw (prefix)
   (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
 
 (defun company-semantic-annotation (argument tags)
-  (let* ((tag (assoc argument tags))
+  (let* ((tag (assq 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 "->\\|\\." (- (point) 2))
-        (goto-char (match-beginning 0))
-        (skip-syntax-backward "w_"))
-      (- pos (point)))))
-
-(defun company-semantic--grab ()
-  "Grab the semantic prefix, but return everything before -> or . as length."
-  (let ((symbol (company-grab-symbol)))
-    (when symbol
-      (cons symbol (company-semantic--pre-prefix-length (length symbol))))))
+(defun company-semantic--prefix ()
+  (if company-semantic-begin-after-member-access
+      (company-grab-symbol-cons "\\.\\|->\\|::" 2)
+    (company-grab-symbol)))
 
 ;;;###autoload
 (defun company-semantic (command &optional arg &rest ignored)
@@ -135,7 +132,7 @@ Symbols are chained by \".\" or \"->\"."
                  (semantic-active-p)
                  (memq major-mode company-semantic-modes)
                  (not (company-in-string-or-comment))
-                 (or (company-semantic--grab) 'stop)))
+                 (or (company-semantic--prefix) 'stop)))
     (candidates (if (and (equal arg "")
                          (not (looking-back "->\\|\\." (- (point) 2))))
                     (company-semantic-completions-raw arg)
@@ -148,6 +145,7 @@ Symbols are chained by \".\" or \"->\"."
                  (assoc arg company-semantic--current-tags)))
     ;; Because "" is an empty context and doesn't return local variables.
     (no-cache (equal arg ""))
+    (duplicates t)
     (location (let ((tag (assoc arg company-semantic--current-tags)))
                 (when (buffer-live-p (semantic-tag-buffer tag))
                   (cons (semantic-tag-buffer tag)