This is not directly possible.
See :help abbreviations
which talks about the three types of abbreviations, but even the (least restrictive) "non-id" type mentions "the other characters may be of any type, excluding space and tab."
And also:
Examples of strings that cannot be abbreviations: a.b
, #def
, a b
, _$r
You can work around this, by using an <expr>
abbreviation that triggers a function that checks the words preceding the one currently being abbreviated and decide to expand it or not (not expanding it means expanding it to the same text.)
But even that doesn't really help much in your particular case, since "an abbreviation is only recognized when you type a non-keyword character." So you would have to expect a symbol or whitespace after the (
to trigger the abbreviation, but you're quite likely to find a variable name or function call there, which would be an alphanumeric character and would not expand and abbreviation.
Perhaps a more convenient way to handle this is to use an inoremap
, since that will trigger when the key itself is pressed and not after the whole word is entered as a word. You could use an inoremap <expr> ( ...
to trigger the mapping when the (
is typed, then check whether it's preceded by an if
word and, in that case, expand the sequence you wanted.
See this answer for an iabbrev <expr>
that inspects the preceding word when deciding whether to expand an abbreviation, and this answer for an advanced use of inoremap <expr>
that might be somewhat similar to yours.
But if you're really serious about having Vim type your code for you, you should really look into a snippet engine such as UltiSnips.
UltiSnips allows you to define your snippets using a much higher level templating language and it takes care of the low-level details such as the Vim mappings needed to make the snippets work.
It also allows you to define "fields" through markers in your templates, which you'll find you really need for a template to an if
or a for
, since you typically want to enter one or more expressions before the cursor lands in the inner code block.
I'd seriously recommend that you'd take a look into it.