Jawaban ini ada di sini untuk 1) menunjukkan kode yang benar untuk ditempelkan ke .vimrc
untuk vim 7.4+
melakukan blok komentar / komentar sambil menjaga tingkat lekukan dengan 1 pintasan dalam mode visual dan 2) untuk menjelaskannya.
let b:commentChar='//'
: Ini menciptakan variabel dalam vim. di b
sini merujuk pada ruang lingkup, yang dalam hal ini terkandung ke buffer, yang berarti file yang sedang dibuka. Karakter komentar Anda adalah string dan perlu dibungkus dengan tanda kutip, tanda kutip itu bukan bagian dari apa yang akan diganti ketika bertukar komentar.
autocmd BufNewFile,BufReadPost *...
: Perintah otomatis memicu pada hal-hal yang berbeda, dalam hal ini, ini memicu ketika file baru atau file yang dibaca berakhir dengan ekstensi tertentu. Setelah dipicu, jalankan perintah berikut, yang memungkinkan kita untuk mengubahcommentChar
tergantung pada tipe file. Ada cara lain untuk melakukan ini, tetapi mereka lebih membingungkan bagi pemula (seperti saya).
function! Docomment()
: Fungsi dideklarasikan dengan mulai function
dan diakhiri dengan endfunction
. Fungsi harus dimulai dengan modal. itu !
memastikan bahwa fungsi ini menimpa setiap fungsi sebelumnya yang didefinisikan Docomment()
dengan versi ini Docomment()
. Tanpa itu !
, saya punya kesalahan, tapi itu mungkin karena saya mendefinisikan fungsi baru melalui baris perintah vim.
execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
: Jalankan panggilan perintah. Dalam hal ini, kami mengeksekusi substitute
, yang dapat mengambil rentang (secara default ini adalah baris saat ini) seperti %
untuk seluruh buffer atau '<,'>
untuk bagian yang disorot. ^\s*
adalah regex untuk mencocokkan awal baris diikuti oleh jumlah spasi, yang kemudian ditambahkan ke (karena &
). Di .
sini digunakan untuk penggabungan string, karena escape()
tidak dapat dibungkus dengan tanda kutip. escape()
memungkinkan Anda untuk keluar dari karakter commentChar
yang cocok dengan argumen (dalam hal ini, \
dan /
) dengan menambahkannya dengan a \
. Setelah ini, kami menyatukan lagi dengan ujung substitute
string kami , yang memilikie
bendera. Bendera ini memungkinkan kami gagal secara diam-diam, artinya jika kami tidak menemukan kecocokan pada baris yang diberikan, kami tidak akan berteriak tentang hal itu. Secara keseluruhan, baris ini memungkinkan kita menempatkan karakter komentar diikuti oleh spasi tepat sebelum teks pertama, yang berarti kita menjaga tingkat lekukan kita.
execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
: Ini mirip dengan perintah besar terakhir kami. Unik untuk yang satu ini, kami punya \v
, yang memastikan bahwa kami tidak harus melarikan diri dari kami ()
, dan 1
, yang mengacu pada grup yang kami buat dengan kami ()
. Pada dasarnya, kami mencocokkan garis yang dimulai dengan jumlah spasi putih apa pun dan kemudian karakter komentar kami diikuti oleh jumlah spasi putih apa pun, dan kami hanya menyimpan set spasi putih pertama. Sekali lagi, e
mari kita gagal secara diam-diam jika kita tidak memiliki karakter komentar di baris itu.
let l:line=getpos("'<")[1]
: ini menetapkan variabel seperti yang kami lakukan dengan karakter komentar kami, tetapi l
merujuk ke lingkup lokal (lokal ke fungsi ini). getpos()
mendapat posisi, dalam hal ini, awal dari penyorotan kami, dan [1]
sarana kami hanya peduli dengan nomor baris, bukan hal-hal lain seperti nomor kolom.
if match(getline(l:line), '^\s*'.b:commentChar)>-1
: Anda tahu cara if
kerjanya. match()
memeriksa apakah hal pertama berisi hal kedua, jadi kami mengambil garis yang kami mulai sorot kami, dan memeriksa apakah itu dimulai dengan spasi putih diikuti oleh karakter komentar kami. match()
mengembalikan indeks di mana ini benar, dan -1
jika tidak ada kecocokan yang ditemukan. Karena if
mengevaluasi semua angka bukan nol menjadi benar, kita harus membandingkan output kita untuk melihat apakah itu lebih besar dari -1. Perbandingan dalam vim
pengembalian 0 jika salah dan 1 jika benar, yang if
ingin dilihat untuk mengevaluasi dengan benar.
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>
: vnoremap
berarti memetakan perintah berikut dalam mode visual, tetapi jangan memetakannya secara rekursif (artinya tidak mengubah perintah lain yang mungkin digunakan dengan cara lain). Pada dasarnya, jika Anda seorang pemula, selalu gunakan noremap
untuk memastikan Anda tidak merusak barang-barang. <silent>
berarti "Saya tidak ingin kata-kata Anda, hanya tindakan Anda" dan mengatakan itu untuk tidak mencetak apa pun ke baris perintah. <C-r>
adalah hal yang kami pemetaan, yaitu ctrl + r dalam hal ini (perhatikan bahwa Anda masih dapat menggunakan Cr secara normal untuk "redo" dalam mode normal dengan pemetaan ini). C-u
agak membingungkan, tetapi pada dasarnya itu memastikan Anda tidak kehilangan jejak penyorotan visual Anda (menurut jawaban ini membuat perintah Anda mulai dengan '<,'>
yang kami inginkan).call
sini hanya memberitahu vim untuk menjalankan fungsi yang kami beri nama, dan <cr>
mengacu pada memukulenter
tombol. Kita harus menekannya sekali untuk benar-benar memanggil fungsi (jika tidak kita baru saja mengetik call function()
pada baris perintah, dan kita harus menekannya lagi untuk mendapatkan pengganti kita untuk pergi sepanjang jalan (tidak benar-benar yakin mengapa, tapi apa pun).
Bagaimanapun, semoga ini membantu. Ini akan mengambil apa pun yang disorot dengan v
,, V
atau C-v
, periksa apakah baris pertama dikomentari, jika ya, coba batalkan komentar pada semua baris yang disorot, dan jika tidak, tambahkan lapisan karakter komentar tambahan untuk setiap baris. Inilah perilaku yang saya inginkan; Saya tidak hanya ingin beralih apakah setiap baris di blok dikomentari atau tidak, jadi itu berfungsi dengan baik bagi saya setelah mengajukan beberapa pertanyaan pada subjek.