ฉันจะแทนที่ - วางข้อความ yanked ในกลุ่มโดยไม่ต้อง yanking บรรทัดที่ถูกลบได้อย่างไร


39

ดังนั้นฉันมักจะพบว่าตัวเองกำลังคัดลอกข้อความจากจุดหนึ่งไปอีกจุดหนึ่งในขณะที่เขียนทับข้อความเก่าที่วางใหม่:

blah1
newtext
blah2
wrong1
blah3
wrong2
blah4

สมมติว่าฉันทำเครื่องหมายภาพnewtextและyถามมัน ตอนนี้ผมเลือกwrong1(ซึ่งอาจเป็นอะไรก็ได้ไม่จำเป็นต้องเป็นเพียงแค่คำ) และpASTE newtextแต่ถ้าตอนนี้ผมทำเช่นเดียวกันกับwrong2ที่มันจะถูกแทนที่ด้วยแทนwrong1newtext

ดังนั้นฉันจะเก็บข้อความที่อยู่ในบัฟเฟอร์จากการสลับกับข้อความที่ฉันกำลังเขียนทับได้อย่างไร

แก้ไข 1

แม้ว่าฉันจะชอบคำแนะนำการลงทะเบียนใหม่ (ฉันคิดว่าฉันจะเริ่มใช้การลงทะเบียนมากขึ้นตอนนี้ที่ฉันค้นพบ:disคำสั่ง) ฉันจะแก้ไขคำตอบของjinfieldเพราะฉันไม่ได้ใช้โหมดการแลกเปลี่ยน

vnoremap p "0p
vnoremap P "0P
vnoremap y "0y
vnoremap d "0d

หลอกลวงได้อย่างสมบูรณ์แบบ

แก้ไข 2

ฉันเร็วเกินไป romainlวิธีการแก้ปัญหาก็คือสิ่งที่ผมกำลังมองหาโดยไม่ต้องสับในการแก้ไข 1
จริงๆแล้วvnoremap p "_dPก็เพียงพอแล้ว!
ดังนั้นการเปลี่ยนคำตอบที่ยอมรับได้


2
เฮ้ fyi ฉันใช้มานานvnoremap p "_dP mapแล้วและฉันสังเกตว่ามันใช้งานไม่ได้กับคำ / ตัวละครสุดท้ายในหนึ่งบรรทัด ฉันกลับไปที่vnoremap p "0p, vnoremap P "0Pและset clipboard=unnamed(สำหรับ OSX)
Kache

vnoremap p "_dPลบ white space บน paste แก้ไข 1 ทำงานได้อย่างสมบูรณ์
Vaclav Kasal

คำตอบ:


21

ฉันมีการแม็พเหล่านี้ใน. vimrc ของฉัน:

" delete without yanking
nnoremap <leader>d "_d
vnoremap <leader>d "_d

" replace currently selected text with default register
" without yanking it
vnoremap <leader>p "_dP

"_คือ "blackhole register" ตาม:help "_:

"เมื่อเขียนลงทะเบียนนี้ไม่มีอะไรเกิดขึ้นสิ่งนี้สามารถใช้เพื่อลบข้อความโดยไม่มีผลต่อการลงทะเบียนปกติเมื่ออ่านจากการลงทะเบียนนี้จะไม่มีการส่งคืนอะไร {ไม่ใช่ใน Vi}"


1
ฉันเคยใช้มันvnoremap p "_dP mapและสังเกตว่ามันใช้งานไม่ได้กับคำ / ตัวละครสุดท้ายในบรรทัด ฉันกลับไปที่vnoremap p "0p, vnoremap P "0Pและset clipboard=unnamed(สำหรับ OSX)
Kache

vnoremap p "_dPหยุดทำงานให้ฉันในโหมดเลือก แต่vnoremap <leader>p "_dPทำงานได้
whitesiroi

