lisp/cedet/semantic/db-el.el (semanticdb-elisp-sym->tag): Require
[bpt/emacs.git] / lisp / cedet / semantic / symref / list.el
CommitLineData
a4bdf715
CY
1;;; semantic/symref/list.el --- Symref Output List UI.
2
3;;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
4
5;; Author: Eric M. Ludlam <eric@siege-engine.com>
6
7;; This file is part of GNU Emacs.
8
9;; This program is free software; you can redistribute it and/or
10;; modify it under the terms of the GNU General Public License as
11;; published by the Free Software Foundation; either version 2, or (at
12;; your option) any later version.
13
14;; This program is distributed in the hope that it will be useful, but
15;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17;; General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with this program; see the file COPYING. If not, write to
21;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22;; Boston, MA 02110-1301, USA.
23
24;;; Commentary:
25;;
26;; Provide a simple user facing API to finding symbol references.
27;;
28;; This UI will is the base of some refactoring tools. For any
29;; refactor, the user will execture `semantic-symref' in a tag. Once
30;; that data is collected, the output will be listed in a buffer. In
31;; the output buffer, the user can then initiate different refactoring
32;; operations.
33;;
34;; NOTE: Need to add some refactoring tools.
35
36(require 'semantic/symref)
37(require 'pulse)
38
39;;; Code:
40
41(defun semantic-symref ()
42 "Find references to the current tag.
43This command uses the currently configured references tool within the
44current project to find references to the current tag. The
45references are the organized by file and the name of the function
46they are used in.
47Display the references in`semantic-symref-results-mode'"
48 (interactive)
49 (semantic-fetch-tags)
50 (let ((ct (semantic-current-tag))
51 (res nil)
52 )
53 ;; Must have a tag...
54 (when (not ct) (error "Place cursor inside tag to be searched for"))
55 ;; Check w/ user.
56 (when (not (y-or-n-p (format "Find references for %s? " (semantic-tag-name ct))))
57 (error "Quit"))
58 ;; Gather results and tags
59 (message "Gathering References...")
60 (setq res (semantic-symref-find-references-by-name (semantic-tag-name ct)))
61 (semantic-symref-produce-list-on-results res (semantic-tag-name ct))))
62
63(defun semantic-symref-symbol (sym)
64 "Find references to the symbol SYM.
65This command uses the currently configured references tool within the
66current project to find references to the input SYM. The
67references are the organized by file and the name of the function
68they are used in.
69Display the references in`semantic-symref-results-mode'"
70 (interactive (list (car (senator-jump-interactive "Symrefs for: " nil nil t)))
71 )
72 (semantic-fetch-tags)
73 (let ((res nil)
74 )
75 ;; Gather results and tags
76 (message "Gathering References...")
77 (setq res (semantic-symref-find-references-by-name sym))
78 (semantic-symref-produce-list-on-results res sym)))
79
80
81(defun semantic-symref-produce-list-on-results (res str)
82 "Produce a symref list mode buffer on the results RES."
83 (when (not res) (error "No references found"))
84 (semantic-symref-result-get-tags res t)
85 (message "Gathering References...done")
86 ;; Build a refrences buffer.
87 (let ((buff (get-buffer-create
88 (format "*Symref %s" str)))
89 )
90 (switch-to-buffer-other-window buff)
91 (set-buffer buff)
92 (semantic-symref-results-mode res))
93 )
94
95;;; RESULTS MODE
96;;
97(defgroup semantic-symref-results-mode nil
98 "Symref Results group."
99 :group 'semantic)
100
101(defvar semantic-symref-results-mode-map
102 (let ((km (make-sparse-keymap)))
103 (define-key km "\C-i" 'forward-button)
104 (define-key km "\M-C-i" 'backward-button)
105 (define-key km " " 'push-button)
106 (define-key km "-" 'semantic-symref-list-toggle-showing)
107 (define-key km "=" 'semantic-symref-list-toggle-showing)
108 (define-key km "+" 'semantic-symref-list-toggle-showing)
109 (define-key km "n" 'semantic-symref-list-next-line)
110 (define-key km "p" 'semantic-symref-list-prev-line)
111 (define-key km "q" 'semantic-symref-hide-buffer)
112 km)
113 "Keymap used in `semantic-symref-results-mode'.")
114
115(defcustom semantic-symref-results-mode-hook nil
116 "*Hook run when `semantic-symref-results-mode' starts."
117 :group 'semantic-symref
118 :type 'hook)
119
120(defvar semantic-symref-current-results nil
121 "The current results in a results mode buffer.")
122
123(defun semantic-symref-results-mode (results)
124 "Major-mode for displaying Semantic Symbol Reference RESULTS.
125RESULTS is an object of class `semantic-symref-results'."
126 (interactive)
127 (kill-all-local-variables)
128 (setq major-mode 'semantic-symref-results-mode
129 mode-name "Symref"
130 )
131 (use-local-map semantic-symref-results-mode-map)
132 (set (make-local-variable 'semantic-symref-current-results)
133 results)
134 (semantic-symref-results-dump results)
135 (goto-char (point-min))
136 (buffer-disable-undo)
137 (set (make-local-variable 'font-lock-global-modes) nil)
138 (font-lock-mode -1)
139 (run-hooks 'semantic-symref-results-mode-hook)
140 )
141
142(defun semantic-symref-hide-buffer ()
143 "Hide buffer with sematinc-symref results"
144 (interactive)
145 (bury-buffer))
146
147(defcustom semantic-symref-results-summary-function 'semantic-format-tag-prototype
148 "*Function to use when creating items in Imenu.
149Some useful functions are found in `semantic-format-tag-functions'."
150 :group 'semantic-symref
151 :type semantic-format-tag-custom-list)
152
153(defun semantic-symref-results-dump (results)
154 "Dump the RESULTS into the current buffer."
155 ;; Get ready for the insert.
156 (toggle-read-only -1)
157 (erase-buffer)
158
159 ;; Insert the contents.
160 (let ((lastfile nil)
161 )
162 (dolist (T (oref results :hit-tags))
163
164 (when (not (equal lastfile (semantic-tag-file-name T)))
165 (setq lastfile (semantic-tag-file-name T))
166 (insert-button lastfile
167 'mouse-face 'custom-button-pressed-face
168 'action 'semantic-symref-rb-goto-file
169 'tag T
170 )
171 (insert "\n"))
172
173 (insert " ")
174 (insert-button "[+]"
175 'mouse-face 'highlight
176 'face nil
177 'action 'semantic-symref-rb-toggle-expand-tag
178 'tag T
179 'state 'closed)
180 (insert " ")
181 (insert-button (funcall semantic-symref-results-summary-function
182 T nil t)
183 'mouse-face 'custom-button-pressed-face
184 'face nil
185 'action 'semantic-symref-rb-goto-tag
186 'tag T)
187 (insert "\n")
188
189 ))
190
191 ;; Clean up the mess
192 (toggle-read-only 1)
193 (set-buffer-modified-p nil)
194 )
195
196;;; Commands for semantic-symref-results
197;;
198(defun semantic-symref-list-toggle-showing ()
199 "Toggle showing the contents below the current line."
200 (interactive)
201 (beginning-of-line)
202 (when (re-search-forward "\\[[-+]\\]" (point-at-eol) t)
203 (forward-char -1)
204 (push-button)))
205
206(defun semantic-symref-rb-toggle-expand-tag (&optional button)
207 "Go to the file specified in the symref results buffer.
208BUTTON is the button that was clicked."
209 (interactive)
210 (let* ((tag (button-get button 'tag))
211 (buff (semantic-tag-buffer tag))
212 (hits (semantic--tag-get-property tag :hit))
213 (state (button-get button 'state))
214 (text nil)
215 )
216 (cond
217 ((eq state 'closed)
218 (toggle-read-only -1)
219 (save-excursion
220 (set-buffer buff)
221 (dolist (H hits)
222 (goto-char (point-min))
223 (forward-line (1- H))
224 (beginning-of-line)
225 (back-to-indentation)
226 (setq text (cons (buffer-substring (point) (point-at-eol)) text)))
227 (setq text (nreverse text))
228 )
229 (goto-char (button-start button))
230 (forward-char 1)
231 (delete-char 1)
232 (insert "-")
233 (button-put button 'state 'open)
234 (save-excursion
235 (end-of-line)
236 (while text
237 (insert "\n")
238 (insert " ")
239 (insert-button (car text)
240 'mouse-face 'highlight
241 'face nil
242 'action 'semantic-symref-rb-goto-match
243 'tag tag
244 'line (car hits))
245 (setq text (cdr text)
246 hits (cdr hits))))
247 (toggle-read-only 1)
248 )
249 ((eq state 'open)
250 (toggle-read-only -1)
251 (button-put button 'state 'closed)
252 ;; Delete the various bits.
253 (goto-char (button-start button))
254 (forward-char 1)
255 (delete-char 1)
256 (insert "+")
257 (save-excursion
258 (end-of-line)
259 (forward-char 1)
260 (delete-region (point)
261 (save-excursion
262 (forward-char 1)
263 (forward-line (length hits))
264 (point))))
265 (toggle-read-only 1)
266 )
267 ))
268 )
269
270(defun semantic-symref-rb-goto-file (&optional button)
271 "Go to the file specified in the symref results buffer.
272BUTTON is the button that was clicked."
273 (let* ((tag (button-get button 'tag))
274 (buff (semantic-tag-buffer tag))
275 (win (selected-window))
276 )
277 (switch-to-buffer-other-window buff)
278 (pulse-momentary-highlight-one-line (point))
279 (when (eq last-command-char ? ) (select-window win))
280 ))
281
282
283(defun semantic-symref-rb-goto-tag (&optional button)
284 "Go to the file specified in the symref results buffer.
285BUTTON is the button that was clicked."
286 (interactive)
287 (let* ((tag (button-get button 'tag))
288 (buff (semantic-tag-buffer tag))
289 (win (selected-window))
290 )
291 (switch-to-buffer-other-window buff)
292 (semantic-go-to-tag tag)
293 (pulse-momentary-highlight-one-line (point))
294 (when (eq last-command-char ? ) (select-window win))
295 )
296 )
297
298(defun semantic-symref-rb-goto-match (&optional button)
299 "Go to the file specified in the symref results buffer.
300BUTTON is the button that was clicked."
301 (interactive)
302 (let* ((tag (button-get button 'tag))
303 (line (button-get button 'line))
304 (buff (semantic-tag-buffer tag))
305 (win (selected-window))
306 )
307 (switch-to-buffer-other-window buff)
308 (goto-line line)
309 (pulse-momentary-highlight-one-line (point))
310 (when (eq last-command-char ? ) (select-window win))
311 )
312 )
313
314(defun semantic-symref-list-next-line ()
315 "Next line in `semantic-symref-results-mode'."
316 (interactive)
317 (forward-line 1)
318 (back-to-indentation))
319
320(defun semantic-symref-list-prev-line ()
321 "Next line in `semantic-symref-results-mode'."
322 (interactive)
323 (forward-line -1)
324 (back-to-indentation))
325
326(provide 'semantic/symref/list)
327
328;;; semantic/symref/list.el ends here