-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Comments
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! |
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. |
Ditto, see how Xcode does it. It's really nice, your snippets are offered as autocompletion, it's super neat. |
+1 (ultisnips) "snippets offered as autocompletion" is something I didn't imagine, it could be awesome. |
Although, binding |
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. |
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 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. |
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. |
Wow, how often does a maintainer remain open-minded after dismissing an issue. Loving YCM and now @Valloric too. Respect. |
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. |
@Townk I didn't know UltiSnips provided such an API. I'll be using it then. |
This is the active clone of snipmate which is used quite a lot: https://github.com/garbas/vim-snipmate |
@sotte From the top of the README in that branch:
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:
I think this means that SnipMate is dead, or very close to it. |
@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! |
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.. |
In your vimrc you have to :set macmeta for the options key to work correctly. |
Can someone give me their config with working keybindings? Can't get UltiSnips to work in terminal. |
Mapping UltiSnips to ctrl-j/k works fine for me.
See That said I like the idea of it being more integrated with YCM. |
Thanks @bmedicke, works like a charm |
👍 |
+1 for UltiSnips. It is awesome! |
+1 |
1 similar comment
👍 |
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. |
In the meantime you should mention the |
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>" |
@lucapette does that work when YCM pops up a completion box when you're typing inside an ultisnips completion? For example, I type:
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? |
@SirVer, @Valloric could I kindly ask you guys to give a definitive answer in your respective docs on how to integrate YCM and Ultisnips? |
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. |
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. |
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.
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. |
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. |
that is what the snippet posted on SO does. Just use it. |
I did. Like I said, UltiSnips gets stuck when YCM has completions. The "if that's not applicable" logic doesn't exist today. |
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... |
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> |
It’s better to make YCM not use 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 |
@consen thanks for the suggestion. Works like a charm over here. +1 |
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.
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 :) 👍 |
I set |
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. |
I'm really curious to ask: why? |
Just change default key binding for ultisnips: |
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 |
There's another answer which solves pretty much all use cases:
|
Suppose the scenario bellow:
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? |
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.
|
@puremourning Yeah, :set completopt-=preview did the trick. However i lost the ability to see function/methods arguments through the preview window. |
Discussion of ultisnips and YCM: ycm-core/YouCompleteMe#36 (comment)
@agauniyal Thanks a lot! |
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.
The text was updated successfully, but these errors were encountered: