Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SnipMate/UltiSnips integration #36

Closed
kballenegger opened this issue Feb 5, 2013 · 96 comments
Closed

SnipMate/UltiSnips integration #36

kballenegger opened this issue Feb 5, 2013 · 96 comments

Comments

@kballenegger
Copy link
Contributor

A killer feature would be for YCM to include SnipMate snippets in its suggestions.

I'm making this an issue in case a contributor sees this. I unfortunately do not have the skills required to build this.

@Valloric
Copy link
Member

Valloric commented Feb 5, 2013

I'm not a fan of this. I use snippets as well (UltiSnips) but I don't think integrating it with a code-completion system would be the best approach.

Thanks for the feedback though!

@Valloric Valloric closed this as completed Feb 5, 2013
@capitalist
Copy link

For what it's worth. I think snippet integration would be nice as well. My snippets no longer complete with YCM, so I may have explore changing the trigger.

@kballenegger
Copy link
Contributor Author

Ditto, see how Xcode does it. It's really nice, your snippets are offered as autocompletion, it's super neat.

@drasill
Copy link

drasill commented Feb 8, 2013

+1 (ultisnips)

"snippets offered as autocompletion" is something I didn't imagine, it could be awesome.

@drasill
Copy link

drasill commented Feb 8, 2013

Although, binding <C-j> to ultisnips make it easy to use again.

@Valloric
Copy link
Member

Valloric commented Feb 9, 2013

I'm slowly changing my mind about this. If we could figure out a way for YCM to talk to UltiSnips/Snipmate in a way that doesn't complicate matters too much, I'd support it.

UltiSnips support will probably come first; I'm not sure about Snipmate because upstream has a note about Snipmate dying and it recommends UltiSnips, so that's not a good sign.

@Valloric Valloric reopened this Feb 9, 2013
@Townk
Copy link

Townk commented Feb 9, 2013

The way clang_complete uses Ultisnips is the best approach. Besides allow you to complete snippets with once you accepted a completion and this completion is a function call, than YCM should provide an "anonymous" snippet with the parameters of the function to be completed. Ex:

I type:

prtf

Than YCM offers me "printf" among others. After I press than , YMC shuld give me this:

printf("format string", parameters);

Where:

"format string" - is the first argument of the snippet
, parameters - is the optional argument

Also, regarding how to complete a snippets or "other completions", I think YMC should do this:

I type:

if

YMC provides me some options. The snippets should be listed on top of the options and marked somehow so user can clearly see what's this about. If user, press , than Ultisnips should be triggered and if the offered snippet has more than one possibility, than YCM should change the completion list to show all snippets available for the chosen snippet.

I'm pretty sure if you contact the developers of Ultisnips they can help you figure out a way to implement that.

@Valloric
Copy link
Member

Valloric commented Feb 9, 2013

I'll probably talk to the UltiSnips developer at some point, yes.

I like your first feature, where pressing TAB after "ptrf" also inserts the parameter names. But this can be implemented without UltiSnips actually.

The second feature sound good too, but that will not be easy to implement and will require quite a bit of cooperation with the snippets plugin.

@capitalist
Copy link

Wow, how often does a maintainer remain open-minded after dismissing an issue.

Loving YCM and now @Valloric too. Respect.

@Townk
Copy link

Townk commented Feb 10, 2013

Agree that "parameter" completion can be achieved without Ultisnips. That being said, Ultisnips already provide a python API to do that, and it'll give you the possibility to use powerful snippets features like python interpolation.

@Valloric
Copy link
Member

@Townk I didn't know UltiSnips provided such an API. I'll be using it then.

@sotte
Copy link

sotte commented Feb 10, 2013

This is the active clone of snipmate which is used quite a lot: https://github.com/garbas/vim-snipmate

@Valloric
Copy link
Member

@sotte From the top of the README in that branch:

See snipmate-snippets readme about how to configure and use Ultisnips as alternative That branch also supports completion menu now Thus there is only one reason left to keep using snipmate from my point of view: not having python support. In other words: upstream of snipmate is almost dead.

Also see the issue linked from the first line in the README. This is written by the maintainers of the snipmate clone. Here's an excerpt:

