UltiSnips และ YouCompleteMe


130

ฉันมีชุด ultisnips และ youcompleteme ที่ติดตั้งบน macvim ของฉัน ปัญหาคือ ultisnips ไม่ทำงานเนื่องจากแท็บถูกผูกด้วย ycm ฉันพยายามใส่let g:UltiSnipsExpandTrigger = "<s-tab>"เพื่อให้สามารถเรียกใช้ข้อมูลโค้ดที่เสร็จสมบูรณ์ด้วย shift-tab ได้ แต่ใช้ไม่ได้ด้วยเหตุผลบางประการ ฉันสามารถใช้ตัวพิมพ์ใหญ่เป็นตัวกระตุ้นได้ แต่จนถึงตอนนี้ฉันไม่พบวิธีที่จะทำเช่นนั้น

คุณมีใครใช้โปรแกรมเสริมสองตัวนี้ร่วมกันหรือไม่? ฉันจะทำอย่างไรเพื่อให้แถบกะทำงานได้ คุณสามารถแนะนำคีย์อื่นเพื่อทริกเกอร์ตัวอย่างได้หรือไม่


YCM ยังทำแผนที่<S-Tab>UltiSnips, IIRC เช่นกัน คุณควรถามผู้เขียนของ YCM ฉันเดา
romainl

ฉันเปลี่ยนคีย์สำหรับการเสร็จสิ้นก่อนหน้านี้บน ycm และลบ s-tab ยังไม่ทำงาน ฉันจะลองส่งข้อความถึงเขาใน github ฉันเดา
pvinis

1
ดูว่าแผนที่ของคุณใช้:verbose map <S-Tab>งานได้หรือไม่ แต่อาจใช้ไม่ได้กับกลุ่มบรรทัดคำสั่ง ทดแทนที่ดีงาม IMO <CR>คือ
Daan Bakker

ขอบคุณที่ฉันกระตือรือร้นที่จะหาวิธีแก้ปัญหาและความจริงที่ว่า YouCompleteMe ไม่มีฟอรัมนั้นน่ารำคาญ ขอบคุณ
atmosx

2
คุณลองอีกครั้งเมื่อเร็ว ๆ นี้หรือไม่? ต้องอัปเดตปลั๊กอินหนึ่งหรือทั้งสองอย่างเนื่องจากเอกสารของ UltiSnips ระบุว่า: "YouCompleteMe - มาพร้อมกับการสนับสนุน UltiSnips แบบสำเร็จรูปโดยนำเสนอบทสนทนาที่สมบูรณ์แบบสำหรับตัวอย่างข้อมูล"
Kyle Strand

คำตอบ:


188

อีกทางเลือกหนึ่งคือการใช้ปลั๊กอิน 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 เข้ากับแท็บได้โดยตรงและทุกอย่างก็จะเป็นจริง


7
คำแนะนำของ Joey Liu ไม่ได้ผลสำหรับฉัน (แท็บจะไม่ขยายอะไรเลยมันจะเลื่อนไปที่ตัวเลือกการเติมข้อความอัตโนมัติถัดไปเท่านั้น) คำตอบนี้ใช้งานได้ดี แต่ฉันต้องอัปเดตและคอมไพล์ YouCompleteMe ใหม่ก่อน
BenjaminGolder

1
ดังที่คนอื่น ๆ กล่าวถึงวิธีการแก้ปัญหาของ Joey Liu ไม่ทำงานอีกต่อไป อันนี้ไม่!
สมอ

3
มีวิธีใดบ้างในการเน้นตัวอย่างข้อมูลในรายการเติมข้อความอัตโนมัติ
syntagma

3
แช่ง! ชาย ! ทำงานอย่างมีเสน่ห์! ทางออกที่ดีที่สุด!
Yves Lange

4
นี่เป็นสิ่งที่ดี แต่การกดปุ่มtabภายในตัวอย่างข้อมูลจะไปที่แท็บถัดไปแทนที่จะทำตามคำแนะนำ YCM ฉันต้องเพิ่มlet g:UltiSnipsJumpForwardTrigger = "<Right>"และlet g:UltiSnipsJumpBackwardTrigger = "<Left>"ทำให้งานนี้
Gabriel Florit

48

