Tip: #79 - Use grep to get a clickable list of function names
Created: June 14, 2001 2:13 Complexity: basic Author: Flemming Madsen Version: 6.0 Karma: 130/40 Imported from: Tip#79
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
When I try this from a .c source file: I get the following error message:
Error detected while processing function ShowFunc: Regular expressions can't be delimited by letters Not an editor command: cwindow
tim--AT--johnsons-web.com
, June 14, 2001 9:11
I guess this works only with vim 6.0 so cwindow isnt recognized in the above node. This is a really useful functions. But somehow when I use it on a file opened using explorer.vim it doesnt work as expected. It does list the functions in cwindow but somehow the links dont work. Does anyone know how to fix this. It the file is opened normally using :e then things work just fine. Very useful, especially with big files.
Thanks. Parth
parth.malwankar--AT--usa.net
, June 15, 2001 6:38
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.
Flemming , June 18, 2001 0:14
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.
leifw at bigfoot , com , July 19, 2001 11:16
for some reason this failes 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
feline3344--AT--yahoo.com , September 10, 2001 3:38
WOW! this is absolutely kewl!! thx!!
supergrass--AT--gmx.net , February 9, 2002 4:50
Ok, after installing Exuberant Ctags (ctags.sourceforge.net), and tweaking it a little while, this version of the function works with C, Perl, PHP, Python, Shell and Vim filetypes.
if !exists("*ShowFunc")
function! ShowFunc() let gf_s = &grepformat let gp_s = &grepprg if ( &filetype == "c" ) let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --c-types=f --sort=no' elseif ( &filetype == "perl" ) let &grepformat='%*\k%*\ssubroutine%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --perl-types=s --sort=no' elseif ( &filetype == "php" ) let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --php-types=f --sort=no' elseif ( &filetype == "python" ) let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --python-types=f --sort=no' elseif ( &filetype == "sh" ) let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --sh-types=f --sort=no' elseif ( &filetype == "vim" ) let &grepformat='%*\k%*\sfunction!%*\s%l%*\s%f %m' let &grepprg = 'ctags -x --vim-types=f --sort=no' endif if (&readonly == 0) | update | endif silent! grep % cwindow redraw let &grepformat = gf_s let &grepprg = gp_s endfunc
endif
Dave V.
davev--AT--ziplip.com , February 25, 2002 20:07
It doesn't seem to work or do anything at all for me.
Anyone have any ideas?
kkm9--AT--cornell.edu , March 7, 2002 6:22
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.
Dave V.
davev--AT--ziplip.com , March 16, 2002 19:56
I am using vim 6.1 on Unix, it's seems like not working at all. When I do F3 or Shift F3, VIM screen refreshes but nothing else Himanshu
himanshu_patel--AT--hotmail.com , April 17, 2002 6:08
Do you have filetype detection enabled?
If not, add "filetype on" to your .vimrc.
Dave V.
davev--AT--ziplip.com , April 27, 2002 21:34
This is really cool! Is there any chance someone could add a java case as well. I don't really understand whats happening here but adding it to the c et al case doesn't work.
bmonnahan--AT--subdimension.com , July 19, 2002 0:21
Try this:
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
Good luck,
Dave
davev--AT--ziplip.com , August 3, 2002 21:50
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 a script ([/scripts/script.php?script_id=397 vimscript #397]) to make it easier to install, and to get it out of my vimrc file.
Dave Vehrs
davev--AT--ziplip.com
, August 24, 2002 16:57
I installed the exuberant-ctags deb file from unstable (after having the same error from testing) and all I get is this error: ctags: unrecognized option `--c-types=f'
It seems the problem is with ctags but it also seems to be version 5.3 and I can see that line referenced as an example in the man page.
montagne--AT--boora.com
, August 27, 2002 8:17
dear sir how do you sh convert this into straight forward PERL.
#!/usr/bin/sh
if test $# -ne "2" then
echo "" echo Error: Usage: $0 rooms echo "" exit 1
fi if test ! -f $1 then
echo "" echo Error: File '$1' does not exist echo "" exit 2
fi
if test -z "`grep -i $2 $1`" then
echo "" echo Error: No records found for '$2' building echo "" exit 3
else echo "" echo List of rooms in '$2' building in ascending seat_capacity order echo "" grep -i $2 $1 $3 | sort -b -n -k3 echo "" fi exit 0 set
pritchard_albany_uk--AT--hotmail.com
, November 7, 2004 9:28
dear sir how do you sh convert this into straight forward PERL.
#!/usr/bin/sh
if test $# -ne "2" then
echo "" echo Error: Usage: $0 rooms echo "" exit 1
fi if test ! -f $1 then
echo "" echo Error: File '$1' does not exist echo "" exit 2
fi
if test -z "`grep -i $2 $1`" then
echo "" echo Error: No records found for '$2' building echo "" exit 3
else echo "" echo List of rooms in '$2' building in ascending seat_capacity order echo "" grep -i $2 $1 $3 | sort -b -n -k3 echo "" fi exit 0 set
pritchard_albany_uk--AT--hotmail.com
, November 7, 2004 9:29