Dear fellow snipmate community. It was a great honor working for you. [...] However for quite a long time snipmate has been broken in various ways - and me and Rok wonder whether its worth fixing snipmate - cause there are other snippet engines for Vim which are more powerful and which do just work - such as ultisnips or xptemplate.

I think this means that SnipMate is dead, or very close to it.

@Townk
Copy link

Townk commented Feb 10, 2013

@sotte another thing is that Ultisnips kind provide some snipmate compatibility. It defines the "Filename" function and the g:snips_author variable that are used by some snippets. It also provides a script called "convert_snipmate_snippets.py", I believe you can just convert your snippets and start using Ultisnips. Give it a try!

@pvinis
Copy link

pvinis commented Feb 15, 2013

until ultisnips support comes, how can i make to trigger ycm completion, and to trigger ultisnips completion? do you all use another key for ultisnips? i saw on valloric's vimrc a meta key combination, but can't seem to be able to use meta on macvim..

@xgalaxy
Copy link
Contributor

xgalaxy commented Feb 17, 2013

In your vimrc you have to :set macmeta for the options key to work correctly.
If your using macvim in terminal, it wont work regardless.

@mindfulmonk
Copy link

Can someone give me their config with working keybindings? Can't get UltiSnips to work in terminal.

@bmedicke
Copy link

Mapping UltiSnips to ctrl-j/k works fine for me.

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

See :h UltiSnips-triggers.

That said I like the idea of it being more integrated with YCM.

@jbeja
Copy link

jbeja commented Feb 20, 2013

Thanks @bmedicke, works like a charm

@neersighted
Copy link

👍

@UncleBill
Copy link

+1 for UltiSnips. It is awesome!

@AllisonV
Copy link

AllisonV commented Mar 6, 2013

+1

1 similar comment
@fatih
Copy link

fatih commented Mar 8, 2013

👍

@johntyree
Copy link

Neocomplcache also has a feature like this, although it basically reimplemented the snippets engine.

That said, it's a great feature for the same reasons as identifier autocompletion, namely you don't want to have your entire snippet collection in your head at all times. Almost all of the snippets I use I discovered because neocomplcache popped them up as I was typing.

As a final point, I don't know if this still "under vote" or something, but having an endless chain of "+1" and 👍 is pretty terrible for everyone else that has commented in this thread. Please don't.

@dbrgn
Copy link

dbrgn commented Mar 26, 2013

In the meantime you should mention the g:snips_trigger_key option (and the UltraSnips equivalent) in your FAQ.

@JazzCore
Copy link
Contributor

I've managed to get this working, you can check this branch. If you wish to try it, you will need a quite recent version of UltiSnips. I will not make a pull request for this because it's mainly a hack to add general completers and I agree with @Valloric that this is not so useful. Maybe someday @Valloric or I will make a nice implementation for general completers and there will be a better implementation.

For correct completion and snippet expanding with a TAB key you can use this function:

" UltiSnips completion function that tries to expand a snippet. If there's no
" snippet for expanding, it checks for completion window and if it's
" shown, selects first element. If there's no completion window it tries to
" jump to next placeholder. If there's no placeholder it just returns TAB key 
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

Due to fact that YCM maps its keys in autoload script after all plugins, mapping in .vimrc will not help. So, you need to map it manually or some other way. I've used this mapping:

exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=g:UltiSnips_Complete()<cr>"

@bronson
Copy link

bronson commented Jun 20, 2014

@lucapette does that work when YCM pops up a completion box when you're typing inside an ultisnips completion? For example, I type:

def<tab>

And it expands perfectly to

def function_name| *args
  # TODO
end

Great so far. I type 'ta' for the function name, and YCM helpfully pops up a bunch of "table*" completions.

And now I'm stuck.

Hitting tab cycles through YCM's completions instead of moving to the args. Typing anything else cancels the UltiSnips entry. The only way for me to complete the function name is to type something that YCM can't complete, then hit tab, finish, then go back and fix the function name. Takes longer than just not using UltiSnips at all.

Does it work for you?

@jottr
Copy link

