Cara menempelkan tanpa menimpa register

112

Adakah yang tahu tentang cara menempelkan di atas area yang dipilih secara visual tanpa menempatkan pilihan di register default?

Saya tahu saya bisa menyelesaikan masalah dengan selalu menempelkan dari register eksplisit. Tapi itu menyakitkan di leher untuk mengetik, "xpbukan hanyap

Starr Horne
sumber

Jawaban:

33

"{register}ptidak akan berfungsi seperti yang Anda gambarkan. Ini akan menggantikan seleksi dengan konten register. Anda harus melakukan sesuatu seperti:

" I haven't found how to hide this function (yet)
function! RestoreRegister()
  let @" = s:restore_reg
  return ''
endfunction

function! s:Repl()
    let s:restore_reg = @"
    return "p@=RestoreRegister()\<cr>"
endfunction

" NB: this supports "rp that replaces the selection by the contents of @r
vnoremap <silent> <expr> p <sid>Repl()

Yang seharusnya baik-baik saja selama Anda tidak menggunakan plugin yang memiliki vmap non-nore ke p, dan yang mengharapkan register untuk ditimpa.

Kode ini tersedia sebagai skrip di sana . Ingo Karkat juga mendefinisikan plugin yang memecahkan masalah yang sama.

Luc Hermitte
sumber
Sebenarnya, saya pikir ada cara yang rapi untuk mengambil register yang digunakan, tapi tidak ingat caranya. Karenanya kompleksitas fungsinya.
Luc Hermitte
1
Saya pikir ini berlebihan, tidak akan mengingat regtype(secara garis?) Dan bahwa pemetaan ulang pgvysudah cukup.
Benoit
2
Ini mungkin berlebihan, tetapi tidak memiliki efek samping. Pada "xp, ini tidak menimpa @"isi dengan @xsepertipgvy
Luc Hermitte
1
lalu bagaimana :xnoremap p pgv@=v:register.'y'<cr>?
Benoit
1
Itu tidak berhasil untuk saya. Saya juga sudah mencoba mengunduh skrip. Berikut daftar perintah yang saya lakukan: Pertama saya tekan v, lalu e untuk memilih sampai akhir kata, lalu y untuk menariknya. Setelah itu, saya membuka kata lain yang ingin saya ganti. Saya menekan v, e lalu p untuk mengganti yang itu. Lalu saya melakukannya lagi, tapi kali ini kata berikutnya diganti dengan yang saya ganti tadi.
Eddy
41

Aku tidak suka perilaku default vim menyalin semua teks dihapus dengan d, D, c, atauC ke default mendaftar.

Saya menyiasatinya dengan memetakan dke "_d, cke"_c , dan seterusnya.

Dari .vimrc saya:

"These are to cancel the default behavior of d, D, c, C
"  to put the text they delete in the default register.
"  Note that this means e.g. "ad won't copy the text into
"  register a anymore.  You have to explicitly yank it.
nnoremap d "_d
vnoremap d "_d
nnoremap D "_D
vnoremap D "_D
nnoremap c "_c
vnoremap c "_c
nnoremap C "_C
vnoremap C "_C
Jeff Lake
sumber
Meskipun pemetaan ini berguna (saya melakukan sesuatu yang serupa sendiri), mereka tidak menjawab pertanyaan OP, p masih akan menimpa apa yang Anda sisipkan di atas konten yang dipilih.
Magnus
32

Gunakan yang berikut ini:

xnoremap p pgvy

ini akan memilih ulang dan menarik kembali teks yang ditempelkan dalam mode visual.

Sunting: agar ini bekerja, "xpAnda dapat melakukan:

xnoremap p pgv"@=v:register.'y'<cr>

v:register memperluas ke nama register terakhir yang digunakan dalam perintah mode normal.

Benoit
sumber
Di a "xp, pendekatan ini menimpa @"dengan @x.
Luc Hermitte
3
Saran Anda tentang xnoremap p pgv"@=v:register.'y'<cr>tidak berhasil untuk saya. Ini, bagaimanapun, tidak:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak
Ini terlihat menarik. Bisakah Anda menambahkan baris tentang apa g? Saya belum pernah melihatnya sebelumnya.
LondonRob
4
@ LondonRob: gsendiri tidak melakukan apa-apa. Ini menyediakan perintah multi-tombol yang diperluas, seperti z. Misalnya, gopergi ke byte ke-n dalam buffer, gjdan gkpergi ke baris yang ditampilkan berikutnya dan sebelumnya (berbeda dari jksaat garis dibungkus), gamenampilkan informasi tentang karakter di bawah kursor, gJmenggabungkan baris tanpa spasi, dan di sini gvmemulihkan pemilihan visual terakhir. Anda bisa menggunakan :help gv.
Benoit
6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' , saya menambahkan ``> `` Untuk mengembalikan posisi kursor
rox
19

