0

I have following c.vim file:

imap {<CR> {<CR>}<Esc>O
imap [ []<Left>
imap # #include<><Left>

command F %s/\v(\w) ?(\+|-|\*|\/|\>\=|\<\=|!\=|\=|\=\=) ?(\w|-)/\1 \2 \3/g | %s/\v([;,])([^ ])/\1 \2/g

And my sample file is test.c containing

if(a==3)
if(array[4]==3)

Then if I execute command F then the above file is changed into

if(a == 3)
if(array[4]==3)

First == sign is indented but not in second. Why?

1

The only relevant part is the first substitution in the F command:

%s/\v(\w) ?(\+|-|\*|\/|\>\=|\<\=|!\=|\=|\=\=) ?(\w|-)/\1 \2 \3/g

Breaking down the pattern:

  • \v - set 'very magic' option, many characters have special meaning without having to be escaped
  • (\w) - match one word character which is same as [0-9A-Za-z_], the parens allow this match to be inserted into the substitution via back-reference (e.g. \1)
  • <space>? - match 0 or 1 space
  • (\+|-|\*|\/|\>\=|\<\=|!\=|\=|\=\=) - match an arithmetic operator, surrounding with parens for back-ref use
  • <space>? - match 0 or 1 space
  • (\w|-) - same as (\w) above except also allow dash to match

(The substitution \1 \2 \3, with back-reference to each of the paren surrounded pattern parts, adds an extra space before and after the arithmetic operator.)

It should be pretty clear now from the breakdown of the pattern that a==3 matches and array[4]==3 does not as the character preceding the operator, i.e. ], is not a word character. One option to allow ] as well is to replace (\w) with ([]0-9A-Za-z_]) or (]|\w). Choosing the latter we end up with this for F:

command F %s/\v(]|\w) ?(\+|-|\*|\/|\>\=|\<\=|!\=|\=|\=\=) ?(\w|-)/\1 \2 \3/g | %s/\v([;,])([^ ])/\1 \2/g

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.