Belirli dosya türleri için kendi otomatik tamamlama listemi nasıl oluştururum?
Örneğin, FontAwesome css sınıfları listesinden otomatik tamamlama css ve html istiyorum .
Belirli dosya türleri için kendi otomatik tamamlama listemi nasıl oluştururum?
Örneğin, FontAwesome css sınıfları listesinden otomatik tamamlama css ve html istiyorum .
Yanıtlar:
Sözlüğü tamamlamak ucuz ve müdahaleci olmayan bir çözüm olacaktır:
kaydetmek fontawesome.txt makinenizde bir yere,
bunu içine koy after/ftplugin/css.vim
(eğer yoksa dosyayı oluştur):
setlocal complete+=k
setlocal dictionary+=/path/to/fontawesome.txt
setlocal iskeyword+=-
:e
yukarıdaki dosyayı zorla kaynaklamak için yeni bir oturum başlatın veya bir CSS arabelleğinde yapın,
basın <C-n>
veya <C-p>
ekleme modunda,
keyfini çıkarın!
Referans:
:help ins-completion
:help 'complete'
:help 'dictionary'
:help 'iskeyword'
EDIT romainl'in yorumu sayesinde, kullanıcı tanımlı bir tamamlama işlevinin nasıl oluşturulacağını göstermek için cevabımı düzenledim. Önceki sürümde, bu çok iyi olmayan buil-in omni-tamamlamayı geçersiz kılıyordum çünkü kullanıcı oldukça güçlü olan varsayılan tamamlamayı kaybederdi.
Vimscript çözümü
Bir çözüm vimscript ve vim'in size özel bir tamamlama işlevi oluşturmanıza izin vermesidir.
Bu çözümün avantajı, ek bir eklentiye ihtiyacınız olmamasıdır, sadece kullanıcı tanımlı bir tamamlama işlevi oluşturabilir ve yerleşik tamamlama özelliğini kullanabilirsiniz.
FontAwesome sınıfları örneğini css
dosyalarda kullanacağım :
Dosyayı oluşturun ~/.vim/autoload/csscomplete.vim
ve içine aşağıdaki satırları yerleştirin:
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
Sonra dosyayı oluşturun ve ~/.vim/after/ftplugin/css.vim
aşağıdaki satırı ekleyin:
setlocal completefunc=csscomplete#CompleteFA
Ardından, kullanıcı tanımlı tamamlama işlevinizi ile tetikleyebilirsiniz <C-x><C-u>
. Son yazılan kelimeye bir eşleşme bulmaya çalışacaktır.
Ekran görüntüsünde .fa-l
fonksiyonu yazdım ve tetikledim <C-x><C-u>
:
O nasıl çalışır?
İlk olarak, ilgili bazı dokümantasyon konuları şunlardır:
Bir harika bir yanıt dosyalarının organizasyon hakkında.
Belirli bir dosya türü için özel bir tamamlama oluşturmak istiyorsanız, dosyayı dosyaya koymanız gerekir $HOME/.vim/autoload/{FILETYPE}complete.vim
.
Daha sonra bu dosyada iki kez çağrılan tamamlama işlevinizi oluşturmanız gerekir:
İlk çağrıda ilk argümanı imlecin geçerli konumudur ve fonksiyon tamamlanacak kelimeyi belirler. Fonksiyonumda, kelimeyi tamamlamak için 3 karşılaştırma kullandım çünkü sınıf harflerden oluşabilir .
ve -
(bu eşleştirmeyi iyileştirmenin mümkün olduğunu düşünüyorum ama normal ifade ile gerçekten kötüyüm)
İkinci görüşmesinde İkinci argüman maç için sözcüktür ve ardından fonksiyon maç için olası sınıfların listeyle karşılaştırır 1 . Burada, tamamlama menüsünü dolduracak bir sözlük döndürdüğümü görüyorsunuz, ancak belgeleri okuduğunuzda, işlevinizin davranışını daha da özelleştirmek için çok daha karmaşık bir sözlük oluşturabileceğinizi göreceksiniz.
Ayrıca Vim'e "bu tür bir dosya için oluşturduğum bu tam işlevi kullan" demeniz gerekir. Bunu yapmak için completefunc
oluşturduğunuz işlevin adını (burada csscomplete#CompleteFA
) ayarlamanız gerekir ve bu ayarın dosyada yapılması gerekir $HOME/.vim/after/ftplugin/{FILETYPE}.vim
.
1 İşlevimde, değişken s:matches
olası tüm eşleşmeleri içerir. Burada sadece okunabilirlik için bazı öneriler koydum, ancak FontAwesome tarafından sunulan tüm sınıfları koyabilirsiniz ( romainl tarafından oluşturulan bu dosyadaki tam listeyi bulabilirsiniz ).
Vimscript'i sevmezsem ne olur?
Bir olasılık, tamamlama menüsü ile oynamak için bir API sunan YoucompleteMe eklentisini kullanmaktır . Eşleştirme işini yapacak ve Vim arayüzünü doldurmak için API'yı kullanacak olan python işlevi oluşturabilirsiniz. Daha fazla ayrıntı burada .
Bazen, yerleşik veya kullanıcı tanımlı otomatik tamamlamaların hiçbirini etkilemeyen özel bir otomatik tamamlama isteyebilirsiniz. Bu, özellikle çok çeşitli dosya türlerinde çalışması amaçlanan komut dosyaları veya eklentiler için kullanışlıdır.
Bu complete()
işlev ve basit bir sargı ile oldukça kolay yapılabilir
; prosedürün çoğu,
:help complete-functions
kendi eşlemelerinizi tanımlamanız ve complete()
bir değer döndürmek yerine kendinizi çağırmanız gerekmesi dışında Statox'un cevabı ile aynıdır .
İşte temel bir örnek, yorumlar nasıl çalıştığını açıklamalıdır.
" 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
.