Update copyright notices for 2013.
[bpt/emacs.git] / lisp / cedet / semantic / ia.el
index 67653fe..d087ac6 100644 (file)
@@ -1,7 +1,6 @@
 ;;; semantic/ia.el --- Interactive Analysis functions
 
-;;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;;; 2008, 2009 Free Software Foundation, Inc.
+;;; Copyright (C) 2000-2013 Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <zappo@gnu.org>
 ;; Keywords: syntax
 (require 'semantic/analyze)
 (require 'semantic/format)
 (require 'pulse)
+(require 'semantic/senator)
+(require 'semantic/analyze/refs)
 (eval-when-compile
   (require 'semantic/analyze)
-  (require 'semantic/analyze/refs))
+  (require 'semantic/find))
 
 (declare-function imenu--mouse-menu "imenu")
 
 ;; functions.
 
 (defcustom semantic-ia-completion-format-tag-function
-  'semantic-prototype-nonterminal
-  "*Function used to convert a tag to a string during completion."
+  'semantic-format-tag-prototype
+  "Function used to convert a tag to a string during completion."
   :group 'semantic
   :type semantic-format-tag-custom-list)
 
-(defvar semantic-ia-cache nil
-  "Cache of the last completion request.
-Of the form ( POINT . COMPLETIONS ) where POINT is a location in the
-buffer where the completion was requested.  COMPLETONS is the list
-of semantic tag names that provide logical completions from that
-location.")
-(make-variable-buffer-local 'semantic-ia-cache)
-
 ;;; COMPLETION HELPER
 ;;
 ;; This overload function handles inserting a tag
@@ -86,85 +79,115 @@ location.")
           (insert "("))
          (t nil))))
 
-(declare-function semantic-analyze-possible-completions
-                 "semantic/analyze/complete")
-
-(defun semantic-ia-get-completions (context point)
-  "Fetch the completion of CONTEXT at POINT.
-Supports caching."
-  ;; Cache the current set of symbols so that we can get at
-  ;; them quickly the second time someone presses the
-  ;; complete button.
-  (let ((symbols
-        (if (and semantic-ia-cache
-                 (= point (car semantic-ia-cache)))
-            (cdr semantic-ia-cache)
-          (semantic-analyze-possible-completions context))))
-    ;; Set the cache
-    (setq semantic-ia-cache (cons point symbols))
-    symbols))
+(defalias 'semantic-ia-get-completions 'semantic-ia-get-completions-deprecated
+  "`Semantic-ia-get-completions' is obsolete.
+Use `semantic-analyze-possible-completions' instead.")
+
+(defun semantic-ia-get-completions-deprecated (context point)
+  "A function to help transition away from `semantic-ia-get-completions'.
+Return completions based on CONTEXT at POINT.
+You should not use this, nor the aliased version.
+Use `semantic-analyze-possible-completions' instead."
+  (semantic-analyze-possible-completions context))
 
 ;;;###autoload
-(defun semantic-ia-complete-symbol (point)
-  "Complete the current symbol at POINT.
+(defun semantic-ia-complete-symbol (&optional pos)
+  "Complete the current symbol at POS.
+If POS is nil, default to point.
 Completion options are calculated with `semantic-analyze-possible-completions'."
   (interactive "d")
-  ;; Calculating completions is a two step process.
-  ;;
-  ;; The first analyzer the current context, which finds tags
-  ;; for all the stuff that may be references by the code around
-  ;; POINT.
-  ;;
-  ;; The second step derives completions from that context.
-  (let* ((a (semantic-analyze-current-context point))
-        (syms (semantic-ia-get-completions a point))
-        (pre (car (reverse (oref a prefix))))
-        )
-    ;; If PRE was actually an already completed symbol, it doesn't
-    ;; come in as a string, but as a tag instead.
-    (if (semantic-tag-p pre)
-       ;; We will try completions on it anyway.
-       (setq pre (semantic-tag-name pre)))
-    ;; Complete this symbol.
-    (if (null syms)
-       (progn
-         ;(message "No smart completions found.  Trying senator-complete-symbol.")
+  (when (semantic-active-p)
+    (or pos (setq pos (point)))
+    ;; Calculating completions is a two step process.
+    ;;
+    ;; The first analyzer the current context, which finds tags for
+    ;; all the stuff that may be references by the code around POS.
+    ;;
+    ;; The second step derives completions from that context.
+    (let* ((a (semantic-analyze-current-context pos))
+          (syms (semantic-analyze-possible-completions a))
+          (pre (car (reverse (oref a prefix)))))
+      ;; If PRE was actually an already completed symbol, it doesn't
+      ;; come in as a string, but as a tag instead.
+      (if (semantic-tag-p pre)
+         ;; We will try completions on it anyway.
+         (setq pre (semantic-tag-name pre)))
+      ;; Complete this symbol.
+      (if (null syms)
          (if (semantic-analyze-context-p a)
              ;; This is a clever hack.  If we were unable to find any
-             ;; smart completions, lets divert to how senator derives
+             ;; smart completions, let's divert to how senator derives
              ;; completions.
              ;;
-             ;; This is a way of making this fcn more useful since the
-             ;; smart completion engine sometimes failes.
-             (semantic-complete-symbol)))
-      ;; Use try completion to seek a common substring.
-      (let ((tc (try-completion (or pre "")  syms)))
-       (if (and (stringp tc) (not (string= tc (or pre ""))))
-           (let ((tok (semantic-find-first-tag-by-name
-                       tc syms)))
-             ;; Delete what came before...
-             (when (and (car (oref a bounds)) (cdr (oref a bounds)))
-               (delete-region (car (oref a bounds))
-                              (cdr (oref a bounds)))
-               (goto-char (car (oref a bounds))))
-             ;; We have some new text.  Stick it in.
-             (if tok
-                 (semantic-ia-insert-tag tok)
-               (insert tc)))
-         ;; We don't have new text.  Show all completions.
-         (when (cdr (oref a bounds))
-           (goto-char (cdr (oref a bounds))))
-         (with-output-to-temp-buffer "*Completions*"
-           (display-completion-list
-            (mapcar semantic-ia-completion-format-tag-function syms))
-           ))))))
+             ;; This is a way of making this fcn more useful since
+             ;; the smart completion engine sometimes fails.
+             (semantic-complete-symbol))
+       ;; Use try completion to seek a common substring.
+       (let ((tc (try-completion (or pre "")  syms)))
+         (if (and (stringp tc) (not (string= tc (or pre ""))))
+             (let ((tok (semantic-find-first-tag-by-name
+                         tc syms)))
+               ;; Delete what came before...
+               (when (and (car (oref a bounds)) (cdr (oref a bounds)))
+                 (delete-region (car (oref a bounds))
+                                (cdr (oref a bounds)))
+                 (goto-char (car (oref a bounds))))
+               ;; We have some new text.  Stick it in.
+               (if tok
+                   (semantic-ia-insert-tag tok)
+                 (insert tc)))
+           ;; We don't have new text.  Show all completions.
+           (when (cdr (oref a bounds))
+             (goto-char (cdr (oref a bounds))))
+           (with-output-to-temp-buffer "*Completions*"
+             (display-completion-list
+              (mapcar semantic-ia-completion-format-tag-function syms)))))))))
 
 (defcustom semantic-ia-completion-menu-format-tag-function
-  'semantic-uml-concise-prototype-nonterminal
+  'semantic-format-tag-uml-concise-prototype
   "*Function used to convert a tag to a string during completion."
   :group 'semantic
   :type semantic-format-tag-custom-list)
 
+;;;###autoload
+(defun semantic-ia-complete-symbol-menu (point)
+  "Complete the current symbol via a menu based at POINT.
+Completion options are calculated with `semantic-analyze-possible-completions'."
+  (interactive "d")
+  (require 'imenu)
+  (let* ((a (semantic-analyze-current-context point))
+        (syms (semantic-analyze-possible-completions a))
+        )
+    ;; Complete this symbol.
+    (if (not syms)
+       (progn
+         (message "No smart completions found.  Trying Senator.")
+         (when (semantic-analyze-context-p a)
+           ;; This is a quick way of getting a nice completion list
+           ;; in the menu if the regular context mechanism fails.
+           (senator-completion-menu-popup)))
+
+      (let* ((menu
+             (mapcar
+              (lambda (tag)
+                (cons
+                 (funcall semantic-ia-completion-menu-format-tag-function tag)
+                 (vector tag)))
+              syms))
+            (ans
+             (imenu--mouse-menu
+              ;; XEmacs needs that the menu has at least 2 items.  So,
+              ;; include a nil item that will be ignored by imenu.
+              (cons nil menu)
+              (senator-completion-menu-point-as-event)
+              "Completions")))
+       (when ans
+         (if (not (semantic-tag-p ans))
+             (setq ans (aref (cdr ans) 0)))
+         (delete-region (car (oref a bounds)) (cdr (oref a bounds)))
+         (semantic-ia-insert-tag ans))
+       ))))
+
 ;;; Completions Tip
 ;;
 ;; This functions shows how to get the list of completions,
@@ -175,7 +198,7 @@ Completion options are calculated with `semantic-analyze-possible-completions'."
   "Pop up a tooltip for completion at POINT."
   (interactive "d")
   (let* ((a (semantic-analyze-current-context point))
-        (syms (semantic-ia-get-completions a point))
+        (syms (semantic-analyze-possible-completions a))
          (x (mod (- (current-column) (window-hscroll))
                  (window-width)))
          (y (save-excursion
@@ -214,22 +237,62 @@ Completion options are calculated with `semantic-analyze-possible-completions'."
               ;; tag associated with the current context.
               (semantic-analyze-interesting-tag ctxt)))
        )
-    (when pf
-      (message "%s" (semantic-format-tag-summarize pf nil t)))))
+    (if pf
+       (message "%s" (semantic-format-tag-summarize pf nil t))
+      (message "No summary info available"))))
+
+;;; Variants
+;;
+;; Show all variants for the symbol under point.
+
+;;;###autoload
+(defun semantic-ia-show-variants (point)
+  "Display a list of all variants for the symbol under POINT."
+  (interactive "P")
+  (let* ((ctxt (semantic-analyze-current-context point))
+        (comp nil))
+
+    ;; We really want to look at the function if we are on an
+    ;; argument.  Are there some additional rules we care about for
+    ;; changing the CTXT we look at?
+    (when (semantic-analyze-context-functionarg-p ctxt)
+      (goto-char (cdr (oref ctxt bounds)))
+      (setq ctxt (semantic-analyze-current-context (point))))
+
+    ;; Get the "completion list", but remove ALL filters to get the master list
+    ;; of all the possible things.
+    (setq comp (semantic-analyze-possible-completions ctxt 'no-unique 'no-tc))
+
+    ;; Special case for a single type.  List the constructors?
+    (when (and (= (length comp) 1) (semantic-tag-of-class-p (car comp) 'type))
+      (setq comp (semantic-find-tags-by-name (semantic-tag-name (car comp))
+                                            (semantic-tag-type-members (car comp)))))
+
+    ;; Display the results.
+    (cond ((= (length comp) 0)
+          (message "No Variants found."))
+         ((= (length comp) 1)
+          (message "%s" (semantic-format-tag-summarize (car comp) nil t)))
+         (t
+          (with-output-to-temp-buffer "*Symbol Variants*"
+            (semantic-analyze-princ-sequence comp "" (current-buffer)))
+          (shrink-window-if-larger-than-buffer
+           (get-buffer-window "*Symbol Variants*")))
+         )))
 
 ;;; FAST Jump
 ;;
 ;; Jump to a destination based on the local context.
 ;;
 ;; This shows how to use the analyzer context, and the
-;; analyer references objects to choose a good destination.
+;; analyzer references objects to choose a good destination.
 
 (defun semantic-ia--fast-jump-helper (dest)
   "Jump to DEST, a Semantic tag.
 This helper manages the mark, buffer switching, and pulsing."
   ;; We have a tag, but in C++, we usually get a prototype instead
-  ;; because of header files.  Lets try to find the actual
-  ;; implementaion instead.
+  ;; because of header files.  Let's try to find the actual
+  ;; implementation instead.
   (when (semantic-tag-prototype-p dest)
     (let* ((refs (semantic-analyze-tag-references dest))
           (impl (semantic-analyze-refs-impl refs t))
@@ -356,18 +419,21 @@ See `semantic-ia-fast-jump' for details on how it works.
       ;; The default tries to find a comment in front of the tag
       ;; and then strings off comment prefixes.
       (let ((doc (semantic-documentation-for-tag (car pf))))
-       (with-output-to-temp-buffer "*TAG DOCUMENTATION*"
-         (princ "Tag: ")
-         (princ (semantic-format-tag-prototype (car pf)))
-         (princ "\n")
-         (princ "\n")
-         (princ "Snarfed Documentation: ")
-         (princ "\n")
-         (princ "\n")
-         (if doc
-             (princ doc)
-           (princ "  Documentation unavailable."))
-         )))
+       (if (or (null doc) (string= doc ""))
+           (message "Doc unavailable for: %s"
+                    (semantic-format-tag-prototype (car pf)))
+         (with-output-to-temp-buffer "*TAG DOCUMENTATION*"
+           (princ "Tag: ")
+           (princ (semantic-format-tag-prototype (car pf)))
+           (princ "\n")
+           (princ "\n")
+           (princ "Snarfed Documentation: ")
+           (princ "\n")
+           (princ "\n")
+           (if doc
+               (princ doc)
+             (princ "  Documentation unavailable."))
+           ))))
      (t
       (message "Unknown tag.")))
     ))
@@ -415,9 +481,7 @@ parts of the parent classes are displayed."
 
 ;; Local variables:
 ;; generated-autoload-file: "loaddefs.el"
-;; generated-autoload-feature: semantic/loaddefs
 ;; generated-autoload-load-name: "semantic/ia"
 ;; End:
 
-;; arch-tag: ceeed1f2-e5b6-4f7c-a85a-a2f8ee0193ca
 ;;; semantic/ia.el ends here