search function/variable references using ctags?

1,998 views
Skip to first unread message

Steven Woody

unread,
Sep 18, 2009, 11:29:48 AM9/18/09
to Vim
Hi,

I feel happy with ctags except one thing:  while I can jump to a function/variable definition, I can not however get  a list for all the references to the function/variable?  How vim gurus do it?

Thanks

--
Life is the only flaw in an otherwise perfect nonexistence
   -- Schopenhauer

narke
public key at http://subkeys.pgp.net:11371 (narke...@gmail.com)

Matt Wozniski

unread,
Sep 18, 2009, 11:42:11 AM9/18/09
to vim...@googlegroups.com
On Fri, Sep 18, 2009 at 11:29 AM, Steven Woody wrote:
> Hi,
> I feel happy with ctags except one thing:  while I can jump to a
> function/variable definition, I can not however get  a list for all the
> references to the function/variable?  How vim gurus do it?
> Thanks

ctags doesn't support that - it only generates a list of symbols and a
little bit of metadata about each, it doesn't generate a
cross-reference of what symbols are called by what other symbols. You
can try using cscope instead (or in addition), though - it does make
that cross referencein addition to the flat list of symbols.

~Matt

Yegappan Lakshmanan

unread,
Sep 18, 2009, 11:45:52 AM9/18/09
to vim...@googlegroups.com, Vim
Hi,

On Fri, Sep 18, 2009 at 8:29 AM, Steven Woody <narke...@gmail.com> wrote:
> Hi,
> I feel happy with ctags except one thing:  while I can jump to a
> function/variable definition, I can not however get  a list for all the
> references to the function/variable?  How vim gurus do it?
>

You need to use cscope or GNU global or Gnu id-utils for this.
You can get more information about these tools from the following
links:

http://cscope.sourceforge.net/
http://www.gnu.org/software/global/
http://www.gnu.org/software/idutils/manual/idutils.html

Cscope can be used from within Vim. Refer to the following help topic
for more information on this:

:help cscope

To use GNU id-utils from Vim, refer to the following Vim plugin:

http://www.vim.org/scripts/script.php?script_id=251

To use GNU global from Vim, refer to the following page:

http://www.gnu.org/software/global/globaldoc.html#SEC26

- Yegappan

Gary Johnson

unread,
Sep 18, 2009, 11:47:32 AM9/18/09
to vim...@googlegroups.com
On 2009-09-18, Steven Woody wrote:
> Hi,
>
> I feel happy with ctags except one thing: while I can jump to a function/
> variable definition, I can not however get a list for all the references to
> the function/variable? How vim gurus do it?

:help cscope

Regards,
Gary


Gregory Margo

unread,
Sep 18, 2009, 12:21:20 PM9/18/09
to vim...@googlegroups.com, Vim
On Fri, Sep 18, 2009 at 11:29:48PM +0800, Steven Woody wrote:
> I feel happy with ctags except one thing: while I can jump to a
> function/variable definition, I can not however get a list for all the
> references to the function/variable? How vim gurus do it?


I tend to use a big blunt instrument: grep. It works on any
language, not the limited few that cscope/id-utils/global support.
And it works on any string, not just functions/variables.

Here are two scripts/mappings from my .vimrc that I use all the time.
The "_lg" mapping creates a new buffer with the matches, and
the "_le" mapping opens the appropriate file from a given match.

It is limited to grepping from the current directory downward, but I
generally always work from the top level of a project.

" ----- grep on current identifier in top level directory -----
if 1
function! TGrepRun(r)
let curword = expand("<cword>")
if (strlen(curword) == 0)
return
endif
let oreport = &report
let &report = 99999
new
echo "Running grep " . a:r . curword

let s = 'grep ' . a:r . curword . ' * */* */*/* */*/*/* */*/*/*/*'
execute "normal i" . s . "\<Esc>"
execute '1read !' . s . '; :'
2

setlocal nomodified
setlocal bufhidden=delete
let &report = oreport
endfunction

nnoremap _lg :call TGrepRun("-n ")<CR>
nnoremap _lG :call TGrepRun("-ni ")<CR>
endif

" ----- Edit file from 'lid' or 'grep -n' format -----
if 1
" assume curbuf is lid or grep -n output.
" format is ^file:line:text...
function! LidEditFile()
let curline = getline(".")
let matchstart = match(curline, ':\d\+:')
if matchstart >= 0
let matchend = matchend(curline, ':\d\+:')
let pos = strpart(curline, matchstart+1, (matchend-matchstart)-2)
let fname = strpart(curline, 0, matchstart)
execute 'split +' . pos . ' ' . fname
endif
endfunction

nnoremap _le :call LidEditFile()<CR>
endif

--
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Gregory H. Margo
gmargo at yahoo/com, gmail/com, pacbell/net; greg at margofamily/org

Steven Woody

