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

vim在删除时切换缓冲区覆盖行为,vim,vi,Vim,Vi,Vim很棒,但和许多人一样,当我想复制、删除然后粘贴时,我会非常恼火——删除操作会覆盖yank缓冲区 现在我知道有101种变通方法和映射,其中一些在下面的帖子中列举: 但所有这些解决方案都有缺点——即使我是缓冲区专家(我不是)。例如,过多的击键——虽然我通常会快速删除4个字符(只需一次击键,因为我按住它并等待自动重击),但现在切换到、x、x、x或任何我必须使用不同缓冲区的映射是不实际的 真正理想的是简单的模式切换,通过该切换,您可以打开和关闭D、D、X和X键的副作用行为,以便它们交替地将文本写入

Vim很棒,但和许多人一样,当我想复制、删除然后粘贴时,我会非常恼火——删除操作会覆盖yank缓冲区

现在我知道有101种变通方法和映射,其中一些在下面的帖子中列举:

但所有这些解决方案都有缺点——即使我是缓冲区专家(我不是)。例如,过多的击键——虽然我通常会快速删除4个字符(只需一次击键,因为我按住它并等待自动重击),但现在切换到、x、x、x或任何我必须使用不同缓冲区的映射是不实际的

真正理想的是简单的模式切换,通过该切换,您可以打开和关闭D、D、X和X键的副作用行为,以便它们交替地将文本写入或不写入缓冲区。这样我就可以简单地进入“无副作用”模式,删除心中的内容,然后在准备好后粘贴。如果需要,重新启用副作用

有人知道怎么做吗

[更新:解决方案]我明白了:我写了一个函数,可以切换“无副作用”模式。。。很好用!请参阅下面我接受的正确答案

[UPDATE#2]我的解决方案仍然非常有效,我在执行大量删除和粘贴操作时一直使用它。但与此同时,我还找到了一种更轻松的方法来满足复制、粘贴、删除的特定用例,用于简单的情况,其中要删除的文本是连续的

在正常拖动文本之后,我使用v命令在视觉上突出显示要删除的文本,然后使用p命令简单地粘贴到文本上。无需任何特殊映射即可达到预期效果

此工作流的唯一问题是,如果我想再次粘贴,则在高亮显示的文本上粘贴会覆盖原始的粘贴缓冲区,但通过.vimrc中的以下映射,此行为很容易更改:

vnoremap p "_dp
vnoremap P "_dP
我认为,试图“关闭”每个删除/更改命令的副作用即使不是不可能的,也是非常困难的。处理这种情况的基本方法是:

  • 在删除或更改命令中使用黑洞(
    )寄存器。例如,
    “dd
  • 使用
    “0
    寄存器,该寄存器包含粘贴命令的最新yank。例如
    “0p
  • 将文本拖动到指定的寄存器。e、 g.
    “ayy
    然后执行
    ”ap
我个人倾向于
“0p
方法,因为这符合我的思维方式

现在看到您没有要求这样的解决方法,我提供了一些函数,可以改变粘贴命令,在所谓的
paste\u copy
nopaste\u copy
模式之间切换。
nopaste\u 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>
作为最后一条建议,我强烈建议在这种方法上使用
“0p
或使用命名寄存器,因为它们是vim固有的,并且不需要担心一个“模式”。

好的,我明白了——这个脚本在.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>
函数!ToggleSideEffects()
如果地图检查(“dd”、“n”)=“”
noremap dd“\u dd
诺雷马克D“
诺雷马克d“
noremap X“\u X
noremap x“\u x
回声“副作用关闭”
其他的
取消映射dd
未映射
未映射
取消映射X
取消映射x
echo“副作用”
恩迪夫
端功能
nnoremap,,:调用ToggleSideEffects()

然后使用组合键,,(两个逗号)

切换此模式。我认为您链接的那些解决方案旨在放入
vimrc
中。在
vimrc
中使用类似
nnoremap dd“\u dd
的方法对您有效吗?不太有效,因为我已经使用dd删除了整行内容。当然,我所有的映射都在vimrc中,但是这个解决方案仍然不能解决所有其他的d,比如dw、dl、2dw、d$。。。更不用说所有的x了。我必须在每次击键时输入一些特别的东西,我想用它。一个完整的模式会好得多…我不明白全局切换怎么会比在需要时拖动到一个命名缓冲区更简单。拖动到一个命名缓冲区是第二个选择,但它需要事先考虑——我必须事先知道,我想重新使用刚才拖动或删除的文本。此外,如果有大量的复制/粘贴操作进行,则会增加很多额外的击键次数。为什么您要使用
xxxx
而不是
4x
?感谢上面的代码,我们将对其进行测试!我发现“0p方法不合适,因为它只在我猛拉文本时起作用,而在我删除文本时不起作用,通常情况下就是这样。我讨厌使用两种不同的工作流来执行类似的操作。我想命名缓冲区是vim在这里能提供的最好的缓冲区。是否可以有状态地更改vim的默认缓冲区?这可能会满足我正在寻找的一些类似模式的特性。没有办法更改我在
“剪贴板”
之外知道的vim默认寄存器,这在这种情况下是没有用的。我相信命名注册可能是您工作流程的最佳方法。我的建议是试用几周。然后思考简化工作流程的方法。也许您所需要的只是快速映射到后台寄存器或其他命名寄存器。
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>