jottr commented Jul 1, 2014

@SirVer, @Valloric could I kindly ask you guys to give a definitive answer in your respective docs on how to integrate YCM and Ultisnips?
Most people, judging from the length of this thread, would love to get them both work together and share the <Tab>-Trigger.
I've tried remapping Ultisnips to <c-somekey> just to discover that most key combinations in insert mode are used by other plugins/functions, I guess I won't be the only one with that issue. The space of available key combos in insert mode is tight and precious as it is already. Having two plugins, which could conveniently share the <Tab>-key use a different mapping seems to be an awful waste.
Both your plugins are an awesome addition to our toolbox, getting them to integrate nicely would be even awesomer.

@SirVer
Copy link

SirVer commented Jul 1, 2014

The definite answer to use TAB is here: http://stackoverflow.com/a/18685821/200945

PHAT disclaimer though: overloading one key to do more than one function in Vim will come back to bite you because there will always be situations where there is ambiguity: do I want to complete this word or rather expand this as a trigger?

I have bug reports like once per month of people who map TAB to expand and jump forward and complain when UltiSnips can't read their mind what they actually want to do in a certain situation.

@bronson
Copy link

bronson commented Jul 1, 2014

I like that the StackOverflow answer was taken from higher up this thread.

In my experience, the definitive answer is: tell one of them not to use tab. Someone needs to fix all the corner cases before they can both use tab together.

It's a shame... that would be so cool.

@SirVer
Copy link

SirVer commented Jul 2, 2014

I like that the StackOverflow answer was taken from higher up this thread.

I was told the SO answer is only based on the one further up, but the one on SO is fully copy & pastable and therefore 'better'. I have not verified this.

It's a shame... that would be so cool.

You are complaining about the wrong thing. The SO answer solves all technical issues as far as I know, so it is precisely what was asked for. It does not (and in fact can never) solve the semantic overloading issue:

Using it, if you hit tab, completion will happen if possible, otherwise UltiSnips gets its chance. It happens though that you want UltiSnips to act and not insert a completion. The tools cannot know when you want to do the one or the other - only you can. But if you put two different functions on one key, sometimes the wrong thing will happen. So just do not do it.

@bronson
Copy link

bronson commented Jul 2, 2014

I don't mean to complain. Just speculating that it would be nice if tab would do the visible YCM completion and, if that's not applicable, do an UltiSnips JumpForward.

I realize that's an irritating integration problem, though, and probably not worth the effort.

@SirVer
Copy link

SirVer commented Jul 2, 2014

Just speculating that it would be nice if tab would do the visible YCM completion and, if that's not applicable, do an UltiSnips JumpForward.

that is what the snippet posted on SO does. Just use it.

@bronson
Copy link

bronson commented Jul 2, 2014

I did. Like I said, UltiSnips gets stuck when YCM has completions. The "if that's not applicable" logic doesn't exist today.

@cocodrino
Copy link

guys I try the @kirk1h but seems doesnt works for me, I can't expand the snippet,

would be an option than if you highlight the snippet and press enter it expands...I don't know you but I will be happy with it :D ...I understand the @bronson point but an alternative would be close the suggestion with Esc and then press tab, if there are not suggestion then jumpforward , personally I don't like need press Esc for exit of YCM but I prefer it over other alternatives, I dont have many Ctrl keys free just now...

I suppose than pumvisible() would do the trick but my understand of vim script is pretty basic, let me know if it's possible and if a vim hero can write it...

@zfedoran
Copy link

I had to make a few additions to get the script posted above working with the Enter key as the trigger. Posting it here in case someone else also has the same thing in mind.

