如何在VIM命令行上指定“光标下的单词”?

103

我想要在VIM中编写一个命令,指定“光标下的单词”。例如,假设我把光标放在一个单词上并使其出现两次。例如,如果单词是“abc”,而我想要“abcabc”,那么我可以输入:

:s/\(abc\)/\1\1/

但是我希望能够将光标移动到“def”并使用相同的命令将其更改为“defdef”:

:s/\(def\)/\1\1/

我该如何在命令行中编写命令以实现这个功能?

:s/\(*whatever is under the commandline*\)/\1\1
8个回答

159

在命令行模式下,CTRL+R CTRL+W 会插入光标下的单词。

查看 c_CTRL-R 的帮助以获取所有其他特殊寄存器的列表:

:help c_CTRL-R

80

<cword>是指光标下的单词(:help <cword>)。

您可以将其映射到一个命令,或者对于懒惰的人来说,这一系列的按键操作也可正常工作:

b #go to beginning of current word
yw #yank to register

然后,当您输入模式时,您可以按<control-r>0<enter>,这将粘贴命令到第0个寄存器的内容。

您还可以创建一个此命令的快捷方式:

:nmap <leader>w :s/\(<c-r>=expand("<cword>")<cr>\)/

同时按下 '' 和 'w' 键将映射为用新命令行替换当前命令行

:s/\(<currentword>\)/

19
非常感谢您提供的优秀答案,但是基于肌肉记忆的考虑,我可能会建议选择“yiw”而不是“byw”。在光标恰好位于单词第一个字符的情况下,您必须删除“b”,只需键入“yw”,而在“yiw”中,您可以省略“i”。意外情况难免发生,更正错误肯定需要更多的按键操作 :) - Jacob Swartwood
多年以后,又有了一个补充:你可以考虑使用 cnoremap 将一个键绑定到仅扩展 <cword> 部分。我刚刚发现了这个答案,并将 <C-W> 绑定到 <C-R>=expand("<cword>")<CR>,这使得我可以输入例如 :s/\(<C-W>\)/\1\1/ 并为我插入 cword。 - aghast

34
yiwP

yiw: 复制光标下的单词(包括空格)。该命令还将光标移动到单词的开头。

P: 在光标之前粘贴。

然后,您可以将例如:<ALT> - D 映射到此命令:

:nmap < ALT >-D yiwP

4
这个问题特别指定了如何从Vim的命令行指定“光标下的单词”,而不是从命令模式。 - Nathan Fellman

15

另一种简便的方法是使用 * 命令。

在常规模式下,当光标停留在一个单词上时,输入

*:s//\0\0<Enter>

* 将搜索模式设置为当前单词(例如 \<abc\>)。

:s// 使用当前搜索模式进行替换,替换部分中的 \0 代表匹配的字符串。

您可以通过再次键入相同内容或键入

*@:

@: 命令可以重复执行最近一次的 Ex 命令,无需按下 <Enter> 键,本例中指替换命令。

您还可以使用 q 命令记录一个快速宏来执行此操作。

Translated text:

@: command can repeat the last executed Ex command without requiring an <Enter> key press, in this case, the substitution command.

You can also record a quick macro to perform this operation using the q command.

qd*:s//\0\0<Enter>q

然后通过键入重复它,直到你满意为止

@d

当你想要复制一个单词时,在该单词上方运行以下命令。由于这比之前的解决方案只少一个字符,所以可能对您来说不值得 - 除非您将在单词复制之间执行其他ex命令,这将更改@:的行为。


1

@user11211 有最直接的方法 可以复制光标下的单词:

yiwP

复制内部单词(将光标移动到单词开头),然后粘贴(在光标前)。

例如:straigh[t]forward ----> straightforwar[d]straightforward

[] 表示光标

详细说明如下:

您可能希望光标跟随您复制的单词:

yiwPea

直截了当 ----> 直截了当直截了当[]

注意:

yiw

是否复制内部单词(不包括空格)

yaw

删除所有单词(包括尾随的空格)。

yawPea

因此,包括空格和光标位置在内的重复单词。

straigh[t]forward ----> 直截了当的 straightforward[]


这个问题特别指定了从Vim的命令行中指定“光标下的单词”,而不是从命令模式中指定。 - Nathan Fellman
1
您可以在命令模式下使用任何正常的(命令模式)命令,只需在前面加上“:normal”即可。例如,“:normal yiwP”将执行与正常模式下的“yiwP”相同的操作。当然,这是一种较慢的方法来完成您所要求的操作。 - BBW Before Windows

1
ywPx

会执行您所描述的操作。

ywPxw

同时也会将光标移至下一个单词。


这个问题特别是关于如何在Vim的命令行中指定“光标下的单词”,而不是从命令模式下指定。 - Nathan Fellman
1
请描述答案,就像命令中的每个字母一样。 - Vitaly Zdanevich

1

您需要在映射中转义反斜杠。您还可以在映射中包含替换字符串。

:nmap <leader>w :s/\\(<c-r>=expand("<cword>")<cr>\\)/\\1\\1<cr>

-1
" count word  (case sensitive)
nmap <F4> :%s/\(<c-r>=expand("<cword>")<cr>\)//gn<cr>

你能否对这个做一下注释? - Nathan Fellman
1
这里使用了 n 标志来调用 :substitute 命令,以打印出光标下的单词在当前缓冲区中出现的次数。非常聪明,但实际上并不是这个问题的答案。 - Jacob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接