คำตอบ:
ความสมบูรณ์ของพจนานุกรมจะเป็นวิธีแก้ปัญหาราคาถูกและไม่ล่วงล้ำ:
บันทึกfontawesome.txt ที่ใดที่หนึ่งบนเครื่องของคุณ
ใส่สิ่งนี้ในafter/ftplugin/css.vim
(สร้างไฟล์หากไม่มี):
setlocal complete+=k
setlocal dictionary+=/path/to/fontawesome.txt
setlocal iskeyword+=-
เริ่มเซสชันใหม่หรือทำ:e
ในบัฟเฟอร์ CSS เพื่อบีบอัดไฟล์ด้านบน
กด<C-n>
หรือ<C-p>
ในโหมดแทรก
สนุก!
อ้างอิง:
:help ins-completion
:help 'complete'
:help 'dictionary'
:help 'iskeyword'
แก้ไขขอบคุณความคิดเห็นของ romainl ฉันได้แก้ไขคำตอบของฉันเพื่อแสดงวิธีการสร้างฟังก์ชั่นความสมบูรณ์ที่ผู้ใช้กำหนด ในรุ่นก่อนหน้าฉันกำลังเอาชนะ buil-in omni-completion ซึ่งไม่ดีเพราะผู้ใช้จะหลวมความสมบูรณ์เริ่มต้นซึ่งมีประสิทธิภาพมาก
โซลูชัน vimscript
ทางออกหนึ่งคือการใช้ vimscript และความจริงที่ว่า vim ให้คุณสร้างฟังก์ชั่นการเติมเต็มแบบกำหนดเอง
ข้อดีของการแก้ปัญหานี้คือคุณไม่ต้องใช้ปลั๊กอินเพิ่มเติมคุณสามารถสร้างฟังก์ชั่นความสมบูรณ์ที่ผู้ใช้กำหนดและใช้คุณสมบัติความสมบูรณ์แบบในตัว
ฉันจะใช้ตัวอย่างของคลาส fontAwesome ในcss
ไฟล์:
สร้างไฟล์~/.vim/autoload/csscomplete.vim
และวางบรรทัดต่อไปนี้ลงไป:
let s:matches=".fa-lg .fa-2x .fa-3x .fa-4x .fa-5x .fa-fw .fa-ul .fa-ul .fa-li .fa-li.fa-lg .fa-border .fa-pull-left .fa-pull-right .fa.fa-pull-left"
function! csscomplete#CompleteFA(findstart, base)
if a:findstart
" locate the start of the word
let line = getline('.')
let start = col('.') - 1
while start > 0 && (line[start - 1] =~ '\a' || line[start - 1] =~ '.' || line[start - 1] =~ '-')
let start -= 1
endwhile
return start
else
" find classes matching "a:base"
let res = []
for m in split(s:matches)
if m =~ '^' . a:base
call add(res, m)
endif
endfor
return res
endif
endfun
จากนั้นสร้างไฟล์~/.vim/after/ftplugin/css.vim
และวางไว้ในบรรทัดต่อไปนี้:
setlocal completefunc=csscomplete#CompleteFA
<C-x><C-u>
จากนั้นคุณสามารถเรียกฟังก์ชั่นเสร็จสิ้นการที่ผู้ใช้กำหนดของคุณด้วย มันจะพยายามหาคำที่ตรงกับคำที่พิมพ์ล่าสุด
ในภาพหน้าจอฉันพิมพ์.fa-l
แล้วเรียกใช้ฟังก์ชันด้วย<C-x><C-u>
:
มันทำงานยังไง?
ก่อนอื่นนี่คือหัวข้อเอกสารที่เกี่ยวข้อง:
ตอบที่ดีเกี่ยวกับองค์กรของไฟล์
หากคุณต้องการที่จะสร้างเสร็จที่กำหนดเองสำหรับ filetype $HOME/.vim/autoload/{FILETYPE}complete.vim
โดยเฉพาะอย่างยิ่งที่คุณต้องใส่ไว้ในไฟล์
จากนั้นในไฟล์นี้คุณต้องสร้างฟังก์ชั่นความสมบูรณ์ซึ่งเรียกว่าสองครั้ง
ในการโทรครั้งแรกอาร์กิวเมนต์แรกคือตำแหน่งปัจจุบันของเคอร์เซอร์และฟังก์ชั่นจะกำหนดคำให้เสร็จสมบูรณ์ ในฟังก์ชั่นของฉันฉันใช้การเปรียบเทียบ 3 แบบเพื่อทำให้คำศัพท์เสร็จสมบูรณ์เพราะชั้นเรียนสามารถประกอบด้วยตัวอักษร.
และ-
(ฉันคิดว่ามันเป็นไปได้ที่จะปรับปรุงการจับคู่นี้ แต่ฉันแย่มากกับ regex)
บนสายที่สองอาร์กิวเมนต์ที่สองคือคำให้ตรงแล้วฟังก์ชั่นเปรียบเทียบกับรายการของคลาสที่เป็นไปได้เพื่อให้ตรงกับ1 ที่นี่คุณจะเห็นว่าฉันกลับพจนานุกรมซึ่งจะเติมเมนูเสร็จสมบูรณ์แต่เมื่อคุณอ่านเอกสารคุณจะเห็นว่าคุณสามารถสร้างพจนานุกรมที่ซับซ้อนมากขึ้นเพื่อปรับแต่งการทำงานของฟังก์ชันของคุณ
คุณต้องบอกให้ Vim "สำหรับไฟล์ประเภทนี้ใช้ฟังก์ชั่นที่สมบูรณ์ที่ฉันสร้างขึ้นนี้" ต้องการทำเช่นนั้นคุณจะต้องตั้งcompletefunc
ชื่อฟังก์ชั่นที่คุณสร้างขึ้น (ที่นี่csscomplete#CompleteFA
) $HOME/.vim/after/ftplugin/{FILETYPE}.vim
และการตั้งค่านี้จะต้องทำในแฟ้ม
1ในฟังก์ชั่นของฉันตัวแปรs:matches
มีการแข่งขันที่เป็นไปได้ทั้งหมด ที่นี่ฉันใส่คำแนะนำสำหรับการอ่านเท่านั้น แต่คุณสามารถใส่คลาสทั้งหมดที่เสนอโดย FontAwesome (คุณสามารถค้นหารายการทั้งหมดในไฟล์นี้สร้างโดย romainl)
ถ้าฉันไม่ชอบ Vimscript ล่ะ?
ความเป็นไปได้อย่างหนึ่งคือการใช้ปลั๊กอินYoucompleteMeซึ่งให้บริการ API เพื่อเล่นกับเมนูเสร็จ คุณสามารถสร้างฟังก์ชั่นหลามซึ่งจะทำงานจับคู่และจะใช้ API เพื่อเติมอินเทอร์เฟซ Vim รายละเอียดเพิ่มเติมที่นี่
บางครั้งคุณต้องการให้การเติมข้อมูลอัตโนมัติที่กำหนดเองนั้นไม่รบกวนการเติมข้อความอัตโนมัติในตัวหรือที่ผู้ใช้กำหนดเอง สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับสคริปต์หรือปลั๊กอินที่ต้องการใช้งานกับไฟล์ประเภทต่างๆ
สามารถทำได้ค่อนข้างง่ายด้วย
complete()
ฟังก์ชั่นและเสื้อคลุมเรียบง่าย ขั้นตอนส่วนใหญ่เหมือนกับที่อธิบายไว้ใน
:help complete-functions
และคำตอบของ Statox ยกเว้นว่าคุณจำเป็นต้องกำหนดการแมปของคุณเองและต้องโทรหาcomplete()
ตัวเองแทนการส่งคืนค่า
นี่เป็นตัวอย่างพื้นฐานความคิดเห็นควรอธิบายวิธีการทำงาน
" Map <C-x><C-m> for our custom completion
inoremap <C-x><C-m> <C-r>=MyComplete()<CR>
" Make subsequent <C-m> presses after <C-x><C-m> go to the next entry (just like
" other <C-x>* mappings)
inoremap <expr> <C-m> pumvisible() ? "\<C-n>" : "\<C-m>"
" Complete function for addresses; we match the name & address
fun! MyComplete()
" The data. In this example it's static, but you could read it from a file,
" get it from a command, etc.
let l:data = [
\ ["Elmo the Elk", "daring@brave.com"],
\ ["Eek the Cat", "doesnthurt@help.com"]
\ ]
" Locate the start of the word and store the text we want to match in l:base
let l:line = getline('.')
let l:start = col('.') - 1
while l:start > 0 && l:line[l:start - 1] =~ '\a'
let l:start -= 1
endwhile
let l:base = l:line[l:start : col('.')-1]
" Record what matches − we pass this to complete() later
let l:res = []
" Find matches
for m in l:data
" Check if it matches what we're trying to complete; in this case we
" want to match against the start of both the first and second list
" entries (i.e. the name and email address)
if l:m[0] !~? '^' . l:base && l:m[1] !~? '^' . l:base
" Doesn't match
continue
endif
" It matches! See :help complete() for the full docs on the key names
" for this dict.
call add(l:res, {
\ 'icase': 1,
\ 'word': l:m[0] . ' <' . l:m[1] . '>, ',
\ 'abbr': l:m[0],
\ 'menu': l:m[1],
\ 'info': len(l:m) > 2 ? join(l:m[2:], "\n") : '',
\ })
endfor
" Now call the complete() function
call complete(l:start + 1, l:res)
return ''
endfun
:help i_ctrl-x_ctrl-u
ดู