วิธีการวางโดยไม่ต้องเขียนทับลงทะเบียน


112

ไม่มีใครรู้วิธีการวางบนพื้นที่ที่เลือกด้วยสายตาโดยไม่ต้องมีการเลือกไว้ในทะเบียนเริ่มต้น?

ฉันรู้ว่าฉันสามารถแก้ปัญหาได้โดยการวางจากการลงทะเบียนที่ชัดเจนเสมอ แต่มันปวดต้นคอ"xpแทนการพิมพ์เฉยๆp

คำตอบ:


33

"{register}pจะไม่ทำงานตามที่คุณอธิบาย จะแทนที่การเลือกด้วยเนื้อหาของการลงทะเบียน คุณจะต้องทำสิ่งต่อไปนี้แทน:

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

ซึ่งควรจะใช้ได้ตราบเท่าที่คุณไม่ได้ใช้ปลั๊กอินที่มี vmap ที่ไม่ใช่ nore เป็น p และคาดว่าจะมีการเขียนทับรีจิสเตอร์

รหัสนี้สามารถใช้ได้เป็นสคริปต์มี Ingo Karkat ยังกำหนดปลั๊กอินเพื่อแก้ปัญหาเดียวกัน


อันที่จริงฉันมีวิธีเรียกข้อมูลทะเบียนที่ใช้อยู่ แต่จำวิธีการไม่ได้ ดังนั้นความซับซ้อนของฟังก์ชัน
Luc Hermitte

1
ฉันคิดว่านี่เป็นเรื่องที่มากเกินไปจำไม่ได้regtype(linewise?) และการรีแมป p pgvyเป็นก็เพียงพอแล้ว
Benoit

2
มันอาจจะมากเกินไป แต่ก็ไม่มีผลข้างเคียง ในวัน"xpนี้จะไม่เขียนทับ@"เนื้อหาที่@xไม่เหมือนpgvy
Luc Hermitte

1
แล้ว:xnoremap p pgv@=v:register.'y'<cr>ไงล่ะ?
Benoit

1
มันไม่ได้ผลสำหรับฉัน ฉันได้ลองดาวน์โหลดสคริปต์แล้วด้วย นี่คือรายการคำสั่งที่ฉันทำ: ขั้นแรกให้กด v จากนั้นกด e เพื่อเลือกที่ท้ายคำจากนั้น y เพื่อดึงมัน หลังจากนั้นฉันไปที่คำอื่นที่ฉันต้องการแทนที่ ฉันกด v, e แล้ว p เพื่อแทนที่อันนั้น จากนั้นฉันก็ทำอีกครั้ง แต่คราวนี้คำถัดไปจะถูกแทนที่ด้วยคำที่ฉันแทนที่ก่อนหน้านี้
Eddy

41

ฉันไม่ชอบพฤติกรรมที่เป็นกลุ่มเริ่มต้นของการคัดลอกข้อความทั้งหมดที่ถูกลบด้วยd, D, cหรือCลงในทะเบียนเริ่มต้น

ผมเคยไปรอบ ๆ ได้โดยการทำแผนที่dการ"_d, cการ"_cและอื่น ๆ

จาก. vimrc ของฉัน:

"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

มีประโยชน์พอ ๆ กับการแมปเหล่านี้ (ฉันทำอะไรคล้าย ๆ ตัวเอง) พวกเขาไม่ตอบคำถามของ OP แต่ p จะยังคงเขียนทับสิ่งที่คุณดึงมาจากเนื้อหาที่เลือก
Magnus

32

ใช้สิ่งต่อไปนี้:

xnoremap p pgvy

สิ่งนี้จะเลือกและดึงข้อความที่วางในโหมดภาพอีกครั้ง

แก้ไข: เพื่อให้สามารถใช้งานได้"xpคุณสามารถทำได้:

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

v:register ขยายเป็นนามสกุลรีจิสเตอร์ที่ใช้ในคำสั่งโหมดปกติ


ใน a "xpวิธีนี้จะเขียนทับ@"ด้วย@x.
Luc Hermitte

3
คำแนะนำของคุณxnoremap p pgv"@=v:register.'y'<cr>ไม่ได้ผลสำหรับฉัน อย่างไรก็ตามสิ่งนี้ทำ:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak

นี่ดูน่าสนใจ คุณสามารถเพิ่มบรรทัดเกี่ยวกับสิ่งที่g? ฉันไม่เคยเห็นมาก่อน
LondonRob

