2009-08-31 02:16:34 +00:00
|
|
|
|
;;; semantic/find.el --- Search routines for Semantic
|
2009-08-28 19:18:35 +00:00
|
|
|
|
|
2009-10-01 04:54:05 +00:00
|
|
|
|
;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
|
|
|
|
;; Free Software Foundation, Inc.
|
2009-08-28 19:18:35 +00:00
|
|
|
|
|
|
|
|
|
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
|
|
|
|
;; Keywords: syntax
|
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
;;
|
|
|
|
|
;; Routines for searching through lists of tags.
|
|
|
|
|
;; There are several groups of tag search routines:
|
|
|
|
|
;;
|
|
|
|
|
;; 1) semantic-brute-find-tag-by-*
|
|
|
|
|
;; These routines use brute force hierarchical search to scan
|
|
|
|
|
;; through lists of tags. They include some parameters
|
|
|
|
|
;; used for compatibility with the semantic 1.x search routines.
|
|
|
|
|
;;
|
|
|
|
|
;; 1.5) semantic-brute-find-first-tag-by-*
|
2009-10-01 04:54:05 +00:00
|
|
|
|
;; Like 1, except searching stops on the first match for the given
|
2009-08-28 19:18:35 +00:00
|
|
|
|
;; information.
|
|
|
|
|
;;
|
|
|
|
|
;; 2) semantic-find-tag-by-*
|
2009-10-01 04:54:05 +00:00
|
|
|
|
;; These preferred search routines attempt to scan through lists
|
2009-08-28 19:18:35 +00:00
|
|
|
|
;; in an intelligent way based on questions asked.
|
|
|
|
|
;;
|
|
|
|
|
;; 3) semantic-find-*-overlay
|
|
|
|
|
;; These routines use overlays to return tags based on a buffer position.
|
|
|
|
|
;;
|
|
|
|
|
;; 4) ...
|
|
|
|
|
|
2009-09-28 15:15:00 +00:00
|
|
|
|
;;; Code:
|
|
|
|
|
|
2009-08-31 02:16:34 +00:00
|
|
|
|
(require 'semantic)
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(require 'semantic/tag)
|
|
|
|
|
|
2009-09-28 15:15:00 +00:00
|
|
|
|
(declare-function semantic-tag-protected-p "semantic/tag-ls")
|
|
|
|
|
|
2009-08-28 19:18:35 +00:00
|
|
|
|
;;; Overlay Search Routines
|
|
|
|
|
;;
|
|
|
|
|
;; These routines provide fast access to tokens based on a buffer that
|
|
|
|
|
;; has parsed tokens in it. Uses overlays to perform the hard work.
|
2009-09-13 15:58:30 +00:00
|
|
|
|
;;
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-find-tag-by-overlay (&optional positionormarker buffer)
|
|
|
|
|
"Find all tags covering POSITIONORMARKER by using overlays.
|
|
|
|
|
If POSITIONORMARKER is nil, use the current point.
|
|
|
|
|
Optional BUFFER is used if POSITIONORMARKER is a number, otherwise the current
|
|
|
|
|
buffer is used. This finds all tags covering the specified position
|
|
|
|
|
by checking for all overlays covering the current spot. They are then sorted
|
|
|
|
|
from largest to smallest via the start location."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(when positionormarker
|
|
|
|
|
(if (markerp positionormarker)
|
|
|
|
|
(set-buffer (marker-buffer positionormarker))
|
|
|
|
|
(if (bufferp buffer)
|
|
|
|
|
(set-buffer buffer))))
|
|
|
|
|
(let ((ol (semantic-overlays-at (or positionormarker (point))))
|
|
|
|
|
(ret nil))
|
|
|
|
|
(while ol
|
|
|
|
|
(let ((tmp (semantic-overlay-get (car ol) 'semantic)))
|
|
|
|
|
(when (and tmp
|
|
|
|
|
;; We don't need with-position because no tag w/out
|
|
|
|
|
;; a position could exist in an overlay.
|
|
|
|
|
(semantic-tag-p tmp))
|
|
|
|
|
(setq ret (cons tmp ret))))
|
|
|
|
|
(setq ol (cdr ol)))
|
|
|
|
|
(sort ret (lambda (a b) (< (semantic-tag-start a)
|
|
|
|
|
(semantic-tag-start b)))))))
|
|
|
|
|
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-find-tag-by-overlay-in-region (start end &optional buffer)
|
|
|
|
|
"Find all tags which exist in whole or in part between START and END.
|
2009-10-01 04:54:05 +00:00
|
|
|
|
Uses overlays to determine position.
|
2009-08-28 19:18:35 +00:00
|
|
|
|
Optional BUFFER argument specifies the buffer to use."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(if buffer (set-buffer buffer))
|
|
|
|
|
(let ((ol (semantic-overlays-in start end))
|
|
|
|
|
(ret nil))
|
|
|
|
|
(while ol
|
|
|
|
|
(let ((tmp (semantic-overlay-get (car ol) 'semantic)))
|
|
|
|
|
(when (and tmp
|
|
|
|
|
;; See above about position
|
|
|
|
|
(semantic-tag-p tmp))
|
|
|
|
|
(setq ret (cons tmp ret))))
|
|
|
|
|
(setq ol (cdr ol)))
|
|
|
|
|
(sort ret (lambda (a b) (< (semantic-tag-start a)
|
|
|
|
|
(semantic-tag-start b)))))))
|
|
|
|
|
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-find-tag-by-overlay-next (&optional start buffer)
|
|
|
|
|
"Find the next tag after START in BUFFER.
|
|
|
|
|
If START is in an overlay, find the tag which starts next,
|
|
|
|
|
not the current tag."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(if buffer (set-buffer buffer))
|
|
|
|
|
(if (not start) (setq start (point)))
|
|
|
|
|
(let ((os start) (ol nil))
|
|
|
|
|
(while (and os (< os (point-max)) (not ol))
|
|
|
|
|
(setq os (semantic-overlay-next-change os))
|
|
|
|
|
(when os
|
|
|
|
|
;; Get overlays at position
|
|
|
|
|
(setq ol (semantic-overlays-at os))
|
|
|
|
|
;; find the overlay that belongs to semantic
|
|
|
|
|
;; and starts at the found position.
|
|
|
|
|
(while (and ol (listp ol))
|
|
|
|
|
(if (and (semantic-overlay-get (car ol) 'semantic)
|
|
|
|
|
(semantic-tag-p
|
|
|
|
|
(semantic-overlay-get (car ol) 'semantic))
|
|
|
|
|
(= (semantic-overlay-start (car ol)) os))
|
|
|
|
|
(setq ol (car ol)))
|
|
|
|
|
(when (listp ol) (setq ol (cdr ol))))))
|
|
|
|
|
;; convert ol to a tag
|
|
|
|
|
(when (and ol (semantic-tag-p (semantic-overlay-get ol 'semantic)))
|
|
|
|
|
(semantic-overlay-get ol 'semantic)))))
|
|
|
|
|
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-find-tag-by-overlay-prev (&optional start buffer)
|
|
|
|
|
"Find the next tag before START in BUFFER.
|
|
|
|
|
If START is in an overlay, find the tag which starts next,
|
|
|
|
|
not the current tag."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(if buffer (set-buffer buffer))
|
|
|
|
|
(if (not start) (setq start (point)))
|
|
|
|
|
(let ((os start) (ol nil))
|
|
|
|
|
(while (and os (> os (point-min)) (not ol))
|
|
|
|
|
(setq os (semantic-overlay-previous-change os))
|
|
|
|
|
(when os
|
|
|
|
|
;; Get overlays at position
|
|
|
|
|
(setq ol (semantic-overlays-at (1- os)))
|
|
|
|
|
;; find the overlay that belongs to semantic
|
|
|
|
|
;; and ENDS at the found position.
|
|
|
|
|
;;
|
|
|
|
|
;; Use end because we are going backward.
|
|
|
|
|
(while (and ol (listp ol))
|
|
|
|
|
(if (and (semantic-overlay-get (car ol) 'semantic)
|
|
|
|
|
(semantic-tag-p
|
|
|
|
|
(semantic-overlay-get (car ol) 'semantic))
|
|
|
|
|
(= (semantic-overlay-end (car ol)) os))
|
|
|
|
|
(setq ol (car ol)))
|
|
|
|
|
(when (listp ol) (setq ol (cdr ol))))))
|
|
|
|
|
;; convert ol to a tag
|
|
|
|
|
(when (and ol
|
|
|
|
|
(semantic-tag-p (semantic-overlay-get ol 'semantic)))
|
|
|
|
|
(semantic-overlay-get ol 'semantic)))))
|
|
|
|
|
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-find-tag-parent-by-overlay (tag)
|
|
|
|
|
"Find the parent of TAG by overlays.
|
|
|
|
|
Overlays are a fast way of finding this information for active buffers."
|
|
|
|
|
(let ((tag (nreverse (semantic-find-tag-by-overlay
|
|
|
|
|
(semantic-tag-start tag)))))
|
|
|
|
|
;; This is a lot like `semantic-current-tag-parent', but
|
|
|
|
|
;; it uses a position to do it's work. Assumes two tags don't share
|
|
|
|
|
;; the same start unless they are siblings.
|
|
|
|
|
(car (cdr tag))))
|
|
|
|
|
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-current-tag ()
|
|
|
|
|
"Return the current tag in the current buffer.
|
|
|
|
|
If there are more than one in the same location, return the
|
|
|
|
|
smallest tag. Return nil if there is no tag here."
|
|
|
|
|
(car (nreverse (semantic-find-tag-by-overlay))))
|
|
|
|
|
|
2009-09-03 03:58:13 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-current-tag-parent ()
|
|
|
|
|
"Return the current tags parent in the current buffer.
|
|
|
|
|
A tag's parent would be a containing structure, such as a type
|
|
|
|
|
containing a field. Return nil if there is no parent."
|
|
|
|
|
(car (cdr (nreverse (semantic-find-tag-by-overlay)))))
|
|
|
|
|
|
|
|
|
|
(defun semantic-current-tag-of-class (class)
|
|
|
|
|
"Return the current (smallest) tags of CLASS in the current buffer.
|
|
|
|
|
If the smallest tag is not of type CLASS, keep going upwards until one
|
|
|
|
|
is found.
|
|
|
|
|
Uses `semantic-tag-class' for classification."
|
|
|
|
|
(let ((tags (nreverse (semantic-find-tag-by-overlay))))
|
|
|
|
|
(while (and tags
|
|
|
|
|
(not (eq (semantic-tag-class (car tags)) class)))
|
|
|
|
|
(setq tags (cdr tags)))
|
|
|
|
|
(car tags)))
|
|
|
|
|
|
|
|
|
|
;;; Search Routines
|
|
|
|
|
;;
|
|
|
|
|
;; These are routines that search a single tags table.
|
|
|
|
|
;;
|
|
|
|
|
;; The original API (see COMPATIBILITY section below) in semantic 1.4
|
|
|
|
|
;; had these usage statistics:
|
|
|
|
|
;;
|
|
|
|
|
;; semantic-find-nonterminal-by-name 17
|
|
|
|
|
;; semantic-find-nonterminal-by-name-regexp 8 - Most doing completion
|
|
|
|
|
;; semantic-find-nonterminal-by-position 13
|
|
|
|
|
;; semantic-find-nonterminal-by-token 21
|
|
|
|
|
;; semantic-find-nonterminal-by-type 2
|
|
|
|
|
;; semantic-find-nonterminal-standard 1
|
|
|
|
|
;;
|
|
|
|
|
;; semantic-find-nonterminal-by-function (not in other searches) 1
|
|
|
|
|
;;
|
|
|
|
|
;; New API: As above w/out `search-parts' or `search-includes' arguments.
|
|
|
|
|
;; Extra fcn: Specific to completion which is what -name-regexp is
|
|
|
|
|
;; mostly used for
|
|
|
|
|
;;
|
|
|
|
|
;; As for the sarguments "search-parts" and "search-includes" here
|
|
|
|
|
;; are stats:
|
|
|
|
|
;;
|
|
|
|
|
;; search-parts: 4 - charting x2, find-doc, senator (sans db)
|
|
|
|
|
;;
|
|
|
|
|
;; Implement command to flatten a tag table. Call new API Fcn w/
|
|
|
|
|
;; flattened table for same results.
|
|
|
|
|
;;
|
|
|
|
|
;; search-include: 2 - analyze x2 (sans db)
|
|
|
|
|
;;
|
|
|
|
|
;; Not used effectively. Not to be re-implemented here.
|
|
|
|
|
|
|
|
|
|
(defsubst semantic--find-tags-by-function (predicate &optional table)
|
|
|
|
|
"Find tags for which PREDICATE is non-nil in TABLE.
|
|
|
|
|
PREDICATE is a lambda expression which accepts on TAG.
|
|
|
|
|
TABLE is a semantic tags table. See `semantic-something-to-tag-table'."
|
|
|
|
|
(let ((tags (semantic-something-to-tag-table table))
|
|
|
|
|
(result nil))
|
|
|
|
|
; (mapc (lambda (tag) (and (funcall predicate tag)
|
|
|
|
|
; (setq result (cons tag result))))
|
|
|
|
|
; tags)
|
|
|
|
|
;; A while loop is actually faster. Who knew
|
|
|
|
|
(while tags
|
|
|
|
|
(and (funcall predicate (car tags))
|
|
|
|
|
(setq result (cons (car tags) result)))
|
|
|
|
|
(setq tags (cdr tags)))
|
|
|
|
|
(nreverse result)))
|
|
|
|
|
|
|
|
|
|
;; I can shave off some time by removing the funcall (see above)
|
|
|
|
|
;; and having the question be inlined in the while loop.
|
|
|
|
|
;; Strangely turning the upper level fcns into macros had a larger
|
|
|
|
|
;; impact.
|
|
|
|
|
(defmacro semantic--find-tags-by-macro (form &optional table)
|
|
|
|
|
"Find tags for which FORM is non-nil in TABLE.
|
|
|
|
|
TABLE is a semantic tags table. See `semantic-something-to-tag-table'."
|
|
|
|
|
`(let ((tags (semantic-something-to-tag-table ,table))
|
|
|
|
|
(result nil))
|
|
|
|
|
(while tags
|
|
|
|
|
(and ,form
|
|
|
|
|
(setq result (cons (car tags) result)))
|
|
|
|
|
(setq tags (cdr tags)))
|
|
|
|
|
(nreverse result)))
|
|
|
|
|
|
|
|
|
|
;;; Top level Searches
|
2009-09-13 15:58:30 +00:00
|
|
|
|
;;
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun semantic-find-first-tag-by-name (name &optional table)
|
2009-08-28 19:18:35 +00:00
|
|
|
|
"Find the first tag with NAME in TABLE.
|
|
|
|
|
NAME is a string.
|
|
|
|
|
TABLE is a semantic tags table. See `semantic-something-to-tag-table'.
|
|
|
|
|
This routine uses `assoc' to quickly find the first matching entry."
|
|
|
|
|
(funcall (if semantic-case-fold 'assoc-ignore-case 'assoc)
|
|
|
|
|
name (semantic-something-to-tag-table table)))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-find-tags-by-name (name &optional table)
|
|
|
|
|
"Find all tags with NAME in TABLE.
|
|
|
|
|
NAME is a string.
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'."
|
|
|
|
|
`(let ((case-fold-search semantic-case-fold))
|
|
|
|
|
(semantic--find-tags-by-macro
|
|
|
|
|
(string= ,name (semantic-tag-name (car tags)))
|
|
|
|
|
,table)))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-find-tags-for-completion (prefix &optional table)
|
2009-10-01 04:54:05 +00:00
|
|
|
|
"Find all tags whose name begins with PREFIX in TABLE.
|
2009-08-28 19:18:35 +00:00
|
|
|
|
PREFIX is a string.
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'.
|
|
|
|
|
While it would be nice to use `try-completion' or `all-completions',
|
|
|
|
|
those functions do not return the tags, only a string.
|
|
|
|
|
Uses `compare-strings' for fast comparison."
|
|
|
|
|
`(let ((l (length ,prefix)))
|
|
|
|
|
(semantic--find-tags-by-macro
|
|
|
|
|
(eq (compare-strings ,prefix 0 nil
|
|
|
|
|
(semantic-tag-name (car tags)) 0 l
|
|
|
|
|
semantic-case-fold)
|
|
|
|
|
t)
|
|
|
|
|
,table)))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-find-tags-by-name-regexp (regexp &optional table)
|
|
|
|
|
"Find all tags with name matching REGEXP in TABLE.
|
|
|
|
|
REGEXP is a string containing a regular expression,
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'.
|
|
|
|
|
Consider using `semantic-find-tags-for-completion' if you are
|
|
|
|
|
attempting to do completions."
|
|
|
|
|
`(let ((case-fold-search semantic-case-fold))
|
|
|
|
|
(semantic--find-tags-by-macro
|
|
|
|
|
(string-match ,regexp (semantic-tag-name (car tags)))
|
|
|
|
|
,table)))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-find-tags-by-class (class &optional table)
|
|
|
|
|
"Find all tags of class CLASS in TABLE.
|
|
|
|
|
CLASS is a symbol representing the class of the token, such as
|
|
|
|
|
'variable, of 'function..
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'."
|
|
|
|
|
`(semantic--find-tags-by-macro
|
|
|
|
|
(eq ,class (semantic-tag-class (car tags)))
|
|
|
|
|
,table))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-find-tags-by-type (type &optional table)
|
|
|
|
|
"Find all tags of with a type TYPE in TABLE.
|
|
|
|
|
TYPE is a string or tag representing a data type as defined in the
|
|
|
|
|
language the tags were parsed from, such as \"int\", or perhaps
|
|
|
|
|
a tag whose name is that of a struct or class.
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'."
|
|
|
|
|
`(semantic--find-tags-by-macro
|
|
|
|
|
(semantic-tag-of-type-p (car tags) ,type)
|
|
|
|
|
,table))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-find-tags-of-compound-type (&optional table)
|
|
|
|
|
"Find all tags which are a compound type in TABLE.
|
|
|
|
|
Compound types are structures, or other data type which
|
|
|
|
|
is not of a primitive nature, such as int or double.
|
|
|
|
|
Used in completion."
|
|
|
|
|
`(semantic--find-tags-by-macro
|
|
|
|
|
(semantic-tag-type-compound-p (car tags))
|
|
|
|
|
,table))
|
|
|
|
|
|
2009-09-03 03:58:13 +00:00
|
|
|
|
;;;###autoload
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(define-overloadable-function semantic-find-tags-by-scope-protection (scopeprotection parent &optional table)
|
|
|
|
|
"Find all tags accessable by SCOPEPROTECTION.
|
|
|
|
|
SCOPEPROTECTION is a symbol which can be returned by the method
|
|
|
|
|
`semantic-tag-protection'. A hard-coded order is used to determine a match.
|
|
|
|
|
PARENT is a tag representing the PARENT slot needed for
|
|
|
|
|
`semantic-tag-protection'.
|
|
|
|
|
TABLE is a list of tags (a subset of PARENT members) to scan. If TABLE is nil,
|
|
|
|
|
the type members of PARENT are used.
|
|
|
|
|
See `semantic-tag-protected-p' for details on which tags are returned."
|
|
|
|
|
(if (not (eq (semantic-tag-class parent) 'type))
|
|
|
|
|
(signal 'wrong-type-argument '(semantic-find-tags-by-scope-protection
|
|
|
|
|
parent
|
|
|
|
|
semantic-tag-class type))
|
|
|
|
|
(:override)))
|
|
|
|
|
|
|
|
|
|
(defun semantic-find-tags-by-scope-protection-default
|
|
|
|
|
(scopeprotection parent &optional table)
|
2009-10-01 04:54:05 +00:00
|
|
|
|
"Find all tags accessible by SCOPEPROTECTION.
|
2009-08-28 19:18:35 +00:00
|
|
|
|
SCOPEPROTECTION is a symbol which can be returned by the method
|
|
|
|
|
`semantic-tag-protection'. A hard-coded order is used to determine a match.
|
|
|
|
|
PARENT is a tag representing the PARENT slot needed for
|
|
|
|
|
`semantic-tag-protection'.
|
|
|
|
|
TABLE is a list of tags (a subset of PARENT members) to scan. If TABLE is nil,
|
|
|
|
|
the type members of PARENT are used.
|
|
|
|
|
See `semantic-tag-protected-p' for details on which tags are returned."
|
|
|
|
|
(if (not table) (setq table (semantic-tag-type-members parent)))
|
|
|
|
|
(if (null scopeprotection)
|
|
|
|
|
table
|
2009-08-31 02:16:34 +00:00
|
|
|
|
(require 'semantic/tag-ls)
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(semantic--find-tags-by-macro
|
|
|
|
|
(not (semantic-tag-protected-p (car tags) scopeprotection parent))
|
|
|
|
|
table)))
|
|
|
|
|
|
|
|
|
|
(defsubst semantic-find-tags-included (&optional table)
|
|
|
|
|
"Find all tags in TABLE that are of the 'include class.
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'."
|
|
|
|
|
(semantic-find-tags-by-class 'include table))
|
|
|
|
|
|
|
|
|
|
;;; Deep Searches
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-deep-find-tags-by-name (name &optional table)
|
|
|
|
|
"Find all tags with NAME in TABLE.
|
|
|
|
|
Search in top level tags, and their components, in TABLE.
|
|
|
|
|
NAME is a string.
|
|
|
|
|
TABLE is a tag table. See `semantic-flatten-tags-table'.
|
|
|
|
|
See also `semantic-find-tags-by-name'."
|
|
|
|
|
`(semantic-find-tags-by-name
|
|
|
|
|
,name (semantic-flatten-tags-table ,table)))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-deep-find-tags-for-completion (prefix &optional table)
|
2009-10-01 04:54:05 +00:00
|
|
|
|
"Find all tags whose name begins with PREFIX in TABLE.
|
2009-08-28 19:18:35 +00:00
|
|
|
|
Search in top level tags, and their components, in TABLE.
|
|
|
|
|
TABLE is a tag table. See `semantic-flatten-tags-table'.
|
|
|
|
|
See also `semantic-find-tags-for-completion'."
|
|
|
|
|
`(semantic-find-tags-for-completion
|
|
|
|
|
,prefix (semantic-flatten-tags-table ,table)))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-deep-find-tags-by-name-regexp (regexp &optional table)
|
|
|
|
|
"Find all tags with name matching REGEXP in TABLE.
|
|
|
|
|
Search in top level tags, and their components, in TABLE.
|
|
|
|
|
REGEXP is a string containing a regular expression,
|
|
|
|
|
TABLE is a tag table. See `semantic-flatten-tags-table'.
|
|
|
|
|
See also `semantic-find-tags-by-name-regexp'.
|
|
|
|
|
Consider using `semantic-deep-find-tags-for-completion' if you are
|
|
|
|
|
attempting to do completions."
|
|
|
|
|
`(semantic-find-tags-by-name-regexp
|
|
|
|
|
,regexp (semantic-flatten-tags-table ,table)))
|
|
|
|
|
|
|
|
|
|
;;; Specialty Searches
|
2009-08-31 02:16:34 +00:00
|
|
|
|
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(defun semantic-find-tags-external-children-of-type (type &optional table)
|
|
|
|
|
"Find all tags in whose parent is TYPE in TABLE.
|
|
|
|
|
These tags are defined outside the scope of the original TYPE declaration.
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'."
|
|
|
|
|
(semantic--find-tags-by-macro
|
|
|
|
|
(equal (semantic-tag-external-member-parent (car tags))
|
|
|
|
|
type)
|
|
|
|
|
table))
|
|
|
|
|
|
|
|
|
|
(defun semantic-find-tags-subclasses-of-type (type &optional table)
|
|
|
|
|
"Find all tags of class type in whose parent is TYPE in TABLE.
|
|
|
|
|
These tags are defined outside the scope of the original TYPE declaration.
|
|
|
|
|
TABLE is a tag table. See `semantic-something-to-tag-table'."
|
|
|
|
|
(semantic--find-tags-by-macro
|
|
|
|
|
(and (eq (semantic-tag-class (car tags)) 'type)
|
|
|
|
|
(or (member type (semantic-tag-type-superclasses (car tags)))
|
|
|
|
|
(member type (semantic-tag-type-interfaces (car tags)))))
|
|
|
|
|
table))
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; ************************** Compatibility ***************************
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
;;; Old Style Brute Force Search Routines
|
|
|
|
|
;;
|
|
|
|
|
;; These functions will search through tags lists explicity for
|
|
|
|
|
;; desired information.
|
|
|
|
|
|
|
|
|
|
;; The -by-name nonterminal search can use the built in fcn
|
|
|
|
|
;; `assoc', which is faster than looping ourselves, so we will
|
|
|
|
|
;; not use `semantic-brute-find-tag-by-function' to do this,
|
|
|
|
|
;; instead erroring on the side of speed.
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-first-tag-by-name
|
|
|
|
|
(name streamorbuffer &optional search-parts search-include)
|
|
|
|
|
"Find a tag NAME within STREAMORBUFFER. NAME is a string.
|
|
|
|
|
If SEARCH-PARTS is non-nil, search children of tags.
|
|
|
|
|
If SEARCH-INCLUDE was never implemented.
|
|
|
|
|
|
|
|
|
|
Use `semantic-find-first-tag-by-name' instead."
|
|
|
|
|
(let* ((stream (semantic-something-to-tag-table streamorbuffer))
|
|
|
|
|
(assoc-fun (if semantic-case-fold
|
|
|
|
|
#'assoc-ignore-case
|
|
|
|
|
#'assoc))
|
|
|
|
|
(m (funcall assoc-fun name stream)))
|
|
|
|
|
(if m
|
|
|
|
|
m
|
|
|
|
|
(let ((toklst stream)
|
|
|
|
|
(children nil))
|
|
|
|
|
(while (and (not m) toklst)
|
|
|
|
|
(if search-parts
|
|
|
|
|
(progn
|
|
|
|
|
(setq children (semantic-tag-components-with-overlays
|
|
|
|
|
(car toklst)))
|
|
|
|
|
(if children
|
|
|
|
|
(setq m (semantic-brute-find-first-tag-by-name
|
|
|
|
|
name children search-parts search-include)))))
|
|
|
|
|
(setq toklst (cdr toklst)))
|
|
|
|
|
(if (not m)
|
|
|
|
|
;; Go to dependencies, and search there.
|
|
|
|
|
nil)
|
|
|
|
|
m))))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-brute-find-tag-by-class
|
|
|
|
|
(class streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags with a class CLASS within STREAMORBUFFER.
|
|
|
|
|
CLASS is a symbol representing the class of the tags to find.
|
|
|
|
|
See `semantic-tag-class'.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'.
|
|
|
|
|
|
|
|
|
|
Use `semantic-find-tag-by-class' instead."
|
|
|
|
|
`(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag) (eq ,class (semantic-tag-class tag)))
|
|
|
|
|
,streamorbuffer ,search-parts ,search-includes))
|
|
|
|
|
|
|
|
|
|
(defmacro semantic-brute-find-tag-standard
|
|
|
|
|
(streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags in STREAMORBUFFER which define simple class types.
|
|
|
|
|
See `semantic-tag-class'.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
`(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag) (member (semantic-tag-class tag)
|
|
|
|
|
'(function variable type)))
|
|
|
|
|
,streamorbuffer ,search-parts ,search-includes))
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-type
|
|
|
|
|
(type streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags with type TYPE within STREAMORBUFFER.
|
|
|
|
|
TYPE is a string which is the name of the type of the tags returned.
|
|
|
|
|
See `semantic-tag-type'.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag)
|
|
|
|
|
(let ((ts (semantic-tag-type tag)))
|
|
|
|
|
(if (and (listp ts)
|
|
|
|
|
(or (= (length ts) 1)
|
|
|
|
|
(eq (semantic-tag-class ts) 'type)))
|
|
|
|
|
(setq ts (semantic-tag-name ts)))
|
|
|
|
|
(equal type ts)))
|
|
|
|
|
streamorbuffer search-parts search-includes))
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-type-regexp
|
|
|
|
|
(regexp streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags with type matching REGEXP within STREAMORBUFFER.
|
|
|
|
|
REGEXP is a regular expression which matches the name of the type of the
|
|
|
|
|
tags returned. See `semantic-tag-type'.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag)
|
|
|
|
|
(let ((ts (semantic-tag-type tag)))
|
|
|
|
|
(if (listp ts)
|
|
|
|
|
(setq ts
|
|
|
|
|
(if (eq (semantic-tag-class ts) 'type)
|
|
|
|
|
(semantic-tag-name ts)
|
|
|
|
|
(car ts))))
|
|
|
|
|
(and ts (string-match regexp ts))))
|
|
|
|
|
streamorbuffer search-parts search-includes))
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-name-regexp
|
|
|
|
|
(regex streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags whose name match REGEX in STREAMORBUFFER.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag) (string-match regex (semantic-tag-name tag)))
|
|
|
|
|
streamorbuffer search-parts search-includes)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-property
|
|
|
|
|
(property value streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags with PROPERTY equal to VALUE in STREAMORBUFFER.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag) (equal (semantic--tag-get-property tag property) value))
|
|
|
|
|
streamorbuffer search-parts search-includes)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-attribute
|
|
|
|
|
(attr streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags with a given ATTR in STREAMORBUFFER.
|
|
|
|
|
ATTR is a symbol key into the attributes list.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag) (semantic-tag-get-attribute tag attr))
|
|
|
|
|
streamorbuffer search-parts search-includes)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-attribute-value
|
|
|
|
|
(attr value streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags with a given ATTR equal to VALUE in STREAMORBUFFER.
|
|
|
|
|
ATTR is a symbol key into the attributes list.
|
|
|
|
|
VALUE is the value that ATTR should match.
|
|
|
|
|
Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
|
|
|
|
|
`semantic-brute-find-tag-by-function'."
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
(lambda (tag) (equal (semantic-tag-get-attribute tag attr) value))
|
|
|
|
|
streamorbuffer search-parts search-includes)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-tag-by-function
|
|
|
|
|
(function streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find all tags for which FUNCTION's value is non-nil within STREAMORBUFFER.
|
|
|
|
|
FUNCTION must return non-nil if an element of STREAM will be included
|
|
|
|
|
in the new list.
|
|
|
|
|
|
|
|
|
|
If optional argument SEARCH-PARTS is non-nil, all sub-parts of tags
|
|
|
|
|
are searched. The overloadable function `semantic-tag-componenets' is
|
|
|
|
|
used for the searching child lists. If SEARCH-PARTS is the symbol
|
|
|
|
|
'positiononly, then only children that have positional information are
|
|
|
|
|
searched.
|
|
|
|
|
|
|
|
|
|
If SEARCH-INCLUDES has not been implemented.
|
|
|
|
|
This parameter hasn't be active for a while and is obsolete."
|
|
|
|
|
(let ((stream (semantic-something-to-tag-table streamorbuffer))
|
|
|
|
|
(sl nil) ;list of tag children
|
|
|
|
|
(nl nil) ;new list
|
|
|
|
|
(case-fold-search semantic-case-fold))
|
|
|
|
|
(dolist (tag stream)
|
|
|
|
|
(if (not (semantic-tag-p tag))
|
|
|
|
|
;; `semantic-tag-components-with-overlays' can return invalid
|
|
|
|
|
;; tags if search-parts is not equal to 'positiononly
|
|
|
|
|
nil ;; Ignore them!
|
|
|
|
|
(if (funcall function tag)
|
|
|
|
|
(setq nl (cons tag nl)))
|
|
|
|
|
(and search-parts
|
|
|
|
|
(setq sl (if (eq search-parts 'positiononly)
|
|
|
|
|
(semantic-tag-components-with-overlays tag)
|
|
|
|
|
(semantic-tag-components tag))
|
|
|
|
|
)
|
|
|
|
|
(setq nl (nconc nl
|
|
|
|
|
(semantic-brute-find-tag-by-function
|
|
|
|
|
function sl
|
|
|
|
|
search-parts))))))
|
|
|
|
|
(setq nl (nreverse nl))
|
|
|
|
|
nl))
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-first-tag-by-function
|
|
|
|
|
(function streamorbuffer &optional search-parts search-includes)
|
|
|
|
|
"Find the first tag which FUNCTION match within STREAMORBUFFER.
|
|
|
|
|
FUNCTION must return non-nil if an element of STREAM will be included
|
|
|
|
|
in the new list.
|
|
|
|
|
|
|
|
|
|
The following parameters were never implemented.
|
|
|
|
|
|
|
|
|
|
If optional argument SEARCH-PARTS, all sub-parts of tags are searched.
|
|
|
|
|
The overloadable function `semantic-tag-components' is used for
|
|
|
|
|
searching.
|
|
|
|
|
If SEARCH-INCLUDES is non-nil, then all include files are also
|
|
|
|
|
searched for matches."
|
|
|
|
|
(let ((stream (semantic-something-to-tag-table streamorbuffer))
|
|
|
|
|
(found nil)
|
|
|
|
|
(case-fold-search semantic-case-fold))
|
|
|
|
|
(while (and (not found) stream)
|
|
|
|
|
(if (funcall function (car stream))
|
|
|
|
|
(setq found (car stream)))
|
|
|
|
|
(setq stream (cdr stream)))
|
|
|
|
|
found))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Old Positional Searches
|
|
|
|
|
;;
|
|
|
|
|
;; Are these useful anymore?
|
|
|
|
|
;;
|
|
|
|
|
(defun semantic-brute-find-tag-by-position (position streamorbuffer
|
|
|
|
|
&optional nomedian)
|
|
|
|
|
"Find a tag covering POSITION within STREAMORBUFFER.
|
|
|
|
|
POSITION is a number, or marker. If NOMEDIAN is non-nil, don't do
|
|
|
|
|
the median calculation, and return nil."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(if (markerp position) (set-buffer (marker-buffer position)))
|
|
|
|
|
(let* ((stream (if (bufferp streamorbuffer)
|
* cedet/srecode/srt-mode.el (semantic-analyze-possible-completions):
* cedet/semantic/symref/list.el (semantic-symref-rb-toggle-expand-tag):
* cedet/semantic/symref/grep.el (semantic-symref-perform-search):
* cedet/semantic/bovine/gcc.el (semantic-gcc-query):
* cedet/semantic/bovine/c.el (semantic-c-parse-lexical-token):
* cedet/semantic/analyze/debug.el (semantic-analyzer-debug-add-buttons)
(semantic-analyzer-debug-global-symbol)
(semantic-analyzer-debug-missing-innertype)
(semantic-analyzer-debug-insert-include-summary):
* cedet/semantic/util.el (semantic-file-tag-table):
(semantic-describe-buffer-var-helper, semantic-something-to-tag-table)
(semantic-recursive-find-nonterminal-by-name):
* cedet/semantic/tag-ls.el (semantic-tag-calculate-parent-default):
* cedet/semantic/tag-file.el (semantic-prototype-file):
* cedet/semantic/symref.el (semantic-symref-parse-tool-output):
* cedet/semantic/sb.el (semantic-sb-fetch-tag-table):
* cedet/semantic/lex-spp.el (semantic-lex-spp-lex-text-string):
* cedet/semantic/idle.el (semantic-idle-work-for-one-buffer):
(semantic-idle-summary-maybe-highlight):
* cedet/semantic/ia-sb.el (semantic-ia-speedbar)
(semantic-ia-sb-tag-info):
* cedet/semantic/grammar.el (semantic-analyze-possible-completions):
* cedet/semantic/find.el (semantic-brute-find-tag-by-position):
* cedet/semantic/ede-grammar.el (project-compile-target):
(ede-proj-makefile-insert-variables):
* cedet/semantic/debug.el (semantic-debug-set-parser-location):
(semantic-debug-set-source-location, semantic-debug-interface-layout)
(semantic-debug-mode, semantic-debug):
* cedet/semantic/db.el (semanticdb-needs-refresh-p):
* cedet/semantic/db-typecache.el (semanticdb-typecache-refresh-for-buffer):
* cedet/semantic/db-javascript.el (semanticdb-equivalent-mode):
* cedet/semantic/db-find.el (semanticdb-find-log-new-search)
(semanticdb-find-translate-path-includes--internal)
(semanticdb-reset-log, semanticdb-find-log-activity):
* cedet/semantic/db-file.el (object-write):
* cedet/semantic/db-el.el (semanticdb-equivalent-mode):
* cedet/semantic/db-ebrowse.el (semanticdb-ebrowse-C-file-p)
(semanticdb-create-ebrowse-database):
* cedet/semantic/db-debug.el (semanticdb-table-sanity-check):
* cedet/semantic/complete.el (semantic-displayor-focus-request)
(semantic-collector-calculate-completions-raw)
(semantic-complete-read-tag-analyzer):
* cedet/semantic/analyze.el (semantic-analyze-pulse):
* cedet/ede/util.el (ede-update-version-in-source):
* cedet/ede/proj.el (project-delete-target):
* cedet/ede/proj-elisp.el (ede-update-version-in-source)
(ede-proj-flush-autoconf):
* cedet/ede/pconf.el (ede-proj-configure-synchronize)
(ede-proj-configure-synchronize):
* cedet/ede/locate.el (ede-locate-file-in-project-impl):
* cedet/ede/linux.el (ede-linux-version):
* cedet/ede/emacs.el (ede-emacs-version):
* cedet/ede/dired.el (ede-dired-add-to-target):
* cedet/ede.el (ede-buffer-header-file, ede-find-target)
(ede-buffer-documentation-files, ede-project-buffers, ede-set)
(ede-target-buffers, ede-buffers, ede-make-project-local-variable):
* cedet/cedet-idutils.el (cedet-idutils-fnid-call):
(cedet-idutils-lid-call, cedet-idutils-expand-filename)
(cedet-idutils-version-check):
* cedet/cedet-global.el (cedet-gnu-global-call):
(cedet-gnu-global-expand-filename, cedet-gnu-global-root)
(cedet-gnu-global-version-check, cedet-gnu-global-scan-hits):
* cedet/cedet-cscope.el (cedet-cscope-call)
(cedet-cscope-expand-filename, cedet-cscope-version-check):
Use with-current-buffer.
* cedet/ede.el (ede-make-project-local-variable)
(ede-set-project-variables, ede-set): Use dolist.
2009-10-30 02:16:41 +00:00
|
|
|
|
(with-current-buffer streamorbuffer
|
2009-08-28 19:18:35 +00:00
|
|
|
|
(semantic-fetch-tags))
|
|
|
|
|
streamorbuffer))
|
|
|
|
|
(prev nil)
|
|
|
|
|
(found nil))
|
|
|
|
|
(while (and stream (not found))
|
|
|
|
|
;; perfect fit
|
|
|
|
|
(if (and (>= position (semantic-tag-start (car stream)))
|
|
|
|
|
(<= position (semantic-tag-end (car stream))))
|
|
|
|
|
(setq found (car stream))
|
|
|
|
|
;; Median between to objects.
|
|
|
|
|
(if (and prev (not nomedian)
|
|
|
|
|
(>= position (semantic-tag-end prev))
|
|
|
|
|
(<= position (semantic-tag-start (car stream))))
|
|
|
|
|
(let ((median (/ (+ (semantic-tag-end prev)
|
|
|
|
|
(semantic-tag-start (car stream)))
|
|
|
|
|
2)))
|
|
|
|
|
(setq found
|
|
|
|
|
(if (> position median)
|
|
|
|
|
(car stream)
|
|
|
|
|
prev)))))
|
|
|
|
|
;; Next!!!
|
|
|
|
|
(setq prev (car stream)
|
|
|
|
|
stream (cdr stream)))
|
|
|
|
|
found)))
|
|
|
|
|
|
|
|
|
|
(defun semantic-brute-find-innermost-tag-by-position
|
|
|
|
|
(position streamorbuffer &optional nomedian)
|
|
|
|
|
"Find a list of tags covering POSITION within STREAMORBUFFER.
|
|
|
|
|
POSITION is a number, or marker. If NOMEDIAN is non-nil, don't do
|
|
|
|
|
the median calculation, and return nil.
|
|
|
|
|
This function will find the topmost item, and recurse until no more
|
|
|
|
|
details are available of findable."
|
|
|
|
|
(let* ((returnme nil)
|
|
|
|
|
(current (semantic-brute-find-tag-by-position
|
|
|
|
|
position streamorbuffer nomedian))
|
|
|
|
|
(nextstream (and current
|
|
|
|
|
(if (eq (semantic-tag-class current) 'type)
|
|
|
|
|
(semantic-tag-type-members current)
|
|
|
|
|
nil))))
|
|
|
|
|
(while nextstream
|
|
|
|
|
(setq returnme (cons current returnme))
|
|
|
|
|
(setq current (semantic-brute-find-tag-by-position
|
|
|
|
|
position nextstream nomedian))
|
|
|
|
|
(setq nextstream (and current
|
|
|
|
|
;; NOTE TO SELF:
|
|
|
|
|
;; Looking at this after several years away,
|
|
|
|
|
;; what does this do???
|
|
|
|
|
(if (eq (semantic-tag-class current) 'token)
|
|
|
|
|
(semantic-tag-type-members current)
|
|
|
|
|
nil))))
|
|
|
|
|
(nreverse (cons current returnme))))
|
|
|
|
|
|
|
|
|
|
(provide 'semantic/find)
|
|
|
|
|
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;; Local variables:
|
|
|
|
|
;; generated-autoload-file: "loaddefs.el"
|
2009-09-05 01:00:36 +00:00
|
|
|
|
;; generated-autoload-load-name: "semantic/find"
|
2009-09-02 04:37:10 +00:00
|
|
|
|
;; End:
|
|
|
|
|
|
2009-10-02 10:53:34 +00:00
|
|
|
|
;; arch-tag: db00c93e-e561-4bd6-942b-96eca5aaa9a6
|
2009-08-31 02:16:34 +00:00
|
|
|
|
;;; semantic/find.el ends here
|