;;; semantic/complete.el --- Routines for performing tag completion
-;;; Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
-;;; Free Software Foundation, Inc.
+;; Copyright (C) 2003-2005, 2007-2011 Free Software Foundation, Inc.
;; Author: Eric M. Ludlam <zappo@gnu.org>
;; Keywords: syntax
;; quickly without resorting to "show me every possible option now".
;;
;; In addition, some symbol names will appear in multiple locations.
-;; If it is important to distiguish, then a way to provide a choice
+;; If it is important to distinguish, then a way to provide a choice
;; over these locations is important as well.
;;
;; Beyond brute force offers for completion of plain strings,
;;
;; Here, we will treat each section separately (excluding D)
;; They can then be strung together in user-visible commands to
-;; fullfill specific needs.
+;; fulfill specific needs.
;;
;; COLLECTORS:
;;
;; `semantic-complete-inline-tag-engine' will complete text in
;; a buffer.
-(require 'eieio)
+(eval-when-compile (require 'cl))
+(require 'semantic)
(require 'eieio-opt)
-(require 'semantic/tag-file)
-(require 'semantic/find)
(require 'semantic/analyze)
-(require 'semantic/format)
(require 'semantic/ctxt)
-;; Keep semanticdb optional.
-;; (eval-when-compile
-;; (require 'semantic/db)
-;; (require 'semantic/db-find))
(require 'semantic/decorate)
-(require 'semantic/analyze/complete)
-
+(require 'semantic/format)
(eval-when-compile
- (condition-case nil
- ;; Tooltip not available in older emacsen.
- (require 'tooltip)
- (error nil))
- )
+ ;; For the semantic-find-tags-for-completion macro.
+ (require 'semantic/find))
;;; Code:
-;;; Compatibility
-;;
-(if (fboundp 'minibuffer-contents)
- (eval-and-compile (defalias 'semantic-minibuffer-contents 'minibuffer-contents))
- (eval-and-compile (defalias 'semantic-minibuffer-contents 'buffer-string)))
-(if (fboundp 'delete-minibuffer-contents)
- (eval-and-compile (defalias 'semantic-delete-minibuffer-contents 'delete-minibuffer-contents))
- (eval-and-compile (defalias 'semantic-delete-minibuffer-contents 'erase-buffer)))
-
(defvar semantic-complete-inline-overlay nil
"The overlay currently active while completing inline.")
overlay."
(if semantic-complete-inline-overlay
(semantic-complete-inline-text)
- (semantic-minibuffer-contents)))
+ (minibuffer-contents)))
(defun semantic-completion-delete-text ()
"Delete the text that is actively being completed.
Presumably if you call this you will insert something new there."
(if semantic-complete-inline-overlay
(semantic-complete-inline-delete-text)
- (semantic-delete-minibuffer-contents)))
+ (delete-minibuffer-contents)))
(defun semantic-completion-message (fmt &rest args)
"Display the string FMT formatted with ARGS at the end of the minibuffer."
default-tag initial-input
history)
"Read a semantic tag, and return a tag for the selection.
-Argument COLLECTOR is an object which can be used to to calculate
+Argument COLLECTOR is an object which can be used to calculate
a list of possible hits. See `semantic-completion-collector-engine'
for details on COLLECTOR.
-Argumeng DISPLAYOR is an object used to display a list of possible
+Argument DISPLAYOR is an object used to display a list of possible
completions for a given prefix. See`semantic-completion-display-engine'
for details on DISPLAYOR.
PROMPT is a string to prompt with.
(if (string-match ":" prompt)
(setq prompt (concat
(substring prompt 0 (match-beginning 0))
- " (" default-as-string ")"
+ " (default " default-as-string ")"
(substring prompt (match-beginning 0))))
(setq prompt (concat prompt " (" default-as-string "): "))))
;;
;; semantic-displayor-focus-abstract-child-p is part of the
;; semantic-displayor-focus-abstract class, defined later in this
;; file.
-(declare-function semantic-displayor-focus-abstract-child-p "semantic/complete")
+(declare-function semantic-displayor-focus-abstract-child-p "semantic/complete"
+ t t)
(defun semantic-complete-current-match ()
"Calculate a match from the current completion environment.
\f
;;; Keybindings
;;
-;; Keys are bound to to perform completion using our mechanisms.
+;; Keys are bound to perform completion using our mechanisms.
;; Do that work here.
(defun semantic-complete-done ()
"Accept the current input."
(semantic-displayor-set-completions
displayor
(or
- (and (not (eq na 'displayend))
- (semantic-collector-current-exact-match collector))
+ ;; For the below - This caused problems for Chong Yidong
+ ;; when experimenting with the completion engine. I don't
+ ;; remember what the problem was though, and I wasn't sure why
+ ;; the below two lines were there since they obviously added
+ ;; some odd behavior. -EML
+ ;; (and (not (eq na 'displayend))
+ ;; (semantic-collector-current-exact-match collector))
(semantic-collector-all-completions collector contents))
contents)
;; Ask the displayor to display them.
(lambda () (interactive)
(describe-variable 'semantic-complete-inline-map)))
km)
- "Keymap used while performing Semantic inline completion.
-\\{semantic-complete-inline-map}")
+ "Keymap used while performing Semantic inline completion.")
(defface semantic-complete-inline-face
'((((class color) (background dark))
(defun semantic-complete-inline-tag-engine
(collector displayor buffer start end)
"Perform completion based on semantic tags in a buffer.
-Argument COLLECTOR is an object which can be used to to calculate
+Argument COLLECTOR is an object which can be used to calculate
a list of possible hits. See `semantic-completion-collector-engine'
for details on COLLECTOR.
-Argumeng DISPLAYOR is an object used to display a list of possible
+Argument DISPLAYOR is an object used to display a list of possible
completions for a given prefix. See`semantic-completion-display-engine'
for details on DISPLAYOR.
BUFFER is the buffer in which completion will take place.
This completion is calculated and saved for future use.")
(last-whitespace-completion :type (or null string)
:documentation "The last whitespace completion.
-For partial completion, SPC will disabiguate over whitespace type
+For partial completion, SPC will disambiguate over whitespace type
characters. This is the last calculated version.")
(current-exact-match :type list
:protection :protected
"Calculate the completions for prefix from completionlist.
Output must be in semanticdb Find result format."
;; Must output in semanticdb format
- (let ((table (save-excursion
- (set-buffer (oref obj buffer))
+ (let ((table (with-current-buffer (oref obj buffer)
semanticdb-current-table))
(result (semantic-find-tags-for-completion
prefix
()
"Completion engine for tags in a project.")
+(declare-function semanticdb-brute-deep-find-tags-for-completion
+ "semantic/db-find")
+
(defmethod semantic-collector-calculate-completions-raw
((obj semantic-collector-project-brutish) prefix completionlist)
"Calculate the completions for prefix from completionlist."
+ (require 'semantic/db-find)
(semanticdb-brute-deep-find-tags-for-completion prefix (oref obj path)))
+;;; Current Datatype member search.
+(defclass semantic-collector-local-members (semantic-collector-project-abstract)
+ ((scope :initform nil
+ :type (or null semantic-scope-cache)
+ :documentation
+ "The scope the local members are being completed from."))
+ "Completion engine for tags in a project.")
+
+(defmethod semantic-collector-calculate-completions-raw
+ ((obj semantic-collector-local-members) prefix completionlist)
+ "Calculate the completions for prefix from completionlist."
+ (let* ((scope (or (oref obj scope)
+ (oset obj scope (semantic-calculate-scope))))
+ (localstuff (oref scope scope)))
+ (list
+ (cons
+ (oref scope :table)
+ (semantic-find-tags-for-completion prefix localstuff)))))
+ ;(semanticdb-brute-deep-find-tags-for-completion prefix (oref obj path))))
+
+;;; Smart completion collector
(defclass semantic-collector-analyze-completions (semantic-collector-abstract)
((context :initarg :context
:type semantic-analyze-context
(semantic-analyze-possible-completions (oref obj context))))
;; search our cached completion list. make it look like a semanticdb
;; results type.
- (list (cons (save-excursion
- (set-buffer (oref (oref obj context) buffer))
+ (list (cons (with-current-buffer (oref (oref obj context) buffer)
semanticdb-current-table)
(semantic-find-tags-for-completion
prefix
;; A typical displayor accepts a pre-determined list of completions
;; generated by a collector. This format is in semanticdb search
;; form. This vaguely standard form is a bit challenging to navigate
-;; because the tags do not contain buffer info, but the file assocated
-;; with the tags preceed the tag in the list.
+;; because the tags do not contain buffer info, but the file associated
+;; with the tags precedes the tag in the list.
;;
;; Basic displayors don't care, and can strip the results.
;; Advanced highlighting displayors need to know when they need
(defmethod semantic-displayor-show-request ((obj semantic-displayor-traditional))
"A request to show the current tags table."
- ;; NOTE TO SELF. Find the character to type next, and emphesize it.
+ ;; NOTE TO SELF. Find the character to type next, and emphasize it.
(with-output-to-temp-buffer "*Completions*"
(display-completion-list
)
"Abstract displayor supporting `focus'.
A displayor which has the ability to focus in on one tag.
-Focusing is a way of differentiationg between multiple tags
+Focusing is a way of differentiating among multiple tags
which have the same name."
:abstract t)
(and table (semanticdb-get-buffer table)))))
;; If no buffer is provided, then we can make up a summary buffer.
(when (not buf)
- (save-excursion
- (set-buffer (get-buffer-create "*Completion Focus*"))
+ (with-current-buffer (get-buffer-create "*Completion Focus*")
(erase-buffer)
(insert "Focus on tag: \n")
(insert (semantic-format-tag-summarize tag nil t) "\n\n")
(string= (this-command-keys) "\C-i"))
(oset obj typing-count (1+ typing-count)))
;; At this point, we know we have too many items.
- ;; Lets be brave, and truncate l
+ ;; Let's be brave, and truncate l
(setcdr (nthcdr (oref obj max-tags) l) nil)
(setq msg (mapconcat 'identity l "\n"))
(cond
C)))
(eieio-build-class-alist semantic-displayor-abstract t))
)
- "Possible options for inlince completion displayors.
+ "Possible options for inline completion displayors.
Use this to enable custom editing.")
(defcustom semantic-complete-inline-analyzer-displayor-class
history)
)
+(defun semantic-complete-read-tag-local-members (prompt &optional
+ default-tag
+ initial-input
+ history)
+ "Ask for a tag by name from the local type members.
+Available tags are from the current scope.
+Completion options are presented in a traditional way, with highlighting
+to resolve same-name collisions.
+PROMPT is a string to prompt with.
+DEFAULT-TAG is a semantic tag or string to use as the default value.
+If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.
+HISTORY is a symbol representing a variable to store the history in."
+ (semantic-complete-read-tag-engine
+ (semantic-collector-local-members prompt :buffer (current-buffer))
+ (semantic-displayor-traditional-with-focus-highlight "simple")
+ ;;(semantic-displayor-tooltip "simple")
+ prompt
+ default-tag
+ initial-input
+ history)
+ )
+
(defun semantic-complete-read-tag-project (prompt &optional
default-tag
initial-input
PROMPT is the first part of the prompt. Additional prompt
is added based on the contexts full prefix.
CONTEXT is the semantic analyzer context to start with.
-HISTORY is a symbol representing a variable to stor the history in.
+HISTORY is a symbol representing a variable to store the history in.
usually a default-tag and initial-input are available for completion
prompts. these are calculated from the CONTEXT variable passed in."
(if (not context) (setq context (semantic-analyze-current-context (point))))
:buffer (oref context buffer)
:context context)
(semantic-displayor-traditional-with-focus-highlight "simple")
- (save-excursion
- (set-buffer (oref context buffer))
+ (with-current-buffer (oref context buffer)
(goto-char (cdr (oref context bounds)))
(concat prompt (mapconcat 'identity syms ".")
(if syms "." "")
))
\f
-;;; ------------------------------------------------------------
-;;; Testing/Samples
-;;
-(defun semantic-complete-test ()
- "Test completion mechanisms."
- (interactive)
- (message "%S"
- (semantic-format-tag-prototype
- (semantic-complete-read-tag-project "Symbol: ")
- )))
-
+;;;###autoload
(defun semantic-complete-jump-local ()
- "Jump to a semantic symbol."
+ "Jump to a local semantic symbol."
(interactive)
- (let ((tag (semantic-complete-read-tag-buffer-deep "Symbol: ")))
+ (let ((tag (semantic-complete-read-tag-buffer-deep "Jump to symbol: ")))
(when (semantic-tag-p tag)
(push-mark)
(goto-char (semantic-tag-start tag))
(semantic-tag-class tag)
(semantic-tag-name tag)))))
+;;;###autoload
(defun semantic-complete-jump ()
"Jump to a semantic symbol."
(interactive)
- (let* ((tag (semantic-complete-read-tag-project "Symbol: ")))
+ (let* ((tag (semantic-complete-read-tag-project "Jump to symbol: ")))
(when (semantic-tag-p tag)
(push-mark)
(semantic-go-to-tag tag)
(semantic-tag-class tag)
(semantic-tag-name tag)))))
+;;;###autoload
+(defun semantic-complete-jump-local-members ()
+ "Jump to a semantic symbol."
+ (interactive)
+ (let* ((tag (semantic-complete-read-tag-local-members "Jump to symbol: ")))
+ (when (semantic-tag-p tag)
+ (let ((start (condition-case nil (semantic-tag-start tag)
+ (error nil))))
+ (unless start
+ (error "Tag %s has no location" (semantic-format-tag-prototype tag)))
+ (push-mark)
+ (goto-char start)
+ (semantic-momentary-highlight-tag tag)
+ (message "%S: %s "
+ (semantic-tag-class tag)
+ (semantic-tag-name tag))))))
+
+;;;###autoload
(defun semantic-complete-analyze-and-replace ()
"Perform prompt completion to do in buffer completion.
`semantic-analyze-possible-completions' is used to determine the
(insert (semantic-tag-name tag))
(message "%S" (semantic-format-tag-summarize tag))))
+;;;###autoload
(defun semantic-complete-analyze-inline ()
"Perform prompt completion to do in buffer completion.
`semantic-analyze-possible-completions' is used to determine the
(semantic-complete-inline-analyzer
(semantic-analyze-current-context (point))))
;; Report a message if things didn't startup.
- (if (and (interactive-p)
+ (if (and (called-interactively-p 'any)
(not (semantic-completion-inline-active-p)))
(message "Inline completion not needed.")
;; Since this is most likely bound to something, and not used
;; at idle time, throw in a TAB for good measure.
- (semantic-complete-inline-TAB)
- ))
+ (semantic-complete-inline-TAB)))
+;;;###autoload
(defun semantic-complete-analyze-inline-idle ()
"Perform prompt completion to do in buffer completion.
`semantic-analyze-possible-completions' is used to determine the
(semantic-complete-inline-analyzer-idle
(semantic-analyze-current-context (point))))
;; Report a message if things didn't startup.
- (if (and (interactive-p)
+ (if (and (called-interactively-p 'interactive)
(not (semantic-completion-inline-active-p)))
- (message "Inline completion not needed."))
- )
+ (message "Inline completion not needed.")))
+;;;###autoload
(defun semantic-complete-self-insert (arg)
"Like `self-insert-command', but does completion afterwards.
ARG is passed to `self-insert-command'. If ARG is nil,
;; Prepare for doing completion, but exit quickly if there is keyboard
;; input.
- (when (and (not (semantic-exit-on-input 'csi
- (semantic-fetch-tags)
- (semantic-throw-on-input 'csi)
- nil))
- (= arg 1)
- (not (semantic-exit-on-input 'csi
- (semantic-analyze-current-context)
- (semantic-throw-on-input 'csi)
- nil)))
+ (when (save-window-excursion
+ (save-excursion
+ (and (not (semantic-exit-on-input 'csi
+ (semantic-fetch-tags)
+ (semantic-throw-on-input 'csi)
+ nil))
+ (= arg 1)
+ (not (semantic-exit-on-input 'csi
+ (semantic-analyze-current-context)
+ (semantic-throw-on-input 'csi)
+ nil)))))
(condition-case nil
(semantic-complete-analyze-inline)
;; Ignore errors. Seems likely that we'll get some once in a while.
(error nil))
))
-;; @TODO - I can't find where this fcn is used. Delete?
-
-;;;;###autoload
-;(defun semantic-complete-inline-project ()
-; "Perform inline completion for any symbol in the current project.
-;`semantic-analyze-possible-completions' is used to determine the
-;possible values.
-;The function returns immediately, leaving the buffer in a mode that
-;will perform the completion."
-; (interactive)
-; ;; Only do this if we are not already completing something.
-; (if (not (semantic-completion-inline-active-p))
-; (semantic-complete-inline-tag-project))
-; ;; Report a message if things didn't startup.
-; (if (and (interactive-p)
-; (not (semantic-completion-inline-active-p)))
-; (message "Inline completion not needed."))
-; )
-
-;; End
(provide 'semantic/complete)
+;; Local variables:
+;; generated-autoload-file: "loaddefs.el"
+;; generated-autoload-load-name: "semantic/complete"
+;; End:
+
;;; semantic/complete.el ends here