Vim Tips Wiki
Register
Advertisement
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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 -'
  write
  silent! grep %
  cwindow
  let &grepformat = gf_s
  let &grepprg = gp_s
endfunc

Comments

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'

to

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 %
cwindow
redraw
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
endif
if (&readonly == 0) | update | endif
silent! grep %
cwindow 10
redraw
let &grepformat = gf_s
let &grepprg = gp_s
endfunc

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.


Advertisement