Bagaimana cara memindahkan teks dari satu register ke jumlah register yang berubah-ubah?

10

Apakah ada cara untuk 'pipa' teks dari register ke register lain atau set register? Misalnya, pindah "qke register "1melalui "5.

Saya sering ingin membuat versi yang sedikit berbeda dari makro yang sama, jadi berguna untuk dapat menyalin makro 'templat' ke beberapa register dan kemudian memodifikasi masing-masing di tempat.

Untuk memberikan contoh praktis, inilah masalah yang mendorong pertanyaan ini untuk saya.

Saya perlu mengubah baris berikut dari bahasa deskripsi perangkat keras menjadi banyak blok berulang,

RAM64(in=in, load=load0, address=address[0..5], out=out1);

untuk

RAM64(in=in, load=load1, address=address[0..5], out=out2);
RAM64(in=in, load=load2, address=address[0..5], out=out3);
RAM64(in=in, load=load3, address=address[0..5], out=out4);
RAM64(in=in, load=load4, address=address[0..5], out=out5);

Saya memiliki makro yang melakukan ini, menggunakan fungsi kenaikan, yypW^At)^Ayang saya simpan di register "a.

Terkadang, saya perlu pola kenaikan menjadi sedikit berbeda, seperti

RAM512(in=in, load=load1, address=address[0..8], out=out2);
RAM512(in=in, load=load2, address=address[0..8], out=out4);
RAM512(in=in, load=load3, address=address[0..8], out=out6);
RAM512(in=in, load=load4, address=address[0..8], out=out8);

di mana makro dalam register "bakan berada yypW^At)^A^A.

Saya ingin register melakukan ini, tetapi untuk setiap kenaikan dari 1-5. Register "adapat (entah bagaimana) disalin ke register b hingga e. Kemudian saya akan menempelkan setiap register ke buffer, membuat modifikasi yang diperlukan (menambahkan lebih banyak istilah, mengubah karakter yang mengikuti tgerakan, dll) dan menarik kembali ekspresi yang dimodifikasi kembali ke register. Idealnya langkah terakhir ini bahkan dapat dimasukkan dalam perintah untuk menyalin register

Ini menyelamatkan saya dari pengulangan semua karakter di makro yang TIDAK perlu diubah. Sebagai contoh saya ini mungkin sepele, tetapi saya dapat melihat saat-saat ketika mungkin akan sangat membantu untuk melakukan apa yang saya minta.

Kit
sumber
5
Selain itu, saya tidak akan merekomendasikan menggunakan register bernomor. Satu-satunya register "aman" adalah register alfabet. Semua register lain secara otomatis ditetapkan oleh Vim.
jamessan

Jawaban:

7

Makro hanyalah teks.

Buka buffer kosong baru dan letakkan makro Anda di sana. Anda dapat menduplikasi baris, mengubah satu hal di sini dan sesuatu yang lain di tempat lain, lalu menarik garis dan langsung menggunakannya @".

Tidak perlu mencemari register Anda, terutama register nomor yang melayani tujuan yang sama sekali berbeda.

- edit -

Pertanyaan Anda lebih mudah dipahami sekarang setelah Anda menambahkan beberapa penjelasan.

Ternyata, Anda hanya perlu mengubah rekaman awal Anda untuk mencapai tujuan Anda, tanpa bermain dengan register seolah-olah mereka adalah variabel:

:let i = 1                     " define variable i
qa                             " start recording in register a
yy                             " yank the line
p                              " paste it
W                              " move to next WORD
<C-v><C-a>                     " increment number
t)                             " jump to the other number to increment
:norm <C-r>=i<CR><C-v><C-a>    " increment the number by i
q                              " stop recording

Untuk membuat 5 salinan dari baris saat ini dengan angka terakhir ditambah 2:

:let i = 2|norm 5@a

atau 12 salinan, dengan angka terakhir bertambah 23:

