Saya telah membaca halaman bantuan tentang fold-expr ( :h fold-expr
) tetapi tidak menjelaskan apa yang digunakan sintaksis dalam ekspresi.
Ada empat contoh:
:set foldexpr=getline(v:lnum)[0]==\"\\t\"
:set foldexpr=MyFoldLevel(v:lnum)
:set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
:set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1
Saya mengerti bahwa itu v:lnum
adalah garis yang membutuhkan tingkat indentasi, dan ekspresi dua adalah panggilan ke fungsi.
bagaimana dengan ekspresi 1,3 dan 4? Bisakah seseorang tolong jelaskan kepada saya?
Jawaban:
Dari
:help 'foldexpr'
:The
foldexpr
dievaluasi, sehingga perlu kode VimL; tidak disebutkan "sintaks khusus" atau sejenisnya. Hasil evaluasi ini mengontrol apa yang dianggap Vim sebagai lipatan atau tidak.Nilai yang mungkin adalah
Ini bukan daftar lengkap; hanya yang digunakan dalam contoh di pertanyaan Anda. Lihat
:help foldexpr
daftar lengkapnya.Pertama
Yang pertama cukup sederhana setelah kita menambahkan beberapa spasi dan menghapus garis miring terbalik yang kita perlukan agar ini berfungsi dalam
:set
perintah:getline(v:lnum)
mendapat seluruh baris.[0]
mendapat karakter pertama dari itu== "\t"
memeriksa apakah itu karakter tab.Jika Anda ingin memperluas ini untuk menghitung jumlah tab Anda akan memiliki lipatan berbasis lekukan (setidaknya, ketika
expandtab
tidak diaktifkan).Ketiga
Yang ketiga benar-benar tidak jauh lebih rumit dari yang pertama; seperti contoh pertama, pertama-tama kita ingin membuatnya lebih mudah dibaca:
getline(v:lnum)
=~
untuk'^\s*$'
;^
jangkar ke awal,\s
berarti karakter spasi putih,*
berarti mengulangi nol sebelumnya atau lebih banyak kali, dan$
jangkar ke akhir. Jadi regexp ini cocok (mengembalikan true) untuk baris kosong atau baris dengan spasi kosong saja .getline(v:lnum + 1)
mendapat baris berikutnya .\S
, yang cocok dengan karakter non-spasi putih mana pun di baris ini.<1
, jika tidak1
,. Hal ini dilakukan dengan "terner"if
diketahui dari C dan beberapa bahasa lain:condition ? return_if_true : return_if_false
.<1
berarti lipatan berakhir pada garis ini, dan1
berarti lipatan tingkat satu.Jadi, Jika kita mengakhiri lipatan jika garis kosong dan baris berikutnya tidak kosong. Kalau tidak, kita berada di foldlevel 1. Atau, seperti yang
:h foldexpr
dikatakan:Keempat
Yang keempat berperilaku sama dengan yang ketiga, tetapi melakukannya dengan cara yang sedikit berbeda. Diperluas, ini:
Jika garis sebelumnya adalah garis kosong, dan garis saat ini adalah garis tidak-kosong, kita mulai lipatan pada garis ini (
>1
), jika tidak, kita mengatur lipatan tingkat ke 1.Kata penutup
Jadi logika pada ketiga contoh ini sangat sederhana. Sebagian besar kesulitan datang dalam kurangnya ruang dan beberapa penggunaan backslash.
Saya menduga bahwa memanggil fungsi memiliki beberapa overhead, dan karena ini dievaluasi untuk setiap baris Anda ingin memiliki kinerja yang layak. Saya tidak tahu seberapa besar perbedaannya pada mesin-mesin modern, dan saya sarankan Anda menggunakan fungsi (seperti pada contoh ke-2) kecuali Anda memiliki masalah kinerja. Remember The Knuth: "optimasi prematur adalah akar dari semua kejahatan" .
Pertanyaan ini juga ada di StackOverflow , yang memiliki jawaban yang sedikit berbeda. Tapi milikku tentu saja lebih baik ;-)
sumber
Anda pada dasarnya bertanya apa unsur-unsur lain dalam ekspresi ini, yang dapat ditemukan dengan memanggil
:help
salah satu dari mereka secara bergantian:Saya telah memecah ekspresi ini dengan bagian-bagian mereka di bawah untuk membantu mengilustrasikan artinya:
1 Akan mengembalikan 1 untuk semua baris dimulai dengan tab dan 0 untuk baris lain:
3 Berakhir dengan garis kosong setelah paragraf:
4 Mulai lipatan pada baris kosong paragraf awal:
Arti dari
<1
,>1
, dll tepat di bawah ekspresi ini di:help fold-expr
sumber
Sengaja mengeposkan jawaban saya sebagai komentar dan mengirimkannya lebih awal. Sial mobile.
Pemahaman saya adalah bahwa ekspresi harus mengembalikan angka, dan angka itu akan digunakan untuk menentukan pada level mana garis yang diberikan akan dilipat. 0 tidak terlipat, 1 adalah lipatan terluar, 2 adalah lipatan bersarang di dalam lipatan level 1, dan seterusnya.
Ekspresi dalam contoh terlihat seperti mereka akan mengevaluasi benar atau salah. VimScript tidak memiliki tipe Boolean yang tepat, jadi ini akan benar-benar 1 atau 0, yang merupakan level lipatan yang valid.
Anda bisa menulis ekspresi Anda sendiri menggunakan VimScript yang semudah mengembalikan 1 atau 0, atau lebih rumit, memungkinkan untuk lipatan bersarang.
sumber