1
อาจ<leader>จะเป็นตัวยึดตำแหน่งที่ฉันควรจะรู้ว่าจะแทนที่ด้วยบางสิ่งบางอย่าง แต่สิ่งนี้ใช้ได้เฉพาะกับฉันถ้าฉันลบมันออก มันหมายความว่าอะไรที่นี่?
Hashbrown

1
:help mapleader@Hashbrown,
romainl

ข้อแม้เล็ก ๆ : การvnoremap <leader>pทำแผนที่ทำงานไม่ถูกต้องในบรรทัดสุดท้ายของบัฟเฟอร์เพราะทันทีที่คุณลบบรรทัดสุดท้ายของบัฟเฟอร์ตอนนี้คุณอยู่ในบรรทัดที่สองครั้งที่แล้วและPจะวางเหนือบรรทัดนั้น แทนด้านล่าง
Kal

13

นอกเหนือจากบัฟเฟอร์มาตรฐานแล้วคุณสามารถดึงข้อความลงในบัฟเฟอร์ที่กำหนดชื่อแล้วใส่จากบัฟเฟอร์ที่ตั้งชื่อเหล่านั้น มีบัฟเฟอร์ชื่อมากถึง 26 ชื่อที่คุณสามารถใช้ได้ (หนึ่งอันสำหรับแต่ละตัวอักษร) ใช้เครื่องหมายคำพูดคู่และตัวอักษรเพื่อเข้าถึงบัฟเฟอร์ที่ตั้งชื่อ ตัวอย่าง:

"dyy - ดึงบรรทัดปัจจุบันลงในบัฟเฟอร์ d
"a7yy- งัดเจ็ดบรรทัดถัดไปลงในบัฟเฟอร์ a
"dP- ใส่เนื้อหาของบัฟเฟอร์ d ก่อนเคอร์เซอร์
"ap- ใส่เนื้อหาของบัฟเฟอร์ a หลังจากเคอร์เซอร์

สิ่งที่ยอดเยี่ยมอีกอย่างหนึ่งถ้าคุณใช้ตัวพิมพ์ใหญ่แทนตัวพิมพ์เล็กนั่นคือ"Dyyบรรทัดปัจจุบันจะถูกต่อท้ายบัฟเฟอร์ d แทนการแทนที่ รายละเอียดเพิ่มเติมในหนังสือ O`Reilly: http://docstore.mik.ua/orelly/unix/vi/ch04_03.htm


3
สิ่งที่ยอดเยี่ยมมาก ฉันรู้เกี่ยวกับบัฟเฟอร์ แต่ไม่ได้เชื่อมโยงพวกเขากับปัญหานี้ มันยังคงยุ่งยากสำหรับ"aทุกอย่าง แต่ก็โอเค
bitmask

4

เมื่อใช้putในโหมดแสดงภาพข้อความที่คุณกำลังเปลี่ยนwrong1จะถูกเขียนทับโดยเนื้อหาของการลงทะเบียน 'unamed'

วิธีนี้ใช้งานได้โดย 'วาง' การลงทะเบียนหลังจากการเลือกแล้วลบการเลือก ปัญหาคือตอนนี้การลบนี้ถูกเก็บไว้ในunnamedรีจิสเตอร์และจะถูกใช้สำหรับการputดำเนินการต่อไป

วิธีการแก้ปัญหาตาม:h v_pคืองัดเข้าไปในการลงทะเบียนชื่อเช่น"0yแล้ววางโดยใช้"0pเวลามากเท่าที่คุณต้องการ อาจเป็นประโยชน์ในการแมป<leader>yและ<leader>pใช้การลงทะเบียนชื่อถ้านี่คือสิ่งที่คุณทำบ่อยๆ

:map <leader>y "0y
:map <leader>p "0p

สำหรับความช่วยเหลือเพิ่มเติมดู:

:help v_p
:help map

