vim - Bagaimana cara menghapus blok teks besar tanpa menghitung baris?

193

Dalam vim, saya sering menemukan diri saya menghapus (atau menyalin) blok teks yang besar. Orang dapat menghitung baris teks dan berkata (misalnya) 50dduntuk menghapus 50 baris.

Tetapi bagaimana cara seseorang menghapus blok teks yang besar ini tanpa harus tahu berapa banyak baris yang harus dihapus?

Justin Ethier
sumber
1
Jika jendela cukup besar, penomoran baris relatif bermanfaat di sini. Tempatkan kursor di bagian atas jendela, cari nomor baris relatif dari baris terakhir yang akan dihapus (katakanlah, n), tambahkan satu, lalu ketik nomor itu, lalu ketik dd. Misalkan jika n = 50, maka 51dd. Atau, gunakan perintah gerak -50d<down arrow>
BallpointBen
"Temukan nomor baris relatif" - atau, gunakan :set rnudan Vim akan langsung melakukannya! Baris yang Anda gunakan masih akan dinomori secara total, tetapi baris di atas dan di bawah kursor akan simetris diberi nomor 1, 2, ... (dan perbarui dengan gerakan kursor, peristiwa level file, dll.)
John P

Jawaban:

287

Saya bukan guru vim, tetapi apa yang saya gunakan dalam keadaan ini adalah "mode visual". Dalam mode perintah, ketik V(huruf besar). Kemudian pindah ke atas / bawah untuk menyorot blok yang ingin Anda hapus (semua perintah gerakan biasa berfungsi). Kemudian hapus dengan xatau d.

Tikar
sumber
2
Aneh. Saya tahu itu berfungsi untuk saya (tm) di sini di Linux (vim 7.3.50) dan dengan gVim di Windows. Dan menilai dengan jawaban yang lain, bekerja untuk orang lain. Mungkin beberapa pengaturan di Anda .vimrcmembuatnya bertindak?
Mat
OK, untuk beberapa alasan saya tidak menyadari bahwa Anda dapat memasuki mode garis visual menggunakan Shift- v... Saya sedang mencoba menggunakan CTRLkunci juga. Jadi ini berfungsi dan mungkin cara yang paling nyaman.
Justin Ethier
7
Anda mungkin ingin memperjelas bahwa ada dua mode visual - Garis Visual ( CTRL- v) dan Blok Visual ( Shift- v).
Justin Ethier
2
Saya sering melakukan ini. Tapi saya selalu menganggapnya curang dan kurang ideal.
Jim Mitchener
9
Sebenarnya ada tiga mode visual: Mode Visual (Berbasis karakter {v}), Mode Garis Visual (Line based {Sv}) dan Mode Blok Visual (Memungkinkan pemilihan blok {Cv})
Tom Regner
293

Pergi ke garis awal dan ketik ma(tandai "a"). Lalu pergi ke baris terakhir dan masukkan d'a(hapus untuk menandai "a").

Itu akan menghapus semua baris dari saat ini ke yang ditandai (termasuk). Ini juga kompatibel dengan viserta vim, pada off kesempatan bahwa lingkungan Anda tidak diberkati dengan yang terakhir.

paxdiablo
sumber
3
Batuan yang menakutkan ini! Saya benci berapa lama saya hanya melakukan sesuatu (seperti menghitung garis) sebelum saya mencari solusi yang lebih baik. Terima kasih!
ryanjdillon
1
benar-benar luar biasa Saya selalu menggunakan mode visual untuk menghapus blok tetapi cara ini lebih baik +1
hish
4
Saya menemukan ini lebih bermanfaat daripada mode visual untuk menghapus 500k + baris
Michael - Where's Clay Shirky
Jawaban yang sangat praktis. Saya menggunakannya untuk menghapus email di server saya dari file /var/mail/usernamesecara massal, dan membiarkan email terakhir tetap utuh. Saya membuat tanda, lalu saya memasukkan misalnya 50000diikuti oleh gguntuk pergi ke baris 50.000, lalu saya menghapus semua baris di antaranya. bekerja seperti pesona!
otmezger
1
@horta, saya mungkin tidak akan menggunakan vimsebagai alat untuk mengedit file gigabyte - Saya cenderung memilih alat pengolah teks seperti awkdan saudara-saudaranya :-)
paxdiablo
46

