142

I have bundles ultisnips and youcompleteme installed on my macvim. The problem is that ultisnips doesn't work because tab is bound by ycm. I tried putting let g:UltiSnipsExpandTrigger = "<s-tab>" so that I can trigger the snippet completion with shift-tab, but it doesn't work for some unknown reason. I could use caps as the trigger, but so far I've found no way to do that.

Do any of you use those two add-ons together? What can I do to make shift-tab work? Can you recommend another key to trigger snippets?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
pvinis
  • 4,059
  • 5
  • 39
  • 59
  • YCM also maps `` and so does UltiSnips, IIRC. You should ask to YCM's author, I guess. – romainl Feb 15 '13 at 14:14
  • i changed the keys for previous completion on ycm, and removed s-tab. still not working. i'll try messaging him on github i guess – pvinis Feb 15 '13 at 14:44
  • 1
    See if your map is working with `:verbose map `, it will probably not work on command line vim though. A pretty good replacement imo is ``. – Daan Bakker Feb 15 '13 at 15:56
  • Thanks for that I was eager to find a solution and the fact that YouCompleteMe doesn't have a forum is annoying. Thanks – patm Jul 12 '13 at 08:04
  • 2
    Have you tried this again recently? One or both plugins must have been updated, because the UltiSnips documentation says: "YouCompleteMe - comes with out of the box completion support for UltiSnips. It offers a really nice completion dialogue for snippets." – Kyle Strand Mar 26 '15 at 15:59

14 Answers14

209

Another option is using the SuperTab plugin:

" if you use Vundle, load plugins:
Bundle 'ervandew/supertab'
Bundle 'Valloric/YouCompleteMe'
Bundle 'SirVer/ultisnips'

" make YCM compatible with UltiSnips (using supertab)
let g:ycm_key_list_select_completion = ['<C-n>', '<Down>']
let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
let g:SuperTabDefaultCompletionType = '<C-n>'

" better key bindings for UltiSnipsExpandTrigger
let g:UltiSnipsExpandTrigger = "<tab>"
let g:UltiSnipsJumpForwardTrigger = "<tab>"
let g:UltiSnipsJumpBackwardTrigger = "<s-tab>"

Here YouCompleteMe is bound to a different combination Ctrln, but then that combination is bound to tab through SuperTab. UltiSnips and SuperTab play nice together, so you can then just bind UltiSnips to tab directly and everything will work out.

sudo bangbang
  • 27,127
  • 11
  • 75
  • 77
Siegfried Gevatter
  • 3,624
  • 3
  • 18
  • 13
  • 8
    Joey Liu's suggestion wasn't working for me (tab wouldn't expand anything, it would only scroll to the next autocomplete option). This answer worked great, but I had to update and recompile YouCompleteMe first. – BenjaminGolder Apr 07 '14 at 18:05
  • Siegfried, Do you want to consolidate your two answers? – BenjaminGolder Apr 07 '14 at 18:07
  • @BenjaminGolder Oh, not quite sure why I posted it twice. Done, thanks. – Siegfried Gevatter Apr 08 '14 at 08:58
  • Using this makes VIM slow! What happened? – lazywei Jun 29 '14 at 08:40
  • This is great, but I found that it would sometimes eat my ``s when I wasn't expecting. I fixed this by adding `let g:SuperTabCrMapping = 0`. This disables supertab trying to cancel completion when pressing enter (which I don't think is necessary anyway with the way that YCM is designed). – Joe Lencioni Aug 16 '14 at 11:05
  • Thanks! This solution is better than Joey Liu's, as both plugins use tab. – liuyang1 Sep 27 '14 at 16:22
  • 1
    As others have mentioned, Joey Liu's solution is no longer working. This one does! – Anchor Oct 22 '14 at 05:26
  • 3
    Is there any way to highlight snippets on the autocompletion list? – syntagma Jan 02 '15 at 12:37
  • 4
    DAMN ! Man ! Working like a charm ! Best solution ever ! – Yves Lange Aug 12 '15 at 09:52
  • 7
    This is nice, but hitting `tab` inside a snippet will go to next tabstop, instead of completing the YCM suggestion. I had to add `let g:UltiSnipsJumpForwardTrigger = ""` and `let g:UltiSnipsJumpBackwardTrigger = ""` to make this work. – Gabriel Florit Dec 13 '15 at 19:31
  • 1
    Is this solution supposed to let ycm completion still work with tab? Ycm completion doesn't work with tab anymore. – ElefEnt Feb 25 '16 at 19:13
  • This was my option before i migrate to neovim, now in neovim i use deoplete and neosnippets for this (bye SuperTab) but for vim 7.4 was YouCompleteMe needed for async plugin process. – Yonsy Solis Sep 08 '16 at 01:14