วิธีนี้ดูเหมือนจะใช้งานได้ดีที่สุดจนกว่าจะมีบางสิ่งที่ฉลาดเกิดขึ้นจากกลุ่มตัวเอง
Yugal Jindle

4

การวางจากการ"0ลงทะเบียนเป็นสิ่งสำคัญที่ต้องรู้ แต่บ่อยครั้งที่คุณต้องการแทนที่หลายครั้ง หากคุณทำให้เป็นการกระทำที่ทำซ้ำได้คุณสามารถใช้.โอเปอเรเตอร์ดังที่ garyjohn พูดถึง มันอธิบายไว้ใน vim wiki :

yiw     yank inner word (copy word under cursor, say "first". Same as above).
...     Move the cursor to another word (say "second").
ciw<C-r>0   select "second", then replace it with "first" If you are at the start of the word then cw<C-r>0 is sufficient.
...     Move the cursor to another word (say "third").
.   select "third", then replace it with "first". 

3

เมื่อคุณดึงข้อความลงในทะเบียนที่ไม่มีชื่อ * สำเนาจะถูกใส่เข้าไปใน register 0 ทุกครั้งที่คุณแทนที่ข้อความที่เลือกคุณสามารถวางจาก 0 register ดู

:help registers

.นอกจากนี้หากคุณเปลี่ยนจำนวนของคำที่มีคำเดียวกันคุณก็สามารถย้ายไปยังจุดเริ่มต้นของคำว่าจะถูกแทนที่และประเภท ที่จะทำซ้ำการแก้ไขครั้งล่าสุด ดู

:help single-repeat

* ที่เก็บสินค้าที่คุณดึงและนำเข้ามาจะเรียกว่ารีจิสเตอร์ บัฟเฟอร์คือสิ่งที่คุณแก้ไขโดยปกติแล้วจะเป็นการคัดลอกไฟล์จากดิสก์


1

ฉันต้องการนี้จึงมักจะผมเขียนปลั๊กอินที่: ReplaceWithRegister

ปลั๊กอินนี้มีgrคำสั่งแบบสองในหนึ่งที่แทนที่ข้อความที่ครอบคลุมโดย {motion}, ทั้งบรรทัด (s) หรือเลือกปัจจุบันด้วยเนื้อหาของการลงทะเบียน; ข้อความเก่าจะถูกลบในการลงทะเบียนหลุมดำนั่นคือมันหายไป


1

