5

I am wondering if it is possible to define a macro in Vim that will let you do the following. Suppose you have a class definition

class CRectangle {
  int x;
  int y;
  _
};

where _ specifies the current cursor position.

Running the macro should automatically generate

class CRectangle {
  int x;
  int y;

public:
  CRectangle (int x, int y);
  ~CRectangle ();
};

CRectangle::(int x, int y) {
  this->x = x;
  this->y = y;
}

I have been thinking about this for a while but didn't get anywhere. Perhaps creating the constructor definition is a bit too much to ask. Is it feasible to get at least the constructor declaration?

====

As sftrabbit points out, it is perhaps more desirable to generate something like

CRectangle::(int _x, int _y) : x(_x), y(_y) {}
5
  • 3
    Wouldn't you rather it used member initialization lists? Anyway, I have no doubt this is possible - this is vim we're talking about. I'm just not sure it's really that useful. Commented Mar 23, 2013 at 0:18
  • I'm afraid I had't heard of member initialization lists before. Thanks for pointing it out. Commented Mar 23, 2013 at 0:26
  • 2
    It's rather better to use snippets for that task. For instance, I highly recommend UltiSnips. Be sure to check out screencast to see all the amazing stuff you can do with it. Commented Mar 23, 2013 at 0:46
  • I have been using snipMate. I didn't know that UltiSnips supported regex on variables. Thanks much. Commented Mar 23, 2013 at 0:59
  • Including the syntax errors? scnr Commented Mar 23, 2013 at 1:13

1 Answer 1

10

Okay... I was bored...

qm           ; Gentlemen... start your macros (we'll call it 'm')
ma           ; Mark your current location as 'a'
v            ; switch to 'visual' mode
?{<cr>       ; Search back to the opening brace (actually hit 'enter' for that <cr>)
l"by         ; Go forward one character and yank the selection to buffer 'b'
b            ; Go back one word
"cyw         ; Copy the class name into buffer 'c'
'a           ; Jump back to the starting location
opublic:<cr> ; add "public:"
()<esc>B"cP  ; create an empty constructor
t)"bp        ; Paste the list of arguments in
             ; Rather complex reformatting regex on the next line
:.,/)/s/\s*\w\+\s+\(\w+\);\n/_\1, /<cr>
kJ:s/,\s*)/)/<cr> ; Simple cleanup
A : {}<esc>  ; Finish some of the basics
F:"bp        ; Paste in the fields again for generating the initialization
             ; Below: Another fairly complicated formatting regex
:.,/{}/s/\s*\w\+\s\+\(\w\+\);\n/\1(_\1),/<cr>
:s/,\s*{/ {/<cr>     ; Cleanup
kJ                   ; Finished with the constructor
q                    ; Finish macro (I'm going to omit the rather trivial destructor)

I'm sure this can be simplified... but as an answer to "can it be done?" yes... it certainly can.

Note that you'll also have to modify it somewhat to handle however your vim is configured for formatting (auto-indentation, and such).

If you've been a bit sloppy about assembling your variables in the class, you might have to swap /\s*\w\+\s\+\(\w\+\)\s*;\s*\n/ in for /\s*\w\+\s\+\(\w\+\);\n/ both places. (handling a few extra spaces around things)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.