Dalam Anda .vimrc

xnoremap p "_dP

Saya menemukan ini dari tanggapan di utas serupa, tetapi sumber aslinya adalah http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text . Ini menyebutkan beberapa kekurangan, namun berfungsi dengan baik untuk saya.

Jason Denney
sumber
2
Ini sepertinya solusi paling sederhana.
rudolph9
1
Bekerja untuk saya. Dan jawaban ini jelas. .vimrc.localbaik juga.
BaiJiFeiLong
3
Tidak berfungsi jika pilihan Anda meluas hingga akhir baris.
John Freeman
6

Solusi Luc Hermitte bekerja seperti pesona. Saya menggunakannya selama sekitar satu minggu atau lebih. Kemudian saya menemukan solusi dari .vimrc Steve Losh yang berfungsi dengan baik jika YankRing adalah bagian dari daftar plugin / bundel Anda:

function! YRRunAfterMaps()                                                                                                      
    " From Steve Losh, Preserve the yank post selection/put.    
    vnoremap p :<c-u>YRPaste 'p', 'v'<cr>gv:YRYankRange 'v'<cr> 
endfunction  
Taine
sumber
6

Coba ini di ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapartinya ini hanya untuk Visualmode, bukan Visual + Selectmode.

  • <expr>berarti bahwa {rhs}dari xnoremap {lhs} {rhs}pengaturan dievaluasi sebagai ekspresi.

  • Dalam hal ini, ekspresi kita 'pgv"'.v:register.'y'sedang digunakan .untuk penggabungan.

  • v:register dievaluasi ke register yang digunakan selama pemenuhan pemetaan.

Hasil dari "xpakan mengevaluasi ke pgv"xy, dimana xregister.

Saya dibantu oleh jawaban untuk pertanyaan stackoverflow ini: Vim - pemetaan dengan prefiks register opsional sehubungan dengan jawaban Benoit di halaman ini

mrak
sumber
4

Fungsi Luc bekerja dengan baik untuk saya setelah saya membuat perubahan untuk mendukung fakta bahwa saya memiliki clipboard = set tanpa nama:

function! RestoreRegister()
    let @" = s:restore_reg
    if &clipboard == "unnamed"
        let @* = s:restore_reg
    endif
    return ''
endfunction
danprice
sumber
1
Untuk referensi: menggunakan clipboard=unnamedplusini harus @+daripada @*.
Sebastian Blask
2

Luc Hermitte berhasil! Sangat bagus. Inilah solusinya yang dimasukkan ke dalam fungsi toggle, sehingga Anda dapat beralih antara perilaku normal dan put no-replace-register.

perintahnya, u mengubah perilakunya

let s:putSwap = 1 
function TogglePutSwap()
    if s:putSwap
        vnoremap <silent> <expr> p <sid>Repl()
        let s:putSwap = 0 
        echo 'noreplace put'
    else
        vnoremap <silent> <expr> p p 
        let s:putSwap = 1 
        echo 'replace put'
    endif
    return
endfunction
noremap ,p :call TogglePutSwap()<cr>
Joernsn
sumber
Anda juga dapat mengubah s: Repl untuk mengembalikan "p" daripada "p @ = RestoreRegister () \ <cr>" bergantung pada nilai s: putSwap.
Luc Hermitte
1
lebih suka silent! vunmapdaripadavnoremap <silent> <expr> p p
Luc Hermitte
0

pemrograman lakban, tetapi bekerja untuk saya:

nmap viwp viwpyiw
nmap vi'p vi'pyi'
nmap vi"p vi"pyi"
nmap vi(p vi(pyi(
nmap vi[p vi[pyi[
nmap vi<p vi<pyi<
steven_noble
sumber
-4

coba -

:set guioptions-=a
:set guioptions-=A
Gowri
sumber
3
Mereka mengontrol apakah teks yang dipilih ditambahkan ke clipboard sistem windowing (misalnya, X11 atau Win32), bukan ke register salinan internal Vim.
Rob Kennedy