我需要在一个文件中做一堆单词替换,并且想用 vi 命令来做,而不是 EX 命令,例如:%s///g
.
我知道这是在当前光标位置替换单词的典型方式:cw<text><esc>
但是有没有办法将未命名寄存器的内容作为替换文本而不覆盖寄存器?
我在想“粘贴”是指未命名的(yank/put/change/delete/substitute)寄存器,对吧?(因为那是被更改命令覆盖的那个。)
寄存器通常通过键入"
然后输入寄存器的名称(单个字符)来指定,例如"ay
然后"ap
拉入寄存器a
,然后放入寄存器的内容a
。更改命令也是如此。在这种情况下,如果您不希望使用 change 命令删除的文本移动到任何地方,您可以使用黑洞寄存器"_
: "_cw
。然后一旦进入插入模式,您可以按 ctrl-R 后跟您想要(可能"
)放入该寄存器内容的寄存器。
"*
- 选择寄存器(中键粘贴)"+
- 剪贴板寄存器(可能也可以通过终端使用 ctrl-shift-v 访问)""
- vim 的默认(未命名)yank/put/change/delete/substitute 寄存器。简短的回答:"_cw^R"
编辑:正如其他人所建议的那样,您当然可以对将文本放入默认寄存器的 yank(或其他)使用不同的寄存器。但是,您并不总是首先想到这一点,因此最好执行一个更改命令而不把它吹走。虽然它并没有完全被吹走。有编号的寄存器"0
通过"9
:
Vim 用来自 yank 和 delete 命令的文本填充这些寄存器。
编号寄存器 0 包含来自最近的 yank 命令的文本,除非该命令用 ["x] 指定了另一个寄存器。
编号寄存器 1 包含最近删除或更改命令删除的文本,除非命令指定另一个寄存器或文本少于一行(然后使用小删除寄存器)。具有以下移动命令的删除运算符例外:
%
,(
,)
,`
,/
,?
,n
,N
,{
和}
。然后总是使用寄存器“1”(这是与 Vi 兼容的)。如果删除在一行内,也使用“-”寄存器。每次连续删除或更改时,Vim 将寄存器 1 的先前内容移入寄存器 2,将 2 移入寄存器 3,依此类推,丢失寄存器 9 的先前内容。
使用这篇文章中的信息,我已经形成了这个有用的映射。我选择了“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
为此,您可以使用 vim 的可视模式。例如复制一个单词:ye
然后用复制的单词覆盖另一个单词:vep
如果光标位于要替换为未命名寄存器内容的单词上,则可以使用viwp
. v
切换到可视模式,iw
选择内部单词,p
并将寄存器的内容放在它的位置。
在实践中,当我需要用另一个词替换一个词(函数名等)时,我会移动到用作替换的那个,yiw
将内部词拉到未命名的寄存器中,然后移动到词 I' m 替换,并viwp
替换它。用一个词替换另一个词的非常快速的方法。如果您在 ( /
) 中搜索要替换的单词以找到它,那么您只需点击n
即可找到您需要替换的下一个匹配项。显然不能替代 using :%s/find/replace/g
,但对于几个快速替换它可能很方便,特别是如果您已经在寄存器中有了新单词。
如果您使用命名寄存器(即使用"ay
or"ad
等来填充您的粘贴寄存器),您可以执行类似的操作
cw<CTRL-R>a<esc>
它将用 register 的内容替换单词a
。据我所知,您不能使用默认寄存器,因为当您使用cw
该命令剪切的单词时,它将被填充。
你的意思是系统粘贴缓冲区还是vi寄存器?
如果您想使用系统粘贴缓冲区,那么您很好并且可以这样做dw"+P
-"
选择一个寄存器,并且"+
是系统粘贴缓冲区。
否则复制到非默认寄存器中说"ay
复制到寄存器a
然后替换一些东西dw"aP
您可以使用yw
拉出单词,然后您可以将带有拉出单词的单词更改vipw
为拉出单词并粘贴先前被拉出的单词。
您可以为此使用寄存器:
寄存器中的第一个替换文本
<mark some text>"ay
a
注册名称在哪里
那么您可以使用该寄存器代替
ve"ap
或者你可以做Shift+ v- p(选择整行并粘贴到它的位置)