Skip to content

Instantly share code, notes, and snippets.

@themadsens
Last active January 18, 2018 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save themadsens/0f671199915a6387204d6966ebb3cc58 to your computer and use it in GitHub Desktop.
Save themadsens/0f671199915a6387204d6966ebb3cc58 to your computer and use it in GitHub Desktop.
Original VimTip #79. Origin of ShowFunc.vim (VimScript #397) From http://vim.wikia.com/wiki/Use_grep_to_get_a_clickable_list_of_function_names

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></somekey> :call ShowFunc()

function&#33; ShowFunc()
  let gf_s &#61; &amp;grepformat
  let gp_s &#61; &amp;grepprg
  let &amp;grepformat &#61; &#39;%&#42;\k%&#42;\sfunction%&#42;\s%l%&#42;\s%f %&#42;\s%m&#39;
  let &amp;grepprg &#61; &#39;ctags &#45;x &#45;&#45;c&#45;types&#61;f &#45;&#45;sort&#61;no &#45;o &#45;&#39;
  write
  silent&#33; grep %
  cwindow
  let &amp;grepformat &#61; gf_s
  let &amp;grepprg &#61; gp_s
endfunc

Comments

Some enhancements courtesy of Bill McCarthy:

&gt; let &amp;grepprg &#61; &#39;ctags &#45;x &#45;&#45;c&#45;types&#61;f &#45;&#45;sort&#61;no &#45;o &#45;&#39;
or just&#58; let &amp;grepprg &#61; &#39;ctags &#45;x &#45;&#45;c&#45;types&#61;f &#45;&#45;sort&#61;no&#39;
since the &#39;&#45;o &#45;&#39; is redundant with &#39;&#45;x&#39;.
&gt; write
or better yet&#58; update
which will not change the filedate on a file that hasn&#39;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&#33; ShowFunc(sort)
let gf_s &#61; &amp;grepformat
let gp_s &#61; &amp;grepprg
if ( &amp;filetype &#61;&#61; &quot;c&quot; &#124;&#124; &amp;filetype &#61;&#61; &quot;php&quot; &#124;&#124; &amp;filetype &#61;&#61; &quot;python&quot; &#124;&#124;
  \ &amp;filetype &#61;&#61; &quot;sh&quot; )
  let &amp;grepformat&#61;&#39;%&#42;\k%&#42;\sfunction%&#42;\s%l%&#42;\s%f %m&#39;
  let &amp;grepprg &#61; &#39;ctags &#45;x &#45;&#45;&#39;.&amp;filetype.&#39;&#45;types&#61;f &#45;&#45;sort&#61;&#39;.a&#58;sort
elseif ( &amp;filetype &#61;&#61; &quot;perl&quot; )
  let &amp;grepformat&#61;&#39;%&#42;\k%&#42;\ssubroutine%&#42;\s%l%&#42;\s%f %m&#39;
  let &amp;grepprg &#61; &#39;ctags &#45;x &#45;&#45;perl&#45;types&#61;s &#45;&#45;sort&#61;&#39;.a&#58;sort
elseif ( &amp;filetype &#61;&#61; &quot;vim&quot; )
  let &amp;grepformat&#61;&#39;%&#42;\k%&#42;\sfunction%&#42;\s%l%&#42;\s%f %m&#39;
  let &amp;grepprg &#61; &#39;ctags &#45;x &#45;&#45;vim&#45;types&#61;f &#45;&#45;language&#45;force&#61;vim &#45;&#45;sort&#61;&#39;.a&#58;sort
endif
if (&amp;readonly &#61;&#61; 0) &#124; update &#124; endif
silent&#33; grep %
cwindow 10
redraw
let &amp;grepformat &#61; gf_s
let &amp;grepprg &#61; 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 &lt;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 to make it easier to install, and to get it out of my vimrc file.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment