Tek bir vim tamponunda iki farklı renk arka planı kullanmak mümkün müdür?


20

Bu yüce metin örneğinde olduğu gibi bağlama bağlı olarak tek bir vim tampon içine iki farklı arka plan renkleri uygulamak için olası bir çözüm arıyorum .

Bunun bir kullanım şekli, işaretleme dosyalarındaki kod parçacıklarını farklı şekilde renklendirmektir, böylece daha fazla öne çıkarlar.

Ancak böyle bir kurulumla hiç örnek görmedim.

Vim'de bu mümkün mü?


2
gerçekten bunun cevabını bilmek istiyorum, sözdizimi ile SO bu yazı vurgulayarak mümkün olacağını öneririm ilgili stackoverflow.com/questions/7033310/…
Nick J Adams

Yanıtlar:


9

Bunun ne kadar iyi çalışacağını merak ettiğim için birlikte bu tür işleri hackledim.

resim açıklamasını buraya girin

Daha önceki cevabın yorumlarında belirtildiği gibi, bunu yapmanın tek yolu bölgeleri boşluklarla doldurmaktır; ki tam olarak bunu yapıyoruz; yazmadan önce bu boşlukları kaldırıyoruz, bu yüzden onunla kimseyi rahatsız etmemelisiniz.

Bu örneğin, işaretleme dosya türü için çok özel olduğunu unutmayın!

Yan etkileri :

  • Metin kopyalandığında da çok fazla alan kopyalanır
  • Kullanılması $ve Endartık çalışmaz (Bu sütunda 80 gider) beklendiği gibi ve anahtarlar gibi jve kaynı zamanda farklı davranırlar.
  • 'list'Etkinleştirildiğinde arka plan görüntülenmez
  • Tamamen boş satırlar çalışmıyor, manuel olarak bir sekme veya 4 boşluk eklemeniz gerekiyor
  • ... Belki daha fazlası?

İlk olarak, bunu aşağıdakilere eklemeniz gerekir ~/.vim/after/syntax/markdown.vim:

syn clear markdownCodeBlock                                                 
syn region markdownCodeBlock start="    \|\t" end="$"                       
hi def markdownCodeBlock ctermbg=230 guibg=lightyellow                      

Elbette renkleri beğeninize göre ayarlayabilirsiniz ;-)

Ardından, bunu vimrc'nize ekleyin:

fun! MarkdownBlocks()                                                       
    fun! s:fill(line)                                                       
        " Remove all trailing whitespace                                    
        let l:line = substitute(a:line, " *$", "", "")                      

        " Add trailing whitespace up to 'textwidth' length                  
        return l:line . repeat(' ', (&tw > 0 ? &tw : 80) - strdisplaywidth(l:line))
    endfun                                                                  

    " Get all lines in a list                                               
    let l:lines = getline(1, line('$'))                                     

    " Map s:fill() to the lines that are a code block                       
    call map(l:lines, 'v:val[0] == "\t" || v:val[:3] == "    " ? s:fill(v:val) : v:val')

    " Reset the buffer to the lines                                         
    call setline(1, l:lines)                                                
endfun                                                                      

" Remove all the trailing spaces                                            
fun! MarkdownBlocksClean()                                                  
    let l:save_cursor = getpos(".")                                         
    silent %s/^\(    \|\t\)\(.\{-}\)\( *\)$/\1\2/e                          
    call setpos('.', l:save_cursor)                                         
endfun                                                                      
au BufWritePre *.markdown call MarkdownBlocksClean()                        

" Set spaces on loading the file, leaving insert mode, and after writing it 
au FileType markdown call MarkdownBlocks()                                  
au InsertLeave *.markdown call MarkdownBlocks()                             
au BufWritePost *.markdown call MarkdownBlocks()                            

Kodu satır satır açıklamayacağım, yorumlar genel özünü açıklığa kavuşturmalıdır ;-)


Bu cevap için teşekkürler. @Rich tarafından verilen ilk cevap yerine kabul ettim çünkü daha eksiksiz görünüyordu. Ben denemek ama tüm yan etkileri nedeniyle kullanacağım emin değilim bu yüzden burada hiçbir söz :) Büyük Tüm çaba için teşekkür ederiz!
Karolis Koncevičius

1
@ KarolisKoncevičius Teşekkürler. Bunu vimrc'ime de ekledim. Güzel görünüyor :-) Sorunlarla karşılaşırsanız bana bildirin.
Martin Tournoij

Hahaha. Bunun çılgınca nitelendirildiğini düşünüyorum, ama beklediğim kadar korkunç değil. İyi iş. Tabii ki, şimdi bu kadar ileri gittiğinize göre, j, k, $, vb. İle olan sorunları yeniden eşleştirerek ve sormadan önce beyaz boşluğu kaldırmak zorunda hissetmiyor musunuz? ;)
Zengin

