db-global.el 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. ;;; semantic/db-global.el --- Semantic database extensions for GLOBAL
  2. ;; Copyright (C) 2002-2006, 2008-2012 Free Software Foundation, Inc.
  3. ;; Author: Eric M. Ludlam <zappo@gnu.org>
  4. ;; Keywords: tags
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;
  18. ;; Use GNU Global for by-name database searches.
  19. ;;
  20. ;; This will work as an "omniscient" database for a given project.
  21. ;;
  22. (require 'cedet-global)
  23. (require 'semantic/db-find)
  24. (require 'semantic/symref/global)
  25. (eval-when-compile
  26. ;; For generic function searching.
  27. (require 'eieio)
  28. (require 'eieio-opt)
  29. )
  30. ;;; Code:
  31. ;;;###autoload
  32. (defun semanticdb-enable-gnu-global-databases (mode)
  33. "Enable the use of the GNU Global SemanticDB back end for all files of MODE.
  34. This will add an instance of a GNU Global database to each buffer
  35. in a GNU Global supported hierarchy."
  36. (interactive
  37. (list (completing-read
  38. "Enable in Mode: " obarray
  39. #'(lambda (s) (get s 'mode-local-symbol-table))
  40. t (symbol-name major-mode))))
  41. ;; First, make sure the version is ok.
  42. (cedet-gnu-global-version-check)
  43. ;; Make sure mode is a symbol.
  44. (when (stringp mode)
  45. (setq mode (intern mode)))
  46. (let ((ih (mode-local-value mode 'semantic-init-mode-hook)))
  47. (eval `(setq-mode-local
  48. ,mode semantic-init-mode-hook
  49. (cons 'semanticdb-enable-gnu-global-hook ih))))
  50. )
  51. (defun semanticdb-enable-gnu-global-hook ()
  52. "Add support for GNU Global in the current buffer via `semantic-init-hook'.
  53. MODE is the major mode to support."
  54. (semanticdb-enable-gnu-global-in-buffer t))
  55. (defclass semanticdb-project-database-global
  56. ;; @todo - convert to one DB per directory.
  57. (semanticdb-project-database eieio-instance-tracker)
  58. ()
  59. "Database representing a GNU Global tags file.")
  60. (defun semanticdb-enable-gnu-global-in-buffer (&optional dont-err-if-not-available)
  61. "Enable a GNU Global database in the current buffer.
  62. When GNU Global is not available for this directory, display a message
  63. if optional DONT-ERR-IF-NOT-AVAILABLE is non-nil; else throw an error."
  64. (interactive "P")
  65. (if (cedet-gnu-global-root)
  66. (setq
  67. ;; Add to the system database list.
  68. semanticdb-project-system-databases
  69. (cons (semanticdb-project-database-global "global")
  70. semanticdb-project-system-databases)
  71. ;; Apply the throttle.
  72. semanticdb-find-default-throttle
  73. (append semanticdb-find-default-throttle
  74. '(omniscience))
  75. )
  76. (if dont-err-if-not-available
  77. nil; (message "No Global support in %s" default-directory)
  78. (error "No Global support in %s" default-directory))
  79. ))
  80. ;;; Classes:
  81. (defclass semanticdb-table-global (semanticdb-search-results-table)
  82. ((major-mode :initform nil)
  83. )
  84. "A table for returning search results from GNU Global.")
  85. (defmethod semanticdb-equivalent-mode ((table semanticdb-table-global) &optional buffer)
  86. "Return t, pretend that this table's mode is equivalent to BUFFER.
  87. Equivalent modes are specified by the `semantic-equivalent-major-modes'
  88. local variable."
  89. ;; @todo - hack alert!
  90. t)
  91. ;;; Filename based methods
  92. ;;
  93. (defmethod semanticdb-get-database-tables ((obj semanticdb-project-database-global))
  94. "For a global database, there are no explicit tables.
  95. For each file hit, get the traditional semantic table from that file."
  96. ;; We need to return something since there is always the "master table"
  97. ;; The table can then answer file name type questions.
  98. (when (not (slot-boundp obj 'tables))
  99. (let ((newtable (semanticdb-table-global "GNU Global Search Table")))
  100. (oset obj tables (list newtable))
  101. (oset newtable parent-db obj)
  102. (oset newtable tags nil)
  103. ))
  104. (call-next-method))
  105. (defmethod semanticdb-file-table ((obj semanticdb-project-database-global) filename)
  106. "From OBJ, return FILENAME's associated table object."
  107. ;; We pass in "don't load". I wonder if we need to avoid that or not?
  108. (car (semanticdb-get-database-tables obj))
  109. )
  110. ;;; Search Overrides
  111. ;;
  112. ;; Only NAME based searches work with GLOBAL as that is all it tracks.
  113. ;;
  114. (defmethod semanticdb-find-tags-by-name-method
  115. ((table semanticdb-table-global) name &optional tags)
  116. "Find all tags named NAME in TABLE.
  117. Return a list of tags."
  118. (if tags
  119. ;; If TAGS are passed in, then we don't need to do work here.
  120. (call-next-method)
  121. ;; Call out to GNU Global for some results.
  122. (let* ((semantic-symref-tool 'global)
  123. (result (semantic-symref-find-tags-by-name name 'project))
  124. )
  125. (when result
  126. ;; We could ask to keep the buffer open, but that annoys
  127. ;; people.
  128. (semantic-symref-result-get-tags result))
  129. )))
  130. (defmethod semanticdb-find-tags-by-name-regexp-method
  131. ((table semanticdb-table-global) regex &optional tags)
  132. "Find all tags with name matching REGEX in TABLE.
  133. Optional argument TAGS is a list of tags to search.
  134. Return a list of tags."
  135. (if tags (call-next-method)
  136. (let* ((semantic-symref-tool 'global)
  137. (result (semantic-symref-find-tags-by-regexp regex 'project))
  138. )
  139. (when result
  140. (semantic-symref-result-get-tags result))
  141. )))
  142. (defmethod semanticdb-find-tags-for-completion-method
  143. ((table semanticdb-table-global) prefix &optional tags)
  144. "In TABLE, find all occurrences of tags matching PREFIX.
  145. Optional argument TAGS is a list of tags to search.
  146. Returns a table of all matching tags."
  147. (if tags (call-next-method)
  148. (let* ((semantic-symref-tool 'global)
  149. (result (semantic-symref-find-tags-by-completion prefix 'project))
  150. (faketags nil)
  151. )
  152. (when result
  153. (dolist (T (oref result :hit-text))
  154. ;; We should look up each tag one at a time, but I'm lazy!
  155. ;; Doing this may be good enough.
  156. (setq faketags (cons
  157. (semantic-tag T 'function :faux t)
  158. faketags))
  159. )
  160. faketags))))
  161. ;;; Deep Searches
  162. ;;
  163. ;; If your language does not have a `deep' concept, these can be left
  164. ;; alone, otherwise replace with implementations similar to those
  165. ;; above.
  166. ;;
  167. (defmethod semanticdb-deep-find-tags-by-name-method
  168. ((table semanticdb-table-global) name &optional tags)
  169. "Find all tags name NAME in TABLE.
  170. Optional argument TAGS is a list of tags to search.
  171. Like `semanticdb-find-tags-by-name-method' for global."
  172. (semanticdb-find-tags-by-name-method table name tags))
  173. (defmethod semanticdb-deep-find-tags-by-name-regexp-method
  174. ((table semanticdb-table-global) regex &optional tags)
  175. "Find all tags with name matching REGEX in TABLE.
  176. Optional argument TAGS is a list of tags to search.
  177. Like `semanticdb-find-tags-by-name-method' for global."
  178. (semanticdb-find-tags-by-name-regexp-method table regex tags))
  179. (defmethod semanticdb-deep-find-tags-for-completion-method
  180. ((table semanticdb-table-global) prefix &optional tags)
  181. "In TABLE, find all occurrences of tags matching PREFIX.
  182. Optional argument TAGS is a list of tags to search.
  183. Like `semanticdb-find-tags-for-completion-method' for global."
  184. (semanticdb-find-tags-for-completion-method table prefix tags))
  185. (provide 'semantic/db-global)
  186. ;; Local variables:
  187. ;; generated-autoload-file: "loaddefs.el"
  188. ;; generated-autoload-load-name: "semantic/db-global"
  189. ;; End:
  190. ;;; semantic/db-global.el ends here