(note: I haven't yet had time to test this thoroughly)

let g:UltiSnipsExpandTrigger       ="<c-tab>"
let g:UltiSnipsJumpForwardTrigger  = "<tab>"
let g:UltiSnipsJumpBackwardTrigger = "<s-tab>"

" Enable tabbing through list of results
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 InsertEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=g:UltiSnips_Complete()<cr>"

" Expand snippet or return
let g:ulti_expand_res = 0
function! Ulti_ExpandOrEnter()
    call UltiSnips#ExpandSnippet()
    if g:ulti_expand_res
        return ''
    else
        return "\<return>"
endfunction

" Set <space> as primary trigger
inoremap <return> <C-R>=Ulti_ExpandOrEnter()<CR>

@consen
Copy link

consen commented Nov 16, 2014

It’s better to make YCM not use Tab key, I just put these settings in my vimrc:

let g:ycm_key_list_select_completion=['<C-n>', '<Down>']
let g:ycm_key_list_previous_completion=['<C-p>', '<Up>']

let g:UltiSnipsExpandTrigger="<Tab>"
let g:UltiSnipsJumpForwardTrigger="<Tab>"                                           
let g:UltiSnipsJumpBackwardTrigger="<S-Tab>"

Then I use Ctrl-n to select completion and Tab to trigger snippet, it works well.

@fabianhjr
Copy link

@consen thanks for the suggestion. Works like a charm over here. +1

wincent added a commit to wincent/wincent that referenced this issue Jun 11, 2015
So, I'm using YouCompleteMe everywhere now, not just on my Mac, so I am
expecting to be doing a lot more autocompletion from here on. Time to
fix some long-held grievances I have with the way autocompletion is
working with UltiSnips, YouCompleteMe and Supertab.

Here's an example scenario.

I have a snippet `log` that expands to `console.log();`, with a
placeholder inside the parens. Now, say I have a file with:

   var fooBar = 1;

and I type:

    log<tab>

UltiSnips puts me here:

    console.log(|);
                ^
                (cursor here)

If I then type:

    console.log(fooB<tab>);

I wind up here:

    console.log(fooB);|
                      ^
                      (cursor here)

When what I really want is:

    console.log(fooBar|);
                      ^
                      (cursor here)

ie. if Supertab _can_ complete something, I want it to, otherwise I want
UltiSnips to get the tab.

With YouCompleteMe in the picture, the experience is even worse, because
you'll see the pop-up as soon as you start typing "fooB". Reflexively,
you'd think you could push `<Tab>` to expand the suggestion, but you
can't; you have to remember to push `<C-j>` or `<C-n>` or `<Down>` (ugh)
instead.

Historically, the way I've gotten YouCompleteMe and UltiSnips to play
nicely is as described here:

    http://0x3f.org/blog/make-youcompleteme-ultisnips-compatible/

Effectively:

- Override YouCompleteMe's default bindings, freeing up `<Tab>` and
  `<S-Tab>`; set a new completion binding like `<C-j>` or something
- Install Supertab and tell it to use the completion binding that you
  just set up (in other words, pressing `<Tab>` will get "forwarded" to
  the `<C-j>` or other binding that you set up for YouCompleteMe)
- Tell UltiSnips to use `<Tab>` and `<S-Tab>` to do its thing

So, this works pretty darn well, except for the awkwardness described
above. In this commit, we make things better with a trick similar to the
one described here:

  ycm-core/YouCompleteMe#36 (comment)
  [via http://stackoverflow.com/questions/14896327/ultisnips-and-youcompleteme]

Specifically:

- Get rid of Supertab
- Make a custom function that does the following when `<Tab>` is pressed
  (note, the precedence here is different than in the linked examples):
  - Try to expand a snippet
  - If that doesn't work, try to cycle through completion options (if
    the YouCompleteMe popup is visible) and otherwise try to jump to the
    next UltiSnips placeholder
  - If none of this works, just do a normal tab
- Set up mappings for `<Tab>` and `<S-Tab>` that call this custom
  function; note that these have to happen inside an autocommand in
  order to overwrite the late-mapped default shortcuts set by
  YouCompleteMe (although, as I write this, I think that may not be true
  any more because I can select non-clashing mappings)
- Get rid of `g:UltiSnipsJumpBackwardTrigger` so that it doesn't
  overwrite our `<S-Tab>` mapping
- Set up `<CR>` to accept completion; this gives us an easy way to break
  out of an endless cycle when choosing YouCompleteMe completions inside
  an  UltiSnips placeholder

Some TODOs noted inline, but this basically works. It basically means:

- `<Tab>` to cycle completions, `<S-Tab>` in reverse
- `<Tab>` to expand snippets
- `<Tab>` to jump between placeholders (for now `<S-Tab>` doesn't work
  here, although I think I could make it do so; `<C-k> does work)
- `<Enter>` to get out of completion mode (as noted inline, may need to
  tap twice; not sure why, as the same happens with `<C-y>`)

This last behavior is a slight deviation from how Vim normally handles
autocomplete mappings (see `:h ins-completion-menu`). Basically, it
sometimes inserts newlines when you hit `<Enter>` during completion. I
find this annoying far more often than not, so I am happy to drop this
behavior in the name of progress.
@wladston
Copy link
Contributor

I tested almost everyone's settings, @zfedoran's was the only one that correctly overloaded the tab key and let me select a snippet with the key. Thanks :) 👍

@maonx
Copy link

maonx commented Aug 12, 2015

I set ctrl-j to trigger snippet and tab to seletc completion,it works well

@tu-nv
Copy link

tu-nv commented Oct 27, 2015

I also like @zfedoran setting, this is the closest to modern-like IDE or sublime text/atom behavior. However, it should be perfect if Tab key go through the popup without completing item. This complete action should be done only when we Enter key is pressed.

@vheon
Copy link
Contributor

vheon commented Oct 27, 2015

However, it should be perfect if Tab key go through the popup without completing item.

I'm really curious to ask: why?

@colinwjd
Copy link

Just change default key binding for ultisnips:
let g:UltiSnipsExpandTrigger="<c-j>"
It works well for me.

@sadid
Copy link

sadid commented Dec 28, 2015

This is mine, I can use Tab for switching between item, C-Space for insert the snippet and just switch between ycm suggestion and press space as type...

" YCM-UltiSnip-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="<c-Space>"
let g:UltiSnipsJumpForwardTrigger = "<tab>" " you can use <c-j>
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
" UltiSnip
" ---------
let g:UltiSnipsEditSplit="vertical"
let g:UltiSnipsSnippetDirectories=['MyUltiSnips']
let g:UltiSnipsListSnippets="<c-l>"
" YCM
" ------
let g:ycm_complete_in_comments = 1
let g:ycm_seed_identifiers_with_syntax = 1
let g:ycm_collect_identifiers_from_comments_and_strings = 1

@agauniyal
Copy link

There's another answer which solves pretty much all use cases:

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

@josefson
Copy link

josefson commented May 31, 2016

Suppose the scenario bellow:

def function(args): #function and ages are stop places to Ultisnips
    pass            #pass is a stop place for Ultisnips

If i get to the args place and try some youcompleteme completion, i lose the ability to jump within Ultisnips, meaning i can not go back to function nor forward to pass. This is not a pain for a little structure like this, but for a large structured snippet this is sad. I kind of tried lots of configurations i found here, none solve this issue for me. Is it like this for someone else?

@puremourning
Copy link
Member

I have a ultisnips hack which I think fixes this. It is because of the preview option in completeopt. Try removing preview from completeopt and unsettling ycm_add_preview_to_conpleteopt (see README for details). If that fixes it then it is what I experienced. My hack removes this option while within the ultisnips snippet and returns after.

On 31 May 2016, at 15:57, josefson notifications@github.com wrote:

Suppose the scenario bellow:
'''
def function(args): #function and ages are stop places to Ultisnips
pass #pass is a stop place for Ultisnips
'''
If i get to the args place and try some youcompleteme completion, i lose my Ultisnips jumps, i can not go back to function nor forward to pass. This is not a pain for a little structure like this, but for a large structured snippet this is sad. I kind of tried lots of configurations i found here, none solve this issue for me. Is it like this for someone else?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@josefson
Copy link

josefson commented Jun 1, 2016

@puremourning Yeah, :set completopt-=preview did the trick. However i lost the ability to see function/methods arguments through the preview window.
I managed to get the arguments kind of working with jedi-vim#show_call_signatures function, but i would still prefer the preview window for most cases. Is it to impolite to ask for your hack around it?

@roachsinai
Copy link

@agauniyal Thanks a lot!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests