Dalam Vim apakah ada cara untuk menghapus tanpa memasukkan teks ke dalam register?

470

Menggunakan Vim, saya sering ingin mengganti satu blok kode dengan satu blok yang baru saja saya tarik.

Tetapi ketika saya menghapus blok kode yang akan diganti, blok itu sendiri masuk ke register yang menghapus blok yang baru saja saya tarik. Jadi saya punya kebiasaan menarik, kemudian memasukkan, kemudian menghapus apa yang tidak saya inginkan, tetapi dengan blok kode yang besar ini menjadi berantakan mencoba untuk menjaga blok yang dimasukkan dan blok untuk menghapus terpisah.

Jadi apa cara tercepat dan paling cepat untuk mengganti teks dalam Vim?

  • apakah ada cara untuk menghapus teks tanpa memasukkannya ke dalam register?
  • apakah ada cara untuk mengatakan misalnya "ganti kata berikutnya" atau "ganti hingga paragraf berikutnya"
  • atau apakah cara terbaik untuk menggunakan fitur multi-register entah bagaimana?
Edward Tanguay
sumber
1
vim-easyclip ( github.com/svermeulen/vim-easyclip ) dirancang untuk mengatasi masalah ini
Steve Vermeulen
1
Saya mengajukan pertanyaan, tanpa sadar (pada saat itu) duplikat dari masalah Anda yang sebenarnya , tetapi tidak terlalu banyak pada pertanyaan judul. TL; DR - ganti dengan apa yang Anda gunakan menggunakan viwp(untuk word).
OJFord

Jawaban:

429

Untuk menghapus sesuatu tanpa menyimpannya dalam register, Anda dapat menggunakan "register lubang hitam":

"_d

Tentu saja Anda juga bisa menggunakan register lain yang tidak memiliki apa pun yang Anda minati.

Christian Berg
sumber
4
Awalnya saya pikir perintah ini tidak berfungsi dengan baik. Kemudian saya menyadari bahwa saya menggunakan versi "kunci mati" dari keyboard Amerika. Dengan tata letak keyboard ini saya harus mengetik "<space>_d. Ruang diperlukan untuk benar-benar mengetikkan ".
Sebastián Grignoli
4
Adakah ide untuk melakukan ini secara selektif hanya pada baris kosong? (Jika saya ddpada baris kosong itu masuk ke lubang hitam, kalau tidak ddseperti biasa).
Jonathan Dumaine
6
Untuk menghapus satu karakter, coba:"_x
kenorb
54
Ini adalah salah satu area di mana editor teks standar menang. Anda cukup menekan tombol hapus.
Vince Panuccio
22
Anda juga dapat menarik sesuatu dengan yyatau '3yy' (atau apa pun), yang menempatkannya dalam register yang tidak disebutkan namanya, tetapi juga dalam 0. Anda kemudian dapat menempelkannya dengan "0p, meskipun telah digunakan dsetelah itu.
Halfgaar
102

Ya. Ini sedikit lebih berbelit-belit daripada menghapus teks "lama" terlebih dahulu, tetapi:

Saya mulai dengan ..

line1
line2
line3
line4

old1
old2
old3
old4

Saya shift+ vmemilih baris1, baris 2, 3 dan 4, dan menghapusnya dengan dperintah

Kemudian saya menghapus 1-4 baris lama dengan cara yang sama.

Lalu, lakukan

"2p

Itu akan menempelkan kedua baris terakhir yang dicabut (baris 1-4). "3pakan melakukan yang ketiga dari terakhir, dan seterusnya ..

Jadi saya berakhir dengan

line1
line2
line3
line4

Referensi: Dokumentasi Vim tentang register bernomor

dbr
sumber
Jika Anda memilih baris dengan <Shift-v> Anda menghapusnya hanya dengan d, bukan dd
Heikki Naski
31
1 hingga 9 berfungsi untuk penghapusan. Untuk menempelkan hal terakhir yang benar-benar menarik (dengan 'y') Anda harus menggunakan "0p. Itu berguna dalam kasus di mana Anda pertama kali menarik sesuatu yang bermaksud untuk mengganti sesuatu yang lain, tetapi kemudian sesuatu yang lain menimpa register tempel default.
Rafael de F. Ferreira
Untuk lebih undo kecanggihan check out yang Gundo (undo grafis) naskah .
Lumi
@ RafaeldeF.Ferreira: Komentar Anda bukan jawaban untuk pertanyaan ini, tetapi sebenarnya ini memecahkan kemungkinan masalah sebenarnya yang membuat OP mengajukan pertanyaan sejak awal. Bagi saya, itulah masalah sebenarnya.
0xc0de
76

