Michael
Michael

Reputation: 905

Vimscript autocmd function fail

" ----------------------------------------------------------------------------
" Functions
" ----------------------------------------------------------------------------

function! g:UltiSnips_Complete()
  call UltiSnips#ExpandSnippet()
  if g:ulti_expand_res == 0
    if pumvisible()
      return "\<c-n>"
    else
      call UltiSnips#JumpForwards()
      if g:ulti_jump_forwards_res == 0
        return "\<tab>"
      endif
    endif
  endif
  return ""
endfunction
"
" ----------------------------------------------------------------------------
" Autocmds
" ----------------------------------------------------------------------------

augroup relativenumber
  autocmd InsertEnter,focusLost * :set norelativenumber
  autocmd InsertLeave,focusGained * :set relativenumber
augroup END

autocmd BufEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <c-r>=g:UltiSnips_Complete()<cr>"

The above code is what comprises the end of my .vimrc file. This function use to work but after some updates (either YouCompleteMe or UltiSnips, unsure) the only time these work is when I first open vim in a directory and then open a file from there. I think it has something to do with the autocmd, but to be honest I don't know where to even start. I've tried changing the autocmd event to BufRead but, unfortunately, that made no difference. Any help is appreciated, thanks!

EDIT: If you think there is a better place I could post this question or you need more details, please tell me! I'm happy to help.

Upvotes: 1

Views: 1309

Answers (2)

Dhruva Sagar
Dhruva Sagar

Reputation: 7307

There are a few corrections that I can suggest :

  1. You don't need to put the mapping in an autocmd BufEnter *, if you want this mapping to be available everywhere, just add the

    exec "inoremap <silent>" g:UltiSnipsExpandTrigger "<c-r>=g:UltiSnips_Complete()<cr>"`
    
  2. From the looks of it, what you really need is an <expr> mapping, something like this should work better :

    exec "inoremap <expr> <silent>" g:UltiSnipsExpandTrigger g:UltiSnips_Complete()
    

NOTE: exec takes in multiple args separated by spaces, if you want to just add a space between strings just add the space, you should use concatenation only when you want to avoid the space that exec would add automatically to it's space separated args.

Edit:

  1. Updated the expression mapping so that <expr> must be the first argument.
  2. Since g:UltiSnipsExpandTrigger is defined by UltiSnips plugin, it is not yet available / defined within your vimrc, it being sourced before all plugins. You should hence put this snippet of code in after/plugin/ultisnips_complete.vim. Then you shouldn't get the error.

Upvotes: 1

FDinoff
FDinoff

Reputation: 31429

It seems BufEnter runs before VimEnter. This is a problem since SnipMate puts up its mappings in VimEnter. So the very first buffer has the SnipMate mapping instead of your custom one. And when you switch to a new buffer the autocmd run again putting the mapping in place for the new buffer.

To fix this just make the BufEnter mapping a buffer local mapping. This means that the mapping won't get over written by the SnipMate mapping. And the buffer local mapping has precedence when vim looks to run different mappings.

autocmd BufEnter * exec "inoremap <buffer> <silent> " . g:UltiSnipsExpandTrigger . " <cr>=g:UltiSnips_Complete()<cr>"

Upvotes: 2

Related Questions