Cách dán mà không ghi đè lên thanh ghi


112

Có ai biết cách dán lên vùng được chọn trực quan mà không cần đặt vùng chọn trong thanh ghi mặc định không?

Tôi biết tôi có thể giải quyết vấn đề bằng cách luôn dán từ một sổ đăng ký rõ ràng. Nhưng rất đau cổ khi gõ "xpthay vì chỉp

Câu trả lời:


33

"{register}psẽ không hoạt động như bạn mô tả. Nó sẽ thay thế lựa chọn bằng nội dung của sổ đăng ký. Thay vào đó, bạn sẽ phải làm điều gì đó như:

" 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()

Điều này sẽ ổn miễn là bạn không sử dụng một plugin có vmap sang p không nore và điều đó mong muốn một đăng ký bị ghi đè.

Mã này có sẵn dưới dạng tập lệnh ở đó . Ingo Karkat cũng xác định một plugin giải quyết vấn đề tương tự.


Trên thực tế, tôi mặc dù đã có một cách gọn gàng để lấy sổ đăng ký được sử dụng, nhưng không thể nhớ cách làm. Do đó độ phức tạp của hàm.
Luc Hermitte

1
Tôi nghĩ rằng điều này là quá mức cần thiết, sẽ không nhớ regtype(linewise?) Và ánh xạ lại p thành pgvylà đủ.
Benoit

2
Nó có thể là quá mức cần thiết, nhưng nó không có tác dụng phụ. Trên một "xp, điều này không ghi đè @"nội dung với @xkhông giống nhưpgvy
Lục Hermitte

1
sau đó thì :xnoremap p pgv@=v:register.'y'<cr>sao?
Benoit

1
Nó không hiệu quả với tôi. Tôi cũng đã thử tải xuống tập lệnh. Đây là danh sách các lệnh tôi thực hiện: Đầu tiên tôi nhấn v, sau đó nhấn e để chọn đến cuối từ, sau đó nhấn y để kéo nó. Sau đó, tôi chuyển sang một từ khác mà tôi muốn thay thế. Tôi nhấn v, e rồi p để thay thế cái đó. Sau đó, tôi làm lại, nhưng lần này từ tiếp theo được thay thế bằng từ mà tôi đã thay thế trước đó.
Eddy

41

Tôi không thích những hành vi vim mặc định sao chép tất cả văn bản đã xóa với d, D, c, hoặc Cvào sổ đăng ký mặc định.

Tôi đã vượt qua nó bằng cách ánh xạ dtới "_d, ctới "_c, v.v.

Từ .vimrc của tôi:

"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

Các ánh xạ này cũng hữu ích như vậy (tôi tự làm điều gì đó tương tự), chúng không trả lời câu hỏi của OP, p sẽ vẫn ghi đè lên những gì bạn đã kéo dán lên nội dung đã chọn.
Magnus

32

Sử dụng như sau:

xnoremap p pgvy

điều này sẽ chọn lại và kéo lại bất kỳ văn bản nào được dán ở chế độ trực quan.

Chỉnh sửa: để điều này làm việc với "xpbạn, bạn có thể làm:

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

v:register mở rộng đến tên thanh ghi cuối cùng được sử dụng trong lệnh chế độ bình thường.


Trên a "xp, cách tiếp cận này ghi đè @"với @x.
Luc Hermitte

3
Đề xuất của bạn xnoremap p pgv"@=v:register.'y'<cr>không phù hợp với tôi. Tuy nhiên, điều này thực hiện:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak

Điều này có vẻ thú vị. Bạn có thể thêm một dòng về những gì gkhông? Tôi đã không nhìn thấy nó trước đây.
LondonRob

