ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.46k stars 2.81k forks source link

SnipMate/UltiSnips integration #36

Closed kballenegger closed 11 years ago

kballenegger commented 11 years ago

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.

fatih commented 11 years ago

I have the same problem. I definetly see the snippets:

ultisnip

But what should I do select them? They do not expand. I select multiple times with via tab and also try to select with enter but it doesn't expand. (sidenote: file completer works fine via / and ./)

fatih commented 11 years ago

Ok because there seems no single source I've just packed them togheter.

  1. Install YCM
  2. Install UltiSnips

After that it just works, but the keys are kinda different. If you want to expand with tab and jump forward with tab you have to add these additional to your vimrc.

3 . Add function from @JazzCore:

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

4 . Create a automatic BufEnter for the function above:

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

5 . Finally define the tab key for expansion:

let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<tab>"

It seems to work very nicely. I just want to sure if all three steps are necessary? Thanks for this great work.

JazzCore commented 11 years ago

@gbataille there is a typo in your config. You have:

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

Should be:

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

Note the space before <C-R>, its important

JazzCore commented 11 years ago

@fatih, you need only g:UltiSnipsJumpForwardTrigger="<tab>", g:UltiSnipsExpandTrigger is set to Tab by default

gbataille commented 11 years ago

@JazzCore thanks. I can see now how it was wrong, but it still does not work though :(

I changed it and created a new gist https://gist.github.com/gbataille/5549590

JazzCore commented 11 years ago

@gbataille you are using VERY outdated version of UltiSnips. You should use upstream version. Change Bundle 'vim-scripts/UltiSnips' to Bundle 'SirVer/ultisnips', update and check if it will fix it. By update i mean remove a ultisnips dir from bundle folder and run BundleInstall again

fatih commented 11 years ago

@JazzCore thanks a lot. Just merged them into https://github.com/fatih/subvim. Awesome Work!

JazzCore commented 11 years ago

@fatih dont forget about an issue about this function: https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-15722669. This can be a stopper for some people. I have a fix for this planned but this will be a ultisnips patch, not YCM.

gbataille commented 11 years ago

this is getting frustrating... thanks @JazzCore. I did not know indeed which repo to use when I found several. still. Does not work :( just in case, I have uploaded a new Gist https://gist.github.com/gbataille/5549742

trying a few things, I tried to comment all the other plugins but to no effect.

would you have an idea how I could debug the situation maybe? I'm quite lost as to how to investigate this.

thanks

JazzCore commented 11 years ago

Keep in mind that you set autocmd on BufEnter. So the key will be remapped only when you switch buffer or open new file, not directly after vim startup. Have you switched buffers? If this still does not work, print output of :verbose imap <tab> ( after buffer switch ) and :py print UltiSnips_Manager.

Otherwise, your .vimrc works fine for me.

gbataille commented 11 years ago

come on :) I use to test it properly at the beginning, but to save time, I started to open vim with a file directly! ok so it works now.

thanks for the support

On Thu, May 9, 2013 at 9:18 PM, Stanislav notifications@github.com wrote:

Keep in mind that you set autocmd on BufEnter. So the key will be remapped only when you switch buffer or open new file, not directly after vim startup. Have you switched buffers? If this still does not work, print output of :verbose imap ( after buffer switch ) and :py print UltiSnips_Manager

— Reply to this email directly or view it on GitHubhttps://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-17683961 .

jcostello commented 11 years ago

I tried to snip a "def" but when i was typing the name of the function, it fires another snip, so I change de order of the g:UltiSnips_Complete function to try first a jump forwards intead of a expand. Enjoy

    function! g:UltiSnips_Complete()
      call UltiSnips_JumpForwards()
      if g:ulti_jump_forwards_res == 0
        call UltiSnips_ExpandSnippet()
        if g:ulti_expand_res == 0
          if pumvisible()
            return "\<C-n>"
          else
            return "\<TAB>"
          endif
        endif
      endif
      return ""
    endfunction
fatih commented 11 years ago

@JazzCore I'm using this thing in vimrc

" Stop completion with enter, in addition to default ctrl+y
imap <expr> <CR> pumvisible() ? "\<c-y>" : "<Plug>delimitMateCR"

You can stop an auto completion via ctrl+y. This will map it to enter + will not break delimitMate. Therefore it just works like charm.

zx9597446 commented 11 years ago

hi, there, I still can't get YCM working with Ultisnippets, I use gvim on windows, YCM can list snips, but can't expand it. I tried two ways: -------------------------A------------------------- let g:UltiSnipsExpandTrigger="" let g:UltiSnipsJumpForwardTrigger="" let g:UltiSnipsJumpBackwardTrigger="" ------------------------A--------------------------

------------------------B----------------------------- function! g:UltiSnips_Complete() call UltiSnips_ExpandSnippet() if g:ulti_expand_res == 0 if pumvisible() return "" else call UltiSnips_JumpForwards() if g:ulti_jump_forwards_res == 0 return "" endif endif endif return "" endfunction

BufEnter * exec "inoremap " . g:UltiSnipsExpandTrigger . " =g:UltiSnips_Complete()"

let g:UltiSnipsExpandTrigger="" let g:UltiSnipsJumpForwardTrigger="" ---------------------------B------------------------------ none of these work, I'm using most recently YCM and Ultisnippets.

here's my _vimrc:

filetype off filetype plugin indent off set runtimepath+=$GOROOT/misc/vim filetype plugin indent on syntax on

filetype off " required! set rtp+=~/vimfiles/bundle/vundle/ call vundle#rc()

" let Vundle manage Vundle " required! Bundle 'gmarik/vundle'

" My Bundles here: Bundle 'Valloric/YouCompleteMe' Bundle 'SirVer/ultisnips'
Bundle 'kien/ctrlp.vim' Bundle 'scrooloose/syntastic' filetype plugin indent on " required!

source $VIM_vimrc

set number set tabstop=4 set shiftwidth=4 set backupdir=$TMP set noswapfile set cmdheight=3

set guifont=Courier_New:h12:cANSI set guioptions-=T set ic set nowrapscan set cursorline set autochdir

map :cn

map :NERDTreeToggle map :silent !ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . map :silent !start cmd.exe . map :simalt ~x

set tags+=tags;

autocmd BufEnter .bat map :!cmd /c % autocmd BufEnter .js map :!cscript % autocmd BufEnter .lua map :!lua % autocmd BufEnter .vbs map :!cscript % autocmd BufEnter .html map :!cmd /c % autocmd BufEnter .htm map :!cmd /c % autocmd BufEnter .py map :!python % autocmd BufEnter .orbit.lua map :!orbit -p80 %

" Automatically open, but do not go to (if there are errors) the quickfix / " location list window, or close it when is has become empty. " " Note: Must allow nesting of autocmds to enable any customizations for quickfix " buffers. " Note: Normally, :cwindow jumps to the quickfix window if the command opens it " (but not if it's already open). However, as part of the autocmd, this doesn't " seem to happen. "autocmd QuickFixCmdPost [^l]* nested cwindow "autocmd QuickFixCmdPost l* nested lwindow

autocmd BufEnter .go set makeprg=go\ build autocmd BufEnter .go map :!go run % autocmd BufEnter .go map :make autocmd BufEnter .go set tags+=$GOROOT/tags,$GOPATH/tags autocmd BufEnter *.go map :!ctags --extra=+q -f \%GOPATH\%\tags -R \%GOPATH\%

autocmd BufWritePre *.go :silent Fmt

color Vc set autoread

set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1

let g:UltiSnipsExpandTrigger="" let g:UltiSnipsJumpForwardTrigger="" let g:UltiSnipsJumpBackwardTrigger=""

let g:syntastic_auto_jump=1

map zz :w

by use this _vimrc, even can't expand snips

chtenb commented 11 years ago

@zx9597446 Just like suggested earlier in this issue, having ycm and ultisnips installed properly, the following lines in your .vimrc should do the trick:

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

No idea if this is what you want, but it is a sane mapping and it works. It says also in the FAQ that you'll have to change the UltiSnips mappings. https://github.com/Valloric/YouCompleteMe#ycm-conflicts-with-ultisnips-tab-key-usage

avoine commented 10 years ago

I found that using the supertab plugin is also working:

http://stackoverflow.com/a/22253548

elmart commented 10 years ago

Hi,

I just wanted to know which is the current status of this: @fatih Is your summary (https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-17680963) current / still the last word on this? @JazzCore What about the UltiSnips patch you mentioned at https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-17683047 ? Still consider doing it? Done? @Valloric What about adding @JazzCore 's snippet to YCM you mentioned at https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-16875520 ? Still consider doing it? Done?

Thanks, guys. Great work.

elmart commented 10 years ago

Ok, I leave here the results of my own investigation:

https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-17680963 is no more current. Two reasons:

So, summing up:

meonkeys commented 10 years ago

Bummer, still broken. I tried today with the latest YouCompleteMe and UltiSnips. @Chiel92's workaround (using different keys for UltiSnips) worked for me.

Whoops! This is expected behavior, see the FAQ (search for "YCM conflicts with UltiSnips TAB key usage". Sorry for the noise.

lynndylanhurley commented 10 years ago

I'm having the same issue as @elmart. The snippet from this comment was working for me: https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-17680963

I ran an update this morning, and UltiSnips started complaining about deprecated method names.

I tried renaming the broken methods to this:

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

This silenced the errors, but now I don't get snippet expansion. Has anyone been able to solve this?

lucapette commented 10 years ago

@lynndylanhurley this works for me:

let g:UltiSnipsExpandTrigger       = "<tab>"
let g:UltiSnipsJumpForwardTrigger  = "<tab>"
let g:UltiSnipsJumpBackwardTrigger = "<s-tab>"
let g:UltiSnipsSnippetDirectories  = ["snips"]

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

I'm using InsertEnter instead of BufEnter as suggested a few comments before since having switch buffer before getting the correct mapping is a bit annoying. I think it would be great to have the integration built-in. It's not ideal that such a good plugin doesn't play nicely with other famous plugins out of the box.

arnojernej commented 10 years ago

i have added emmet to the script. it only expands emmet snippets starting with a . or # works fine for me.

function! g:smart_tab()
  if (matchstr(getline("."), '^\s*#') != "") || (matchstr(getline("."), '^\s*\.') != "")
    call emmet#expandAbbr(3, "")
    return "\<esc>cit\<cr>\<esc>O"
  else
    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 ""
  endif
endfunction
let g:UltiSnipsJumpForwardTrigger="<tab>"
autocmd BufEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=g:smart_tab()<cr>"
lynndylanhurley commented 10 years ago

@lucapette - that's working for me, thx :D

bronson commented 10 years ago

@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 commented 10 years ago

@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 commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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

cocodrino commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

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 commented 9 years ago

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

wladston commented 9 years ago

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 :) :+1:

maonx commented 9 years ago

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

tu-nv commented 9 years ago

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 commented 9 years ago

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

I'm really curious to ask: why?

colinwjd commented 8 years ago

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

sadid commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

@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 commented 5 years ago

@agauniyal Thanks a lot!