Vim Tips Wiki

Use grep to get a clickable list of function names

1,624pages on
this wiki
Add New Page
Talk0 Share
Tip 79 Printable Monobook Previous Next

created June 14, 2001 · complexity basic · author Flemming Madsen · version 6.0

The following function will make a :cwindow window with a line per function in the current C source file. NOTE: It writes the file as a side effect.

Invoke with ':call ShowFunc()'

You may want to do :nmap <somekey> :call ShowFunc()<CR>

function! ShowFunc()
  let gf_s = &grepformat
  let gp_s = &grepprg
  let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m'
  let &grepprg = 'ctags -x --c-types=f --sort=no -o -'
  silent! grep %
  let &grepformat = gf_s
  let &grepprg = gp_s


Some enhancements courtesy of Bill McCarthy:

> let &grepprg = 'ctags -x --c-types=f --sort=no -o -'
or just: let &grepprg = 'ctags -x --c-types=f --sort=no'
since the '-o -' is redundant with '-x'.
> write
or better yet: update
which will not change the filedate on a file that hasn't changed.

I'd suggest that the call to write or update (as noted in the note above) be changed to:

if (&readonly == 0) | update | endif

so that you don't get an error message when attempting this on a read only file.

For some reason this fails in vim6.0au under unix with file names longer than about 14 characters. however, if you change

let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m'


let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %m'

then it works fine regardless of file name length.

running on a terminal, if there are a lot of functions in a file then the screen tends to get messed up, which can be fixed by insering a call to redraw after the cwindow call, so you get:

silent! grep %
let &grepformat = gf_s

Ok, couple of small bugs and mistakes fixed. Try this version:

function! ShowFunc(sort)
let gf_s = &grepformat
let gp_s = &grepprg
if ( &filetype == "c" || &filetype == "php" || &filetype == "python" ||
  \ &filetype == "sh" )
  let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m'
  let &grepprg = 'ctags -x --'.&filetype.'-types=f --sort='.a:sort
elseif ( &filetype == "perl" )
  let &grepformat='%*\k%*\ssubroutine%*\s%l%*\s%f %m'
  let &grepprg = 'ctags -x --perl-types=s --sort='.a:sort
elseif ( &filetype == "vim" )
  let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m'
  let &grepprg = 'ctags -x --vim-types=f --language-force=vim --sort='.a:sort
if (&readonly == 0) | update | endif
silent! grep %
cwindow 10
let &grepformat = gf_s
let &grepprg = gp_s

I map this function to F3 to produce a list in the order the functions appear in the file or Shift-F3 to list them in alphabetical order.

noremap <F3> <Esc>:call ShowFunc("no")<CR><Esc>
noremap <S-F3> <Esc>:call ShowFunc("yes")<CR><Esc>

And last be sure you have Exuberant CTags installed or it won't work.

Try this for Java:

elseif ( &filetype == "java" )
let &grepformat='%*\k%*\sclass%*\s%l%*\s%f %m'
let &grepprg = 'ctags -x --java-types=c --sort='.a:sort

If this produces blank results, then you can try changing the last line to:

let &grepprg = 'ctags -x --java-types=c --language-force=java --sort='.a:sort

I increased the number of file types supported to 19.

You can now search for 1. Classes - Java 2. Functions - Awk, C, C++, Fortran, Lisp, Pascal, PHP, Python, Ruby, Shell Scripts, Scheme, Slang, and Vim 3. Macros - Makefiles 4. Procedures - Expect, and Tcl 5. Subroutines - Perl and Rexx

C, Shell Scripts, Vim, Expect, Tcl and Perl are well tested. The rest work on the few tests that I have given them. Let me know of any bugs and I'll work them out.

Additionally, I changed it so that it opens a dynamically sized cwindow based on the height of the window it was called from and/or the number of links in the results. An empty search returns a cwindow a single line tall.

Last, I packaged this function as script#397 to make it easier to install, and to get it out of my vimrc file.

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Also on Fandom

Random Wiki