help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Search within function for text


From: Drew Adams
Subject: RE: Search within function for text
Date: Tue, 24 Mar 2015 08:21:47 -0700 (PDT)

> I would like to find all occurences of a bit of text that fall within a
> certain function name.  I'm programming in C++, and several classes have
> their own implementations of foo(), and I'd like to find all occurrences
> of the string "bar" within functions named "foo()".
> 
> Does anyone know of a way I can do this?

When you say "within functions named 'foo()'", what do you mean?
Do you mean within each `foo' function call?  Within the various
_definitions_ functions named `foo'?

In either case, if you can define either a regexp or a function
that can locate those occurrences then yes, you can use Icicles
search to interactively search only within those contexts (i.e.,
the `foo' function calls or the `foo' function definitions or
whatever).

The function (and command) `icicle-search' takes, as one of its
arguments, a regexp or a function that defines the set of
contexts to search.  (It also accepts a set of files or buffers
that contain the contexts to search.  The default is to search
only the current buffer.)

There are several predefined Icicles commands that specialize
`icicle-search' to limit search to contexts that are similar to
what you are asking for.  You can use their definitions as models.
These commands take advantage of Imenu definitions for Emacs Lisp. 

For function (or whatever) definitions as search contexts, you
too can likely take advantage of Imenu, which provides regexps
that locate definitions in various languages (modes).

For example, for Emacs Lisp, Imenu can locate definitions of
functions, global variables, types, etc.  Icicles then uses the
Imenu regexps to define commands that search only the definitions
of such kinds of things.  (You can also search outside the search
contexts BTW, i.e., the complement buffer zones.)

There are thus predefined Icicles commands for searching the
definitions of these kinds of things in an Emacs-Lisp buffer:

* macros
* commands
* non-interactive functions
* user options
* all variables (including options)
* faces
* keys defined in named keymaps (e.g., `org-mode-map')
* global/local key definitions (no keymap specified explicitly)
* definitions of all types (i.e., all of the above)

Each of the command names starts with `icicle-imenu-' and ends
with `-full' (meaning that the full definition is the search
context - there are also command that just locate definitions,
without matching their full definitions.).

In between is the name of the definition type: `macro' (e.g.,
`icicle-imenu-macro-full'), `command', `non-interactive-function',
`user-option', `variable', `face', `key-explicit-map',
`key-implicit-map'.  

The last, most general command just has name `icicle-imenu-full'.

For a language other than Emacs Lisp, you would start with the
Imenu regexp(s) that exist for it - or you would roll your own
if you cannot find existing regexps that are useful.

However, Imenu regexps match only up to the end of the name being
defined, not the full definition.  Helper function `icicle-imenu-1'
accepts a flag argument, FULL, that tells it to use the full
definition.  Non-nil FULL means that the search context is from
the regexp-match beginning through `forward-sexp' from there.

So if `forward-sexp' works correctly for the language you use then
you need only (a) pass the Imenu regexp for the kind of object
(e.g. function, type, class) you want, and (b) pass non-nil FULL.

If `forward-sexp' is not sufficiently accurate for your language
then you will need to modify the existing Imenu regexp so that
it matches not just up to the end of the name being defined but
the full definition.

Once you have defined, for your language, an Icicles search
command for a particular type of object (e.g. functions) as
described above, you can use it.  When you invoke it, `S-TAB'
shows you all of the search contexts as candidates.

You type a pattern to match within the candidates.  As you type,
the set of candidates is narrowed by matching.  Your input can
be matched literally (as a substring) or as a regexp.  Change
your typed input on the fly to see the matching candidates change.

You can "lock in" a set of matches by hitting `S-SPC', and then
use another pattern to narrow further.  This is "progressive
completion".

You can use `C-~' to complement the current set of matches,
subtracting it from the previous set.  E.g., if you type `toto'
then the set of candidates is narrowed from whatever it was to
just those that contain `toto'.  `C-~' then gives you back the
wider set of matches shown previously, minus the matches for
`toto'.  This is "chipping away".

When you have a given set of candidates, you can navigate among
them in the source buffers/files.  Use `C-down' etc. to cycle.
Use `C-RET' or `C-mouse-2' to go to an individual candidate.
Use `down' to cycle among candidates without visiting the source
location (then hit `C-RET' to visit the current one).

For full-definition searching, the contexts, hence the candidates,
are typically multi-line.  Sometimes it is more convenient to not
see the full candidates (even though you are still using them)
but to just see their lines that match your current input (pattern).
You can hide the non-matching lines in each candidate definition
by using `C-u C-x .' (this is a toggle).

More information:

* Icicles overview
  http://www.emacswiki.org/emacs/Icicles_-_Nutshell_View

* Icicles search
  http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview

* Icicles Imenu commands
  http://www.emacswiki.org/emacs/Icicles_-_Other_Search_Commands#IciclesImenu

  The screenshot there shows the use of non-full command
  `icicle-imenu-command', with candidates that match `kill' typed
  in the minibuffer.  Use of `icicle-imenu-command-full' would
  instead show the full command definitions highlighted in the
  source buffer and shown in buffer *Completions* (which is where
  candidates are shown).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]