3

In Vim, you can make it so each time you write "FF" on insert mode changes to some code by using:

:iab FF for ( int i = 0 ; i < n ; i++ )

But is there any way to use this with arguments? Something like C's #defines, so if I write

FF(e, 10)

It becomes:

for ( int e = 0 ; e < 10 ; e++ )
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Martín Fixman
  • 9,055
  • 9
  • 38
  • 46

4 Answers4

7

Take a look at SnipMate (a vim plugin). You won't get arguments, but upon expansion of an abbreviation, it allows you to tab through modifiable areas. In the for example, you'll be brought to the i first, can edit it to be e, and it will change it to e in all areas of the for declaration. Then simply tab to the next area you'd like to change.

From the docs:

snipMate.vim aims to be an unobtrusive, concise vim script that implements some of TextMate's snippets features in Vim. A snippet is a piece of often-typed text that you can insert into your document using a trigger word followed by a .

For instance, in a C file using the default installation of snipMate.vim, if you type "for" in insert mode, it will expand a typical for loop in C:

for (i = 0; i < count; i++) {

}

To go to the next item in the loop, simply over to it; if there is repeated code, such as the "i" variable in this example, you can simply start typing once it's highlighted and all the matches specified in the snippet will be updated.

The following is a nice helpful change to remap tab and s-tab to c-d and c-a, in case you don't want to lose the functionality of tab (in ~/.vim/after/plugin/snipMate.vim):

"""ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
"""snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
"""ino <silent> <s-tab> <c-r>=BackwardsSnippet()<cr>
"""snor <silent> <s-tab> <esc>i<right><c-r>=BackwardsSnippet()<cr>
"""ino <silent> <c-r><tab> <c-r>=ShowAvailableSnips()<cr>
ino <silent> <c-d> <c-r>=TriggerSnippet()<cr>
snor <silent> <c-d> <esc>i<right><c-r>=TriggerSnippet()<cr>
ino <silent> <c-a> <c-r>=BackwardsSnippet()<cr>
snor <silent> <c-a> <esc>i<right><c-r>=BackwardsSnippet()<cr>
ino <silent> <c-r><tab> <c-r>=ShowAvailableSnips()<cr>
Community
  • 1
  • 1
nearlymonolith
  • 946
  • 4
  • 7
  • I agree. I also made some changes to the ~/.vim/after/plugin/snipMate.vim file to remap away from `` since that was causing problems for me. I edited them in above - basically just changed `` and `` to `` and ``. – nearlymonolith Jun 25 '10 at 13:20
4

You can include function definitions in abbreviations, but they cannot take arguments. This is an example from the vimdocs:

func Eatchar(pat)
   let c = nr2char(getchar(0))
   return (c =~ a:pat) ? '' : c
endfunc
iabbr <silent> if if ()<Left><C-R>=Eatchar('\s')<CR>

I guess you could maybe parse the abbreviation expression in the function, but I'm not sure if you can also include characters like parenthesis in the abbreviation. Maybe something here will give you an idea.

Edit: You can always do something like this:

:iab for() for(int i = 0; i < ; i++)<C-o>T<

Which lacks the argument autocompletion of course but lets you start typing it immediately.

kprobst
  • 16,165
  • 5
  • 32
  • 53
1

It worked for me:

iab FF <c-o>:FF
com -nargs=* FF call s:FF(<f-args>)
fu s:FF(i, n)
    let t = "for (int a = 0; a < b; ++a) {\e"
    let t1 = substitute(t, 'a', a:i, 'g')
    exe 'normal! A'.substitute(t1, 'b', a:x, 'g')
    exe "normal o\<space>\<BS>\e"
endf

at insert mode FF e 10<cr> will be for (int e = 0; e < 10; ++e) {<cr>.

014
  • 497
  • 4
  • 6
  • When I ran this command, I got this error: Error detected while processing function 89_FF: line 3: E121: Undefined variable: a:x E116: Invalid arguments for function substitute(t1, 'b', a:x, 'g') – Felipe Valdes Aug 22 '19 at 10:30
  • has vim changed in the way it deals with variables in the last 4 years? @014 – Felipe Valdes Aug 22 '19 at 10:31
  • this line: exe `normal! A'.substitute(t1, 'b', a:x, 'g')` refers to variable 'x' which is not defined (see `FF(i, n)`. Replacing `a:x` with `a:n` works – mschr Sep 06 '21 at 08:58
0

mu-template support interactive templates. With it, you can either ask something to the user, or reuse any variable, apply computation on it if you which (detecting that i is already use in the current scope is doable), and use the result in the text you will expand.

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83