如何在Vim中同时编辑多个位置

12
在某些文本编辑器(如 E)中,我可以选择多个位置,在我输入时,所有选定的位置都会被替换为我正在输入的字符。
例如,如果我有:
<tag1 class=""></tag1>
<tag2><tag3 class=""></tag3></tag2>

在 E 编辑器中,我可以选择两个引号内的位置,然后开始输入,这样两个位置都会同时更新。在 Vim 中,我可以同时选择几列连接的文本块进行编辑,但我想知道是否有一种方法可以选择多个不对齐的位置。


你能详细解释一下你所说的“所有选定位置”是什么意思吗?这些选定位置是否都具有相同的形状,比如一列?或者它们是否都包含相同的初始文本? - Greg Hewgill
@Greg - 我已经编辑了问题以澄清。希望有所帮助。 - Daniel
对我来说,这个功能更像是搜索和替换,但以一种更加高级的方式。 - Dzung Nguyen
参见:https://dev59.com/SnRC5IYBdhLWcg3wJNmf - dreftymac
6个回答

10

这里是我可能会如何编辑那些特定的行(有很多种方法):

/""<enter>
aText to replace...<esc>
n
.

首先,搜索空引号将光标定位在第一个引号上。使用 "a"(追加)命令,键入要放在引号内的新文本。完成后,使用 "n"(下一步)进入下一个实例,使用 "."(重复上一条命令)再次插入相同的文本。必要时多次重复 "n ."。

这种方法需要较少的准备工作,让您可以立即开始而不需要预先确定需要添加文本的所有位置。


那绝对是快速获取文本的好方法。然而,这并不像e所做的那样是同步编辑的一个例子。也许这是“vim”的做事方式(正如您所指出的具有预先知道所有地方的优点)。 - Daniel
1
Vim 无法进行同时编辑(可能可以通过 vimscript 模拟)。在我看来,设置可重复的命令需要更多的工作量,但这是使用 Vim 的方法。 - Svend
我想补充一下,第二行的命令可以是任何其他的vim操作,比如:5x,i<some_text> - Abhishek Kumar
@Svend 我对vim相对较新,惊讶地发现它不能进行同时编辑(它似乎有一种方法可以做到几乎所有的事情) - stevec
@stevec 那个评论也已经超过13年了,vim自那时以来已经有了很多发展。由于我已经有近乎同样长的时间没有使用vim了,所以我不再对那个评论给予任何价值。快速搜索似乎表明现在有办法可以做到这一点,但正如我的评论所指出的那样,这可能与当今常见编辑器中实现的多光标/编辑方式有所不同。 - Svend
@Svend 好的,非常感谢回复。我会再做一些研究并尝试理清楚它。 - stevec

5

你可能正在寻找块状可视模式,它将允许一次性在多行上进行插入、删除等操作。

块状模式将允许使用方形选择,其中初始点的列和行位于一个角落,而当前光标位置定义了另一个角落的列和行。这与默认的基于行的选择不同。

CTRL-v 将使你进入块状可视模式。

如果你有多行文本如下:

INSERT INTO Users VALUES(1, 'Jim');
INSERT INTO Users VALUES(2, 'Jack');
INSERT INTO Users VALUES(3, 'Joseph');

我想在每行id后面插入"0,",然后将光标放在第一行的逗号后:

INSERT INTO Users VALUES(1,* 'Jim');

用星号代表光标,命令序列应为:
CTRL-v  # Put into blockwise visual mode
j       # Down a line
j       # Down a line
CTRL-I  # Captial I for insert
0,      # the text to insert
Esc     # escape

文本现在应该是这样的:
INSERT INTO Users VALUES(1, 0, 'Jim');
INSERT INTO Users VALUES(2, 0, 'Jack');
INSERT INTO Users VALUES(3, 0, 'Joseph');

此外,块状可视模式下,按下x将删除所选内容,按下y将复制所选内容。

:help CTRL-V 可以提供更多的文档说明。


2
CTRL-v 的限制在于它只能处理连续的文本块,如果你想编辑的文本没有整齐地排列在一列中,那么你就不能使用它! - Daniel
1
啊,这种情况下你可以找我。有一个多选插件,但我从未使用过:http://www.vim.org/scripts/script.php?script_id=953 - John Kane
它真的是 <C-I>,而不是 <C-i> 吗? - lindhe
1
CTRL-I 不会给你大写的 I - NoBackingDown

2

对于你的例子,我会使用替换:

:%s/class=""/class="something"/g

谢谢你的回答!然而,我的问题不是关于找到任何解决方案来解决这个明显虚构的例子,而是关于使用同时编辑来解决这个例子。 - Daniel

2
请看SnippetsEmu,它应该会做与您需求非常相似的事情。它模拟了TextMate的片段。您应该能够有一个带有相同标签的片段重复出现,并且在编辑时会自动更新所有位置中的相同标签,随着您的输入而更新。

原来 Ayman 你是完全正确的!还有另一个名为 snipMate 的脚本也可以做到这一点。请参见此处引用的屏幕录像:http://www.vim.org/scripts/script.php?script_id=2540。它几乎与 e 中演示的屏幕录像功能相同。 - Daniel

0

0

我也在寻找类似的东西,更具体地说是从ST2中非常有用的功能,你按下CTRL+D选择下一个出现的位置,然后通过键入来替换两个出现的位置。


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