VIM用粘贴缓冲区的内容替换单词吗?


110

我需要在文件中进行大量单词替换,并希望使用vi命令而不是EX命令(例如)来进行替换:%s///g。我知道这是在当前光标位置替换单词的典型方法:cw<text><esc>但是,有没有一种方法可以使用未命名寄存器的内容作为替换文本,而不会覆盖寄存器?


8
解决方案:为了我的迫切需要,我曾经拉12yl12个字符并"_cw^r0替换了一个单词。然后,我可以使用.命令在整个文件中重复替换。
plong

Answers:


127

我想说的是“粘贴”,您的意思是未命名的(yank / put / change / change / delete / substitute)寄存器,对吗?(因为那是被change命令覆盖的那个。)

通常通过键入"然后键入寄存器的名称(单个字符)来指定寄存器,例如"ay然后"ap将其拉入寄存器a,然后放入register的内容a。更改命令也是如此。在这种情况下,如果您不希望将使用change命令删除的文本放在任何地方,则可以使用黑洞寄存器"_"_cw。然后,在插入模式下,您可以先按ctrl-R,再按"要放入(可能是)该寄存器内容的寄存器。

  • "* -选择寄存器(中间按钮粘贴)
  • "+ -剪贴板寄存器(也可能通过终端通过ctrl-shift-v访问)
  • "" -vim的默认(未命名)yank / put / change / delete / substitute寄存器。

简短答案: "_cw^R"

编辑:正如其他人所建议的那样,您当然可以使用其他寄存器来获取将文本放入默认寄存器的yank(或其他)。不过,您不一定总是首先想到这一点,因此最好执行一个change命令而不丢掉它。虽然还没有完全吹走。"0通过"9以下方式编号的寄存器:

Vim用yank和delete命令中的文本填充这些寄存器。

编号为0的寄存器包含来自最新yank命令的文本,除非该命令用[“ x]指定了另一个寄存器。

编号寄存器1包含由最近的删除或更改命令删除的文本,除非命令指定了另一个寄存器或文本少于一行(然后使用较小的删除寄存器)。一个例外是delete运算符与这些运动命令进行:%()`/?nN{}。则始终使用寄存器“ 1”(这与Vi兼容)。如果删除在一行内,则也使用“-”寄存器。

每次连续删除或更改时,Vim会将寄存器1的先前内容移入寄存器2,将2移至3,依此类推,从而丢失寄存器9的先前内容。


1
好吧,认为我已经将寄存器中的足够文档复制到我的答案中了吗?都在下面:help registers
卡斯卡贝尔

48

利用本文中的信息,我形成了这个有用的映射。我选择“ cp”是因为它表示“更改粘贴”

nmap <silent> cp "_cw<C-R>"<Esc>

编辑:

另外,我进一步迈出了一步,并支持任何动议。

要获得与上述命令等效的命令,那就是cpw“更改粘贴字”

"This allows for change paste motion cp{motion}
nmap <silent> cp :set opfunc=ChangePaste<CR>g@
function! ChangePaste(type, ...)
    silent exe "normal! `[v`]\"_c"
    silent exe "normal! p"
endfunction

<silent>导致它对我不起作用...为什么会这样呢?我是n00b的映射和函数。
Hollister

唯一的问题是您不能选择要粘贴的寄存器...但是在那种情况下,我想您可以使用cw并使用CTRL + R
Steve Vermeulen

2
可能会有更好的方法来添加寄存器命名,但是对我而言,以下工作有效: nmap <silent> cp :let g:currentRegister=v:register<cr>:set opfunc=ChangePaste<CR>g@ function! ChangePaste(type, ...) silent exe "normal! `[v`]\"_c".getreg(g:currentRegister) endfunction
Steve Vermeulen 2013年

@eventualEntropy可以很好地替换行,如何使它适用于单词而不是行,我仍然在学习vim。谢谢您的帮助。
Xavitoj Cheema

@XavitojCheema我什至不记得发表评论了,哈哈。但事实证明,我其实一直以来写了一个插件来提供这种功能(github.com/svermeulen/vim-easyclip
史蒂夫Vermeulen的

27

您可以为此使用vim的可视模式。例如复制一个单词:ye,然后用复制的单词覆盖另一个单词:vep


9
这是可行的,但还应注意,可视粘贴会覆盖新删除的文本的yank缓冲区。
ostler.c 2011年

24

如果光标位于要用未命名寄存器的内容替换的单词上,则可以使用viwpv切换到可视模式,iw选择内部字,然后p将寄存器的内容放在其位置。

在实践中,当我需要将一个单词(函数名称等)替换为另一个单词时,我将移至yiw该单词以用作替换,将内部单词拉到未命名的寄存器中,然后移至单词I' m更换,然后viwp更换。用一个单词替换另一个单词的快速方法。如果您在(/)中搜索了要替换的单词,则可以直接点击n以找到需要替换的下一个单词。显然,没有替代品using :%s/find/replace/g,但是对于几个快速替代品来说,它可以派上用场,特别是如果您已经在寄存器中有了新词的话。


4
令我惊讶的是,这不是一个可以接受的解决方案:以上所有方法虽然在某些情况下更为灵活,对于仅“将当前未命名的寄存器交换到某个地方进行选择”而言,却显得更为冗长。问问者是来这里的。
ELLIOTTCABLE 2015年

1
这是非常有用和直观的。
lacostenycoder

6

如果您使用命名寄存器(即,使用"ay"ad等填充您的粘贴寄存器),则可以执行以下操作

cw<CTRL-R>a<esc>

这将用register的内容替换单词a。据我所知,您不能使用默认寄存器,因为当您cw使用该命令剪切的单词时,它将被填充。


您可以使用默认寄存器!看看我的答案。
卡斯卡贝尔

2

您是指系统粘贴缓冲区还是vi寄存器?

如果您想使用系统粘贴缓冲区,那么您可以做得到dw"+P- "选择一个寄存器,它"+就是系统粘贴缓冲区。

否则,复制到非默认寄存器,并说"ay复制到寄存器a,然后替换某些内容dw"aP


谢谢,哈米什。我尝试过,但是dw删除了我认为是“单词”之后的结尾空格,而cw只更改了单词。因此,dw不会为我工作。
plong

在这种情况下,它de应该为您工作-它将删除到该单词的末尾,而dw将删除到下一个单词的开始。
Hamish Downer 2010年

1

您可以使用yw来拉动单词,然后可以使用拉动的单词来更改单词vipw以拉动单词并粘贴先前拉出的单词。


0

您可以为此使用寄存器:

寄存器中的第一位替换文字 <mark some text>"ay

a寄存器名称在哪里

那么您可以使用该寄存器替换

ve"ap


不幸的是,我不能简单地通过重复上一次粘贴操作.,这是我想做的另一件事。不过谢谢 非常感激。
plong

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.