1
" ----------------------------------------------------------------------------
" 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.

Michaelslec
  • 905
  • 1
  • 9
  • 20
  • The autocmd above will create the imaps on every buffer -- so what is the point of using the autocmd? Wouldn't be the same without it, replacing it with the `exec "inoremap...`? – mMontu May 20 '14 at 10:46
  • Unfortunately no. It throws an invalid expression error: `Invalid expression: "inoremap " . g:UltiSnipsExpandTrigger . " =g:UltiSnips_Complete()"` – Michaelslec May 21 '14 at 04:40
  • Even so, this does no fix my problem. For some reason, the function only works when I resource my vimrc after I directly open a file in vim or a open a directory first followed by the file I want to edit. – Michaelslec May 21 '14 at 04:42
  • That is strange, as it does not throw any error here. Did you included the `exec`? I mean this: `exec "inoremap " . g:UltiSnipsExpandTrigger . " =g:UltiSnips_Complete()"`. – mMontu May 21 '14 at 10:31
  • Yes I did. I'm not quite sure why this is happening... – Michaelslec May 22 '14 at 22:37
  • Can you copy and paste the exact error message? Also make sure you actually have UltiSnips is installed. (You can check it is being loaded with `:scriptnames`) – FDinoff May 24 '14 at 00:36
  • There actually is no error message. The function seems to not even be executed. Unless I open a directory first or resource my .vimrc, it simply scrolls through the rest of the options in the YouCompleteMe list. – Michaelslec May 24 '14 at 07:07

2 Answers2

2

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>"
FDinoff
  • 30,689
  • 5
  • 75
  • 96
  • This works perfectly!! Do you know, by chance, if there was a way we could make this a little more efficient? Or, is an autocmd the best choice? – Michaelslec May 25 '14 at 20:27
  • @Michaelslec if you want to edit SnipMate (Not sure I recommend this) you can remove the mappings from there. Other than that I can't think of one right now. And even if you did remove it from there you would still have to stick it in an autocmd for VimEnter since `g:UltiSnipsExpandTrigger` isn't defined during your vimrc. (Unless you define it yourself). – FDinoff May 25 '14 at 20:29
1

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.
Dhruva Sagar
  • 7,089
  • 1
  • 25
  • 34