sponsor Vim development Vim logo Vim Book Ad

intermediate Tip #1454: Shows what function the cursor is in. (for C/C++)

 tip karma   Rating 9/3, Viewed by 531 

created:   January 1, 2007 2:46      complexity:   intermediate
author:   AOYAMA Shotaro      as of Vim:  

This is a function to show what C/C++ function/struct/class
the cursor is in.

I think this method is fast enough for practical use,
but not complete.
Any feedback is appreciated.

function! GetProtoLine()
  let ret       = ""
  let line_save = line(".")
  let col_save  = col(".")
  let top       = line_save - winline() + 1
  let so_save = &so;
  let &so; = 0
  let istypedef = 0
  " find closing brace
  let closing_lnum = search('^}','cW')
  if closing_lnum > 0
    if getline(line(".")) =~ '\w\s*;\s*$'
      let istypedef = 1
      let closingline = getline(".")
    endif
    " go to the opening brace
    normal! %
    " if the start position is between the two braces
    if line(".") <= line_save
      if istypedef
        let ret = matchstr(closingline, '\w\+\s*;')
      else
        " find a line contains function name
        let lnum = search('^\w','bcnW')
        if lnum > 0
          let ret = getline(lnum)
        endif
      endif
    endif
  endif
  " restore position and screen line
  exe "normal! " . top . "Gz\<CR>"
  call cursor(line_save, col_save)
  let &so; = so_save
  return ret
endfunction

function! WhatFunction()
  if &ft; != "c" && &ft; != "cpp"
    return ""
  endif
  let proto = GetProtoLine()
  if proto == ""
    return "?"
  endif
  if stridx(proto, '(') > 0
    let ret = matchstr(proto, '\w\+(\@=')
  elseif proto =~# '\<struct\>'
    let ret = matchstr(proto, 'struct\s\+\w\+')
  elseif proto =~# '\<class\>'
    let ret = matchstr(proto, 'class\s\+\w\+')
  else
    let ret = strpart(proto, 0, 15) . "..."
  endif
  return ret
endfunction

" You may want to call WhatFunction in the statusline
set statusline=%f:%{WhatFunction()}\ %m%=\ %l-%v\ %p%%\ %02B


This function works well in the following testcase:

void draw()
{
    // When cursor is here, WhatFunction() shows "draw"
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

typedef struct {
    int ident;  // { <- braces in comments are ignored thanks to %. Great!
    int version;    // here it shows "} HEADER"
} HEADER;

# define EX(a, b, c, d)  a
enum CMD_index
#endif
{
EX(CMD_append, "append", ex_append); // here "enum CMD_index..."
};

class Sys {
public:
    load() {
        // NG: here, it shows "Sys" instead of "load"...
    }
};

class Camera : public Object
{
public:
    void init();
};

void Camera::init()
{
    // here WhatFunction shows "init"
}

 rate this tip  Life Changing Helpful Unfulfilling 

<<Quick switch buffers in one window | Jumps to a local/global definition by same key >>

Additional Notes

Anonymous, January 4, 2007 4:20
It would have been better if you could also tell how to use it!!!
Anonymous, January 4, 2007 14:03
To use it, simply
:echo WhatFunction()
shows the function name.
Or use it in the statusline as already mentioned.

The method of finding opening brace can be replaced by the on of vimscript # 1628.
That's better?
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to [email protected] after searching the archive. Help Bram help Uganda.
    stats
Sponsored by Web Concept Group Inc. SourceForge.net Logo