-;;; db.el --- Semantic tag database manager
+;;; semantic/db.el --- Semantic tag database manager
-;;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;;; 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 2000-2011 Free Software Foundation, Inc.
;; Author: Eric M. Ludlam <zappo@gnu.org>
;; Keywords: tags
;; By default, assume one database per directory.
;;
-(require 'eieio)
-;; (require 'inversion)
-;; (eval-and-compile
-;; (inversion-require 'eieio "1.0"))
+;;; Code:
+
(require 'eieio-base)
(require 'semantic)
-(eval-when-compile
- (require 'semantic/lex-spp))
+
+(declare-function semantic-lex-spp-save-table "semantic/lex-spp")
;;; Variables:
(defgroup semanticdb nil
"Parser Generator Persistent Database interface."
- :group 'semantic
- )
-;;; Code:
+ :group 'semantic)
+
(defvar semanticdb-database-list nil
"List of all active databases.")
(defvar semanticdb-default-find-index-class 'semanticdb-find-search-index
"The default type of search index to use for a `semanticdb-table's.
-This can be changed to try out new types of search indicies.")
+This can be changed to try out new types of search indices.")
(make-variable-buffer-local 'semanticdb-default-find=index-class)
+;;;###autoload
+(defvar semanticdb-current-database nil
+ "For a given buffer, this is the currently active database.")
+(make-variable-buffer-local 'semanticdb-current-database)
+
+;;;###autoload
+(defvar semanticdb-current-table nil
+ "For a given buffer, this is the currently active database table.")
+(make-variable-buffer-local 'semanticdb-current-table)
;;; ABSTRACT CLASSES
;;
)
+;;; SEARCH RESULTS TABLE
+;;
+;; Needed for system databases that may not provide
+;; a semanticdb-table associated with a file.
+;;
+(defclass semanticdb-search-results-table (semanticdb-abstract-table)
+ (
+ )
+ "Table used for search results when there is no file or table association.
+Examples include search results from external sources such as from
+Emacs' own symbol table, or from external libraries.")
+
+(defmethod semanticdb-refresh-table ((obj semanticdb-search-results-table) &optional force)
+ "If the tag list associated with OBJ is loaded, refresh it.
+This will call `semantic-fetch-tags' if that file is in memory."
+ nil)
+
;;; CONCRETE TABLE CLASSES
;;
(defclass semanticdb-table (semanticdb-abstract-table)
If the buffer is in memory, return that buffer.
If the buffer is not in memory, load it with `find-file-noselect'."
(or (semanticdb-in-buffer-p obj)
- (find-file-noselect (semanticdb-full-filename obj) t)))
+ ;; Save match data to protect against odd stuff in mode hooks.
+ (save-match-data
+ (find-file-noselect (semanticdb-full-filename obj) t))))
(defmethod semanticdb-set-buffer ((obj semanticdb-table))
"Set the current buffer to be a buffer owned by OBJ.
"Get a cache object on TABLE of class DESIRED-CLASS.
This method will create one if none exists with no init arguments
other than :table."
- (assert (child-of-class-p desired-class 'semanticdb-abstract-cache))
+ (unless (child-of-class-p desired-class 'semanticdb-abstract-cache)
+ (error "Invalid SemanticDB cache"))
(let ((cache (oref table cache))
(obj nil))
(while (and (not obj) cache)
"Get a cache object on DB of class DESIRED-CLASS.
This method will create one if none exists with no init arguments
other than :table."
- (assert (child-of-class-p desired-class 'semanticdb-abstract-db-cache))
+ (unless (child-of-class-p desired-class 'semanticdb-abstract-cache)
+ (error "Invalid SemanticDB cache"))
(let ((cache (oref db cache))
(obj nil))
(while (and (not obj) cache)
is not in a buffer. Avoid using FORCE for most uses, as an old cache
may be sufficient for the general case. Forced updates can be slow.
This will call `semantic-fetch-tags' if that file is in memory."
- (when (or (semanticdb-in-buffer-p obj) force)
+ (cond
+ ;;
+ ;; Already in a buffer, just do it.
+ ((semanticdb-in-buffer-p obj)
+ (semanticdb-set-buffer obj)
+ (semantic-fetch-tags))
+ ;;
+ ;; Not in a buffer. Forcing a load.
+ (force
+ ;; Patch from Iain Nicol. --
+ ;; @TODO: I wonder if there is a way to recycle
+ ;; semanticdb-create-table-for-file-not-in-buffer
(save-excursion
- (semanticdb-set-buffer obj)
- (semantic-fetch-tags))))
+ (let ((buff (semantic-find-file-noselect
+ (semanticdb-full-filename obj))))
+ (set-buffer buff)
+ (semantic-fetch-tags)
+ ;; Kill off the buffer if it didn't exist when we were called.
+ (kill-buffer buff))))))
(defmethod semanticdb-needs-refresh-p ((obj semanticdb-table))
"Return non-nil of OBJ's tag list is out of date.
(buff (semanticdb-in-buffer-p obj))
)
(if buff
- (save-excursion
- (set-buffer buff)
+ (with-current-buffer buff
;; Use semantic's magic tracker to determine of the buffer is up
;; to date or not.
(not (semantic-parse-tree-up-to-date-p))
;; Assume it is now up to date.
(oset table unmatched-syntax semantic-unmatched-syntax-cache)
;; The lexical table should be good too.
- (when (featurep 'semantic-lex-spp)
+ (when (featurep 'semantic/lex-spp)
(oset table lexical-table (semantic-lex-spp-save-table)))
;; this implies dirtyness
(semanticdb-set-dirty table)
(semanticdb-set-dirty table)
;; The lexical table may be modified.
- (when (featurep 'semantic-lex-spp)
+ (when (featurep 'semantic/lex-spp)
(oset table lexical-table (semantic-lex-spp-save-table)))
;; Incremental parser doesn't mokey around with this.
(semanticdb-save-db semanticdb-current-database)
(message "Saving current tag summaries...done"))
+;; This prevents Semanticdb from querying multiple times if the users
+;; answers "no" to creating the Semanticdb directory.
+(defvar semanticdb--inhibit-create-file-directory)
+
(defun semanticdb-save-all-db ()
"Save all semantic tag databases."
(interactive)
(message "Saving tag summaries...")
- (mapc 'semanticdb-save-db semanticdb-database-list)
+ (let ((semanticdb--inhibit-make-directory nil))
+ (mapc 'semanticdb-save-db semanticdb-database-list))
(message "Saving tag summaries...done"))
(defun semanticdb-save-all-db-idle ()
nil))
(defvar semanticdb-match-any-mode nil
- "Non-nil to temporarilly search any major mode for a tag.
+ "Non-nil to temporarily search any major mode for a tag.
If a particular major mode wants to search any mode, put the
`semantic-match-any-mode' symbol onto the symbol of that major mode.
Do not set the value of this variable permanently.")
(defmacro semanticdb-with-match-any-mode (&rest body)
- "A Semanticdb search occuring withing BODY will search tags in all modes.
-This temporarilly sets `semanticdb-match-any-mode' while executing BODY."
+ "A Semanticdb search occurring withing BODY will search tags in all modes.
+This temporarily sets `semanticdb-match-any-mode' while executing BODY."
`(let ((semanticdb-match-any-mode t))
,@body))
(put 'semanticdb-with-match-any-mode 'lisp-indent-function 0)
(defmethod semanticdb-equivalent-mode ((table semanticdb-abstract-table) &optional buffer)
"Return non-nil if TABLE's mode is equivalent to BUFFER.
-Equivalent modes are specified by by `semantic-equivalent-major-modes'
+Equivalent modes are specified by the `semantic-equivalent-major-modes'
local variable."
nil)
(defmethod semanticdb-equivalent-mode ((table semanticdb-table) &optional buffer)
"Return non-nil if TABLE's mode is equivalent to BUFFER.
-Equivalent modes are specified by by `semantic-equivalent-major-modes'
+Equivalent modes are specified by the `semantic-equivalent-major-modes'
local variable."
(save-excursion
(if buffer (set-buffer buffer))
(defcustom semanticdb-project-roots nil
"*List of directories, where each directory is the root of some project.
All subdirectories of a root project are considered a part of one project.
-Values in this string can be overriden by project management programs
+Values in this string can be overridden by project management programs
via the `semanticdb-project-root-functions' variable."
:group 'semanticdb
:type '(repeat string))
(setq root (run-hook-with-args-until-success
'semanticdb-project-root-functions
dir))
- ;; Find roots based on strings
- (while (and roots (not root))
- (let ((r (file-truename (car roots))))
- (if (string-match (concat "^" (regexp-quote r)) dir)
- (setq root r)))
- (setq roots (cdr roots)))
+ (if root
+ (setq root (file-truename root))
+ ;; Else, Find roots based on strings
+ (while roots
+ (let ((r (file-truename (car roots))))
+ (if (string-match (concat "^" (regexp-quote r)) dir)
+ (setq root r)))
+ (setq roots (cdr roots))))
;; If no roots are found, use this directory.
(unless root (setq root dir))
"For FILE, associate DBTABLE in the hash table."
(puthash file dbtable semanticdb-file-table-hash))
+;;;###autoload
(defun semanticdb-file-table-object (file &optional dontload)
"Return a semanticdb table belonging to FILE, make it up to date.
If file has database tags available in the database, return it.
(provide 'semantic/db)
-;;; semanticdb.el ends here
+;; Local variables:
+;; generated-autoload-file: "loaddefs.el"
+;; generated-autoload-load-name: "semantic/db"
+;; End:
+
+;;; semantic/db.el ends here