Anda dapat menggunakan mode visual juga (beberapa perintah dapat digunakan dengan opsi hapus juga) vip vapuntuk memilih paragraf, v2apuntuk memilih dua paragraf dapberfungsi d2apjuga. Anda dapat menghapus dalam blok [ ]sukada[

Untuk referensi: jenis-jenis objek. Dari dokumentasi vim: bagian 4. http://vimdoc.sourceforge.net/htmldoc/visual.html

4. Operating on the Visual area             *visual-operators*

...    
The objects that can be used are:
aw  a word (with white space)           
iw  inner word                  
aW  a WORD (with white space)           
iW  inner WORD                  
as  a sentence (with white space)           
is  inner sentence                  
ap  a paragraph (with white space)          
ip  inner paragraph                 
ab  a () block (with parenthesis)           
ib  inner () block                  
aB  a {} block (with braces)            
iB  inner {} block                  
a<  a <> block (with <>)                
i<  inner <> block                  
a[  a [] block (with [])                
i[  inner [] block                  
Nyonya
sumber
1
da [, da {, da "semua berguna untuk programmer
Rene Wooller
1
Terima kasih! dapsangat mudah diingat sebagai "hapus paragraf"
Tropilio
38

Ada banyak jawaban yang lebih baik di sini, tetapi untuk kelengkapan saya akan menyebutkan metode yang saya gunakan sebelum membaca beberapa jawaban hebat yang disebutkan di atas.

Misalkan Anda ingin menghapus dari baris 24-39. Anda dapat menggunakan perintah ex

:24,39d

Anda juga dapat menarik garis menggunakan

:24,39y

Dan temukan dan ganti hanya menggunakan 24-39 baris

:24,39s/find/replace/g
daviewales
sumber
11

Jika Anda mengaktifkan nomor baris via set numberAnda dapat dengan mudah dNNGyang akan menghapus ke baris NN dari posisi saat ini. Jadi Anda dapat menavigasi ke awal baris yang ingin Anda hapus dan hanya d50Gdengan asumsi itu adalah baris terakhir yang ingin Anda hapus.

Jim Mitchener
sumber
10

Itu semacam tergantung pada apa blok besar itu. Mungkin Anda hanya bermaksud menghapus paragraf yang dipakan dilakukan.

René Nyffenegger
sumber
Terima kasih atas tipnya. Sayangnya saya bekerja dengan kode di sini, dan biasanya membutuhkan kontrol yang lebih baik daripada itu.
Justin Ethier
1
Saya bekerja dengan kode juga, dan saya memisahkan blok logis dengan baris kosong. Tip ini hanya membuat saya senang. Sekarang saya dapat menghapus blok logika besar dengan tiga kali penekanan tombol.
minimal
ini berfungsi karena 'd' berarti hapus, 'p' dalam konteks ini berarti paragraf
user98761
7

Ada beberapa kemungkinan, apa yang terbaik tergantung pada teks yang Anda kerjakan.

Ada dua kemungkinan yang muncul:

  • beralih ke mode visual ( V,, S-V...), pilih teks dengan gerakan kursor dan tekand
  • hapus seluruh paragraf dengan: dap
Tom Regner
sumber
saya menggunakan dap sangat sering sekarang bahwa saya tahu tentang itu dan lebih suka dis dan dip, tetapi selalu menghapus blok dan baris kosong yang datang setelah blok, tetapi merupakan cara untuk menghapus blok dan baris kosong yang datang sebelum itu?
Funkodebat
Di tengah teks dengan paragraf tidak ada perbedaan sintaksis dalam hasilnya, bukan? Jika ada saya sarankan untuk menulis apa yang Anda inginkan, dengan contoh, dalam pertanyaan baru.
Tom Regner
6

Jika seluruh blok terlihat di layar, Anda dapat menggunakan pengaturan nomor relativen. Lihat: bantu relativenumber. Tersedia dalam 7.3

Rumple Stiltskin
sumber
Saya tidak menyadari betapa berguna: se rnu adalah sampai saya mulai menggunakannya - bagus untuk mengetahui ke 50dd serta navigasi, 50j
rshdev
3

Anda dapat menempatkan kursor di awal atau akhir blok dan memasuki mode visual (shift-v). Kemudian cukup naik atau turun sampai blok yang diinginkan disorot. Akhirnya, salin teks dengan menekan y atau memotong teks dengan menekan d.

Hakim Maygarden
sumber
mungkin aneh, tetapi dari sini saya menemukan cara memilih teks dari beberapa titik tengah yang diinginkan dalam satu baris dan memilih beberapa baris di bawah ini pada titik yang sama hingga akhir setiap baris. Persis apa yang saya cari.
nanker
3

Bersamaan dengan gerakan lain yang sudah disebutkan di sini, ada juga /{pattern}<CR>gerakan, jadi jika Anda tahu bahwa Anda ingin menghapus ke baris yang berisi foo, Anda bisa melakukannya dV/foo<CR>. Vada di sini untuk memaksa gerakan menjadi garis-bijaksana karena secara default /karakter.

ZyX
sumber
3

Menghitung garis terlalu membosankan bagi saya, tetapi menghitung 'paragraf' tidak begitu buruk. '{' dan '}' memindahkan kursor ke baris kosong pertama sebelum dan sesudah kursor. Operasi pemindahan kursor dapat digabungkan dengan penghapusan, dan beberapa jawaban lain menggunakan pendekatan yang serupa (dd untuk satu baris, dG untuk akhir dokumen, dll.)
Misalnya:

/* Lorem ipsum dolor sit amet, consectetur adipiscing elit. */

Lorem *ipsum(void) {
  return dolor(sit, amet);
}

Jika kursor Anda mulai di atas blok komentar, 'd}' menghapus blok komentar, dan 'd2}' menghapus baik blok komentar maupun blok kode. Jika kursor Anda mulai di bawah blok kode, 'd {' menghapus kode, dan 'd2 {' menghapus keduanya. Tentu saja, Anda dapat melewati satu blok dengan menggerakkan kursor terlebih dahulu: '{d {' atau '} d}'.

Jika Anda konsisten dengan spasi putih Anda, atau Anda dapat menghitung paragraf sekilas, ini akan berhasil. File bantuan Vim memiliki lebih banyak trik kursor jika Anda tertarik.

John P.
sumber
1

Anda juga dapat memasukkan angka yang sangat besar, dan kemudian tekan ddjika Anda ingin menghapus semua garis di bawah kursor.

Rohit Pruthi
sumber
Mungkin bahkan lebih mudah digunakan dG, yang dihapus sampai akhir dokumen, sebagai Gdefault untuk pergi ke baris terakhir.
andyg0808
1

Menghapus satu blok teks

Dengan asumsi kursor Anda berada di awal blok:

V/^$<CR>d (where <CR> is the enter/return key)

Penjelasan

  • Masuk ke mode "linewise-visual": V
  • Sorot sampai baris kosong berikutnya: /^$<CR>
  • Menghapus: d

Ikatan kunci

Solusi yang lebih kuat:

:set nowrapscan
:nnoremap D V/^\s*$\\|\%$<CR>d

Penjelasan

  • Nonaktifkan bungkus pencarian: :set nowrapscan
  • Remap Dkunci (untuk perintah berikut)::nnoremap D
  • Masuk ke mode "linewise-visual": V
  • Sorot hingga baris kosong / spasi berikutnya atau EOF: /^\s*$\\|\%$<CR>
  • Menghapus: d
Jon Nadal
sumber