ลองใช้คำแนะนำนี้ในหน้าจากเครื่องมือติดตามปัญหา YouCompleteMe ใน. vimrc ของคุณ:

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

แม้ว่าการตั้งค่านี้จะทำให้การขยายข้อมูลโค้ดแชร์การแมปเริ่มต้นสำหรับการกระโดดไปข้างหน้าภายในตัวอย่างข้อมูลแต่จะจำลองพฤติกรรมของ TextMates ตามที่กล่าวไว้ในแท็กวิธีใช้ UltiSnips

เนื่องจากฉันได้แมปปุ่ม Caps Lock กับ Ctrl การทำแผนที่นี้จึงทำงานได้อย่างราบรื่น


1
นี่น่าจะเป็นคำตอบที่ดีที่สุดเรียบง่ายและตรงประเด็นแม้ว่าใน macvim ของฉันบน macOS 10.12 <cj> ใช้งานไม่ได้ฉันเปลี่ยนเป็น <ck> แล้วทุกอย่างก็ใช้ได้ดี <tab> ไปข้างหน้า <s-tab> ย้อนกลับ <ck> ขยายข้อมูลโค้ด ขอบคุณ
gpanda

40

คัดลอกรหัสต่อไปนี้ไปยัง 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>"

27
เครดิตบางส่วนที่ถึงกำหนดฉันคิดว่า: github.com/Valloric/YouCompleteMe/issues/… และ BufEnter autocmd ลงความคิดเห็นเล็กน้อย
ches

3
ดูเหมือนจะไม่ได้ผลสำหรับฉันสำหรับ Mac OS X ณ วันที่ 10 กรกฎาคม 2014 อย่างไรก็ตามคำตอบของ Siegfried ได้ผล
miguel.martin

ดูเหมือนดีมาก! แต่ฉันจะ "แท็บผ่าน" เบรกพอยต์ของข้อมูลโค้ดได้อย่างไร
chmanie

1
ฉันพบว่ามันสะดวกในการผูกg:UltiSnipsJumpForwardTrigger="<cr>"เพื่อให้ฉันยังคงสามารถแท็บผ่านความสำเร็จ / ตัวอย่างที่เป็นไปได้ทั้งหมด
alaroldai

1
สิ่งนี้ช่วยให้ฉันสามารถแท็บผ่าน YCM ที่แสดงรายการเสร็จสมบูรณ์ (รวมถึงคำแนะนำ Ultisnips) แต่บรรทัด inoremap <expr> สุดท้ายดูเหมือนจะไม่ส่งผลกระทบต่อการกดปุ่ม Enter ของฉัน ฉันสามารถเรียกใช้ <Cy> ด้วยตนเองได้ แต่ Enter ไม่ได้ทำอะไรเลย ข้อเสนอแนะใด ๆ ?
HaaR

18

ฉันมีสิ่งนี้ใน vimrc ของฉัน

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

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

นั่นคือสิ่งที่ฉันทำในการลองครั้งแรก แต่ฉันสะกด UltiSnips ด้วย Ultisnips ผิด .. โอ้ได้ผลในที่สุด!


17

ฉันเองเลือกที่จะไม่ใช้<tab>กับ YouCompleteMe แต่นำทางด้วยตนเอง

ดังนั้นฉันจึงเพิ่มสิ่งนี้ใน.vimrc:

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

ซึ่งเพียงแค่ปิดใช้งานtabคีย์สำหรับ YCM แต่คุณใช้แป้นเคลื่อนไหว (ลูกศรหรือCTRL-N/ CTRL-P) CRและเลือกรายการที่มี UltiSnips ใช้งานได้กับtabไฟล์.


5

เพียงรวบรวมคำตอบโดย 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>"

สิ่งนี้มีประโยชน์มากเมื่อพยายามแก้ไขปัญหาเดียวกันกับ COC และ Ultisnips เป็นหลัก ต้องการใช้ <TAB> และ <S-TAB> เพื่อเลื่อนขึ้นและลง PUM รวมทั้งเลื่อนไปมาภายในตัวยึดตำแหน่ง Ultisnips ขอบคุณ
110100100

4

แม้ว่าฉันจะรู้ว่าโพสต์นี้เก่าไปหน่อย แต่ฉันก็มีฟังก์ชันของตัวเองที่ได้รับการปรับให้เหมาะสมกว่าที่ระบุไว้ข้างต้นเล็กน้อย:

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