เป็นสิ่งที่ชอบvnoremap p "_dP(ฉันลองxหรือc) มีปัญหาเกี่ยวกับการเริ่มต้นและสิ้นสุดของบรรทัดฉันจึงลงเอยด้วยการทำสิ่งนี้: vnoremap p :<C-U>let @p = @+<CR>gvp:let @+ = @p<CR>ซึ่งฉันพบว่าง่ายกว่าปลั๊กอินที่มีอยู่set clipboard=unnamedplusแล้ว ดังนั้นมันคืออะไร:

  • เปลี่ยนเป็นโหมดคำสั่ง
  • ลบช่วง ( C-U)
  • การสำรองข้อมูล+การลงทะเบียน (เนื่องจาก unnamedplus ทางเลือกที่มี"และ*ขึ้นอยู่กับการกำหนดค่าของคุณ) เพื่อp
  • กู้คืนส่วนที่เลือกและวาง
  • เปลี่ยนเป็นโหมดคำสั่งอีกครั้ง
  • กู้คืนการลงทะเบียน

ที่สมบูรณ์แบบ! นี่เป็นตัวเลือกแรกของตัวเลือกเหล่านี้ที่ทำงานได้ตามที่คาดหวังสำหรับฉัน ขอบคุณ!
Jamis Charles

1

นี่คือสิ่งที่ฉันใช้ (คัดลอกอย่างแท้จริงจาก. vimrc ของฉัน) สำหรับ Windows-style Control + X cut / Control + C copy / Control + V paste / Control + S save / Control + F find / Control + H แทนที่พฤติกรรม

ฟังก์ชั่น smartpaste () ควรมีสิ่งที่คุณต้องการเช่นวิธีการวางทับข้อความที่เน้นสีโดยไม่ต้องทำการดึงสิ่งที่เลือกไว้

" Windows common keyboard shortcuts and pasting behavior {{{

" Uncomment to enable debugging.
" Check debug output with :messages
let s:debug_smart_cut = 0
let s:debug_smart_copy = 0
let s:debug_smart_paste = 0

function! SmartCut()
    execute 'normal! gv"+c'

    if visualmode() != "\<C-v>" " If not Visual-Block mode
        " Trim the last \r\n | \n | \r character in the '+' buffer
        " NOTE: This messes up Visual-Block pasting.
        let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
    endif

    if exists("s:debug_smart_cut") && s:debug_smart_cut
        echomsg "SmartCut '+' buffer: " . @+
    endif
endfunction

function! SmartCopy()
    execute 'normal! gv"+y'

    if visualmode() != "\<C-v>" " If not Visual-Block mode
        " Trim the last \r\n | \n | \r character in the '+' buffer
        " NOTE: This messes up Visual-Block pasting.
        let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
    endif

    if exists("s:debug_smart_copy") && s:debug_smart_copy
        echomsg "SmartCopy '+' buffer: " . @+
    endif
endfunction

" Delete to black hole register before pasting. This function is a smarter version of "_d"+P or "_dp to handle special cases better.
" SOURCE: http://stackoverflow.com/questions/12625722/vim-toggling-buffer-overwrite-behavior-when-deleting
function! SmartPaste()
    let mode = 'gv'

    let delete = '"_d'

    let reg = '"+'

    " See :help '> for more information. Hint: if you select some text and press ':' you will see :'<,'>
    " SOURCE: http://superuser.com/questions/723621/how-can-i-check-if-the-cursor-is-at-the-end-of-a-line
    " SOURCE: http://stackoverflow.com/questions/7262536/vim-count-lines-in-selected-range
    " SOURCE: https://git.zug.fr/config/vim/blob/master/init.vim
    " SOURCE: https://git.zug.fr/config/vim/blob/master/after/plugin/zzzmappings.vim
    let currentColumn = col(".")
    let currentLine = line(".")
    let lastVisibleLetterColumn = col("$") - 1
    let lastLineOfBuffer = line("$")
    let selectionEndLine = line("'>")
    let selectionEndLineLength = len(getline(selectionEndLine))
    let nextLineLength = len(getline(currentLine + 1))
    let selectionStartColumn = col("'<")
    let selectionEndColumn = col("'>")

    " If selection does not include or go beyond the last visible character of the line (by also selecting the invisible EOL character)
    if selectionEndColumn < selectionEndLineLength
        let cmd = 'P'

        if exists("s:debug_smart_paste") && s:debug_smart_paste
            echomsg "SmartPaste special case #1"
        endif

    " If attempting to paste on a blank last line
    elseif selectionEndLineLength == 0 && selectionEndLine == lastLineOfBuffer
        let cmd = 'P'

        if exists("s:debug_smart_paste") && s:debug_smart_paste
            echomsg "SmartPaste special case #2"
        endif

    " If selection ends after the last visible character of the line (by also selecting the invisible EOL character) and next line is not blank and not the last line
    elseif selectionEndColumn > selectionEndLineLength && nextLineLength > 0 && selectionEndLine != lastLineOfBuffer
        let cmd = 'P'

        if exists("s:debug_smart_paste") && s:debug_smart_paste
            echomsg "SmartPaste special case #3"
        endif

    " If selection ends after the last visible character of the line (by also selecting the invisible EOL character), or the line is visually selected (Shift + V), and next line is the last line
    elseif selectionEndColumn > selectionEndLineLength && selectionEndLine == lastLineOfBuffer
        " SOURCE:  http://vim.wikia.com/wiki/Quickly_adding_and_deleting_empty_lines

        " Fixes bug where if the last line is fully selected (Shift + V) and a paste occurs, that the paste appears to insert after the first character of the line above it because the delete operation [which occurs before the paste]
        " is causing the caret to go up a line, and then 'p' cmd causes the paste to occur after the caret, thereby pasting after the first letter of that line.
        " However this but does not occur if there's a blank line underneath the selected line, prior to deleting it, as the cursor goes down after the delete in that situation.
        call append(selectionEndLine, "")

        let cmd = 'p'

        if exists("s:debug_smart_paste") && s:debug_smart_paste
            echomsg "SmartPaste special case #4"
        endif

    else
        let cmd = 'p'

        if exists("s:debug_smart_paste") && s:debug_smart_paste
            echomsg "SmartPaste default case"
        endif
    endif

    if exists("s:debug_smart_paste") && s:debug_smart_paste
        echomsg "SmartPaste debug info:"
        echomsg "    currentColumn: " . currentColumn
        echomsg "    currentLine: " . currentLine
        echomsg "    lastVisibleLetterColumn: " . lastVisibleLetterColumn
        echomsg "    lastLineOfBuffer: " . lastLineOfBuffer
        echomsg "    selectionEndLine: " . selectionEndLine
        echomsg "    selectionEndLineLength: " . selectionEndLineLength
        echomsg "    nextLineLength: " . nextLineLength
        echomsg "    selectionStartColumn: " . selectionStartColumn
        echomsg "    selectionEndColumn: " . selectionEndColumn
        echomsg "    cmd: " . cmd
        echo [getpos("'<")[1:2], getpos("'>")[1:2]]
        echo "visualmode(): " . visualmode()
        echo "mode(): " . mode()
    endif

    if visualmode() != "\<C-v>" " If not Visual-Block mode
        " Trim the last \r\n | \n | \r character in the '+' buffer
        " NOTE: This messes up Visual-Block pasting.
        let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
    endif

    try
        execute 'normal! ' . mode . delete . reg . cmd
    catch /E353:\ Nothing\ in\ register\ +/
    endtry

    " Move caret one position to right
    call cursor(0, col(".") + 1)
endfunction

" p or P delete to black hole register before pasting
" NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
vnoremap <silent> p :<C-u>call SmartPaste()<CR>
vnoremap <silent> P :<C-u>call SmartPaste()<CR>

" MiddleMouse delete to black hole register before pasting
nnoremap <MiddleMouse> "+p " Changes default behavior from 'P' mode to 'p' mode for normal mode middle-mouse pasting
" NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
vnoremap <silent> <MiddleMouse> :<C-u>call SmartPaste()<CR>
inoremap <MiddleMouse> <C-r><C-o>+

" Disable weird multi-click things you can do with middle mouse button
" SOURCE: http://vim.wikia.com/wiki/Mouse_wheel_for_scroll_only_-_disable_middle_button_paste
noremap <2-MiddleMouse> <Nop>
inoremap <2-MiddleMouse> <Nop>
noremap <3-MiddleMouse> <Nop>
inoremap <3-MiddleMouse> <Nop>
noremap <4-MiddleMouse> <Nop>
inoremap <4-MiddleMouse> <Nop>

if os != "mac" " NOTE: MacVim provides Command+C|X|V|A|S and undo/redo support and also can Command+C|V to the command line by default
    " SOURCE: https://opensource.apple.com/source/vim/vim-62.41.2/runtime/macmap.vim.auto.html
    " NOTE: Only copy and paste are possible in the command line from what i can tell.
    "       Their is no undo for text typed in the command line and you cannot paste text onto a selection of text to replace it.
    cnoremap <C-c> <C-y>
    cnoremap <C-v> <C-r>+
    " TODO: Is their a select-all for the command line???

    " Cut, copy, and paste support for visual and insert mode (not for normal mode)
    " SOURCE: http://superuser.com/questions/10588/how-to-make-cut-copy-paste-in-gvim-on-ubuntu-work-with-ctrlx-ctrlc-ctrlv
    " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
    vnoremap <silent> <C-x> :<C-u>call SmartCut()<CR>
    vnoremap <silent> <C-c> :<C-u>call SmartCopy()<CR>
    vnoremap <silent> <C-v> :<C-u>call SmartPaste()<CR>
    inoremap <C-v> <C-r><C-o>+

    " Select-all support for normal, visual, and insert mode
    " http://vim.wikia.com/wiki/Using_standard_editor_shortcuts_in_Vim
    nnoremap <C-a> ggVG
    vnoremap <C-a> ggVG
    inoremap <C-a> <Esc>ggVG

    " Save file support for normal, visual, and insert mode
    " SOURCE: http://vim.wikia.com/wiki/Map_Ctrl-S_to_save_current_or_new_files
    " If the current buffer has never been saved, it will have no name,
    " call the file browser to save it, otherwise just save it.
    command -nargs=0 -bar Update if &modified |
                                \    if empty(bufname('%')) |
                                \        browse confirm write |
                                \    else |
                                \        confirm write |
                                \    endif |
                                \endif
    nnoremap <silent> <C-s> :update<CR>
    " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
    vnoremap <silent> <C-s> :<C-u>update<CR>V
    " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
    "inoremap <silent> <C-s> <C-o>:update<CR>
    "
    " <C-o> doesn't seem to work while also using the "Open the OmniCompletion menu as you type" code while the menu is visible.
    " Doing "call feedkeys("\<C-x>\<C-o>", "n")" to perform omni completion seems to be the issue.
    " However doing "call feedkeys("\<C-x>\<C-i>", "n")" to perform keywork completion seems to work without issue.
    "
    " Workaround will exit insert mode to execute the command and then enter insert mode.
    inoremap <silent> <C-s> <Esc>:update<CR>I

    " Undo and redo support for normal, visual, and insert mode
    nnoremap <C-z> <Esc>u
    nnoremap <C-y> <Esc><C-r>

    " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
    vnoremap <C-z> :<C-u>uV
    vnoremap <C-y> :<C-u><C-r>V

    inoremap <C-z> <Esc>uI
    inoremap <C-y> <Esc><C-r>I

    function! Find()
        let wordUnderCursor = expand('<cword>')
        if len(wordUnderCursor) > 0
            execute 'promptfind ' . wordUnderCursor
        else
            execute 'promptfind'
        endif
    endfunction

    function! Replace()
        let wordUnderCursor = expand('<cword>')
        if len(wordUnderCursor) > 0
            execute 'promptrepl ' . wordUnderCursor
        else
            execute 'promptrepl'
        endif
    endfunction

    " Find and Find/Replace support for normal, visual, and insert mode
    nnoremap <C-f> :call Find()<CR>
    nnoremap <C-h> :call Replace()<CR>

    " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
    vnoremap <C-f> :<C-u>call Find()<CR>
    vnoremap <C-h> :<C-u>call Replace()<CR>

    " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
    inoremap <C-f> <C-o>:call Find()<CR>
    inoremap <C-h> <C-o>:call Replace()<CR>
endif

" }}} Windows common keyboard shortcuts and pasting behavior

-1

tl; dr - vnoremap p "_c *

นี่คือรายการของแมปของฉันเต็ม:
"คัดลอกแก้ไขการลงทะเบียน / วาง
nnoremap DD" * DD
nnoremap D "* d
vnoremap D" d
nnoremap d "_D
nnoremap DD" _dd
vnoremap d "_D
nnoremap s" _S
vnoremap s "_S
nnoremap c "_c
vnoremap c" _c
nnoremap x "_x
vnoremap x" _x
vnoremap p "_c

"วางบนบรรทัดใหม่
nnoremap, p op
nnoremap, P Op

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