Bagaimana cara menghapus blok teks besar tanpa menghitung garis?


91

Dalam vim, saya sering perlu menghapus, atau menarik / meletakkan blok teks yang besar.

Saya bisa menghitung baris teks dan memasukkan sesuatu seperti 50ddmenghapus 50 baris.

Tapi itu agak menyebalkan. Bagaimana saya bisa menghapus blok teks yang besar ini tanpa harus tahu berapa banyak baris yang harus dihapus terlebih dahulu?


4
Bagaimana Anda tahu di mana akhirnya? Jika Anda bisa menggambarkan akhir, Anda dapat menghapus ke titik itu. Jika Anda bisa menggambarkan bagaimana Anda bisa movesampai akhir. Maka menghapus sampai akhir tidak berbeda dengan pindah ke akhir.
Martin York

@Loki, pindah ke ujung biasanya hanya menggunakan page-down dan tombol panah hingga aku sampai di sana. Ini mungkin merupakan baris kosong pertama atau kesepuluh, mungkin merupakan kurung kurawal pertama. Intinya adalah, ini sedikit bervariasi.

2
juga periksa jawaban ini: stackoverflow.com/a/16407391/164835
Kent

Jawaban:


111

Pergi ke baris awal blok Anda, dan ketik ma(tandai "a", meskipun Anda tentu saja dapat menggunakan huruf yang berbeda , dan bahkan beberapa huruf untuk tanda yang berbeda asalkan Anda dapat tetap lurus di kepala Anda apa setiap huruf adalah tanda) .

Kemudian pergi ke baris terakhir dan masukkan d'a(hapus untuk menandai "a") atau y'a(tarik untuk menandai "a") (a) .

Itu akan menghapus / menarik semua baris dari saat ini ke yang ditandai (inklusif).

Kemudian Anda dapat menempelkannya di tempat lain dengan perintah tempel normal, seperti patau P.

Ini juga kompatibel dengan viserta vim, pada kesempatan bahwa lingkungan Anda tidak diberkati dengan yang terakhir.


(a) Saya juga menggunakan ini untuk menyimpan tempat saya dalam file jika saya harus mencari di tempat lain untuk sesuatu seperti, misalnya, menyalin-menempelkan definisi fungsi yang ingin saya panggil.

Saya cukup menandai baris saat ini dengan cara yang sama ma,, lalu berjalan-jalan untuk menemukan apa pun yang Anda cari.

Kemudian, setelah saya menemukannya dan menyalinnya ke register, saya hanya memasukkan 'auntuk kembali untuk menandai "a", baris yang saya simpan sebelumnya, di mana saya kemudian dapat menempelkannya.


9
Mungkin juga menggunakan mode visual untuk ini, kan?
jmc

3
Itu satu arah, jmc, tapi saya tidak yakin standar vi memiliki mode visual.

5
Karena saya pindah dari pemilihan visual ke penandaan dan nomor garis relatif sekitar setahun yang lalu saya menemukan bahwa perintah vi motion jauh lebih cepat dan efisien daripada pemilihan visual. Meskipun nanti lebih mudah setiap kali saya menekan vtombol saya bertanya pada diri saya apakah saya benar-benar membutuhkannya atau apakah ada cara gerak yang lebih baik?
Sukima

1
Ya, dengan cara yang sama menarik, @Sukima, bahwa saya merasa lebih efisien semakin sedikit saya menggunakan mouse, bahkan dalam GUI. Saya menemukan diri saya menjadi lebih cepat jika saya dapat tetap menggunakan keyboard.

3
Jika Anda pernah mengedit sesuatu dengan garis yang sangat panjang, versi backtick ini mungkin sangat berguna (yang merujuk pada tempat di dalam garis, bukan seluruh baris).
msouth

65

Di Vim, gunakan mode garis visual :

  1. Letakkan kursor Anda di baris atas blok teks / kode untuk dihapus
  2. Tekan V(Itu modal "V": Shift+ v)
  3. Pindahkan kursor ke bawah ke bagian bawah blok teks / kode untuk dihapus
  4. tekan d

Untuk menghapus blok teks yang besar ini lebih disukai daripada mode visual sederhana karena Anda tidak perlu khawatir tentang kolom di mana kursor berada.


3
Di langkah 3. Anda bisa bergerak lebih cepat menggunakan gerakan objek. Misalnya bisa digunakan }untuk memilih seluruh paragraf atau )untuk kalimat. Masih ada lagi, Anda dapat membacanya di:h object-motions
mxlian

2
Juga mencari substring dengan /something<CR>adalah metode yang sangat efisien untuk mencapai hingga akhir blok pilihan Anda
mxlian

