删除时vim切换缓冲区覆盖行为

Mag*_*nus 4 vi vim

Vim很棒,但是和很多人一样,当我想要复制,删除,然后粘贴时,我会非常恼火 - 抓取行动会覆盖yank缓冲区.

现在我知道有101种解决方法和映射,其中一些是在这样的帖子中列举的:有什么办法在vim中删除而不覆盖你的上一次猛拉?

但所有这些解决方案都有缺点 - 即使我是一个缓冲大师(我不是).例如,多余的键击 - 而我通常xxxx快速删除4个字符(只有一个按键因为我按住它并等待自动重复),现在切换到x,x,x,x或无论映射我必须使用不同的缓冲区.

真正理想的只是一个模式切换,你可以打开和关闭D,d,X和x键的副作用行为,这样他们可以交替地或不也将它们的文本写入缓冲区.这样我就可以简单地进入"无副作用"模式并删除内容,然后在我准备好时粘贴.如果需要,重新启用副作用.

有谁知道这样做的方法?

[更新:解决方案]好吧我明白了:我写了一个能够切换"无副作用"模式的功能......完美运行!请参阅下面我接受的正确答案

[更新#2]我的解决方案仍然很好用,我一直在使用它时,我正在进行大量的删除和粘贴.但同时我还发现了一种更简单的方法来满足复制,粘贴,删除的特定用例 - 对于要删除的文本是连续的简单情况.

在正常处理文本之后,我会使用v命令在视觉上突出显示要删除的文本,然后使用p命令将其粘贴到其上.在没有任何特殊映射的情况下实现了期望的效果.

这个工作流程的唯一问题是,如果我想再次粘贴,粘贴突出显示文本的行为会覆盖原始粘贴缓冲区,但是使用.vimrc中的以下映射可以轻松更改此行为:

vnoremap p "_dp
vnoremap P "_dP
Run Code Online (Sandbox Code Playgroud)

Mag*_*nus 7

好吧,我明白了 - .vimrc中的这个脚本让我有效地切换了"无缓冲副作用"模式,当激活"无缓冲区副作用"模式时,d和x键不再覆盖缓冲区.

在.vimrc中添加它

function! ToggleSideEffects()
    if mapcheck("dd", "n") == ""
        noremap dd "_dd
        noremap D "_D
        noremap d "_d
        noremap X "_X
        noremap x "_x
        echo 'side effects off'
    else
        unmap dd
        unmap D
        unmap d
        unmap X
        unmap x
        echo 'side effects on'
    endif
endfunction
nnoremap ,, :call ToggleSideEffects()<CR>
Run Code Online (Sandbox Code Playgroud)

然后切换进入和退出此模式使用组合键,(两个逗号)


Pet*_*ker 5

我认为尝试"关闭"每个删除/更改命令的副作用将是非常困难,如果不是不可能的话.处理这种情况的基本方法:

  • "_删除或更改命令中使用黑洞()寄存器.例如"_dd
  • 使用"0包含粘贴命令的包含最近yank的寄存器.例如"0p
  • 将文本描述为命名寄存器.例如,"ayy然后再做"ap

我个人倾向于这种"0p方法,因为这符合我的思维方式.

现在看到你要求没有这样的解决方法,我提供了一些改变粘贴命令的功能,以便在我所谓的模式paste_copynopaste_copy模式之间切换.nopaste_copy是Vim的默认行为.将以下内容放入您的~/.vimrc:

function! PasteCopy(cmd, mode)
  let reg = ""
  if exists('g:paste_copy') && g:paste_copy == 1 && v:register == '"'
    let reg = '"0'
  elseif v:register != '"'
    let reg = '"' . v:register
  endif
  let mode = ''
  if a:mode == 'v'
    let mode = 'gv'
  endif
  exe "norm! " . mode . reg . a:cmd
endfunction

command! -bar -nargs=0 TogglePasteCopy let g:paste_copy = exists('g:paste_copy') && g:paste_copy == 1 ? 0 : 1<bar>echo g:paste_copy ? '  paste_copy' : 'nopaste_copy'

nnoremap <silent> p :call PasteCopy('p', 'n')<cr>
nnoremap <silent> P :call PasteCopy('P', 'n')<cr>
nnoremap <silent> ]p :call PasteCopy(']p', 'n')<cr>
nnoremap <silent> [p :call PasteCopy('[p', 'n')<cr>
nnoremap <silent> ]P :call PasteCopy(']P', 'n')<cr>
nnoremap <silent> [P :call PasteCopy('[P', 'n')<cr>
vnoremap <silent> p :<c-u>call PasteCopy('p', 'v')<cr>
vnoremap <silent> P :<c-u>call PasteCopy('P', 'v')<cr>
Run Code Online (Sandbox Code Playgroud)

您可以通过切换paste_copy模式:TogglePasteCopy.您可能更喜欢这样的映射

nnoremap <leader>tp :TogglePasteCopy<cr>
Run Code Online (Sandbox Code Playgroud)

作为最后的建议,我强烈建议"0p在这种方法中使用或使用命名寄存器,因为它们是vim原生的,并且有一种"模式"需要担心.