แน่นอนว่าหากคุณเก็บการตั้งค่าที่ Joey Liu ให้ไว้แล้วใช้ฟังก์ชันนี้ทุกอย่างก็จะทำงานได้อย่างสมบูรณ์แบบ!

แก้ไข: นอกจากนี้ฉันใช้ฟังก์ชันอื่นเพื่อเพิ่มฟังก์ชันการย้อนกลับระหว่าง 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>"และชุดของคุณ!


3

ฉันใช้ทั้งสองอย่างร่วมกัน ตามค่าเริ่มต้น YouCompleteMe จะผูก<Tab>และ<Down>เพื่อเลือกรายการที่เสร็จสมบูรณ์ถัดไป<S-Tab>และ<Up>เพื่อเลือกรายการที่เสร็จสมบูรณ์ก่อนหน้านี้ คุณสามารถเปลี่ยนการผูก YouCompleteMe กับ g: ycm_key_list_select_completionและg: ycm_key_list_previous_completionตัวเลือก โปรดทราบว่าชื่อของตัวเลือกเหล่านี้เพิ่งเปลี่ยนเมื่อตัวเลือกถูกเปลี่ยนจากสตริงเดี่ยวเป็นรายการสตริง


3

ฉันติดตั้งปลั๊กอิน UltiSnips หลังจากปลั๊กอิน YouCompleteMe ดังนั้นฉันจึงคิดว่ามันขัดแย้งกัน แต่ในความเป็นจริงฉันมีบางอย่างที่รบกวนมากกว่านี้:

set paste

อย่าลืมลบออก.vimrcหากมีอยู่


2

ในขณะที่คำตอบจำนวนมากทำงานได้ดีในโพสต์นี้ฉันแค่อยากจะบอกว่าปัญหาเกิดจากการชนกันของการผูกคีย์ระหว่าง YCM และ UltiSnip ในขณะที่ YCM รองรับตัวอย่าง UltiSnip ตามค่าเริ่มต้น แต่จะใช้ทริกเกอร์การขยาย UltiSnip เริ่มต้น<tab>เป็นคีย์การเลือกที่สมบูรณ์ดังนั้น ตัวอย่าง UltiSnip จะไม่ถูก expaned <tab>โดย ให้การผูกคีย์ที่แตกต่างกันจะช่วยแก้ปัญหาได้ฉันใช้เป็นการส่วนตัว<c-nและ<c-p>สำหรับ YCM และใช้ค่าเริ่มต้น<tab>สำหรับ UltiSnip คุณสามารถรับรายละเอียดเพิ่มเติมได้จากhelp youcompletemedoc in vim


2

จากคำตอบของ Siegfried ฉันใช้สิ่งต่อไปนี้ซึ่งดูเป็นธรรมชาติมากกว่า:

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ผูกที่อื่น (เปลี่ยนจากบานหน้าต่างไปเป็นบานหน้าต่างอื่น) แต่จะอยู่ในโหมดปกติเท่านั้นจึงไม่มีปัญหา


1

ฉันใช้;เพื่อขยาย UltiSnips มันดีมากสำหรับฉัน

let g:UltiSnipsExpandTrigger = ";"

แก้ไข: ตอนนี้ฉันใช้\เพราะฉันพบว่าฉันไม่สามารถพิมพ์;ในโหมดแทรกของ Vim ได้
Ruto Collins

0

ฉันใช้kj. นี่คือสิ่งที่อยู่ใน.vimrc:

let g:UltisnipsExpandTrigger="kj".

แทบจะไม่เกิดขึ้นเลยที่ฉันเจอคำที่มีkjอยู่ในนั้น หากเป็นกรณีนี้ฉันจะรอสองสามวินาทีหลังจากพิมพ์kและพิมพ์jนั้น


0

ดังที่ผู้อื่นกล่าวไว้การแมป Cj กับ ultisnips นั้นใช้งานได้ดี
let g:UltiSnipsExpandTrigger="<c-j>"

ตอนนี้ถ้าคุณไปไกลกว่านี้และติดตั้ง xcape และใช้
xcape -e "Shift_L=Control_R|J"

คุณปลดปล่อยพลังของการใช้เพียงปุ่ม shift สำหรับ utlitsnips

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.