Dokumen VIM: Register bernomor 0 berisi teks dari perintah yank terbaru, kecuali jika perintah tersebut menentukan register lain dengan ["x].

Misalnya kita mencabut "foo" dan menghapus "bar" - registri 0 masih mengandung "foo"! Karenanya "foo" dapat ditempel menggunakan"0p

alex2k8
sumber
53

Berguna untuk memiliki pemetaan yang mudah yang memungkinkan Anda mengganti pilihan saat ini dengan buffer.

Misalnya ketika Anda meletakkan ini di .vimrc Anda

vmap r "_dP       // it's a capital 'p' on the end

kemudian, setelah menyalin sesuatu ke dalam register (yaitu dengan 'y'), Anda cukup memilih teks yang ingin Anda ganti, dan cukup tekan 'r' pada keyboard Anda. Pilihan akan diganti dengan daftar Anda saat ini.

Penjelasan:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste
João Portela
sumber
1
Untuk versi yang lebih lanjut, periksa: stackoverflow.com/questions/290465/…
Luc Hermitte
Saya ingin menggunakanvmap <C-P> "_dP
Harry Lee
7
Anda cukup meletakkan teks tanpa menghapus pilihan. Misalnya Vpmengganti baris Anda saat ini dengan yang disentak segera.
Bobby Marinoff
Solusi ini tidak memperbaiki masalah dengan dyang sering digunakan untuk dihapus.
Victor Yarema
35

Saya memasukkan yang berikut ini di vimrc saya:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Sekarang saya menarik dan memasukkan dari daftar clipboard, dan tidak perlu peduli dengan apa yang terjadi dengan register default. Manfaat tambahan adalah saya dapat menempelkan dari aplikasi lain dengan kerumitan minimal. Saya kehilangan beberapa fungsi, saya tahu, tetapi saya tidak bisa melacak lebih dari satu register / clipboard.

Magnus
sumber
6
Alih-alih semua remaps itu, Anda juga bisa set clipboard=unnamedatau set clipboard=unnamedplus, yang mengubah clipboard default menjadi *atau +, masing-masing.
Steve
5
@Steve Jika Anda melakukan itu, maka d akan menghapus yank terakhir ke register clipboard juga, yang merupakan pertanyaan yang coba dihindari.
79E09796
1
@ 79E09796, saya tidak bermaksud mengatakan bahwa itu akan terjadi; Saya mengomentari jawaban ini dan bukan pertanyaan aslinya.
Steve
1
Saya meletakkan ini di .vimrc saya dan sekarang menarik tidak berfungsi. Ada yang tahu kenapa?
tba
2
@ tba ganti noremap dengan nnoremap (dua n's) dan itu akan berfungsi dengan baik.
meain
24

Untuk contoh spesifik yang Anda berikan, jika saya mengerti pertanyaannya maka ini mungkin berhasil:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
EBGreen
sumber
6
Ini berfungsi dengan baik kecuali jika Anda ingin menempel beberapa pilihan.
23

Semua operasi penarikan dan penghapusan menulis ke register yang tidak disebutkan namanya secara default. Namun, penarikan terakhir dan penghapusan terbaru selalu disimpan (secara terpisah) dalam register bernomor. Register 0memegang yank terbaru. Register 1-9memegang 9 penghapusan terbaru (dengan 1menjadi yang terbaru).

Dengan kata lain, sebuah penghapusan menimpa yank terbaru dalam register yang tidak disebutkan namanya, tetapi itu masih ada di dalam 0register. Trik daftar "_ddlubang hitam ( ) yang disebutkan dalam jawaban lain berfungsi karena mencegah menimpa register yang tidak disebutkan namanya, tetapi itu tidak perlu.

Anda mereferensikan register menggunakan tanda kutip ganda, sehingga menempelkan teks yang baru-baru ini ditarik bisa dilakukan seperti ini:

"0p

Ini adalah referensi yang bagus:

Wayne
sumber
16

Untuk menekankan apa yang dikatakan EBGreen :

Jika Anda menempel ketika memilih teks, teks yang dipilih diganti dengan teks yang ditempel.

Jika Anda ingin menyalin beberapa teks lalu menempelkannya di beberapa lokasi, gunakan "0puntuk menempelkan. Register bernomor 0 berisi teks dari perintah yank terbaru.


Anda juga dapat membuat daftar isi dari semua register Anda:

:registers

Perintah itu membuatnya lebih mudah untuk mengetahui register apa yang Anda inginkan ketika melakukan sesuatu seperti jawaban dbr . Anda juga akan melihat register /,%, #. (Lihat juga :help registers)


Dan akhirnya, periksa cWdan cWubah kata termasuk dan tidak termasuk spasi tambahan. (Menggunakan modal Wtermasuk tanda baca.)

idbrii
sumber
10

Jika Anda menggunakan Vim maka Anda akan memiliki mode visual, yang seperti memilih, tetapi dengan mode pemisahan itu adalah dasar dari vi / vim.

Yang ingin Anda lakukan adalah menggunakan mode visual untuk memilih sumber, lalu menarik, lalu menggunakan mode visual lagi untuk memilih ruang lingkup tujuan, dan kemudian menempelkan ke teks dari buffer default.

Contoh:

Dalam file teks dengan:

1 | qwer
2 | asdf
3 | zxcv
4 | poiu

dengan urutan berikut: ggVjyGVkpAnda akan diakhiri dengan:

1 | qwer
2 | asdf
3 | qewr
4 | asdf

Dijelaskan:

  • gg: buka baris pertama
  • V: mulai mode visual dengan seluruh garis
  • j: turun satu baris (dengan seleksi dimulai pada baris sebelumnya ini menumbuhkan seleksi satu baris ke bawah)
  • y: tarik ke buffer default (dua baris yang dipilih, dan secara otomatis keluar dari mode visual)
  • G: pergi ke baris terakhir
  • V: mulai mode visual (sama seperti sebelumnya)
  • k: naik satu baris (seperti sebelumnya, dengan mode visual diaktifkan, ini meningkatkan seleksi satu baris ke atas)
  • p: paste (dengan pilihan pada dua baris terakhir, itu akan mengganti garis-garis itu dengan apa pun yang ada di buffer - 2 baris pertama dalam kasus ini)

Ini memiliki sedikit ketidaknyamanan yang menempatkan blok terakhir pada buffer, jadi entah bagaimana tidak diinginkan untuk mengulangi hal yang sama, jadi Anda ingin menyimpan sumber ke buffer bernama dengan sesuatu seperti "ay(ke buffer yang disebut "a ") dan rekatkan dengan sesuatu seperti "ap(tetapi kemudian jika Anda pemrograman, Anda mungkin tidak ingin menempel beberapa kali tetapi untuk membuat fungsi dan menyebutnya, kan? KANAN ?).

Jika Anda hanya menggunakan vi, maka Anda harus menggunakan tanda yang tidak terlihat alih-alih mode visual, :he markuntuk lebih lanjut tentang ini, saya minta maaf tapi saya tidak terlalu baik dengan hal tanda yang tidak terlihat ini, saya cukup terkontaminasi dengan mode visual.

Maeghith
sumber
10

Untuk 'ganti kata', coba cwdalam mode normal.

Untuk 'ganti paragraf', coba capdalam mode normal.

Swaroop CH
sumber
1
Untuk 'mengganti hingga paragraf berikutnya', coba c}dalam mode normal.
jabirali
Mengapa "topi" melakukan ini? Bukankah "a" dan "p" adalah singkatan dari "append" dan "paste"?
WiSaGaN
2
@WiSaGaN "ap" adalah singkatan dari "a paragraph": vimhelp.appspot.com/motion.txt.html#object-select
Swaroop CH
9

Solusi invasif minimal untuk yang malas:

Daftar 0selalu berisi yank terakhir (seperti yang telah disebutkan Rafael , alex2k8 dan idbrii ). Sayangnya memilih register 0sepanjang waktu bisa sangat mengganggu, jadi alangkah baiknya jika pdigunakan "0secara default. Ini dapat dicapai dengan menempatkan baris berikut ke dalam Anda .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

Baris pertama memetakan setiap pstroke ke "0p. Namun, ini mencegah pdari mengakses register lain. Oleh karena itu semua pgoresan dengan register yang dipilih secara eksplisit dipetakan ke ekspresi commandline yang setara dalam for-loop. Hal yang sama dilakukan untuk P.

Dengan cara ini perilaku standar dipertahankan, kecuali untuk implisit pdan Pstroke, yang sekarang menggunakan register 0secara default.

Petunjuk 1: Perintah cut sekarang "0dbukan hanya d. Tapi karena saya malas ini terlalu lama bagi saya;) Oleh karena itu saya menggunakan pemetaan berikut:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

Kunci pemimpin \secara default, sehingga Anda dapat dengan mudah memotong teks dengan mengetik \datau \D.

Petunjuk 2: Batas waktu default untuk pemetaan multi-kunci cukup singkat. Anda mungkin ingin menambahnya agar memiliki lebih banyak waktu ketika memilih register. Lihat :help timeoutlenuntuk detail, saya menggunakan:

set timeout timeoutlen=3000 ttimeoutlen=100
Torben
sumber
7

Baiklah, pertama lakukan perintah ini:

:h d

Maka Anda akan menyadari bahwa Anda dapat menghapus ke dalam register tertentu. Dengan begitu Anda tidak akan mengubah apa yang ada di register default Anda.

EBGreen
sumber
1
["x]d{motion} Delete text that {motion} moves over [into register x]- Vim:h d
Wes Turner
5

Situasi saya: dalam Normalmode, ketika saya menghapus karakter menggunakan xpenekanan tombol, penghapusan itu menimpa register terakhir saya - suntingan yang menyulitkan di mana saya ingin menghapus karakter menggunakan xdan menempelkan sesuatu yang saya miliki di register terbaru saya (misalnya menempelkan teks yang sama di dua atau lebih banyak tempat).

Saya mencoba saran di jawaban yang diterima ( "_d), tetapi tidak berhasil.

Namun, dari jawaban / komentar yang diterima di /vi/122/performing-certain-operations-without-clearing-register , saya menambahkan ini ke my ~/.vimrc, yang berfungsi (Anda mungkin harus me-restart Vim ):

nnoremap x "_x

Yaitu, sekarang saya dapat melakukan perintah yank ( y), delete ( d), dan paste ( p) saya yang normal - dan karakter yang saya hapus menggunakan xtidak lagi mengisi register yang paling baru.

Victoria Stuart
sumber
4

Teks yang dihapus, saat dalam mode sisipkan, tidak masuk ke register standar.


sumber
2
tetapi menghapus sejumlah besar teks dalam mode default adalah SLOW
Hamish Downer
3

Dua solusi yang saya gunakan dalam konteks yang benar adalah;

  • sorot apa yang ingin Anda ganti menggunakan VISUALmode Vims kemudian rekatkan register.

Saya menggunakan ini sebagian besar karena kebiasaan karena saya hanya menemukan solusi kedua jauh kemudian, misalnya

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Dengan plugin ini Anda dapat menggunakan pengikat tombol <ctrl>+<p>untuk mengganti register bernomor sebelumnya dengan yang baru saja Anda tempelkan.

Pada dasarnya Anda melakukan paste seperti yang Anda inginkan, tetapi ketika Anda menyadari bahwa Anda telah menimpa register default sehingga kehilangan apa yang sebenarnya ingin Anda tempel, Anda dapat <C-P>menemukan dan mengganti dari sejarah YankRing!

Salah satunya harus memiliki plugin ...

pengusir
sumber
3

Saya menemukan pemetaan yang sangat berguna untuk tujuan Anda:

xnoremap p "_dP

Teks yang dihapus dimasukkan ke dalam "register lubang hitam", dan teks yang ditarik kembali tetap ada.

Sumber: http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text

Hieu Nguyen
sumber
2

Dalam versi windows (mungkin di Linux juga), Anda dapat menarik ke dalam sistem copy / paste buffer menggunakan "*y(yaitu mendahului perintah yank Anda dengan tanda kutip ganda dan tanda bintang).

Anda kemudian dapat menghapus garis yang dapat diganti secara normal dan menempelkan teks yang disalin menggunakan "*p.

JayG
sumber
2

Saya sering membuat kesalahan ketika mengikuti perintah 'y'ank, lalu' "_d'elete ke dalam black hole lalu 'p'aste. Saya lebih suka ke' y'ank, lalu hapus sesuka saya, kemudian '" 0p' dari register 0, yang merupakan tempat teks terakhir yang disalin didorong ke.

Tidak mengerti
sumber
2

Untuk pengguna emacs-evil, fungsi (evil-paste-pop)ini dapat dipicu setelah menempel, dan menggilir entri sebelumnya di kill-ring. Dengan asumsi Anda mengikatnya <C-p>(default di Spacemacs), Anda akan menekan pdiikuti oleh sebanyak yang <C-p>diperlukan.

Adrien Vakili
sumber
1

Untuk pengguna Dvorak, satu metode yang sangat mudah adalah dengan hanya menghapus teks yang tidak dibutuhkan ke dalam register "1 bukannya" black hole register, jika hanya karena Anda dapat menekan "+ 1 dengan tombol shift yang sama dan gerakan pinky yang cepat karena 1 adalah kunci tepat di atas "di Dvorak (PLUS d ada di sisi lain, yang membuat seluruh perintah cepat sekali).

Maka tentu saja, register "1 dapat digunakan untuk hal-hal lain karena kenyamanannya, tetapi kecuali jika Anda memiliki tujuan yang lebih umum daripada mengganti teks, saya akan mengatakan itu adalah penggunaan register yang cukup baik.

Vic Goldfeld
sumber
1

Bagi Anda yang tertarik untuk tidak menimpa register yang tidak disebutkan namanya saat Anda mengganti teks melalui seleksi virtual dan tempel.

Anda dapat menggunakan solusi berikut ini yang mudah dan paling cocok untuk saya:

xnoremap <expr> p 'pgv"'.v:register.'y'

Ini dari jawaban (dan komentar) di sini: Cara menempel tanpa mendaftar ulang

Ini melewati seleksi pertama, lalu pemilihan dengan teks baru dipilih lagi (gv). Sekarang register yang terakhir digunakan dalam mode visual (biasanya register yang tidak disebutkan namanya tetapi berfungsi juga efek samping gratis jika Anda menggunakan register lain untuk menempel). Dan kemudian tarik nilai baru ke register lagi.

PS: Jika Anda memerlukan varian yang lebih sederhana yang bekerja juga dengan plugin intellj idea vim-simulasi, Anda dapat menggunakan yang ini (downside: timpa register yang tidak disebutkan namanya meskipun ada register lain yang diberikan untuk ditempelkan):

vnoremap p pgvy

jepret
sumber
0

Preferensi Vim sesekali untuk kompleksitas daripada kepraktisan membebani pengguna dengan menerapkan register untuk menyalin / menghapus tindakan - ketika lebih sering daripada tidak, seseorang hanya ingin menempelkan apa yang disalin dan "melupakan" apa yang telah dihapus.

Namun, alih-alih melawan register rumit vim, buat mereka lebih nyaman: pilih register "default" untuk menyimpan penghapusan terbaru Anda. Sebagai contoh, kirim penghapusan ke register d (membiarkan ac terbuka untuk penggunaan ad-hoc; d adalah mnemonik yang bagus):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Pendekatan ini mencegah penghapusan dari mencabut yanks TETAPI tidak kehilangan mendaftarkan penghapusan - seseorang dapat menempel (kembali) apa yang telah dihapus alih-alih kehilangannya dalam lubang hitam (seperti dalam jawaban yang diterima). Dalam contoh di atas, penarikan kembali ini dilakukan dengan dua pemetaan pemimpin. Manfaat dari pendekatan ini, adalah memberi Anda kemampuan untuk memilih apa yang akan ditempel: (a) apa yang baru saja dicabut, atau (b) apa yang baru saja dihapus.

menyenangkan
sumber
0

daftar 0 sampai 9 adalah hal-hal terbaru yang Anda tarik atau potong dll, dan JANGAN termasuk hal-hal yang dihapus dll. Jadi jika Anda menarik / memotong sesuatu, itu ada dalam daftar 0 juga, bahkan jika Anda mengatakan hal-hal yang dihapus sepanjang hari setelah itu, daftar 0 masih hal terakhir yang kamu tarik / potong.

yiw #harus mendaftar secara default, dan mendaftar 0

itu menarik kata kursor masuk

barang yang dihapus dll akan masuk ke daftar default, tetapi TIDAK mendaftar 0

dalam mode standar:

"0p # masukkan isi register 0

dalam mode sisipkan:

ctrl-r 0 # masukkan konten register 0

Saya juga punya teman yang selalu mencabut / memotong untuk mendaftar x lol.

bob
sumber