5

Vim 很棒,但是像很多人一样,当我想复制、删除、然后粘贴时,我真的很生气—— yank 缓冲区被删除操作覆盖了。

现在我知道有 101 种解决方法和映射,其中一些在像这样的帖子中被列举:任何方式在 vim 中删除而不覆盖你最后的 yank?

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

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

有谁知道这样做的方法?

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

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

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

这个工作流程的唯一问题是,如果我想再次粘贴,原来的粘贴缓冲区会被突出显示的文本粘贴的行为覆盖,但是这种行为很容易通过 .vimrc 中的以下映射进行更改:

vnoremap p "_dp
vnoremap P "_dP
4

2 回答 2

9

好的,我明白了——.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>

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

于 2012-09-29T02:56:49.567 回答
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>

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

nnoremap <leader>tp :TogglePasteCopy<cr>

作为最后的一条建议,我强烈建议"0p在这种方法上使用或使用命名寄存器,因为它们是 vim 的本机并且需要担心的“模式”更少。

于 2012-09-27T17:57:36.417 回答