삭제 된 줄을 잡아 당기지 않고 vim에서 기울어 진 텍스트를 바꾸려면 어떻게해야합니까?


39

따라서 일반적으로 새 텍스트를 붙여 넣은 오래된 텍스트를 덮어 쓰면서 한 지점에서 다른 지점으로 텍스트를 복사합니다.

blah1
newtext
blah2
wrong1
blah3
wrong2
blah4

내가 시각적으로 표시 newtext하고 고정 한다고 가정 y하십시오. 이제 wrong1(단지 단어가 아닌 모든 것이 될 수 있음)을 선택하고를 으 p십시오 newtext. 그러나 이제 내가 똑같이 wrong2하면 wrong1대신 대신 으로 대체됩니다 newtext.

그렇다면 버퍼에있는 텍스트가 현재 덮어 쓰고있는 텍스트와 바뀌지 않게하려면 어떻게해야합니까?

편집 1

나는 reigister 제안을 좋아하지만 ( :dis명령을 발견 했으므로 레지스터 사용을 더 시작할 것이라고 생각하지만 ) 스왑 모드를 사용하지 않기 때문에 jinfield 의 답변을 수정하려고 합니다.

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

트릭을 완벽하게 수행합니다.

편집 2

나는 너무 빨랐다. romainl 의 솔루션은 Edit 1 의 해킹없이 정확하게 내가 찾던 것입니다 .
실제로 vnoremap p "_dP는 충분합니다!
따라서 수락 된 답변을 변경하십시오.


2
안녕, 나는 그것을 오랫동안 사용했고 vnoremap p "_dP map, 나는 그것이 줄의 마지막 단어 / 문자에 대해 잘 작동하지 않는 것을 알았습니다. 나는에 사라 다시했습니다 vnoremap p "0p, vnoremap P "0P그리고 set clipboard=unnamed(OSX 용)
Kache

vnoremap p "_dP붙여 넣기에서 공백을 제거합니다. 편집 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

"_다음과 같이 "블랙홀 레지스터"입니다 :help "_.

"이 레지스터에 쓸 때 아무 일도 일어나지 않습니다. 일반 레지스터에 영향을주지 않고 텍스트를 삭제하는 데 사용할 수 있습니다.이 레지스터에서 읽을 때 아무 것도 반환되지 않습니다. {not in 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
@Hashbrown, :help mapleader.
romainl

작은 경고 : vnoremap <leader>p버퍼의 마지막 행을 삭제하자마자 이제 한 번 마지막 행에 있고 P해당 행 위에 붙여 넣기 때문에 버퍼의 마지막 행 에서 매핑이 올바르게 작동하지 않습니다 . 아래 대신.
Kal

13

표준 버퍼 외에도 텍스트를 명명 된 버퍼에 넣은 다음 명명 된 버퍼에서 넣을 수 있습니다. 사용할 수있는 명명 된 버퍼는 최대 26 개입니다 (각 문자 당 하나씩). 큰 따옴표와 문자를 사용하여 명명 된 버퍼에 액세스하십시오. 예 :

"dyy -완충액으로의 현재 전류 라인 d.
"a7yy-완충 선으로 다음 7 라인 얀크.
"dP-버퍼 d의 내용을 커서 앞에 놓습니다.
"ap-커서 뒤에 버퍼 내용을 넣습니다.

또 다른 멋진 점은 소문자 대신 대문자를 사용하는 경우입니다. 즉 "Dyy, 현재 줄은 바꾸지 않고 버퍼 d에 추가됩니다. O`Reilly 책에 대한 자세한 내용 : http://docstore.mik.ua/orelly/unix/vi/ch04_03.htm


3
아주 멋진 것. 버퍼에 대해 알고 있었지만이 문제와 관련이 없습니다. 여전히 "a모든 것에 번거롭지 만 괜찮습니다.
비트 마스크

4

put비주얼 모드에서 사용 하는 경우 교체중인 텍스트 wrong1가 '무제한'레지스터의 내용으로 덮어 씁니다.

이것은 실제로 선택 후 레지스터를 '입력'한 다음 선택을 삭제하여 작동합니다. 문제는이 삭제가 이제 unnamed레지스터에 저장되어 다음 put조치에 사용된다는 것 입니다.

에 따르면 해결책 :h v_p은와 같은 명명 된 레지스터에 들어가서 필요한만큼 많은 시간 "0y을 붙여 넣는 "0p것입니다. 이름이 지정된 레지스터를 자주 사용하는 경우 매핑 <leader>y하고 <leader>p사용하는 것이 도움이 될 수 있습니다 .

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

자세한 내용은 다음을 참조하십시오.

:help v_p
:help map

이 솔루션은 vim 자체에서 영리한 것이 나올 때까지 가장 유용합니다.
Yugal Jindle

4

"0레지스터 에서 붙여 넣기 를 아는 것이 중요하지만 종종 여러 번 바꾸려고합니다. 반복 가능한 동작 .으로 만들면 garyjohn이 언급 한 것처럼 연산자를 사용할 수 있습니다 . 그것은 vim 위키에 설명 되어 있습니다 :

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

텍스트를 이름이없는 레지스터 *에 넣을 때 복사본도 레지스터 0에 저장됩니다. 선택한 텍스트를 바꿀 때마다 0 레지스터에서 붙여 넣기 만하면됩니다. 만나다

:help registers

또한 여러 단어를 같은 단어로 바꾸는 경우 바꿀 단어의 시작 부분으로 이동하여을 입력하면 .됩니다. 마지막 편집 작업이 반복됩니다. 만나다

:help single-repeat

* 꽉 잡고 저장 위치를 ​​레지스터라고합니다. 버퍼는 일반적으로 디스크에서 파일 사본을 편집하는 것입니다.


1

나는 이것을 너무 자주 필요로하며, ReplaceWithRegister 플러그인을 작성했다 .

이 플러그인은 gr{motion}, 전체 라인 또는 현재 선택 항목이 포함 된 텍스트를 레지스터의 내용으로 바꾸는 투 인원 명령을 제공합니다. 오래된 텍스트는 블랙홀 레지스터로 삭제됩니다. 즉 사라졌습니다.


1

같은으로 vnoremap p "_dP(나는 또한 시도 xc:), 나는이 일을 결국 라인의 시작과 끝의 문제를 가지고 vnoremap p :<C-U>let @p = @+<CR>gvp:let @+ = @p<CR>나는 (또한 작동하지 않던 기존 플러그인보다 간단 발견 set clipboard=unnamedplus상자 밖으로). 그것이하는 일은 :

  • 명령 모드로 전환
  • 범위 제거 ( C-U)
  • 백업 +레지스터 (때문에 unnamedplus에, 대안은 "*구성에 따라)에p
  • 선택을 복구하고 붙여 넣기
  • 명령 모드로 다시 전환
  • 레지스터를 복구

완전한! 이것은 나에게 예상대로 정확하게 작동하는 이러한 옵션 중 첫 번째 옵션입니다. 감사!
Jamis Charles

1

이것은 Windows 스타일의 컨트롤 + X 컷 / 컨트롤 + C 복사 / 컨트롤 + V 붙여 넣기 / 컨트롤 + S 저장 / 컨트롤 + F 찾기 / 컨트롤 + H 바꾸기 동작에 (내가 .vimrc에서 문자 그대로 복사 한 것)입니다.

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.