unread,
Sep 18, 2009, 12:28:25 PM9/18/09
to vim...@googlegroups.com, Vim
Thanks for all the replies!  They are helpful.  Now I am considering using ctags + cscope, because I found cscope is not so good I want to jump to the function/variable definiton, in this area, ctags is better.  On the other hand, cscope is good when I need to get all references.

Gary Johnson

unread,
Sep 18, 2009, 12:45:14 PM9/18/09
to vim...@googlegroups.com
On 2009-09-18, Gregory Margo wrote:
> On Fri, Sep 18, 2009 at 11:29:48PM +0800, Steven Woody wrote:
> > I feel happy with ctags except one thing: while I can jump to a
> > function/variable definition, I can not however get a list for all the
> > references to the function/variable? How vim gurus do it?
>
>
> I tend to use a big blunt instrument: grep. It works on any
> language, not the limited few that cscope/id-utils/global support.
> And it works on any string, not just functions/variables.
>
> Here are two scripts/mappings from my .vimrc that I use all the time.
> The "_lg" mapping creates a new buffer with the matches, and
> the "_le" mapping opens the appropriate file from a given match.

Are you aware of vim's built-in :grep command?

:help :grep

For jumping to particular lines in files from a <file name>:<line
number> pair in a buffer there are:

:help CTRL-W_F
:help gF

> It is limited to grepping from the current directory downward, but I
> generally always work from the top level of a project.

To have grep search recursively through a directory hierarchy, just
use the -r or -R option. Then you can easily specify the top-level
directory and whether or not you want to search recursively. The
--include and --exclude options can also help narrow your search if
your directories contain a mix of file types.

HTH,
Gary


Erik Falor

unread,
Sep 18, 2009, 2:48:23 PM9/18/09
to vim...@googlegroups.com
On Fri, Sep 18, 2009 at 09:45:14AM -0700, Gary Johnson wrote:
>
> On 2009-09-18, Gregory Margo wrote:
> > On Fri, Sep 18, 2009 at 11:29:48PM +0800, Steven Woody wrote:
> > > I feel happy with ctags except one thing: while I can jump to a
> > > function/variable definition, I can not however get a list for all the
> > > references to the function/variable? How vim gurus do it?
> >
> >
> > I tend to use a big blunt instrument: grep. It works on any
> > language, not the limited few that cscope/id-utils/global support.
> > And it works on any string, not just functions/variables.
> >
> > Here are two scripts/mappings from my .vimrc that I use all the time.
> > The "_lg" mapping creates a new buffer with the matches, and
> > the "_le" mapping opens the appropriate file from a given match.
>
> Are you aware of vim's built-in :grep command?
>
> :help :grep

+1 for this suggestion. It has several advantages, not the least of
which being that it is much simpler. And it uses the quickfix list.

:help quickfix

While we're talking about searching source code, I would like to
direct your attention to ack: http://betterthangrep.com/

Set your 'grepprg' to ack. It will change your life.


--
Erik Falor
Registered Linux User #445632 http://counter.li.org

signature.asc

Gregory Margo

unread,
Sep 18, 2009, 3:45:14 PM9/18/09
to vim...@googlegroups.com
On Fri, Sep 18, 2009 at 09:45:14AM -0700, Gary Johnson wrote:
> Are you aware of vim's built-in :grep command?
> :help :grep

Yes, but it is unsuitable. The goal of my script is to create a buffer
with a location list in it. How does :grep do that?

Jump to the first match is _never_ what I want. And it's noisy. And
needs an extra step to get the list, a ":copen". And there's only one
quickfix list. Could use :lgrep and :lopen to get multiple location
lists. (And where does :lopen get off ignoring my setting for
'splitbelow'?) Is there a way to get the location list associated
with a :grep without jumping to the first file?

> For jumping to particular lines in files from a <file name>:<line
> number> pair in a buffer there are:
> :help CTRL-W_F
> :help gF

Which does not work work if 'isfname' contains a colon.
I'm mostly working with perl, and ftplugin/perl.vim adds a colon to
'isfname', so this breaks gF. Yes I could undo it, but there are
reasons to keep it.

And gF does not seem to work right on a location list generated with
:lopen. I'm not sure what it's doing. Some kind of quickfix mode -
also something I never want.

> > It is limited to grepping from the current directory downward, but I
> > generally always work from the top level of a project.
> To have grep search recursively through a directory hierarchy, just
> use the -r or -R option. Then you can easily specify the top-level
> directory and whether or not you want to search recursively. The
> --include and --exclude options can also help narrow your search if
> your directories contain a mix of file types.

The shell does what I want: sorting, ignoring dot directories like .svn
or .git, and ordering by hierarchy depth. "grep -R" does not even sort.

gm

Erik Falor

unread,
Sep 18, 2009, 4:06:41 PM9/18/09
to vim...@googlegroups.com
On Fri, Sep 18, 2009 at 12:45:14PM -0700, Gregory Margo wrote:
> Is there a way to get the location list associated
> with a :grep without jumping to the first file?