4
@LondonRob: gmột mình không làm gì cả. Nó cung cấp các lệnh mở rộng, nhiều phím, như z. Ví dụ: gochuyển đến byte thứ n trong bộ đệm, gjgkchuyển đến dòng tiếp theo và dòng hiển thị trước đó (khác với jkthời điểm các dòng được bao bọc), gahiển thị thông tin về ký tự dưới con trỏ, gJnối các dòng không có khoảng trắng và tại đây gvkhôi phục lựa chọn trực quan cuối cùng. Bạn có thể sử dụng :help gv.
Benoit

6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' , tôi đã thêm `` ``> `` Để khôi phục vị trí con trỏ
rox

19

Trong của bạn .vimrc

xnoremap p "_dP

Tôi tìm thấy điều này từ một phản hồi trên một chủ đề tương tự, nhưng nguồn ban đầu là http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text . Nó đề cập đến một số nhược điểm, tuy nhiên nó hoạt động tốt đối với tôi.


2
Đây có vẻ như là giải pháp đơn giản nhất.
rudolph9

1
Đã làm cho tôi. Và câu trả lời này là rõ ràng. .vimrc.localcũng được.
BaiJiFeiLong

3
Không hoạt động nếu lựa chọn của bạn kéo dài đến cuối dòng.
John Freeman

6

Giải pháp của Luc Hermitte hoạt động như một sự quyến rũ. Tôi đã sử dụng nó trong khoảng một tuần hoặc lâu hơn. Sau đó, tôi đã phát hiện ra một giải pháp từ .vimrc của Steve Losh hoạt động hiệu quả nếu YankRing là một phần của dòng plugin / gói của bạn:

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

6

Hãy thử điều này trong ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapcó nghĩa là điều này chỉ dành cho Visualchế độ, không phải Visual + Selectchế độ.

  • <expr>phương tiện mà {rhs}các xnoremap {lhs} {rhs}thiết lập được đánh giá là một biểu thức.

  • Trong trường hợp này, biểu thức của chúng ta 'pgv"'.v:register.'y'đang sử dụng .để nối.

  • v:register được đánh giá vào sổ đăng ký đang được sử dụng trong quá trình hoàn thành ánh xạ.

Kết quả của "xpsẽ đánh giá pgv"xy, xđăng ký ở đâu.

Tôi đã được trợ giúp bởi câu trả lời cho câu hỏi stackoverflow này: Ánh xạ Vim với tiền tố thanh ghi tùy chọn kết hợp với câu trả lời của Benoit trên trang này


4

Chức năng của Luc hoạt động tốt cho tôi sau khi tôi thực hiện thay đổi để hỗ trợ thực tế là tôi có bộ nhớ tạm = bộ không tên:

function! RestoreRegister()
    let @" = s:restore_reg
    if &clipboard == "unnamed"
        let @* = s:restore_reg
    endif
    return ''
endfunction

1
Để tham khảo: sử dụng clipboard=unnamedplusđiều này phải được @+thay vì @*.
Sebastian Blask

2

Luc Hermitte đã làm được trò lừa gạt! Thật sự tốt. Đây là giải pháp của anh ấy đưa vào một chức năng bật tắt, vì vậy bạn có thể chuyển đổi giữa hành vi bình thường và không cần đăng ký thay thế.

lệnh, bạn chuyển đổi hành vi

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>

Bạn cũng có thể thay đổi s: Repl để trả về "p" thay vì "p @ = RestoreRegister () \ <cr>" tùy thuộc vào giá trị s: putSwap.
Luc Hermitte

1
thích silent! vunmapthay vìvnoremap <silent> <expr> p p
Luc Hermitte

0

lập trình băng keo, nhưng phù hợp với tôi:

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<

-4

thử -

:set guioptions-=a
:set guioptions-=A

3
Những điều đó kiểm soát xem văn bản đã chọn có được thêm vào khay nhớ tạm của hệ thống cửa sổ hay không (ví dụ: X11 hoặc Win32), chứ không phải vào thanh ghi sao chép nội bộ của Vim.
Rob Kennedy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.