Bagaimana cara menghapus kawat gigi

8

Salah satu teman saya mengatakan kepada saya bahwa saya dapat menggunakan trik di bawah ini untuk menghapus sepasang kurung keriting.

Masukkan kursor ke dalam pasangan braket keriting yang ingin Anda hapus.

y i {untuk menarik teks dalam kurung kurawal, v a {lalu menempelkannya p.

Ini berfungsi dengan baik 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];
}

Setelah menjalankan perintah:

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];

sampai saya bertemu dengan situasi ini (Ruang sebelum kurung kurawal pertama hilang).

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];
}

Setelah menjalankan perintah-perintah itu, blok teks 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];
)

Area yang saya pilih dalam mode visual tampak bagus, tetapi mengapa tanda kurung turun?

MrDwZ
sumber
Apakah Anda yakin dengan sampel kode yang Anda poskan? Saya tidak mengerti dari mana return -1;asalnya. Bisakah Anda menentukan di mana Anda meletakkan kursor sebelum menjalankan setiap urutan kunci?
statox
@statox Maaf tentang itu ... Saya telah memperbaiki blok terakhir, dan menambahkan deskripsi tentang di mana saya meletakkan kursor. Terima kasih atas rekomendasi Anda :-)
MrDwZ
Saya tidak bisa meniru ini. yi{menarik antara kurung keriting dan vapsecara visual memilih paragraf (seluruh teks dalam kasus ini) tapi saya tidak melihat bagaimana ini mengubah teks sama sekali. Apakah Anda yakin tidak melakukan yi{+ va{+ p?
jjaderberg
2
Saya baru saja mencoba yi{+ va{+ ppada teks Anda dalam sesi bersih (tanpa vimrc, -u NONE) dan itu mereproduksi hasil Anda. Saya tidak yakin mengapa, misalnya pdan Pkeduanya memberikan hasil ini, meskipun i{dan a{bergerak secara karakter. Ini akan membantu jika Anda dapat a) memberikan contoh teks di mana teknik Anda bekerja dan b) mengkonfirmasi di mana dalam teknik Anda 'perubahan' terjadi. @ Ben menunjukkan solusi yang baik dalam jawabannya (saya menggunakan plugin itu) tapi saya tidak keberatan belajar mengapa ini terjadi.
jjaderberg
Saya seperti @jjaderberg. Saya tidak bisa mereproduksi perilaku yang Anda gambarkan. Memberikan detail yang diminta dalam komentarnya akan menjadi ide yang sangat bagus.
statox

Jawaban:

6

Instal plugin "surround" . Maka Anda bisa melakukannya d s B .

Dari halaman proyek:

Surround.vim adalah semua tentang "lingkungan": tanda kurung, tanda kurung, tanda kutip, tag XML, dan banyak lagi. Plugin ini menyediakan pemetaan untuk dengan mudah menghapus, mengubah, dan menambahkan lingkungan seperti itu berpasangan.

Perintah yang dsdiikuti oleh objek teks apa pun ( Bdalam hal ini, untuk "Block", seperti dalam objek teks aBatau iB) akan menghapus karakter di sekitarnya yang menentukan objek teks. Dengan demikian, d s B dalam kasus Anda mencapai apa yang Anda inginkan.

Perintah lain termasuk c s B b, jika Anda ingin mengubah sekitarnya {...}menjadi (...), atau y s {setiap gerakan kursor atau objek teks} B untuk menambahkan sekitarnya {...}ke teks yang dipilih oleh kursor.

Lihat halaman plugin dan dokumentasi untuk lebih jelasnya.

Ben
sumber
Ini adalah solusi yang bagus. Apakah Anda mempertimbangkan untuk menambahkan satu atau dua kalimat yang menjelaskan cara kerja plugin ini dan mengapa pemetaan tertentu menyelesaikan tugas?
jjaderberg
Apakah ada cara yang elegan untuk menghapus kawat gigi itu tanpa plugin? : (
MrDwZ
Mungkin. Tetapi surround sangat ringan dan merupakan salah satu plugin "esensial". Jadi semoga menginstalnya ...
Ben
6

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 NONEdan 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{ppekerjaan 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>xuntuk 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 xperintah untuk menghapusnya:[{xx]}x

Perintah vanila lainnya

Sekali lagi, perintah yang paling tepat yang dapat saya pikirkan adalah yang ada di jawaban @Gilles, [{x]}xatau [{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 vtidak 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{patauyi{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

  1. 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
  2. Cari mundur untuk awal blok eksentrik dan hapus karakter, lalu cari maju untuk akhir blok eksentrik dan hapus karakter. ?{<CR>x/}<CR>xIni 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 |
+----+------------------------+----------------------------+------------+
jjaderberg
sumber
5

Karena Anda tidak meminta kursor dikembalikan ke posisi semula, [{x]}xlakukan pekerjaan itu. Panjangnya 6 karakter dengan dua penekanan Shifttetapi prinsipnya mudah sehingga mudah diingat.

Jika Anda ingin kembali ke posisi semula, Anda bisa menggunakan [{x``]}x``

Gilles 'SANGAT berhenti menjadi jahat'
sumber