1
Ini adalah metode yang saya sukai. Namun sebagai alternatif tanpa harus berulang kali menekan juntuk memindahkan kursor ke bawah (langkah 3), Anda dapat mengetikkan nomor baris yang diikuti oleh Guntuk memilih hingga garis itu. Contoh:V150Gd
Ranhiru Jude Cooray


39

Anda dapat dengan mudah menghapus blok teks yang besar dengan mengetahui strukturnya.

Jika paragraf, gunakan: d{(mis. Anda dapat awalan dengan jumlah paragraf)

Jika itu adalah blok kode dalam tanda kurung, gunakan: d%

Jika teks muncul hingga akhir file, gunakan: dG

Jika Anda tahu bagaimana itu berakhir, gunakan: d/dan ketikkan teks akhir diikuti oleh Enter(Anda juga dapat menggunakan ekspresi reguler, sehingga kemungkinan tidak terbatas).

Atau gunakan mode visual ( V) dan gunakan tombol gerak untuk dengan cepat memilih teks (misalnya dengan {) dan menghapusnya ( d).

Atau seperti yang disarankan Lie Ryan, gunakan d/search-string/euntuk menghapus teks dari kursor saat ini ke string yang dicari.

Lihat: :help ddan :help motionuntuk info lebih lanjut.


2
Ada juga d/search-string/euntuk menghapus dari kursor saat ini ke akhir string pencarian termasuk string pencarian itu sendiri dan c/search-querymasuk ke mode penyisipan setelah penghapusan. Menggunakan d/dengan set incsearchadalah kombinasi yang rapi karena memungkinkan Anda untuk secara interaktif mengetahui apakah Anda beroperasi pada rentang teks yang tepat, dan membantu Anda tahu kapan harus berhenti mengetik permintaan pencarian untuk menghindari mengetik lebih dari yang diperlukan.
Lie Ryan

4
Saya juga menemukan ddengan a(luar), atau i(dalam) dan specifier objek sangat berguna. Objek seperti wuntuk kata, puntuk paragraf, (atau buntuk (...), [untuk [...], {atau Buntuk dokumentasi{...} dll untuk operator visual .
Shahbaz

22

Anda dapat menggunakan gerakan dan / atau objek teks. Misalnya, Anda dapat menghapus semuanya mulai dari kursor ke baris kosong berikutnya d}. Jika kursor ada di dalam paragraf, paragraf dapat dihapus dengan dipatau dap. Jika kursor berada dalam tag HTML, Anda dapat menghapusnya dengan ditatau dat.

Mnemonik yang bagus untuk ini adalah " d elete i nside" dan " d elete a round" (paragraf / tag / tanda kurung).


11

Biasanya saya lakukan

:<start>,<end>d

yang akan menghapus setiap baris antara nomor baris awal dan akhir yang disediakan (termasuk baris yang diberikan).

Perhatikan bahwa keduanya startdan enddapat berupa angka garis, pola, atau offset absolut dari posisi lain.

Juga lihat komentar doubleDown tentang melihat dokumentasi rentang Vim , ini memiliki beberapa tips yang berguna.

Contoh:

Katakanlah Anda memiliki file berikut:

1. The quick brown
2. fox jumps
3. over the
4. lazy dog.

Kemudian dengan menggunakan perintah :2,3datau :/fox/,/over/datau :/quick/+1,/lazy/-1atau :+1,+2djika Anda berada di baris pertama atau :-1,.djika Anda berada di baris ketiga, Anda berakhir dengan:

1. The quick brown
4. lazy dog.

Tapi ini berarti Anda masih perlu menghitung garis? Atau apakah saya salah mengerti jawaban Anda?
Martin Tournoij

7
Anda tidak perlu menghitung garis, tetapi Anda harus tahu nomor garis.
jmc

Pertama lakukan :set ruler, kemudian pergi ke atas & bawah teks untuk mencari startdan endnomor baris, kemudian lakukan:<start>,<end>d
roblogic

1
Anda juga bisa menggunakan nomor baris relatif:+12,+24d
rpattabi

2
Sebenarnya, Anda bisa menggunakan sepasang nomor garis, sepasang pola, atau pasangan campuran untuk <start>dan <end>untuk ini. Untuk referensi, lihat :h [range]. Jadi sebenarnya ini sedikit lebih fleksibel daripada yang Anda bayangkan.
doubleDown

5

Jika blok dibatasi (misalnya: kode atau tag XML / HTML) yang Anda hadapi, Anda dapat memposisikan kursor di awal blok dan menggunakan mode visual bersama dengan %untuk dengan cepat memilih seluruh blok kode dan kemudian tekan duntuk menghapusnya.


5
Atau, Anda dapat menggunakan dapuntuk menghapus sebuah paragraf, da(, da{, da[, untuk menghapus blok delimeted dengan tanda kurung, kawat gigi, atau tanda kurung persegi. Untuk html ada dat, yang menghapus tag, dan da'dan da"menghapus string. Ada juga dip, di(, dll varian, yang akan menghapus segala sesuatu di dalam pembatas, tapi tinggalkan pembatas utuh. Atau, Anda dapat menggunakan vap(resp vip) untuk memilih semua paragraf (resp dalam). (Dan begitu ada va(dan vi(.) Selanjutnya ada capdan cip(atau ca(dan ci() untuk menghapus dan pergi ke mode insert (yaitu, "ubah"). Dan yapuntuk menarik
jmc

Saya pikir beberapa binding @jmc yang dijelaskan dalam komentar sebelumnya berasal dari plugin surround.vim oleh Tim Pope. Ini adalah plugin yang hebat yang saya sarankan untuk diinstal, tetapi itu berarti binding ini bukan bagian dari instalasi vim default.
Haegin

5

Terlepas dari semua saran bagus lainnya, saya menambahkan d+ Shift+ Luntuk menghapus semuanya dari posisi kursor saat ini ke baris terakhir yang terlihat di layar. Mengulangi perintah akan membuat Anda turun relatif cepat.


5

The numbers.vim Plugin ini sangat berguna untuk ini. Ini adalah cara yang disempurnakan untuk mengawali setiap baris dengan nomor baris. Suka 'number'dan 'relativenumber', keduanya digulirkan menjadi satu!

Ini diaktifkan secara default setelah instalasi, Anda juga ingin menambahkan set numberke vimrc Anda jika Anda belum mendapatkannya, karena berperilaku dengan cara yang aneh jika Anda tidak memilikinya.

Dalam mode normal , tampilannya mirip dengan :set relativenumber:

  3 call plug#begin('~/.vim/plugged')
  2 
  1 Plug 'myusuf3/numbers.vim'
7   set number█
  1 
  2 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
  3 Plug 'Yggdroot/indentLine'

Ini menunjukkan Anda nomor garis relatif, kecuali untuk garis di mana kursor aktif, di mana ia menunjukkan nomor garis absolut (7 dalam kasus ini).

Jika kita beralih ke mode penyisipan , itu akan berperilaku seolah-olah numberdiatur dengan selalu menampilkan angka garis absolut:

  4 call plug#begin('~/.vim/plugged')
  5 
  6 Plug 'myusuf3/numbers.vim'
  7 set number█
  8   
  9 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
 10 Plug 'Yggdroot/indentLine'

Ada beberapa opsi lagi dan beberapa perintah (periksa beranda), tetapi defaultnya akan berfungsi untuk kebanyakan orang.


Awalnya saya pikir jawaban ini sedikit keluar dari topik tetapi kemudian saya menginstal plugin dan saya harus mengatakan itu adalah pengubah permainan bagi saya. Saya biasa bertukar secara manual dan langkah mental ekstra berarti saya menghindar dari menggunakan gerakan itu. Terima kasih!
Sukima

1
Ini kedengarannya seperti sesuatu yang dapat dilakukan oleh salah satu InsertEnter / InsertLeave autocmd untuk mengganti penomoran baris relatif. Apakah saya melewatkan sesuatu?
Ben

Saya SANGAT terlambat ke pesta tetapi @ Ben benar, ini hanya beberapa baris perintah otomatis. Sebagai contoh, di vimrc saya saya miliki set number, set relativenumberlalu autocmd InsertEnter * :set norelativenumberdanautocmd InsertLeave * :set relativenumber
B Layer

4

Pendekatan lain adalah jika Anda mencoba untuk menghapus ke pola tertentu, Anda cukup mengetik d/delimEnter.


2

Anda dapat menggunakan prosedur normal untuk memasukkan dplus gerakan (sebagaimana telah dijelaskan dalam jawaban lain). Plugin EasyMotion, menyediakan gerakan baru yang dapat Anda gunakan yang dapat menyelesaikan masalah Anda dengan cara yang cepat dan mudah.

Katakanlah Anda ingin menghapus dari posisi kursor saat ini ke akhir kata yang diberikan di layar, tombol geraknya akan <Leader><Leader>e(mirip dengan egerakan normal ). Kemudian ketikkan huruf yang disorot yang muncul di akhir kata yang dipertanyakan. Ada juga gerakan garis sehingga Anda dapat menghapus garis saat ini ke garis yang dimaksud <Leader><Leader>j.

Saya telah <Leader>mengatur kunci saya untuk ,. Jadi, perintah lengkapnya adalah d<Leader><Leader>e{highlighted letter (s)}.

Dari :help easymotion:

EasyMotion menyediakan cara yang lebih sederhana untuk menggunakan beberapa gerakan dalam vim. Ini <number>mengeluarkan <number>w atau <number>f {char}dengan menyorot semua pilihan yang memungkinkan dan memungkinkan Anda untuk menekan satu tombol untuk melompat langsung ke target.

Ketika salah satu gerakan yang tersedia dipicu, semua teks yang terlihat sebelum atau mengikuti kursor memudar, dan target gerakan disorot.

Sunting:

EasyMotion ini github repositori adalah di https://github.com/Lokaltog/vim-easymotion .

Reddit ini tentang orang yang menggunakan easymotion mungkin menyenangkan untuk dibaca.


1

Ada solusi sederhana yang bisa menyelesaikan masalah Anda.

Tempatkan kursor Anda di awal blok teks yang ingin Anda hapus, dan lakukan d50gg.

Ini akan menghapus semua baris dari posisi Anda saat ini ke baris ke-50 teks Anda.

eq: jika kursor Anda berada di baris 46 , d50ggakan menghapus 4 baris.


1
Saya sarankan menggunakan Gdaripada gg karena juga berfungsi di vi, dan tentu saja :set numberselalu berguna untuk menemukan nomor baris yang ingin Anda tuju.
Acak832

Inti dari pertanyaan ini adalah Anda tidak tahu berapa banyak baris yang ingin Anda hapus.
200_sukses

200_sukses, Anda tidak perlu tahu berapa banyak baris yang ingin Anda hapus dengan jawaban yang saya posting. Yang harus Anda ketahui adalah "ke baris mana Anda ingin menghapus"
Geee

1

Gunakan mode visual dengan penyorotan garis.

  1. Letakkan kursor Anda di baris atas blok teks / kode untuk dihapus
  2. Tekan Shift+v
  3. Pindahkan kursor ke bawah ke bagian bawah blok teks / kode untuk dihapus
  4. tekan d

Saya lebih suka metode ini untuk menghapus blok kode karena menghapus seluruh baris dibandingkan dengan hanya menggunakan mode visual di mana Anda harus memposisikan kursor di kolom kanan untuk menghapus apa yang Anda inginkan.


3
Anda pada dasarnya mengulangi jawabannya dengan @ 200_success.
Martin Schröder

1

Saya tidak suka memiliki relativenumbersemua waktu, jadi saya mengkonfigurasi Vim saya untuk mengaktifkannya hanya ketika saya dalam Mode Visual:

" Entering Visual mode
nnoremap <silent>     v :set relativenumber cursorcolumn<CR>v
nnoremap <silent> <C-q> :set relativenumber cursorcolumn<CR><C-q>
nnoremap <silent>    gv :set relativenumber cursorcolumn<CR>gv
nnoremap <silent>     V :set relativenumber<CR>V

" When finished
augroup ClearCursorColumnAndLine
    autocmd!
    autocmd CursorHold * set norelativenumber nocursorcolumn nocursorline
augroup END

Ini membuat tugas Anda mudah:

V49jd

karena setelah memukul VAnda dapat melihat seberapa jauh garis targetnya.

Ini mungkin terbukti menjengkelkan dalam jangka panjang (teks bergeser ke kanan dan kiri ketika relativenumber diaktifkan / dinonaktifkan), tetapi sejauh ini saya cukup menikmatinya.


1
Saya pikir Anda menggunakan v<Esc>d50j?
Martin Tournoij

Terima kasih, saya memang salah menuliskannya. Sebenarnya saya mulai dengan Vjika saya tahu saya akan melakukan operasi garis-bijaksana, dan kemudian saya dapat meninggalkan dsampai terakhir, untuk kepercayaan diri yang lebih besar.
joeytwiddle

Jawaban saya tampaknya adalah perkiraan orang miskin dari plugin numbers.vim yang ditawarkan dalam jawaban lain. ;-)
joeytwiddle

1

Apa yang bekerja sangat baik untuk saya vi:

  1. :set number untuk melihat nomor baris sampai tempat saya ingin menghapus;

    +1289 idle 
    +1289 idle 
    +1290 # <- I want to delete until here
    +1291 if [[ ! -z "$SFIN" ]]
    
  2. Kembali ke baris tempat penghapusan harus dimulai

  3. Penghapusan yang digunakan dari baris saat ini, dalam mode normal> d1290G
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.