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