54

Try this suggestion on a page from the YouCompleteMe issue tracker. In your .vimrc:

let g:UltiSnipsExpandTrigger="<c-j>"

While this setting will make expanding a snippet share the default mapping for jumping forward within a snippet, it simulates TextMates' behavior as mentioned in the UltiSnips help tags.

Since I've mapped my Caps Lock key to Ctrl, this mapping works pretty smoothly.

unblevable
  • 1,296
  • 10
  • 14
  • 1
    This should be the best answer, simple and straight, although in my macvim on macOS 10.12, doesn't work, I change it to , then everything works just fine. forward, backward, expand the snippet. Thanks – gpanda Oct 13 '16 at 15:27
  • 1
    I was new to Ultisnips and I tried this suggestion. I wouldn't recommend it as having both "jumping forward" and "expand" mapped to the same key makes nested snippets unusable, which is something you are most likely going to eventually need. – Kevin Oct 31 '20 at 00:28
40

copy the following code to your vimrc, and enjoy. This function will handle all issues between YCM and UltiSnips.

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

au BufEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=g:UltiSnips_Complete()<cr>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsListSnippets="<c-e>"
" this mapping Enter key to <C-y> to chose the current highlight item 
" and close the selection list, same as other IDEs.
" CONFLICT with some plugins like tpope/Endwise
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
Joey Liu
  • 508
  • 4
  • 6
  • 28
    Some credit where it is due I think: https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-15451411 And the BufEnter autocmd a few comments down. – ches Oct 22 '13 at 16:03
  • 3
    This didn't seem to work for me, for Mac OS X; as of the 10th of July 2014. Siegfried's answer worked, however. – miguel.martin Jul 10 '14 at 03:52
  • Seems great so far! But how can I "tab-through" the snippet breakpoints? – chmanie Sep 04 '14 at 16:13
  • @chmanie if the ycm autocomplete popup is visible, hit to close it first, then you could "tab-throuth" – Joey Liu Sep 06 '14 at 19:02
  • 1
    I found it handy to bind `g:UltiSnipsJumpForwardTrigger=""` so that I could still tab through all possible completions/snippets – alaroldai Sep 10 '14 at 01:29
  • 1
    This lets me tab through the YCM listed completes (including Ultisnips suggestions), but the last inoremap line doesn't actually seem to be affecting my pressing of the enter key. I can manually trigger the completion with , but enter doesn't do anything. Any suggestions? – HaaR Oct 28 '14 at 11:47
18

i have this in my vimrc

"" YouCompleteMe
let g:ycm_key_list_previous_completion=['<Up>']

"" Ultisnips
let g:UltiSnipsExpandTrigger="<c-tab>"
let g:UltiSnipsListSnippets="<c-s-tab>"

thats what i did on my first try, but i misspelled UltiSnips with Ultisnips.. oh well, worked out in the end!

dennisyuan
  • 171
  • 1
  • 10
pvinis
  • 4,059
  • 5
  • 39
  • 59
18

I personally chose to not use <tab> with YouCompleteMe but navigate it manually.

So I added this to my .vimrc:

let g:ycm_key_list_select_completion=[]
let g:ycm_key_list_previous_completion=[]

which simply disables the tab key for YCM. Instead you use the movement keys (arrows or CTRL-N/CTRL-P) and select the entry with CR. UltiSnips works default with tab.

mMontu
  • 8,983
  • 4
  • 38
  • 53
Thomas Fankhauser
  • 5,039
  • 1
  • 33
  • 32
5

Just putting together answers by Michaelslec, Joey Liu and along with solutions I found in this issue thread and this guy's vimrc, I now have this which solved pretty much all problems.

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

function! g:UltiSnips_Reverse()
  call UltiSnips#JumpBackwards()
  if g:ulti_jump_backwards_res == 0
    return "\<C-P>"
  endif

  return ""
endfunction


if !exists("g:UltiSnipsJumpForwardTrigger")
  let g:UltiSnipsJumpForwardTrigger = "<tab>"
endif

if !exists("g:UltiSnipsJumpBackwardTrigger")
  let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
endif

au InsertEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger     . " <C-R>=g:UltiSnips_Complete()<cr>"
au InsertEnter * exec "inoremap <silent> " .     g:UltiSnipsJumpBackwardTrigger . " <C-R>=g:UltiSnips_Reverse()<cr>"
sudo bangbang
  • 27,127
  • 11
  • 75
  • 77
  • This was very helpful when essentially trying to fix the same issue with COC and Ultisnips. Wanting to use and to move up and down the PUM as well as move back and forth within Ultisnips placeholders. Thanks. – 110100100 May 12 '20 at 21:01
4

Although I know this post is a little old, I have my own function that is a little more optimized than the one given above:

function! g:UltiSnips_Complete()
  call UltiSnips#ExpandSnippetOrJump()
  if g:ulti_expand_or_jump_res == 0
    if pumvisible()
      return "\<C-N>"
    else
      return "\<TAB>"
    endif
  endif

  return ""
endfunction

Of course, if you just keep the settings that Joey Liu provided and then just use this function everything will work just perfectly!

EDIT: Also, I use another function to increase back-stepping functionality between YouCompleteMe and UltiSnips. I'll show you what I mean:

function! g:UltiSnips_Reverse()                                                                                               
  call UltiSnips#JumpBackwards()                                                                                              
  if g:ulti_jump_backwards_res == 0        
    return "\<C-P>"                                                                                                           
  endif                                                                                                                       

  return ""                                                                                                                   
endfunction

Then just put this in your .vimrc:

au BufEnter * exec "inoremap <silent> " . g:UltiSnipsJumpBackwardTrigger . " <C-R>=g:UltiSnips_Reverse()<cr>"

As well as let g:UltiSnipsJumpBackwardTrigger="<s-tab>" and your set!

sudo bangbang
  • 27,127
  • 11
  • 75
  • 77
Michaelslec
  • 905
  • 1
  • 9
  • 20
4

Based on Siegfried's answer, I am using the following which seems more natural:

let g:ycm_key_list_select_completion = ['<C-j>']
let g:ycm_key_list_previous_completion = ['<C-k>']

let g:UltiSnipsExpandTrigger = "<C-l>"
let g:UltiSnipsJumpForwardTrigger = "<C-j>"
let g:UltiSnipsJumpBackwardTrigger = "<C-k>"

I also use the c-hjkl bindings somewhere else (switching from a pane to another), but that would only be in normal mode, so there's no problem.

Nicolas Mattia
  • 1,269
  • 11
  • 20
3

I use both of them together. By default YouCompleteMe binds <Tab> and <Down> to select the next completion item and also <S-Tab> and <Up> to select the previous completion item. You can change the YouCompleteMe bindings with the g:ycm_key_list_select_completion and g:ycm_key_list_previous_completion options. Note that the names of these options were recently changed when the option was changed from a single string to a list of strings.

David Brown
  • 13,336
  • 4
  • 38
  • 55
3

While Many answer works fine in this post, I just want to say that the problem is caused by key binding collision between YCM and UltiSnip, while YCM support UltiSnip snippets by default, it takes the default UltiSnip expand trigger <tab> as its completion select key, so UltiSnip snippets will not be expaned by <tab>. Give them different key binding will solve the problem, I personally use <c-n and <c-p> for YCM and use the default <tab> for UltiSnip. You can get more details with help youcompleteme doc in vim.

Minghao Ni
  • 185
  • 1
  • 9
3

I installed the UltiSnips plugin after the YouCompleteMe plugin so I thought they were conflicting, but in reality I had something more interfering:

set paste

Make sure to remove that from .vimrc if it's present.

Antoine Snyers
  • 682
  • 3
  • 7
2

I use ; to expand UltiSnips, it's so nifty for me

let g:UltiSnipsExpandTrigger = ";"
Kaka Ruto
  • 4,581
  • 1
  • 31
  • 39
1

I use kj. This is what is in my .vimrc:

let g:UltisnipsExpandTrigger="kj".

It rarely happens that I run into word that has kj in it. If this is the case I would just wait a couple of seconds after typing k and that type j.

Sinister Beard
  • 3,570
  • 12
  • 59
  • 95
dowewas
  • 71
  • 1
  • 2
0

As mentioned by others, mapping C-j to ultisnips works great.
let g:UltiSnipsExpandTrigger="<c-j>"

Now, if you go a bit further and install xcape and use
xcape -e "Shift_L=Control_R|J"

You unleash the power of using just the shift key for utlitsnips.

Hritik
  • 673
  • 1
  • 6
  • 24