Vim Tips Wiki
Advertisement
Tip 277 Printable Monobook Previous Next

created 2002 · complexity basic · author Georgi Slavchev · version 6.0


Have you ever tried to call a function which parameters you have forgotten?

Especially those long named and with long parameter list GTK+ functions like gtk_menu_item_image_from_stock_new(..........).

By accident I saw a function in Vim help. It's name was PreviewWord and it allowed one to jump in the preview window to the tag for the word cursor is on.

I _slightly_ modified this function not to need tags file, but to search included files instead. I wrote another function, which uses the above said one, which triggers PreviewWord when you open the parenthesis after a function name.

Here it is:

" This is literally stolen from Vim help. The only changes are:
" (1) if w != "" becomes if w =~ "\k"
" (2) exe "silent! ptag " . w becomes exe "silent! psearch " . w
" * The first change prevents PreviewWord of searching while cursor is on some
" non-keyword characters, e.g. braces, asterisks, etc.
function! PreviewWord()
  if &previewwindow " don't do this in the preview window
    return
  endif
  let w = expand("<cword>") " get the word under cursor
  if w =~ "\k" " if there is one ":ptag" to it
    " Delete any existing highlight before showing another tag
    silent! wincmd P " jump to preview window
    if &previewwindow " if we really get there...
      match none " delete existing highlight
      wincmd p " back to old window
    endif
    " Try displaying a matching tag for the word under the cursor
    let v:errmsg = ""
    exe "silent! psearch " . w
    if v:errmsg =~ "tag not found"
      return
    endif
    silent! wincmd P " jump to preview window
    if &previewwindow " if we really get there...
      if has("folding")
        silent! .foldopen " don't want a closed fold
      endif
      call search("$", "b") " to end of previous line
      let w = substitute(w, '\', '\\\', "")
      call search('\<\V' . w . '\>') " position cursor on match
      " Add a match highlight to the word at this position
      hi previewWord term=bold ctermbg=green guibg=green
      exe 'match previewWord "\%' . line(".") . 'l\%' . col(".") . 'c\k*"'
      wincmd p " back to old window
    endif
  endif
endfunction
au! CursorHold *.[ch] nested call PreviewWord()

" When you open a parenthesis after a function name, and at the
" line end, that function's definition is previewed through PreviewWord().
" This is inspired from Delphi's CodeInsight technology.
" Something similar (PreviewClassMembers) could be written for
" the C++ users, for previewing the class members when you type
" a dot after an object name.
" If somebody decides to write it, please, mail it to me.
function! PreviewFunctionSignature()
  let CharOnCursor = strpart( getline('.'), col('.')-2, 1)
  if col(".") == col("$")
    call PreviewWord()
  endif
  return "("
endfunction
inoremap <buffer> ( <C-R>=PreviewFunctionSignature()<LF>

Comments[]

There is an error in PreviewWord function. You have to replace line 12 with this:

if w =~ "\i" " if there is one ":psearch" to it

You may also have to convert the fileformat from "dos" to "unix" if you have downloaded the source under a Windows browser:

:set fileformat=unix

If you want to search in certain dirs, you have to specify them in the .vim file, like this:

setlocal path+=/usr/include/gtk-1.2/**
setlocal path+=/usr/include/gnome-1.0/**

I modify some lines make it work for me. And let it try ptag first, then psearch It also avoid previewing some C keyword like for, while, double, etc.

" This is literally stolen from Vim help. The only changes are:
" (1) if w != "" becomes if w =~ "\k"
" (2) exe "silent! ptag " . w becomes exe "silent! psearch " . w
" * The first change prevents PreviewWord of searching while cursor is on some
" non-keyword characters, e.g. braces, asterisks, etc.
function! PreviewWord()
  if &previewwindow " don't do this in the preview window
    return
  endif
  let w = expand("<cword>") " get the word under cursor
  if w =~ '\i'
    if w =~ '\<\v(for|while|if|else|continue|switch|return|break|case)\m\>'
      return
    endif
    if w =~ '\<\v(int|char|double|long|static|unsigned|const|void|define|undef)\m\>'
      return
    endif
    " if there is one ":ptag" to it
    " Delete any existing highlight before showing another tag
    silent! wincmd P " jump to preview window
    if &previewwindow " if we really get there...
      match none " delete existing highlight
      wincmd p " back to old window
    endif
    " Try displaying a matching tag for the word under the cursor
    let v:errmsg = ""
    exe "silent! ptag " . w
    if v:errmsg =~ "tag not found"
      exe "silent! psearch " . w
    endif
    silent! wincmd P " jump to preview window
    if &previewwindow " if we really get there...
      if has("folding")
        silent! .foldopen " don't want a closed fold
      endif
      call search("$", "b") " to end of previous line
      let w = substitute(w, '', '\\', "")
      call search('\<\V' . w . '\>') " position cursor on match
      " Add a match highlight to the word at this position
      hi previewWord term=bold ctermbg=green guibg=green
      exe 'match previewWord "\%' . line(".") . 'l\%' . col(".") . 'c\k*"'
      wincmd p " back to old window
    endif
  endif
endfunction

" When you open a parenthesis after a function name, and at the
" line end, that function's definition is previewed through PreviewWord().
" This is inspired from Delphi's CodeInsight technology.
" Something similar (PreviewClassMembers) could be written for
" the C++ users, for previewing the class members when you type
" a dot after an object name.
" If somebody decides to write it, please, mail it to me.
function! PreviewFunctionSignature()
  let CharOnCursor = strpart( getline('.'), col('.')-2, 1)
  if col(".") == col("$")-1
    normal h
    call PreviewWord()
    normal l
  endif
endfunction

function Register(...)
  let index=1
  while index <= a:0
    execute 'let ext=a:'.index
    execute 'au! CursorHold '.ext.' nested call PreviewWord()'
    execute 'au BufNewFile,BufRead '.ext.' nested inoremap <buffer> ( <Esc>:call PreviewFunctionSignature()<CR>a('
    let index=index+1
  endwhile
endf
call Register('*.[ch]', '*.cc', '*.cpp')
call Register('*.[ch]0','*.cc0','*.cpp0')

Advertisement