:let i = 23|norm 12@a
romainl
sumber
Setuju tentang register numerik — tetapi bagaimana jika Anda ingin menggunakan ini dalam perintah, dan Anda perlu register yang memulai yang sama tetapi menjadi berbeda?
wchargin
@WChargin, tolong jelaskan.
romainl
Seperti dalam, mungkin aku ingin melakukan sesuatu dengan salinan diputar dari string, jadi jika abcdedalam @q, maka saya ingin @x="bcdea", @y="abcde"dan @z="eabcd". Saya mungkin mulai dengan membiarkan @x,, @ydan @zsemuanya sama @qdan kemudian memodifikasi mereka sesuai kebutuhan. Jelas, saya baru saja mengada-ada, tetapi sepertinya ada beberapa kasus di mana sesuatu yang serupa mungkin berguna.
wchargin
2
@Kit, saya agak khawatir dengan kurangnya contoh praktis dalam pertanyaan Anda yang segera membuatnya berbau seperti XY. Saya hampir yakin Anda salah mendaftar jadi saya ingin membaca penjelasan tentang apa yang Anda coba lakukan.
romainl
1
@Kit, itu salah satu dari banyak masalah dengan masalah masalah XY. Jawaban yang paling banyak dipilih adalah jawaban langsung berkualitas tinggi untuk pertanyaan Anda, tetapi pada akhirnya tidak berguna dalam konteks masalah Anda yang sebenarnya, sedangkan jawaban saya yang kurang terangkat adalah solusi aktual untuk masalah mendasar Anda. Kedua jawaban itu benar tetapi mereka menjawab pertanyaan yang berbeda yang membuat Anda sulit untuk memutuskan. Jika itu saya, saya akan menerima jawaban yang membahas masalah inti saya ... tapi itu hanya saya.
romainl
6

Menggunakan getregdansetreg

Untuk menyalin dari qke register 1- 5:

let src=getreg('q', 1)
for i in range(1, 5)
    call setreg(i, src)
endfor

Untuk menyalin ke daftar yang lebih umum:

let src=getreg('q', 1)
for i in ['a', 'c', 'e']
    call setreg(i, src)
endfor

Menggunakan execute

Untuk menyalin dari qke register 1- 5:

for i in range(1, 5)
   execute 'let @' . i . '=@a'
endfor

Untuk menyalin ke daftar yang lebih umum:

for i in ['a', 'c', 'e']
    execute 'let @' . i . '=@a'
endfor

Penjelasan. Perintah letini dapat digunakan sebagai let @x=@y, yang menyalin mendaftar yuntuk mendaftar x. Pada dasarnya, kami hanya membangun perintah-perintah ini dalam satu lingkaran (mengubah nilai xdalam bentuk di atas) dan executememasukkannya.

wchargin
sumber
1
Tidak perlu digunakan di :exesini. The getreg()dan setreg()fungsi akan menjadi lebih bersih.
jamessan
@ joessan Saran yang bagus, terima kasih — apakah saya menggunakan ini dengan benar?
wchargin
Saya telah mengeditnya untuk menambahkan argumen opsional kedua ke getreg () karena itu mengembalikan isi register dan bukan evaluasi yang memungkinkan.
jamessan
1

Untuk langsung menjawab pertanyaan, jika Anda ingin dengan cepat dan mudah menyalin konten dari satu register ke yang lain, Anda dapat memasukkan yang berikut ini di .vimrc Anda. Anda kemudian dapat mengeksekusi <leader>rcabuntuk menyalin isi register auntuk mendaftar b. Sebagai contoh saya memilih <leader>rcuntuk berdiri untuk 'daftar salinan'

function! s:CopyRegister()
    let sourceReg = nr2char(getchar())

    if sourceReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . sourceReg
        return
    endif

    let destinationReg = nr2char(getchar())

    if destinationReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . destinationReg
        return
    endif

    call setreg(destinationReg, getreg(sourceReg, 1))
    echo "Replaced register '". destinationReg ."' with contents of register '". sourceReg ."'"
endfunction

" rc = register copy
nnoremap <leader>rc :call <sid>CopyRegister()<cr>
Steve Vermeulen
sumber
1
Saya akan merekomendasikan getreg(sourceReg, 1).
jamessan
Ah ya benar. Tetap.
Steve Vermeulen