UltiSnips 和 YouCompleteMe

我有很多剪刀,你把我安装在我的 Macvim 上。 问题是 ultisnips 不起作用,因为 tab 是由 ycm 绑定的。 我尝试放置 let g:UltiSnipsExpandTrigger = "<s-tab>",以便能够用 shift-tab 触发代码片段完成,但是由于某些未知的原因它无法工作。我可以用大写字母作为触发器,但目前为止我还没有找到办法。

你们有人一起使用这两个附加组件吗? 我该怎么做才能让 shift-tab 工作呢? 您能推荐另一个触发代码段的键吗?

63808 次浏览

我把它们一起使用。默认情况下,YouCompleteMe 绑定 <Tab><Down>以选择下一个完成项,还绑定 <S-Tab><Up>以选择上一个完成项。可以使用 G: ycm _ key _ list _ select _ completeG: ycm _ key _ list _ before _ complete选项更改 YouCompleteMe 绑定。请注意,当选项从单个字符串更改为字符串列表时,这些选项的名称最近发生了更改。

我的 Vimrc 里有这个

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


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

我第一次就是这么做的,但是我把 UltiSnips 和 UltiSnips 拼错了。.哦,好吧,最后解决了!

在 YouCompleteMe 问题跟踪器的 呼叫上试试这个建议:

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

虽然此设置将扩展代码片段 共享代码段内跳转的默认映射,但它模拟了 UltiSnips 帮助标记中提到的 TextMates 的行为。

因为我已经将大写锁定键映射到 Ctrl,所以这个映射工作得非常顺利。

复制以下代码到你的 vimrc,并享受。此功能将处理 YCM 和 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>"

虽然我知道这篇文章有点老,但我有自己的功能,比上面给出的功能更优化一些:

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

当然,如果你只是保持设置,乔伊刘提供,然后只是使用这个功能,一切都将工作得非常完美!

编辑: 此外,我还使用了另一个函数来增加 YouCompleteMe 和 UltiSnips 之间的后退功能:

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


return ""
endfunction

然后把这个放到你的.vimrc:

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

以及 let g:UltiSnipsJumpBackwardTrigger="<s-tab>"和您的设置!

另一个选择是使用 SuperTab 插件:

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

在这里,YouCompleteMe 绑定到一个不同的组合 Ctrln,但是这个组合必须通过 SuperTab 选项卡。UltiSnips 和 SuperTab 可以很好地结合在一起,所以你可以直接将 UltiSnips 绑定到 Tab 上,然后一切就都解决了。

我个人选择不在 YouCompleteMe 中使用 <tab>,而是手动导航它。

所以我把这个加到了我的 .vimrc里:

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

它只是禁用了 YCM 的 tab键。相反,您使用移动键(箭头或 CTRL-N/CTRL-P) ,并选择与 CR条目。UltiSnips 默认使用 tab

虽然这篇文章中的许多答案都很好用,但我只想说问题是由于 YCM 和 UltiSnip 之间的键绑定冲突造成的,而 YCM 默认支持 UltiSnip 片段,它使用默认的 UltiSnip 展开触发器 <tab>作为完成选择键,所以 UltiSnip 片段不会被 <tab>展开。给他们不同的密钥绑定将解决这个问题,我个人对 YCM 使用 <c-n<c-p>,对 UltiSnip 使用默认的 <tab>。你可以得到更多的细节与 help youcompleteme文档在 vim。

基于齐格弗里德的回答,我使用了下列看起来更自然的答案:

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

我还在其他地方使用 c-hjkl绑定(从一个窗格切换到另一个窗格) ,但这只是在普通模式下,所以没有问题。

只是把 Michaelslec,Joey Liu 的答案和我在 这个问题的线索这家伙是 Vimrc中找到的解决方案放在一起,我现在有了这个,它解决了几乎所有的问题。

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

我在 YouCompleteMe 插件之后安装了 UltiSnips 插件,所以我认为它们之间存在冲突,但实际上我有更多的干扰:

set paste

确保从 .vimrc删除,如果它的存在。

我使用的是 kj。这是我的 .vimrc中的内容:

let g:UltisnipsExpandTrigger="kj".

我很少遇到有 kj的单词。如果是这种情况,我只需要在输入 kj后等待几秒钟。

正如其他人所提到的,将 C-j 映射到 ultisnips 非常有效。
let g:UltiSnipsExpandTrigger="<c-j>"

现在,如果您进一步安装 xcape 并使用
xcape -e "Shift_L=Control_R|J"

您可以释放仅使用 shift 键进行 utlitnips 的能力。

我使用 ;来扩展 UltiSnips,它对我来说太漂亮了

let g:UltiSnipsExpandTrigger = ";"