2
@Rich Evet, bu bir hack. Bunu yapmak eğlenceli hale getirdi ;-) Bazı anahtarları (bir şekilde) düzeltmek de zihnimi geçti, ama zaten bu konuda biraz zaman geçirdim ve önce gerçekten işe yarayıp yaramadığını görmek istiyorum ve eğer hatta daha fazla zaman harcamadan önce :-)
Martin Tournoij

2
@Carpetsmoker En son ne zaman bir şeyin mümkün olabileceğini ima ettiniz, gittiniz ve başardınız, bu yüzden sağlam çok dilli çözümünüzü birkaç hafta içinde görmeyi dört gözle bekliyorum.
Zengin

13

Sözdizimi ile vurgulanan öğeler için farklı bir arka plan rengi kullanmak kesinlikle mümkündür. Komutunuzdaki guibgve ctermbgrenklerini tanımlamanız hilightyeterlidir. Birincisi GUI Vim için arka plan rengini ve terminal Vim için ikincisini ayarlar.

Ancak, bunun yalnızca dosyada bulunan karakterler için arka plan renklerini ayarlayabileceği önemli bir sınırlaması vardır.

Bunun sonucu, arka plan renginin metnin sonunu geçmeyecek şekilde pencerenin kenarına kadar uzanamamasıdır, bu nedenle örneğinizde gösterilen kod bloklarının renklendirilmesi mümkün değildir:

Vim'de mümkün olan arka plan boyama örneği

İmzalama özelliğini kullanarak tüm çizgilerin arka plan rengini de değiştirebilirsiniz. (Bkz linehl. :help sign.txt)

Arka planı işaretlerle renklendirme örneği

Ancak aşağıdakilere dikkat edin:

  1. Bunun için renklendirilmesi gereken her satıra işaretler yerleştirmek ve dosyanın içeriği değiştikçe bunları güncel tutmak için kod yazmayı gerektirir,

  2. Varsayılan olarak, bir işaret yerleştirirken pencerenin solunda işaret sütunu görüntülenir. İşaret sütununun renklendirmesini SignColumnvurgulama grubu ile değiştirmek mümkündür ve Vim'in daha yeni sürümlerinde tamamen kaldırılabilir. (Bkz :help 'signcolumn'.)

Örneğin, Carpetsmoker'ın çözümünü (daha sağlam) işaret mekanizmasını kullanacak şekilde uyarlamak için aşağıdakileri yapabilirsiniz:

" Define a highlight group and a sign that uses it
highlight default markdownCodeBlock ctermbg=230 guibg=lightyellow
sign define codeblock linehl=markdownCodeBlock

" Use signs to highlight code blocks
function! MarkdownBlocks()
    function! s:applySign(idx, val)
        if a:val[0] == "\t" || a:val[:3] == "    "
            let l = a:idx + 1
            execute "sign place " . l . " line=" . l . " name=codeblock file=" . expand("%:p")
        endif
    endfunction

    " Remove old signs
    execute "sign unplace * file=" . expand("%:p")

    " Get all lines in a list
    let l:lines = getline(1, line('$'))
    " Add new signs
    call map(l:lines, function('s:applySign'))
endfunction

" Set signs on loading the file, leaving insert mode, and after writing it
au FileType markdown call MarkdownBlocks()
au InsertLeave *.markdown call MarkdownBlocks()
au BufWritePost *.markdown call MarkdownBlocks()

Bu, kodu bir şekilde basitleştirir ve Carpetsmoker'ın versiyonundan daha az uyarıya sahiptir.

@ChristianBrabandt 'ın DynamicSigns eklentisi kolay bu amaçla İşaret özelliğini kullanarak yapar: o bunu yapmak için kullanabilirsiniz açıklamaktadır Bu cevap .


1
Cevap için +1. Ancak (ve yanılıyorsam düzelt) ama guibgsadece gvim için çalışıyor, doğru mu?
Karolis Koncevičius

1
@Karolis Evet. Terminal Vim için ctermbgbelirtildiği gibi kullanmanız gerekir .
Zengin

1
Kıvrımlar kullanırsanız, istediğinizi elde edersiniz: Kıvrımlar farklı bir bg rengine sahiptir, ancak bu, arka planı farklı bir bg renk kümesi olan boşluk karakterleriyle doldurarak gerçekleştirilir ... Bu, bazı yan etkilere neden olur: kopya / paste artık düzgün çalışmaz (çok fazla boşluk karakteri de kopyalayacağından, bunu kendiniz de nasıl doğrulayabilirsiniz).
Martin Tournoij

@Rich, cevap için teşekkürler. Mükemmel bir çözüm olmasa da (blok vurgulama açısından) bunun mümkün olduğunu gösteren soruyu tam olarak cevaplar. Yanıt Kabul Edildi.
Karolis Koncevičius

3
Birisi böyle bir senaryo yazmak için gerçekten çılgın olmalı.
joeytwiddle
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.