diff options
| author | Chong Yidong | 2009-08-29 20:12:41 +0000 |
|---|---|---|
| committer | Chong Yidong | 2009-08-29 20:12:41 +0000 |
| commit | a4bdf7157468652d2d7730196c142ed234e635ac (patch) | |
| tree | f822be8eef906e1b6e19ff6975231a5af9f0f96d | |
| parent | a6de3d1a7347048f6ef74160583203fbaf323b6b (diff) | |
| download | emacs-a4bdf7157468652d2d7730196c142ed234e635ac.tar.gz emacs-a4bdf7157468652d2d7730196c142ed234e635ac.zip | |
cedet/semantic/symref.el, cedet/semantic/symref/cscope.el.
cedet/semantic/symref/global.el, cedet/semantic/symref/idutils.el,
cedet/semantic/symref/list.el: New files.
cedet/semantic/db-ebrowse.el: Use mapc instead of mapcar.
| -rw-r--r-- | lisp/cedet/semantic/db-ebrowse.el | 10 | ||||
| -rw-r--r-- | lisp/cedet/semantic/symref.el | 485 | ||||
| -rw-r--r-- | lisp/cedet/semantic/symref/cscope.el | 84 | ||||
| -rw-r--r-- | lisp/cedet/semantic/symref/global.el | 69 | ||||
| -rw-r--r-- | lisp/cedet/semantic/symref/idutils.el | 71 | ||||
| -rw-r--r-- | lisp/cedet/semantic/symref/list.el | 328 |
6 files changed, 1042 insertions, 5 deletions
diff --git a/lisp/cedet/semantic/db-ebrowse.el b/lisp/cedet/semantic/db-ebrowse.el index 3302afd83da..b38e6b0a1ca 100644 --- a/lisp/cedet/semantic/db-ebrowse.el +++ b/lisp/cedet/semantic/db-ebrowse.el | |||
| @@ -115,11 +115,11 @@ is specified by `semanticdb-default-save-directory'." | |||
| 115 | ;; to get the file names. | 115 | ;; to get the file names. |
| 116 | 116 | ||
| 117 | 117 | ||
| 118 | (mapcar (lambda (f) | 118 | (mapc (lambda (f) |
| 119 | (when (semanticdb-ebrowse-C-file-p f) | 119 | (when (semanticdb-ebrowse-C-file-p f) |
| 120 | (insert f) | 120 | (insert f) |
| 121 | (insert "\n"))) | 121 | (insert "\n"))) |
| 122 | files) | 122 | files) |
| 123 | ;; Cleanup the ebrowse output buffer. | 123 | ;; Cleanup the ebrowse output buffer. |
| 124 | (save-excursion | 124 | (save-excursion |
| 125 | (set-buffer (get-buffer-create "*EBROWSE OUTPUT*")) | 125 | (set-buffer (get-buffer-create "*EBROWSE OUTPUT*")) |
diff --git a/lisp/cedet/semantic/symref.el b/lisp/cedet/semantic/symref.el new file mode 100644 index 00000000000..acebac032d5 --- /dev/null +++ b/lisp/cedet/semantic/symref.el | |||
| @@ -0,0 +1,485 @@ | |||
| 1 | ;;; semantic/symref.el --- Symbol Reference API | ||
| 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 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 10 | ;; it under the terms of the GNU General Public License as published by | ||
| 11 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 12 | ;; (at your option) any later version. | ||
| 13 | |||
| 14 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | ;; GNU General Public License for more details. | ||
| 18 | |||
| 19 | ;; You should have received a copy of the GNU General Public License | ||
| 20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | |||
| 22 | ;;; Commentary: | ||
| 23 | ;; | ||
| 24 | ;; Semantic Symbol Reference API. | ||
| 25 | ;; | ||
| 26 | ;; Semantic's native parsing tools do not handle symbol references. | ||
| 27 | ;; Tracking such information is a task that requires a huge amount of | ||
| 28 | ;; space and processing not apropriate for an Emacs Lisp program. | ||
| 29 | ;; | ||
| 30 | ;; Many desired tools used in refactoring, however, need to have | ||
| 31 | ;; such references available to them. This API aims to provide a | ||
| 32 | ;; range of functions that can be used to identify references. The | ||
| 33 | ;; API is backed by an OO system that is used to allow multiple | ||
| 34 | ;; external tools to provide the information. | ||
| 35 | ;; | ||
| 36 | ;; The default implementation uses a find/grep combination to do a | ||
| 37 | ;; search. This works ok in small projects. For larger projects, it | ||
| 38 | ;; is important to find an alternate tool to use as a back-end to | ||
| 39 | ;; symref. | ||
| 40 | ;; | ||
| 41 | ;; See the command: `semantic-symref' for an example app using this api. | ||
| 42 | ;; | ||
| 43 | ;; TO USE THIS TOOL | ||
| 44 | ;; | ||
| 45 | ;; The following functions can be used to find different kinds of | ||
| 46 | ;; references. | ||
| 47 | ;; | ||
| 48 | ;; `semantic-symref-find-references-by-name' | ||
| 49 | ;; `semantic-symref-find-file-references-by-name' | ||
| 50 | ;; `semantic-symref-find-text' | ||
| 51 | ;; | ||
| 52 | ;; All the search routines return a class of type | ||
| 53 | ;; `semantic-symref-result'. You can reference the various slots, but | ||
| 54 | ;; you will need the following methods to get extended information. | ||
| 55 | ;; | ||
| 56 | ;; `semantic-symref-result-get-files' | ||
| 57 | ;; `semantic-symref-result-get-tags' | ||
| 58 | ;; | ||
| 59 | ;; ADD A NEW EXTERNAL TOOL | ||
| 60 | ;; | ||
| 61 | ;; To support a new external tool, sublcass `semantic-symref-tool-baseclass' | ||
| 62 | ;; and implement the methods. The baseclass provides support for | ||
| 63 | ;; managing external processes that produce parsable output. | ||
| 64 | ;; | ||
| 65 | ;; Your tool should then create an instance of `semantic-symref-result'. | ||
| 66 | |||
| 67 | (require 'semantic/fw) | ||
| 68 | (require 'ede) | ||
| 69 | (eval-when-compile (require 'data-debug) | ||
| 70 | (require 'eieio-datadebug)) | ||
| 71 | |||
| 72 | ;;; Code: | ||
| 73 | (defvar semantic-symref-tool 'detect | ||
| 74 | "*The active symbol reference tool name. | ||
| 75 | The tool symbol can be 'detect, or a symbol that is the name of | ||
| 76 | a tool that can be used for symbol referencing.") | ||
| 77 | (make-variable-buffer-local 'semantic-symref-tool) | ||
| 78 | |||
| 79 | ;;; TOOL SETUP | ||
| 80 | ;; | ||
| 81 | (defvar semantic-symref-tool-alist | ||
| 82 | '( ( (lambda (rootdir) (file-exists-p (expand-file-name "GPATH" rootdir))) . | ||
| 83 | global) | ||
| 84 | ( (lambda (rootdir) (file-exists-p (expand-file-name "ID" rootdir))) . | ||
| 85 | idutils) | ||
| 86 | ( (lambda (rootdir) (file-exists-p (expand-file-name "cscope.out" rootdir))) . | ||
| 87 | cscope ) | ||
| 88 | ) | ||
| 89 | "Alist of tools usable by `semantic-symref'. | ||
| 90 | Each entry is of the form: | ||
| 91 | ( PREDICATE . KEY ) | ||
| 92 | Where PREDICATE is a function that takes a directory name for the | ||
| 93 | root of a project, and returns non-nil if the tool represented by KEY | ||
| 94 | is supported. | ||
| 95 | |||
| 96 | If no tools are supported, then 'grep is assumed.") | ||
| 97 | |||
| 98 | (defun semantic-symref-detect-symref-tool () | ||
| 99 | "Detect the symref tool to use for the current buffer." | ||
| 100 | (if (not (eq semantic-symref-tool 'detect)) | ||
| 101 | semantic-symref-tool | ||
| 102 | ;; We are to perform a detection for the right tool to use. | ||
| 103 | (let* ((rootproj (when (and (featurep 'ede) ede-minor-mode) | ||
| 104 | (ede-toplevel))) | ||
| 105 | (rootdir (if rootproj | ||
| 106 | (ede-project-root-directory rootproj) | ||
| 107 | default-directory)) | ||
| 108 | (tools semantic-symref-tool-alist)) | ||
| 109 | (while (and tools (eq semantic-symref-tool 'detect)) | ||
| 110 | (when (funcall (car (car tools)) rootdir) | ||
| 111 | (setq semantic-symref-tool (cdr (car tools)))) | ||
| 112 | (setq tools (cdr tools))) | ||
| 113 | |||
| 114 | (when (eq semantic-symref-tool 'detect) | ||
| 115 | (setq semantic-symref-tool 'grep)) | ||
| 116 | |||
| 117 | semantic-symref-tool))) | ||
| 118 | |||
| 119 | (defun semantic-symref-instantiate (&rest args) | ||
| 120 | "Instantiate a new symref search object. | ||
| 121 | ARGS are the initialization arguments to pass to the created class." | ||
| 122 | (let* ((srt (symbol-name (semantic-symref-detect-symref-tool))) | ||
| 123 | (class (intern-soft (concat "semantic-symref-tool-" srt))) | ||
| 124 | (inst nil) | ||
| 125 | ) | ||
| 126 | (when (not (class-p class)) | ||
| 127 | (error "Unknown symref tool %s" semantic-symref-tool)) | ||
| 128 | (setq inst (apply 'make-instance class args)) | ||
| 129 | inst)) | ||
| 130 | |||
| 131 | (defvar semantic-symref-last-result nil | ||
| 132 | "The last calculated symref result.") | ||
| 133 | |||
| 134 | (defun semantic-symref-data-debug-last-result () | ||
| 135 | "Run the last symref data result in Data Debug." | ||
| 136 | (interactive) | ||
| 137 | (if semantic-symref-last-result | ||
| 138 | (progn | ||
| 139 | (data-debug-new-buffer "*Symbol Reference ADEBUG*") | ||
| 140 | (data-debug-insert-object-slots semantic-symref-last-result "]")) | ||
| 141 | (message "Empty results."))) | ||
| 142 | |||
| 143 | ;;; EXTERNAL API | ||
| 144 | ;; | ||
| 145 | |||
| 146 | (defun semantic-symref-find-references-by-name (name &optional scope tool-return) | ||
| 147 | "Find a list of references to NAME in the current project. | ||
| 148 | Optional SCOPE specifies which file set to search. Defaults to 'project. | ||
| 149 | Refers to `semantic-symref-tool', to determine the reference tool to use | ||
| 150 | for the current buffer. | ||
| 151 | Returns an object of class `semantic-symref-result'. | ||
| 152 | TOOL-RETURN is an optional symbol, which will be assigned the tool used | ||
| 153 | to perform the search. This was added for use by a test harness." | ||
| 154 | (interactive "sName: ") | ||
| 155 | (let* ((inst (semantic-symref-instantiate | ||
| 156 | :searchfor name | ||
| 157 | :searchtype 'symbol | ||
| 158 | :searchscope (or scope 'project) | ||
| 159 | :resulttype 'line)) | ||
| 160 | (result (semantic-symref-get-result inst))) | ||
| 161 | (when tool-return | ||
| 162 | (set tool-return inst)) | ||
| 163 | (prog1 | ||
| 164 | (setq semantic-symref-last-result result) | ||
| 165 | (when (interactive-p) | ||
| 166 | (semantic-symref-data-debug-last-result)))) | ||
| 167 | ) | ||
| 168 | |||
| 169 | (defun semantic-symref-find-tags-by-name (name &optional scope) | ||
| 170 | "Find a list of references to NAME in the current project. | ||
| 171 | Optional SCOPE specifies which file set to search. Defaults to 'project. | ||
| 172 | Refers to `semantic-symref-tool', to determine the reference tool to use | ||
| 173 | for the current buffer. | ||
| 174 | Returns an object of class `semantic-symref-result'." | ||
| 175 | (interactive "sName: ") | ||
| 176 | (let* ((inst (semantic-symref-instantiate | ||
| 177 | :searchfor name | ||
| 178 | :searchtype 'tagname | ||
| 179 | :searchscope (or scope 'project) | ||
| 180 | :resulttype 'line)) | ||
| 181 | (result (semantic-symref-get-result inst))) | ||
| 182 | (prog1 | ||
| 183 | (setq semantic-symref-last-result result) | ||
| 184 | (when (interactive-p) | ||
| 185 | (semantic-symref-data-debug-last-result)))) | ||
| 186 | ) | ||
| 187 | |||
| 188 | (defun semantic-symref-find-tags-by-regexp (name &optional scope) | ||
| 189 | "Find a list of references to NAME in the current project. | ||
| 190 | Optional SCOPE specifies which file set to search. Defaults to 'project. | ||
| 191 | Refers to `semantic-symref-tool', to determine the reference tool to use | ||
| 192 | for the current buffer. | ||
| 193 | Returns an object of class `semantic-symref-result'." | ||
| 194 | (interactive "sName: ") | ||
| 195 | (let* ((inst (semantic-symref-instantiate | ||
| 196 | :searchfor name | ||
| 197 | :searchtype 'tagregexp | ||
| 198 | :searchscope (or scope 'project) | ||
| 199 | :resulttype 'line)) | ||
| 200 | (result (semantic-symref-get-result inst))) | ||
| 201 | (prog1 | ||
| 202 | (setq semantic-symref-last-result result) | ||
| 203 | (when (interactive-p) | ||
| 204 | (semantic-symref-data-debug-last-result)))) | ||
| 205 | ) | ||
| 206 | |||
| 207 | (defun semantic-symref-find-tags-by-completion (name &optional scope) | ||
| 208 | "Find a list of references to NAME in the current project. | ||
| 209 | Optional SCOPE specifies which file set to search. Defaults to 'project. | ||
| 210 | Refers to `semantic-symref-tool', to determine the reference tool to use | ||
| 211 | for the current buffer. | ||
| 212 | Returns an object of class `semantic-symref-result'." | ||
| 213 | (interactive "sName: ") | ||
| 214 | (let* ((inst (semantic-symref-instantiate | ||
| 215 | :searchfor name | ||
| 216 | :searchtype 'tagcompletions | ||
| 217 | :searchscope (or scope 'project) | ||
| 218 | :resulttype 'line)) | ||
| 219 | (result (semantic-symref-get-result inst))) | ||
| 220 | (prog1 | ||
| 221 | (setq semantic-symref-last-result result) | ||
| 222 | (when (interactive-p) | ||
| 223 | (semantic-symref-data-debug-last-result)))) | ||
| 224 | ) | ||
| 225 | |||
| 226 | (defun semantic-symref-find-file-references-by-name (name &optional scope) | ||
| 227 | "Find a list of references to NAME in the current project. | ||
| 228 | Optional SCOPE specifies which file set to search. Defaults to 'project. | ||
| 229 | Refers to `semantic-symref-tool', to determine the reference tool to use | ||
| 230 | for the current buffer. | ||
| 231 | Returns an object of class `semantic-symref-result'." | ||
| 232 | (interactive "sName: ") | ||
| 233 | (let* ((inst (semantic-symref-instantiate | ||
| 234 | :searchfor name | ||
| 235 | :searchtype 'regexp | ||
| 236 | :searchscope (or scope 'project) | ||
| 237 | :resulttype 'file)) | ||
| 238 | (result (semantic-symref-get-result inst))) | ||
| 239 | (prog1 | ||
| 240 | (setq semantic-symref-last-result result) | ||
| 241 | (when (interactive-p) | ||
| 242 | (semantic-symref-data-debug-last-result)))) | ||
| 243 | ) | ||
| 244 | |||
| 245 | (defun semantic-symref-find-text (text &optional scope) | ||
| 246 | "Find a list of occurances of TEXT in the current project. | ||
| 247 | TEXT is a regexp formatted for use with egrep. | ||
| 248 | Optional SCOPE specifies which file set to search. Defaults to 'project. | ||
| 249 | Refers to `semantic-symref-tool', to determine the reference tool to use | ||
| 250 | for the current buffer. | ||
| 251 | Returns an object of class `semantic-symref-result'." | ||
| 252 | (interactive "sEgrep style Regexp: ") | ||
| 253 | (let* ((inst (semantic-symref-instantiate | ||
| 254 | :searchfor text | ||
| 255 | :searchtype 'regexp | ||
| 256 | :searchscope (or scope 'project) | ||
| 257 | :resulttype 'line)) | ||
| 258 | (result (semantic-symref-get-result inst))) | ||
| 259 | (prog1 | ||
| 260 | (setq semantic-symref-last-result result) | ||
| 261 | (when (interactive-p) | ||
| 262 | (semantic-symref-data-debug-last-result)))) | ||
| 263 | ) | ||
| 264 | |||
| 265 | ;;; RESULTS | ||
| 266 | ;; | ||
| 267 | ;; The results class and methods provide features for accessing hits. | ||
| 268 | (defclass semantic-symref-result () | ||
| 269 | ((created-by :initarg :created-by | ||
| 270 | :type semantic-symref-tool-baseclass | ||
| 271 | :documentation | ||
| 272 | "Back-pointer to the symref tool creating these results.") | ||
| 273 | (hit-files :initarg :hit-files | ||
| 274 | :type list | ||
| 275 | :documentation | ||
| 276 | "The list of files hit.") | ||
| 277 | (hit-text :initarg :hit-text | ||
| 278 | :type list | ||
| 279 | :documentation | ||
| 280 | "If the result doesn't provide full lines, then fill in hit-text. | ||
| 281 | GNU Global does completion search this way.") | ||
| 282 | (hit-lines :initarg :hit-lines | ||
| 283 | :type list | ||
| 284 | :documentation | ||
| 285 | "The list of line hits. | ||
| 286 | Each element is a cons cell of the form (LINE . FILENAME).") | ||
| 287 | (hit-tags :initarg :hit-tags | ||
| 288 | :type list | ||
| 289 | :documentation | ||
| 290 | "The list of tags with hits in them. | ||
| 291 | Use the `semantic-symref-hit-tags' method to get this list.") | ||
| 292 | ) | ||
| 293 | "The results from a symbol reference search.") | ||
| 294 | |||
| 295 | (defmethod semantic-symref-result-get-files ((result semantic-symref-result)) | ||
| 296 | "Get the list of files from the symref result RESULT." | ||
| 297 | (if (slot-boundp result :hit-files) | ||
| 298 | (oref result hit-files) | ||
| 299 | (let* ((lines (oref result :hit-lines)) | ||
| 300 | (files (mapcar (lambda (a) (cdr a)) lines)) | ||
| 301 | (ans nil)) | ||
| 302 | (setq ans (list (car files)) | ||
| 303 | files (cdr files)) | ||
| 304 | (dolist (F files) | ||
| 305 | ;; This algorithm for uniqing the file list depends on the | ||
| 306 | ;; tool in question providing all the hits in the same file | ||
| 307 | ;; grouped together. | ||
| 308 | (when (not (string= F (car ans))) | ||
| 309 | (setq ans (cons F ans)))) | ||
| 310 | (oset result hit-files (nreverse ans)) | ||
| 311 | ) | ||
| 312 | )) | ||
| 313 | |||
| 314 | (defmethod semantic-symref-result-get-tags ((result semantic-symref-result) | ||
| 315 | &optional open-buffers) | ||
| 316 | "Get the list of tags from the symref result RESULT. | ||
| 317 | Optional OPEN-BUFFERS indicates that the buffers that the hits are | ||
| 318 | in should remain open after scanning. | ||
| 319 | Note: This can be quite slow if most of the hits are not in buffers | ||
| 320 | already." | ||
| 321 | (if (and (slot-boundp result :hit-tags) (oref result hit-tags)) | ||
| 322 | (oref result hit-tags) | ||
| 323 | ;; Calculate the tags. | ||
| 324 | (let ((lines (oref result :hit-lines)) | ||
| 325 | (txt (oref (oref result :created-by) :searchfor)) | ||
| 326 | (searchtype (oref (oref result :created-by) :searchtype)) | ||
| 327 | (ans nil) | ||
| 328 | (out nil) | ||
| 329 | (buffs-to-kill nil)) | ||
| 330 | (save-excursion | ||
| 331 | (setq | ||
| 332 | ans | ||
| 333 | (mapcar | ||
| 334 | (lambda (hit) | ||
| 335 | (let* ((line (car hit)) | ||
| 336 | (file (cdr hit)) | ||
| 337 | (buff (get-file-buffer file)) | ||
| 338 | (tag nil) | ||
| 339 | ) | ||
| 340 | (cond | ||
| 341 | ;; We have a buffer already. Check it out. | ||
| 342 | (buff | ||
| 343 | (set-buffer buff)) | ||
| 344 | |||
| 345 | ;; We have a table, but it needs a refresh. | ||
| 346 | ;; This means we should load in that buffer. | ||
| 347 | (t | ||
| 348 | (let ((kbuff | ||
| 349 | (if open-buffers | ||
| 350 | ;; Even if we keep the buffers open, don't | ||
| 351 | ;; let EDE ask lots of questions. | ||
| 352 | (let ((ede-auto-add-method 'never)) | ||
| 353 | (find-file-noselect file t)) | ||
| 354 | ;; When not keeping the buffers open, then | ||
| 355 | ;; don't setup all the fancy froo-froo features | ||
| 356 | ;; either. | ||
| 357 | (semantic-find-file-noselect file t)))) | ||
| 358 | (set-buffer kbuff) | ||
| 359 | (setq buffs-to-kill (cons kbuff buffs-to-kill)) | ||
| 360 | (semantic-fetch-tags) | ||
| 361 | )) | ||
| 362 | ) | ||
| 363 | |||
| 364 | ;; Too much baggage in goto-line | ||
| 365 | ;; (goto-line line) | ||
| 366 | (goto-char (point-min)) | ||
| 367 | (forward-line (1- line)) | ||
| 368 | |||
| 369 | ;; Search forward for the matching text | ||
| 370 | (re-search-forward (regexp-quote txt) | ||
| 371 | (point-at-eol) | ||
| 372 | t) | ||
| 373 | |||
| 374 | (setq tag (semantic-current-tag)) | ||
| 375 | |||
| 376 | ;; If we are searching for a tag, but bound the tag we are looking | ||
| 377 | ;; for, see if it resides in some other parent tag. | ||
| 378 | ;; | ||
| 379 | ;; If there is no parent tag, then we still need to hang the originator | ||
| 380 | ;; in our list. | ||
| 381 | (when (and (eq searchtype 'symbol) | ||
| 382 | (string= (semantic-tag-name tag) txt)) | ||
| 383 | (setq tag (or (semantic-current-tag-parent) tag))) | ||
| 384 | |||
| 385 | ;; Copy the tag, which adds a :filename property. | ||
| 386 | (when tag | ||
| 387 | (setq tag (semantic-tag-copy tag nil t)) | ||
| 388 | ;; Ad this hit to the tag. | ||
| 389 | (semantic--tag-put-property tag :hit (list line))) | ||
| 390 | tag)) | ||
| 391 | lines))) | ||
| 392 | ;; Kill off dead buffers, unless we were requested to leave them open. | ||
| 393 | (when (not open-buffers) | ||
| 394 | (mapc 'kill-buffer buffs-to-kill)) | ||
| 395 | ;; Strip out duplicates. | ||
| 396 | (dolist (T ans) | ||
| 397 | (if (and T (not (semantic-equivalent-tag-p (car out) T))) | ||
| 398 | (setq out (cons T out)) | ||
| 399 | (when T | ||
| 400 | ;; Else, add this line into the existing list of lines. | ||
| 401 | (let ((lines (append (semantic--tag-get-property (car out) :hit) | ||
| 402 | (semantic--tag-get-property T :hit)))) | ||
| 403 | (semantic--tag-put-property (car out) :hit lines))) | ||
| 404 | )) | ||
| 405 | ;; Out is reversed... twice | ||
| 406 | (oset result :hit-tags (nreverse out))))) | ||
| 407 | |||
| 408 | ;;; SYMREF TOOLS | ||
| 409 | ;; | ||
| 410 | ;; The base symref tool provides something to hang new tools off of | ||
| 411 | ;; for finding symbol references. | ||
| 412 | (defclass semantic-symref-tool-baseclass () | ||
| 413 | ((searchfor :initarg :searchfor | ||
| 414 | :type string | ||
| 415 | :documentation "The thing to search for.") | ||
| 416 | (searchtype :initarg :searchtype | ||
| 417 | :type symbol | ||
| 418 | :documentation "The type of search to do. | ||
| 419 | Values could be `symbol, `regexp, 'tagname, or 'completion.") | ||
| 420 | (searchscope :initarg :searchscope | ||
| 421 | :type symbol | ||
| 422 | :documentation | ||
| 423 | "The scope to search for. | ||
| 424 | Can be 'project, 'target, or 'file.") | ||
| 425 | (resulttype :initarg :resulttype | ||
| 426 | :type symbol | ||
| 427 | :documentation | ||
| 428 | "The kind of search results desired. | ||
| 429 | Can be 'line, 'file, or 'tag. | ||
| 430 | The type of result can be converted from 'line to 'file, or 'line to 'tag, | ||
| 431 | but not from 'file to 'line or 'tag.") | ||
| 432 | ) | ||
| 433 | "Baseclass for all symbol references tools. | ||
| 434 | A symbol reference tool supplies functionality to identify the locations of | ||
| 435 | where different symbols are used. | ||
| 436 | |||
| 437 | Subclasses should be named `semantic-symref-tool-NAME', where | ||
| 438 | NAME is the name of the tool used in the configuration variable | ||
| 439 | `semantic-symref-tool'" | ||
| 440 | :abstract t) | ||
| 441 | |||
| 442 | (defmethod semantic-symref-get-result ((tool semantic-symref-tool-baseclass)) | ||
| 443 | "Calculate the results of a search based on TOOL. | ||
| 444 | The symref TOOL should already contain the search criteria." | ||
| 445 | (let ((answer (semantic-symref-perform-search tool)) | ||
| 446 | ) | ||
| 447 | (when answer | ||
| 448 | (let ((answersym (if (eq (oref tool :resulttype) 'file) | ||
| 449 | :hit-files | ||
| 450 | (if (stringp (car answer)) | ||
| 451 | :hit-text | ||
| 452 | :hit-lines)))) | ||
| 453 | (semantic-symref-result (oref tool searchfor) | ||
| 454 | answersym | ||
| 455 | answer | ||
| 456 | :created-by tool)) | ||
| 457 | ) | ||
| 458 | )) | ||
| 459 | |||
| 460 | (defmethod semantic-symref-perform-search ((tool semantic-symref-tool-baseclass)) | ||
| 461 | "Base search for symref tools should throw an error." | ||
| 462 | (error "Symref tool objects must implement `semantic-symref-perform-search'")) | ||
| 463 | |||
| 464 | (defmethod semantic-symref-parse-tool-output ((tool semantic-symref-tool-baseclass) | ||
| 465 | outputbuffer) | ||
| 466 | "Parse the entire OUTPUTBUFFER of a symref tool. | ||
| 467 | Calls the method `semantic-symref-parse-tool-output-one-line' over and | ||
| 468 | over until it returns nil." | ||
| 469 | (save-excursion | ||
| 470 | (set-buffer outputbuffer) | ||
| 471 | (goto-char (point-min)) | ||
| 472 | (let ((result nil) | ||
| 473 | (hit nil)) | ||
| 474 | (while (setq hit (semantic-symref-parse-tool-output-one-line tool)) | ||
| 475 | (setq result (cons hit result))) | ||
| 476 | (nreverse result))) | ||
| 477 | ) | ||
| 478 | |||
| 479 | (defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-baseclass)) | ||
| 480 | "Base tool output parser is not implemented." | ||
| 481 | (error "Symref tool objects must implement `semantic-symref-parse-tool-output-one-line'")) | ||
| 482 | |||
| 483 | (provide 'semantic/symref) | ||
| 484 | |||
| 485 | ;;; semantic/symref.el ends here | ||
diff --git a/lisp/cedet/semantic/symref/cscope.el b/lisp/cedet/semantic/symref/cscope.el new file mode 100644 index 00000000000..9d6eda9a5cf --- /dev/null +++ b/lisp/cedet/semantic/symref/cscope.el | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | ;;; semantic/symref/cscope.el --- Semantic-symref support via cscope. | ||
| 2 | |||
| 3 | ;;; Copyright (C) 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 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 10 | ;; it under the terms of the GNU General Public License as published by | ||
| 11 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 12 | ;; (at your option) any later version. | ||
| 13 | |||
| 14 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | ;; GNU General Public License for more details. | ||
| 18 | |||
| 19 | ;; You should have received a copy of the GNU General Public License | ||
| 20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | |||
| 22 | ;;; Commentary: | ||
| 23 | ;; | ||
| 24 | ;; Semantic symref support via cscope. | ||
| 25 | |||
| 26 | (require 'cedet-cscope) | ||
| 27 | (require 'semantic/symref) | ||
| 28 | |||
| 29 | ;;; Code: | ||
| 30 | (defclass semantic-symref-tool-cscope (semantic-symref-tool-baseclass) | ||
| 31 | ( | ||
| 32 | ) | ||
| 33 | "A symref tool implementation using CScope. | ||
| 34 | The CScope command can be used to generate lists of tags in a way | ||
| 35 | similar to that of `grep'. This tool will parse the output to generate | ||
| 36 | the hit list. | ||
| 37 | |||
| 38 | See the function `cedet-cscope-search' for more details.") | ||
| 39 | |||
| 40 | (defmethod semantic-symref-perform-search ((tool semantic-symref-tool-cscope)) | ||
| 41 | "Perform a search with GNU Global." | ||
| 42 | (let* ((rootproj (when (and (featurep 'ede) ede-minor-mode) | ||
| 43 | (ede-toplevel))) | ||
| 44 | (default-directory (if rootproj | ||
| 45 | (ede-project-root-directory rootproj) | ||
| 46 | default-directory)) | ||
| 47 | ;; CScope has to be run from the project root where | ||
| 48 | ;; cscope.out is. | ||
| 49 | (b (cedet-cscope-search (oref tool :searchfor) | ||
| 50 | (oref tool :searchtype) | ||
| 51 | (oref tool :resulttype) | ||
| 52 | (oref tool :searchscope) | ||
| 53 | )) | ||
| 54 | ) | ||
| 55 | (semantic-symref-parse-tool-output tool b) | ||
| 56 | )) | ||
| 57 | |||
| 58 | (defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-cscope)) | ||
| 59 | "Parse one line of grep output, and return it as a match list. | ||
| 60 | Moves cursor to end of the match." | ||
| 61 | (cond ((eq (oref tool :resulttype) 'file) | ||
| 62 | ;; Search for files | ||
| 63 | (when (re-search-forward "^\\([^\n]+\\)$" nil t) | ||
| 64 | (match-string 1))) | ||
| 65 | ((eq (oref tool :searchtype) 'tagcompletions) | ||
| 66 | ;; Search for files | ||
| 67 | (when (re-search-forward "^[^ ]+ [^ ]+ [^ ]+ \\(.*\\)$" nil t) | ||
| 68 | (let ((subtxt (match-string 1)) | ||
| 69 | (searchtxt (oref tool :searchfor))) | ||
| 70 | (if (string-match (concat "\\<" searchtxt "\\(\\w\\|\\s_\\)*\\>") | ||
| 71 | subtxt) | ||
| 72 | (match-string 0 subtxt) | ||
| 73 | ;; We have to return something at this point. | ||
| 74 | subtxt))) | ||
| 75 | ) | ||
| 76 | (t | ||
| 77 | (when (re-search-forward "^\\([^ ]+\\) [^ ]+ \\([0-9]+\\) " nil t) | ||
| 78 | (cons (string-to-number (match-string 2)) | ||
| 79 | (expand-file-name (match-string 1))) | ||
| 80 | )))) | ||
| 81 | |||
| 82 | (provide 'semantic/symref/cscope) | ||
| 83 | |||
| 84 | ;;; semantic/symref/cscope.el ends here | ||
diff --git a/lisp/cedet/semantic/symref/global.el b/lisp/cedet/semantic/symref/global.el new file mode 100644 index 00000000000..7a5b8d73efe --- /dev/null +++ b/lisp/cedet/semantic/symref/global.el | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | ;;; semantic/symref/global.el --- Use GNU Global for symbol references | ||
| 2 | |||
| 3 | ;; Copyright (C) 2008, 2009 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Eric Ludlam <eludlam@mathworks.com> | ||
| 6 | |||
| 7 | ;; Author: Eric M. Ludlam <eric@siege-engine.com> | ||
| 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 | ;; GNU Global use with the semantic-symref system. | ||
| 27 | |||
| 28 | (require 'cedet-global) | ||
| 29 | (require 'semantic/symref) | ||
| 30 | |||
| 31 | ;;; Code: | ||
| 32 | (defclass semantic-symref-tool-global (semantic-symref-tool-baseclass) | ||
| 33 | ( | ||
| 34 | ) | ||
| 35 | "A symref tool implementation using GNU Global. | ||
| 36 | The GNU Global command can be used to generate lists of tags in a way | ||
| 37 | similar to that of `grep'. This tool will parse the output to generate | ||
| 38 | the hit list. | ||
| 39 | |||
| 40 | See the function `cedet-gnu-global-search' for more details.") | ||
| 41 | |||
| 42 | (defmethod semantic-symref-perform-search ((tool semantic-symref-tool-global)) | ||
| 43 | "Perform a search with GNU Global." | ||
| 44 | (let ((b (cedet-gnu-global-search (oref tool :searchfor) | ||
| 45 | (oref tool :searchtype) | ||
| 46 | (oref tool :resulttype) | ||
| 47 | (oref tool :searchscope) | ||
| 48 | )) | ||
| 49 | ) | ||
| 50 | (semantic-symref-parse-tool-output tool b) | ||
| 51 | )) | ||
| 52 | |||
| 53 | (defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-global)) | ||
| 54 | "Parse one line of grep output, and return it as a match list. | ||
| 55 | Moves cursor to end of the match." | ||
| 56 | (cond ((or (eq (oref tool :resulttype) 'file) | ||
| 57 | (eq (oref tool :searchtype) 'tagcompletions)) | ||
| 58 | ;; Search for files | ||
| 59 | (when (re-search-forward "^\\([^\n]+\\)$" nil t) | ||
| 60 | (match-string 1))) | ||
| 61 | (t | ||
| 62 | (when (re-search-forward "^\\([^ ]+\\) +\\([0-9]+\\) \\([^ ]+\\) " nil t) | ||
| 63 | (cons (string-to-number (match-string 2)) | ||
| 64 | (match-string 3)) | ||
| 65 | )))) | ||
| 66 | |||
| 67 | (provide 'semantic/symref/global) | ||
| 68 | |||
| 69 | ;;; semantic/symref/global.el ends here | ||
diff --git a/lisp/cedet/semantic/symref/idutils.el b/lisp/cedet/semantic/symref/idutils.el new file mode 100644 index 00000000000..abce2313160 --- /dev/null +++ b/lisp/cedet/semantic/symref/idutils.el | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | ;;; semantic/symref/idutils.el --- Symref implementation for idutils | ||
| 2 | |||
| 3 | ;;; Copyright (C) 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 | ;; Support IDUtils use in the Semantic Symref tool. | ||
| 27 | |||
| 28 | (require 'cedet-idutils) | ||
| 29 | (require 'semantic-symref) | ||
| 30 | |||
| 31 | ;;; Code: | ||
| 32 | (defclass semantic-symref-tool-idutils (semantic-symref-tool-baseclass) | ||
| 33 | ( | ||
| 34 | ) | ||
| 35 | "A symref tool implementation using ID Utils. | ||
| 36 | The udutils command set can be used to generate lists of tags in a way | ||
| 37 | similar to that of `grep'. This tool will parse the output to generate | ||
| 38 | the hit list. | ||
| 39 | |||
| 40 | See the function `cedet-idutils-search' for more details.") | ||
| 41 | |||
| 42 | (defmethod semantic-symref-perform-search ((tool semantic-symref-tool-idutils)) | ||
| 43 | "Perform a search with IDUtils." | ||
| 44 | (let ((b (cedet-idutils-search (oref tool :searchfor) | ||
| 45 | (oref tool :searchtype) | ||
| 46 | (oref tool :resulttype) | ||
| 47 | (oref tool :searchscope) | ||
| 48 | )) | ||
| 49 | ) | ||
| 50 | (semantic-symref-parse-tool-output tool b) | ||
| 51 | )) | ||
| 52 | |||
| 53 | (defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-idutils)) | ||
| 54 | "Parse one line of grep output, and return it as a match list. | ||
| 55 | Moves cursor to end of the match." | ||
| 56 | (cond ((eq (oref tool :resulttype) 'file) | ||
| 57 | ;; Search for files | ||
| 58 | (when (re-search-forward "^\\([^\n]+\\)$" nil t) | ||
| 59 | (match-string 1))) | ||
| 60 | ((eq (oref tool :searchtype) 'tagcompletions) | ||
| 61 | (when (re-search-forward "^\\([^ ]+\\) " nil t) | ||
| 62 | (match-string 1))) | ||
| 63 | (t | ||
| 64 | (when (re-search-forward "^\\([^ :]+\\):+\\([0-9]+\\):" nil t) | ||
| 65 | (cons (string-to-number (match-string 2)) | ||
| 66 | (expand-file-name (match-string 1) default-directory)) | ||
| 67 | )))) | ||
| 68 | |||
| 69 | (provide 'semantic/symref/idutils) | ||
| 70 | |||
| 71 | ;;; semantic/symref/idutils.el ends here | ||
diff --git a/lisp/cedet/semantic/symref/list.el b/lisp/cedet/semantic/symref/list.el new file mode 100644 index 00000000000..74186c754a4 --- /dev/null +++ b/lisp/cedet/semantic/symref/list.el | |||
| @@ -0,0 +1,328 @@ | |||
| 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. | ||
| 43 | This command uses the currently configured references tool within the | ||
| 44 | current project to find references to the current tag. The | ||
| 45 | references are the organized by file and the name of the function | ||
| 46 | they are used in. | ||
| 47 | Display 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. | ||
| 65 | This command uses the currently configured references tool within the | ||
| 66 | current project to find references to the input SYM. The | ||
| 67 | references are the organized by file and the name of the function | ||
| 68 | they are used in. | ||
| 69 | Display 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. | ||
| 125 | RESULTS 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. | ||
| 149 | Some 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. | ||
| 208 | BUTTON 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. | ||
| 272 | BUTTON 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. | ||
| 285 | BUTTON 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. | ||
| 300 | BUTTON 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 | ||