Vim: Mengganti satu baris dengan yang lain ditarik sebelumnya

112

Setidaknya sekali sehari saya mengalami situasi berikut:

A: This line should also replace line X
...
X: This is line should be replaced

Saya percaya bahwa saya tidak melakukan tugas itu dengan efisien.

Apa yang saya lakukan:

  • Pergi ke baris A: AG
  • Yank baris A: yy
  • Pergi ke baris X: XG
  • Tempel baris A: P
  • Pindah ke jalur lama: j
  • Hapus baris lama: dd

Ini memiliki kerugian tambahan bahwa baris X sekarang ada di register default, yang menjengkelkan jika saya menemukan baris lain yang harus diganti dengan A. Yanking dan paste dari register tambahan ( "ayy , " aP ) membuat tugas sederhana ini bahkan kurang efisien.

Pertanyaan saya:

  • Apakah saya melewatkan perintah Vim bawaan untuk mengganti baris yang dicabut sebelumnya?
  • Jika tidak, bagaimana saya dapat mengikat perintah saya sendiri yang meninggalkan (atau memulihkan) baris yang dicabut di register default?
renyah
sumber
2
Ini adalah satu-satunya masalah terbesar saya dengan model pengeditan Vim. Saya ingin tahu solusinya. Editor CUA membedakan antara potong dan hapus, jadi Anda cukup memotong beberapa teks, lalu Anda dapat menghapus dan menempelkan semua yang Anda inginkan. Dengan Vim, setiap penghapusan Anda membuat sampah teks Anda dipotong. Anda akhirnya menggunakan lebih banyak penekanan tombol daripada editor lain.
Lumpur
3
YankRing
ajreal
@Mud belajar tentang :movedan lubang hitam mendaftar ( _) (atau sebenarnya, hanya mendaftar)
lihat
2
@sehe Saya sangat mengetahui register, tapi itu menambahkan 4 penekanan tombol per operasi potong / tempel dan membutuhkan lebih banyak pemikiran. Saat Anda melakukan banyak pengeditan, itu bertambah dengan cepat.
Mud
Selain menghemat beberapa byte memori, apakah ada keuntungan menggunakan register lubang hitam dibandingkan dengan register lain? Saya berpendapat bahwa register apa pun bisa menjadi register lubang hitam jika Anda tidak membacanya kembali.
sleblanc

Jawaban:

91

Apa yang akan saya lakukan :

  1. aG
  2. Y
  3. xG
  4. Vp

Anda tidak harus meninggalkan mode normal, tetapi tidak yank baris. Namun Anda dapat menggunakan V"0pyang akan selalu membuat garis ditarik pada langkah 2.

icecrime.dll
sumber
11
@duddle: ya, Yadalah sinonim untukyy
icecrime
8
Langkah 1 dan 2 dapat digabungkan menggunakan: ay [Misalnya: 20y] Diikuti oleh Vp harus melakukan trik. Anda tidak harus pergi ke antrean untuk menariknya.
Bharad
2
Jika Anda menimpa baris tambahan dengan ccCTRL + r0ESC alih-alih V "0p maka semua baris berikut dapat diganti dengan just. (Pengulang)
Jordan Morris
Yadalah sinonim untuk yy, tetapi saya sarankan untuk memetakannya kembali menjadiy$ untuk mencocokkan Ddan C.
mgold
Lihat jawaban Jordan Morris stackoverflow.com/users/970673/jordan-morris di bawah ini - benar-benar menggunakan perintah vim secara maksimal dengan memungkinkan Anda mengulangi perintah beberapa kali.
JESii
105

Vp: pilih baris, tempel apa yang telah ditarik

Dorian
sumber
3
VPbekerja dengan baik, yang berguna karena Anda dapat menahan Shift untuk seluruh urutan.
George Hilliard
24
Trik yang sangat bagus, meskipun perlu diperhatikan (mungkin) peringatan yang signifikan: ini menyebabkan yank register diperbarui dengan konten baris yang sedang ditimpa, jadi mungkin tidak berfungsi dengan baik dengan beberapa tugas - misalnya jika Anda ingin menimpa jalur yang sama ke beberapa tujuan.
underscore_d
8
@underscore_d, ini berfungsi dengan baik jika Anda melakukannya V"0p, yang menempel dari register yang terakhir dicabut.
timblaktu
@timblaktu Bisa jelaskan apa V"0pfungsinya? V masuk ke mode garis Visual dan p untuk menempel. Apa "dan 0 untuk? Terima kasih
programmer
43

Ini memiliki kerugian tambahan bahwa baris X sekarang ada di register default, yang mengganggu jika saya menemukan baris lain yang harus diganti dengan A.

Untuk menghapus teks tanpa mempengaruhi register normal, Anda dapat menggunakan register lubang hitam "_:

"_dd
Eugene Yarmash
sumber
10
Saya menambahkan beberapa pemetaan untuk Vimrc saya untuk membuat ddan ddselalu menggunakan lubang hitam, dan xdan xxmelakukan apa yang kebanyakan editor sebut "cut" (menghapus dan menyimpan default register):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP
2
Saya berhati-hati dalam memetakan ulang hal-hal di VIM, karena ini mungkin tidak mudah di komputer lain, atau di plugin gaya VIM untuk IDE. Juga desainer VIM cenderung telah memecahkan masalah dengan pemetaan default jika Anda benar-benar menggali.
Jordan Morris
15

Berdasarkan jawaban yang menyarankan penggunaan Vpatau VPtempel di atas garis - untuk menghindari mengubah isi daftar yank, menurut saya perintah yang paling ergonomis adalah:

VPY

RichardW
sumber
Ini adalah solusi paling sederhana yang membuat isi yank tetap sama. Terimakasih banyak!
heylookltsme
14
  1. Y y
  2. j (pindah ke baris yang ingin Anda ganti), lalu
  3. Vp (huruf besar v dan kemudian p, akan diganti dengan konten yang ditarik)
Mariano Anaya
sumber
luar biasa! Memang sangat singkat dan memudahkan untuk memilih banyak garis dengan mode visual. Itu juga membuat buffer pasta tetap utuh. Ini menjengkelkan ketika dd menimpa buffer itu ...
Aktau
@ Aktau ini tidak membiarkan buffer tetap utuh.
Jordan Morris
9

Saya akan menggunakan mode commandline (Ex) dan melakukan dua perintah berikut

:XmA
:Ad

Ini hanya memindahkan baris X ke tepat di bawah A, lalu menghapus A memindahkan baris itu ke atas

Sebagai contoh

:7m3
:3d
ericgamliel.dll
sumber
Bisakah Anda memberi contoh? Ketika saya menekan misalnya 50Gm30G Vim pergi ke baris 50 dan kemudian ke bawah dan hanya itu. Juga: Iklan tidak melakukan apa pun untuk A = 50 atau A = 50G
renyah
7
  1. Pindah ke awal baris pertama.

  2. y, $- salin baris tanpa penghentian baris di bagian akhir

  3. Pindah ke awal garis target.

    1. V, p- ganti hanya satu baris target

    2. c, c, Ctrlr, 0, Esc- mengganti baris target dengan yank asli

  4. Pindah ke awal baris target berikutnya.

  5. . - mengulangi perintah yang dikeluarkan pada 4.2.

Catatan:

  • 4.1 adalah y, $karena jika Anda melakukannya y, yatau YAnda akan menyalin pemutusan baris, dan Ctrlr0sebenarnya menambahkan pemutusan baris di bawah garis target Anda.

  • 4.2 menggantikan V p, yang tidak bekerja dengan repeat karena secara teknis tindakan terakhir adalah delete, jadi .hanya akan menghapus satu baris.

  • Jika ada yang tahu bagaimana mengeluarkan 'ganti baris saat ini dengan register' dari mode EX (baris perintah), saya ingin mendengar dari Anda (dan untuk mengetahui di mana Anda menemukan dokumentasi). Mungkin ada perintah EX berulang yang lebih cepat dari 4.2 dan / atau tidak memiliki peringatan pemutusan baris.

Jordan Morris
sumber
1
Langkah 4.2 adalah pembunuh di sini, karena Anda sekarang dapat mengulangi seluruh proses dengan perintah titik seperti di 4.3 - itulah yang vim adalah tentang!
JESii
1
Saya tidak mengerti ini. 'AG' menempatkan pembuat saya di akhir baris, memasuki mode penyisipan dan memasukkan 'G'. Apa yang tidak saya dapatkan?
mulai
@ Gustafbstrom kritik yang adil - maaf A seharusnya mewakili nomor baris, tapi saya gagal menunjukkannya. Diedit.
Jordan Morris
5

