tags:

views:

93

answers:

1

I am using vim 7.x

I am using alternate file.

I have a mapping of *.hpp <--> *.cpp

Suppose I'm in

class Foo {

  void some_me#mber_func(); // # = my cursor

}

in Foo.hpp

is there a way to tell vim to do the following:

  1. Grab word under # (easy, expand("")
  2. Look up the class I'm inside of ("Foo") <-- I have no idea how to do this
  3. Append `1 & 2 (easy: using ".") --> "Foo::some_member_func" 4: Switch files (easy, :A)
  4. Do a / on 4

So basically, I can script all of this together, except the "find the name of the enclosing class I'm in part (especially if classes are nested).

I know about ctags. I know about cscope. I'm choosing to not use them -- I prefer solutions where I understand where they break. [So readers, please downvote such suggestions.]

Thanks.

+4  A: 

This is relatively easy to do crudely and very difficult to do well. C and C++ are rather complex languages to parse reliably. At the risk of being downvoted, I'd personally recommend parsing the tags file generated by ctags, but if you really want to do it in Vim, there are a few of options for the "crude" method.

  1. Make some assumptions. The assumptions you make depend on how complicated you want it to be. At the simplest level: assume you're in a class definition and there are no other nearby braces. Based on your coding style, assume that the opening brace of the class definition is on the same line as "class".

    let classlineRE = '^class\s\+\(\k\+\)\s\+{.*'
    let match = search(classlineRE, 'bnW')
    if match != 0
        let classline = getline(match)
        let classname = substitute(classline, classlineRE, '\1', '')
        " Now do something with classname
    endif
    

    The assumptions model can obviously be extended/generalised as much as you see fit. You can just search back for the brace and then search back for class and take what's in between (to handle braces on a separate line to "class"). You can filter out comments. If you want to be really clever, you can start looking at what level of braces you're in and make sure it's a top level one (go to the start of the file, add 1 every time you see '{' and subtract one every time you see '}' etc). Your vim script will get very very very complicated.

  2. Another one risking the downvote, you could use one of the various C parsers written in python and use the vim-python interface to make it act like a vim script. To be honest, if you're thinking of doing this, I'd stick with ctags/cscope.

  3. Use rainbow.vim. This does highlighting based on depth of indentation, so you could be a little clever and search back (using search('{', 'bW') or similar) for opening braces, then interrogate the syntax highlighting of those braces (using synIDattr(synID(line("."), col("."),1), "name")) and if it's hlLevel0, you know it's a top-level brace. You can then search back for class and parse as per item 1.

I hope that all of the above gives you some food for thought...

Al