:grep!

signature.asc

Ben Fritz

unread,
Sep 18, 2009, 10:29:50 PM9/18/09
to vim_use


On Sep 18, 2:45 pm, Gregory Margo <gma...@pacbell.net> wrote:
> On Fri, Sep 18, 2009 at 09:45:14AM -0700, Gary Johnson wrote:
> > Are you aware of vim's built-in :grep command?
> >     :help :grep
>
> Yes, but it is unsuitable.  The goal of my script is to create a buffer
> with a location list in it.  How does :grep do that?
>

This is exactly what :grep or :lgrep does.

> Jump to the first match is _never_ what I want.

So use :grep! (with the !)

> And it's noisy.

Huh? It has no more and no less output than whatever your grepprg is
set to.

> And needs an extra step to get the list, a ":copen".

Which you could do in one shot, :grep! blah | botright copen

You could even make a cabbr or a mapping to add whatever you want to
the command for you.

http://vim.wikia.com/wiki/Find_in_files_within_Vim

> And there's only one
> quickfix list.  Could use :lgrep and :lopen to get multiple location
> lists.

As you say, you can use :lgrep instead of :grep to get multiple
location lists. What's the issue?

You can also use just :grep and then use :colder and :cnewer to go
back and forth between the results of multiple searches.

> (And where does :lopen get off ignoring my setting for
> 'splitbelow'?).

Don't know, what's it doing now? I've always seen it below the current
window, where does it show up for you?

Is there a way to get the location list associated
> with a :grep without jumping to the first file?
>

:grep!

> > For jumping to particular lines in files from a <file name>:<line
> > number> pair in a buffer there are:
> >     :help CTRL-W_F
> >     :help gF
>
> Which does not work work if 'isfname' contains a colon.
> I'm mostly working with perl, and ftplugin/perl.vim adds a colon to
> 'isfname', so this breaks gF.  Yes I could undo it, but there are
> reasons to keep it.
>
> And gF does not seem to work right on a location list generated with
> :lopen.  I'm not sure what it's doing.  Some kind of quickfix mode -
> also something I never want.
>

Works fine for me. The location list/quickfix list both use filename|
line number|, not filename:line number so it's all right. What is it
doing for you?

There is no "quickfix mode", only a quickfix window.

>
> The shell does what I want: sorting, ignoring dot directories like .svn
> or .git, and ordering by hierarchy depth.  "grep -R" does not even sort.
>

:grep does whatever your grepprg does, it just parses the results and
puts it in the quickfix list.

Basically, you made a complicated (and probably clever) script, but it
pretty much duplicates built-in functionality.

tekion

unread,
Sep 19, 2009, 8:01:15 AM9/19/09
to vim_use
Hi,
I am just learning how to use ctags. From the looks of this thread, I
gather cscope can do more than ctags. Is worth to skip learning ctags
and just jump into cscope? Thanks.

Steven Woody

unread,
Sep 19, 2009, 12:05:59 PM9/19/09
to vim...@googlegroups.com
On Sat, Sep 19, 2009 at 8:01 PM, tekion <tek...@gmail.com> wrote:

Hi,
I am just learning how to use ctags.  From the looks of this thread, I
gather cscope can do more than ctags.  Is worth to skip learning ctags
and just jump into cscope? Thanks.

I think, yes.  But to my project, I found cscope many times failed in 'g' and 'c' search, though 's' searches always works.

Matt Wozniski

unread,
Sep 19, 2009, 12:09:25 PM9/19/09
to vim...@googlegroups.com
On Sat, Sep 19, 2009 at 8:01 AM, tekion <tek...@gmail.com> wrote:
>
> Hi,
> I am just learning how to use ctags.  From the looks of this thread, I
> gather cscope can do more than ctags.  Is worth to skip learning ctags
> and just jump into cscope? Thanks.

Please bottom post on this mailing list.

Cscope can do everything that ctags can do and much more, but for a
smaller set of languages. So, it's probably worth knowing both.

~Matt

Gregory Margo

unread,
Sep 19, 2009, 12:23:39 PM9/19/09
to vim...@googlegroups.com
On Fri, Sep 18, 2009 at 07:29:50PM -0700, Ben Fritz wrote:
>
> Basically, you made a complicated (and probably clever) script, but it
> pretty much duplicates built-in functionality.


Is it so difficult to understand that:
a. I wrote a script that does what I want.
b. :grep does NOT do what I want.

End of story.

bill lam

unread,
Sep 19, 2009, 6:39:44 PM9/19/09
to vim...@googlegroups.com
On Fri, 18 Sep 2009, Gary Johnson wrote:
> Are you aware of vim's built-in :grep command?
>
> :help :grep

I use the vim project plugin. It has a nice function binded to
<leader>G that search recursively in a project.

--
regards,
====================================================
GPG key 1024D/4434BAB3 2008-08-24
gpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3

Reply all
Reply to author
Forward
0 new messages