4
@LondonRob: gคนเดียวไม่ทำอะไรเลย มีคำสั่งแบบขยายหลายปุ่มเช่นz. ตัวอย่างเช่นgoไปที่ n ไบต์ที่ n ในบัฟเฟอร์gjและgkไปที่บรรทัดที่แสดงถัดไปและก่อนหน้า (แตกต่างจากjkเมื่อมีการรวมบรรทัด) gaแสดงข้อมูลเกี่ยวกับอักขระใต้เคอร์เซอร์gJรวมบรรทัดที่ไม่มีช่องว่างและที่นี่gvจะคืนค่าการเลือกภาพล่าสุด คุณสามารถใช้:help gv.
Benoit

6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' ฉันเพิ่ม ``> `` เพื่อกู้คืนตำแหน่งเคอร์เซอร์
rox

19

ในไฟล์ .vimrc

xnoremap p "_dP

ฉันพบนี้มาจากการตอบสนองในหัวข้อที่คล้ายกัน แต่แหล่งเดิมhttp://vim.wikia.com/wiki/Replace_a_word_with_yanked_text มันกล่าวถึงข้อเสียบางประการ แต่มันก็ใช้ได้ดีสำหรับฉัน


2
นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด
rudolph9

1
ทำงานให้ฉัน และคำตอบนี้ชัดเจน .vimrc.localก็โอเคเช่นกัน
BaiJiFeiLong

3
ใช้ไม่ได้หากการเลือกของคุณขยายไปจนสุดบรรทัด
John Freeman

6

โซลูชันของ Luc Hermitte ทำงานได้อย่างมีเสน่ห์ ฉันใช้มันประมาณหนึ่งสัปดาห์หรือมากกว่านั้น จากนั้นฉันก็ค้นพบวิธีแก้ปัญหาจาก. vimrc ของ Steve Loshที่ใช้งานได้ดีถ้า YankRing เป็นส่วนหนึ่งของปลั๊กอิน / กลุ่มผลิตภัณฑ์:

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

ลองใช้สิ่งนี้ใน~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapหมายความว่านี่เป็นVisualโหมดเท่านั้นไม่ใช่Visual + Selectโหมด

  • <expr>หมายความว่า{rhs}การxnoremap {lhs} {rhs}ตั้งค่านั้นได้รับการประเมินเป็นนิพจน์

  • ในกรณีนี้นิพจน์ของ'pgv"'.v:register.'y'เราใช้.สำหรับการเรียงต่อกัน

  • v:register ได้รับการประเมินไปยังรีจิสเตอร์ที่ใช้ระหว่างการทำแผนที่

ผลมาจากการ"xpที่จะประเมินผลpgv"xyที่xเป็นทะเบียน

ฉันได้รับคำตอบสำหรับคำถาม stackoverflow นี้: Vim - การแมปด้วยคำนำหน้า register ที่เป็นทางเลือก ร่วมกับคำตอบของBenoit ในหน้านี้


4

ฟังก์ชั่นของ Luc ทำงานได้ดีสำหรับฉันหลังจากที่ฉันทำการเปลี่ยนแปลงเพื่อรองรับความจริงที่ว่าฉันมีคลิปบอร์ด = ชุดที่ไม่มีชื่อ:

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

1
สำหรับการอ้างอิง: ใช้clipboard=unnamedplusนี้จะต้องมีแทน@+ @*
Sebastian Blask

2

Luc Hermitte ทำเคล็ดลับ! ดีจริงๆ. นี่คือวิธีแก้ปัญหาของเขาที่ใส่ฟังก์ชันสลับเพื่อให้คุณสามารถสลับไปมาระหว่างพฤติกรรมปกติและการใส่ไม่แทนที่ลงทะเบียน

คำสั่งคุณสลับพฤติกรรม

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>

คุณยังสามารถเปลี่ยน s: Repl เพื่อส่งคืน "p" แทน "p @ = RestoreRegister () \ <cr>" ขึ้นอยู่กับค่า s: putSwap
Luc Hermitte

1
ชอบsilent! vunmapแทนvnoremap <silent> <expr> p p
Luc Hermitte

0

การเขียนโปรแกรมเทปพันท่อ แต่ใช้ได้กับฉัน:

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

ลอง -

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

3
สิ่งเหล่านี้ควบคุมว่าจะเพิ่มข้อความที่เลือกลงในคลิปบอร์ดของระบบหน้าต่าง (เช่น X11 หรือ Win32) ไม่ใช่ลงทะเบียนสำเนาภายในของ Vim
Rob Kennedy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.