Ringkasan
Ini bug dan ada tambalan (743). Bug mempengaruhi kedua contoh Anda, tetapi Anda tidak melihatnya dalam satu kasus karena karakter yang dipindahkan ke bawah adalah (spasi putih). Solusinya adalah dengan menginstal patch, tetapi ada juga banyak solusi atau metode alternatif, tidak terpengaruh oleh bug.
NB : {, }dan Bsemua mengacu pada objek teks yang sama: Block ( :help aB
, :help iB
). Jika jawaban ini atau lainnya menggunakan tanda yang berbeda dari yang digunakan dalam pertanyaan, mungkin itu sebabnya.
Serangga
Saya tidak sepenuhnya memahaminya, tetapi di sini ada penjelasan, jika seseorang tertarik.
Perilaku yang Anda lihat disebabkan oleh bug yang disebutkan oleh Yukihiro Nakadaira di vim_dev dan tambalannya dirilis sebagai 7.4.743: "p" dalam mode Visual menyebabkan perpecahan garis yang tidak terduga .
Mode visual put ( :help v_p
) seharusnya mengganti teks yang dipilih secara visual dengan teks dari register. Bug terjadi ketika a) register bertipe linewise ( :help linewise-register
) tetapi pemilihan visual bertipe characterwise dan b) pemilihan visual berakhir pada kolom terakhir dari sebuah baris. Dalam kasus Anda, jika Anda menarik Blok dalam dan kemudian secara visual memilih Blok dan rekatkan, register yang disentak akan secara linier dan pemilihan visual akan sesuai karakter. Kami dapat menarik Blok dalam dan Blok ke register bernama dan memeriksa:
Di
for(int i = 0; i < s.length(); i++){
int index = s[i] - c;
if(root->next[index] == NULL)
root->next[index] = new TrieNode;
root = root->next[index];
}
kami lakukan
"ayi{
"bya{
:registers ab
yang menunjukkan
--- Registers ---
"a int index = s[i] - c;^J if(root->next[index] == NULL)^J root->next[index] = new TrieNode;^J root = root->next[index];^J
"b {^J int index = s[i] - c;^J if(root->next[index] == NULL)^J root->next[index] = new TrieNode;^J root = root->next[index];^J}
dan
:echo getregtype('a') " displays 'V' for linewise
:echo getregtype('b') " displays 'v' for characterwise
Untuk mengganti pemilihan visual dengan karakter yang mendaftar, garis yang menahan awal dan akhir pemilihan visual harus dibagi dua, sehingga teks dapat dimasukkan di antaranya. Ini biasanya bekerja dengan baik:
Menjalankan vim as vim -u NONE -U NONE
dan mengetik
( a )
iaaa
bbb
ccc
ddd<Esc>ggYjlvp
hasil dalam
aaa
b
aaa
b
ccc
dan ( b )
iaaa
bbb
ccc
ddd<Esc>ggYjvjp
di
aaa
aaa
cc
ddd
Tetapi ketika characterwise visual yang seleksi berakhir pada kolom terakhir dari garis (dan tidak termasuk baris baru /n
/ ^J
) sesuatu yang salah. Ini ada hubungannya dengan posisi kursor, yang tiba-tiba mati oleh -1 dan harus secara khusus bertambah, itulah yang dilakukan patch. Bandingkan ( a ) dengan perintah <Esc>ggYjllvp
, yaitu, perintah yang sama kecuali pindahkan satu kolom lagi ke kanan sehingga kursor berada pada "b" terakhir pada baris. Hasilnya sama seperti sebelumnya!
Sekarang ambil teks berikut:
if (TIRED){
goto bed;
} else {
goto work;
}
Dengan kursor di baris kedua, yi{va{p
pekerjaan Anda baik dan baik saja
if (TIRED)
goto bed;
else {
goto work;
}
Daftar yank masih dalam urutan dan pemilihan visual sesuai karakter, tetapi pemilihan visual tidak berakhir di kolom terakhir lagi, dan semuanya baik-baik saja.
Contoh teks dari pertanyaan
Untuk dua contoh teks, di mana satu-satunya perbedaan adalah ruang kosong antara tanda kurung tutup dan kurung kurawal di baris pertama, ini mungkin tampak seperti perintah Anda berperilaku berbeda, tetapi sebenarnya tidak. Dalam kasus pertama, yang terlihat sukses, harus ada spasi spasi di baris pertama setelah tanda kurung dihapus. Spasi yang tertinggal itu malah ada di baris terakhir. Denganyi{va{p
for(int i = 0; i < s.length(); i++) {
int index = s[i] - c;
if(root->next[index] == NULL)
root->next[index] = new TrieNode;
root = root->next[index];
}
menjadi
for(int i = 0; i < s.length(); i++)
int index = s[i] - c;
if(root->next[index] == NULL)
root->next[index] = new TrieNode;
root = root->next[index];
␣
seperti
for(int i = 0; i < s.length(); i++){
int index = s[i] - c;
if(root->next[index] == NULL)
root->next[index] = new TrieNode;
root = root->next[index];
}
menjadi
for(int i = 0; i < s.length(); i++
int index = s[i] - c;
if(root->next[index] == NULL)
root->next[index] = new TrieNode;
root = root->next[index];
)
Solusi
Solusinya adalah dengan menginstal patch, tetapi ada banyak cara lain untuk menghapus tanda kurung di sekitarnya yang tidak menderita bug. Solusi terbaik adalah jawaban @Gilles tetapi yang paling mudah adalah dengan memilih secara visual sebelum Anda menyentak, untuk menjaga register tetap karakter.
Plugin surround Tim Pope sangat bagus, tetapi (setidaknya bagi saya) itu tidak lebih dari menghapus tanda kurung: itu bergabung dengan baris kedua ke yang pertama, itu menghilangkan lekukan dan memindahkan kursor ke awal baris pertama. Ini menyisakan beberapa pembersihan non-sepele untuk dilakukan. Ingo Karkat dan Luc Hermitte memiliki plugin yang berhubungan dengan register dan paste (saya yakin ada banyak yang lain) dan yang seharusnya bisa melakukan ini. Saya tidak terlalu mengenal mereka, tapi saya percaya dengan kurung kurawal yang mungkin Anda lakukan <M-b>x
untuk menghapus kurung di sekitarnya dan untuk penempatan yang lebih kuat (terutama dalam mode visual) Anda bisa melihat di ReplaceWithRegister dan UnconditionalPaste .
Cara terbaik adalah yang diberikan dalam jawaban @Gilles [{x]}x
,. Itu cepat, menangani Blok yang bersarang dengan baik dan tidak bergabung dengan garis secara tidak tepat atau mengacaukan lekukan. Jika ada ruang putih sebelum braket pembuka, Anda dapat dengan mudah menambahkan x
perintah untuk menghapusnya:[{xx]}x
Perintah vanila lainnya
Sekali lagi, perintah yang paling tepat yang dapat saya pikirkan adalah yang ada di jawaban @Gilles, [{x]}x
atau [{xx]}x
, tapi di sini ada dua alternatif khusus sehubungan dengan bug ini.
Yank secara karakter
Karena bug hanya terjadi untuk visual yang mendaftar di atas seleksi karakter, dan karena itu hanya disengaja ke dalam Blok Anda, itu adalah linewise, Anda dapat memilih untuk menariknya secara karakter sebagai gantinya. Salah satu cara mudah adalah dengan visual memilih Blok batin sebelum mencabutnya, dan untuk memastikan bahwa seleksi visual characterwise (yaitu, penggunaan v
tidak V
): vi{yva{p
. Ini mungkin cara termudah karena sangat mirip dengan bagaimana Anda saat ini melakukan operasi.
Jangan gunakan put visual
Perintah lain, seperti mengubah dan menghapus, tidak terpengaruh oleh bug ini. Anda dapat menarik seperti sebelumnya, tetapi kemudian menghapus Blok ke register lubang hitam ( :help quote_
) dan meletakkan, atau menghapus Blok dan memasukkan dari register 0 ( :help quote0
): yi{"_da{p
atauyi{da{"0p
Keumuman
Akhirnya, ada cara yang mirip dengan @Gilles answer – pindah ke awal Blok, menghapus karakter, pindah ke akhir Blok, menghapus karakter – tetapi yang lebih umum. Satu-satunya alasan untuk menggunakan ini adalah jika "blok" yang Anda hapus adalah eksentrik dan tidak memiliki gerakan terkait yang berfungsi seperti halnya [{
blok yang dibatasi oleh kurung keriting. Ada kemungkinan bahwa vim-surround plugin dapat menangani blok-blok eksentrik ini dengan baik, tetapi ada dua cara vanilla
- Pilih secara visual blok eksentrik dan tinggalkan mode visual. Kursor berada pada karakter terakhir dari seleksi. Hapus itu, lalu pergi ke awal seleksi terakhir (
:help `<
) dan hapus karakter.va{<Esc>x`<x
- Cari mundur untuk awal blok eksentrik dan hapus karakter, lalu cari maju untuk akhir blok eksentrik dan hapus karakter.
?{<CR>x/}<CR>x
Ini mungkin tidak bekerja dengan baik dengan blok bersarang.
Jumlah karakter
+----+------------------------+----------------------------+------------+
| | method | command | characters |
+----+------------------------+----------------------------+------------+
| 1. | vim-surround | ds{ | 3 |
| 2. | @Gilles answer | [{x]}x | 6 |
| 3. | Characterwise yank | vi{yva{p | 8 |
| 4. | Delete, not visual put | yi{"_da{p or yi{da{"0p | 9 |
| 5. | Visual mark | va{<Esc>x`<x | 8 |
| 6. | Search | ?{<CR>x/}<CR>x | 8 |
+----+------------------------+----------------------------+------------+
return -1;
asalnya. Bisakah Anda menentukan di mana Anda meletakkan kursor sebelum menjalankan setiap urutan kunci?