Inilah yang akan saya lakukan

  • Pindah awal baris A, AG(di mana A jelas merupakan nomor baris)
  • Yank baris ke beberapa register, misalnya a (tanpa baris baru). Tipe"ay$
  • Pindah ke sisipkan baris, XG
  • Baris pengganti, S
  • Sisipkan dari register a, Ctrl-Ra
Brian Rasmussen
sumber
4

Anda dapat menggunakan ini dengan mode visual.

  • Pergi ke baris A: AG
  • Pilih garis dengan mode visual: VESC
  • pergi ke baris X: XG
  • Masuk mode pengganti untuk baris: S
  • Tempel baris yang Anda salin: shift+ insert(atau apa pun yang Anda petakan untuk ditempelkan dari papan klip).
Nathan Fellman
sumber
Ah. Tidak tahu tentang V dan S . Namun, langkah Anda tidak berhasil untuk saya karena saya tidak menarik ke papan klip OS saya, yang merupakan satu-satunya yang dapat saya akses dalam mode penyisipan. Jadi saya harus keluar dari mode penyisipan dulu.
renyah
3

Anda juga bisa melakukan:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Tidak membuat spasi atau ujung garis.
  • Kursor ditempatkan di awal teks yang disalin.

Tombol yang sama dapat digunakan untuk menarik / menempelkan lebih dari satu baris.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)
Kozmonaut
sumber
2

Anda dapat menggunakan perintah ini dalam Mode Normal:

:AmX | Xd

yang mperintah untuk m[ove], yang bergerak nomor baris A setelah nomor baris X, jika Anda ingin menyalin bukannya memindahkan baris, penggunaan co[py]. yang dperintah untuk d[elete].

Anda dapat memindahkan (menyalin menggunakan co) berbagai baris menggunakan

:start,end m X
Nafaa Boutefer
sumber
2

Mengingat komentar terbaru oleh cicld (terima kasih!), Saya melihat bahwa saya tidak memahami sepenuhnya masalah aslinya. Memindahkan garis tidak tepat, tetapi menyalinnya (karena garis itu ditarik.) Jadi saya akan merevisinya menjadi:

:1t20:20d_
  1. Salin baris pertama ( :tperintah adalah alias untuk :copy) setelah baris 20 (akan letakkan di baris 21)

  2. Hapus baris 20, letakkan baris yang dihapus ke dalam register 'lubang hitam' ( _) (yaitu tidak mempengaruhi buffer yank saat ini)

Seperti yang disebutkan dalam komentar terbaru, ini tidak akan mempengaruhi posisi kursor saat ini.

nkalvi.dll
sumber
1
  1. : ay (dengan a adalah nomor barisnya. Contoh: 20y). Ini menarik garis (permainan kata-kata).
  2. Vp
Bharad
sumber
1

Saya merasa lebih mudah menggunakan perintah Ex untuk ini; ex. untuk memindahkan baris 9 ke 46:

 :46|9m.|-1d

Ini akan memindahkan kursor ke baris 46, memindahkan baris 9 di bawah arus, lalu menghapus baris sebelumnya (karena baris yang dipindahkan adalah baris saat ini).

Atau menggunakan tanda, menggunakan tanda 'a':

:46ma a|9m'a|'ad
nk3181544
sumber
Keindahan dari perintah EX adalah Anda dapat menjalankannya di mana pun kursor Anda berada (dalam mode normal). Saya lebih suka :1m20|.+1d(pindahkan baris 1 ke baris 20 dan hapus baris berikutnya, yaitu teks yang ada di baris 20 sebelumnya). Ide yang sama sekalipun!
lingkari
1

Saya sering harus Y satu baris dan menggantinya di banyak tempat, yang masing-masing memiliki nilai yang berbeda (yang berarti saya tidak dapat membuat regex).

Y untuk menarik garis asli yang diinginkan

lalu di setiap baris yang ingin Anda ganti, VpzeroY

Ron
sumber
0

saya hanya akan menggunakan register "Lubang hitam":

diberikan:

nnoremap <Cd> "_dd

solusinya adalah:

<Cd> yy

j5shi
sumber