Gönderen :help 'foldexpr'
:
Katlama seviyesini elde etmek için her satır için değerlendirilir
Bu foldexpr
değerlendirilir, bu yüzden VimL kodu olması gerekir; "özel sözdizimi" veya benzerlerinden bahsedilmez. Bu değerlendirmenin sonucu, Vim'in neyi katladığını veya neyi dikkate almadığını kontrol eder.
Olası değerler
0 the line is not in a fold
1, 2, .. the line is in a fold with this level
"<1", "<2", .. a fold with this level ends at this line
">1", ">2", .. a fold with this level starts at this line
Bu tam liste değildir ; sadece sorunuzdaki örneklerde kullanılanlar. Tüm :help foldexpr
liste için bakınız .
İlk
Birincisi boşluk eklediğimizde ve ters eğik çizgileri kaldırdığımızda, bunu bir :set
komutta çalıştırmamız için oldukça basit :
getline(v:lnum)[0] == "\t"
getline(v:lnum)
tüm hattı alır.
[0]
bunun ilk karakterini alır
- ve
== "\t"
bunun bir sekme karakteri olup olmadığını kontrol eder.
- VimL'de "true" veya "false" yoktur, sadece false için "0" ve true için "1" kullanır. Yani bu çizgi bir sekme ile başlıyorsa, 1. düzey katında katlanır. Değilse, bir kat (0) içinde olmaz.
Girintiye dayalı katlama yapacağınız sekme sayısını saymak için bunu genişletirseniz (en azından expandtab
etkin olmadığında).
Üçüncü
Üçüncüsü, birincisi kadar karmaşık değil; ilk örnekte olduğu gibi, önce daha okunabilir hale getirmek istiyoruz:
getline(v:lnum) =~ '^\s*$' && getline(v:lnum + 1) =~ '\S' ? '<1' : 1
- Tüm çizgiyi
getline(v:lnum)
- Biz bir regexp olarak eşleşecek
=~
için '^\s*$'
; ^
başlangıca \s
bağlanır , herhangi bir boşluk karakteri *
anlamına gelir, önceki sıfırı veya daha çok kez tekrar eder $
ve sonuna kadar tutturur. Dolayısıyla bu normal ifade boş satırlarla veya yalnızca boşluklu satırlarla eşleşir (true değerini döndürür) .
getline(v:lnum + 1)
sonraki satırı alır .
- Bunu
\S
, bu satırın herhangi bir yerinde boşluk olmayan herhangi bir karakterle eşleştiriyoruz.
- Bu 2 koşul doğruysa
<1
, aksi takdirde değerlendiririz 1
. Bu "üçlü" ile yapılır if
C'den bilinmektedir ve bazı diğer diller: condition ? return_if_true : return_if_false
.
<1
"Katlama" terimi, bu çizgi üzerinde bir katlama ucu anlamına gelir ve katlama 1
seviyesi bir demektir.
Yani, biz ise son çizgi boş ve sonraki çizgi ise bir kat değil boş. Aksi takdirde, 1. kattayız. Ya da :h foldexpr
dediği gibi:
Bu, boş satırlarla ayrılmış paragrafları katlar.
Dördüncü
Dördüncü, üçüncü olanla aynı şekilde davranır, ancak biraz farklı bir şekilde yapar. Genişletilmiş, bu:
getline(v:lnum - 1) =~ '^\s*$' && getline(v:lnum) =~ '\S' ? '>1' : 1
Eğer önceki hat boş bir satır olduğunu ve şimdiki çizgi olmayan bir boş satır, biz bir bu hat (on kat başlatmak >1
, biz 1 olarak foldlevel ayarladığımız değilse).
Sonsöz
Bu nedenle, 3 örneğin hepsindeki mantık gerçekten oldukça basittir. Zorluğun çoğu, boşlukların olmaması ve bazı ters eğiklik kullanımından kaynaklanmaktadır.
Bir işlevi çağırmanın bazı ek yükleri olduğundan şüpheleniyorum ve bu, iyi bir performansa sahip olmak istediğiniz her satır için değerlendirildiğinden. Modern makinelerdeki farkın ne kadar büyük olduğunu bilmiyorum ve performans problemleriniz yoksa bir işlev (2. örnekte olduğu gibi) kullanmanızı öneririz. The Knuth'u hatırlayın: "erken optimizasyon tüm kötülüklerin köküdür" .
Bu soru aynı zamanda biraz farklı bir cevabı olan StackOverflow'da da var. Ama benimki elbette daha iyi ;-)