ricardo
ricardo

Reputation: 8425

How to Eatchar in a multi-line Vim abbreviation

I would like to trigger a multi line abbreviation in Vim, without entering the 'trigger' character, and with the cursor ending in insert mode at a particular location.

I am nearly there, but just failing to make it.

Thus far, i have added the following to my _vimrc:

" eat characters after abbreviation
function! Eatchar(pat)
    let c = nr2char(getchar(0))
    return (c =~ a:pat) ? '' : c
endfunction
iabbr <silent> if if ()<left><C-R>=Eatchar('\s')<CR>

:iabbr <silent> rfF <- function( )<CR>{<CR>  <CR>}<Esc>3k$h<Insert><c-r>=Eatchar('\m\s<bar>/')<cr> 

Which is mostly successful, in that it yields the following when i type rfF Ctr-] to trigger the abbreviation's expansion:

<- function(  )
{

}

However, the outcome varies depending on how i trigger the abbreviation.

If i trigger with a <space> the space between the brackets expands:

<- function(  )
{

}

... and if i <CR>:

<- function( 
 )
{

}  

I recently asked, and had answered, a question about preventing the characters that trigger an abbreviation from being added in the single line case.

Is this possible with multi-line abbreviations?

Upvotes: 3

Views: 864

Answers (1)

Peter Rincker
Peter Rincker

Reputation: 45087

This is what I came up with.

" eat characters after abbreviation
function! Eatchar(pat)
    let c = nr2char(getchar(0))
    return (c =~ a:pat) ? '' : c
endfunction

inoreabbr <silent> rfF <- function()<cr>{<cr>}<esc>2k$i<c-r>=Eatchar('\m\s\<bar>\r')<cr> 

The regex in this command m\s\<bar>\r will eat any white space or return character. I have also removed the extra space between the { and } because I imagine after you update the function parameter list you will exit back to normal mode then jump down a line with j then execute o to open a new line inside the function block.

Upvotes: 1

Related Questions