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