英文:
Yanking /moving a selection of text in vim
问题
<template>
<h1>你好</h1>
</template>
如果我使用以下搜索:
/<template>\_.*template>
如何剪切选择内容并将其移到文件的其他位置?
有没有更好的方法来做这件事?
英文:
<template>
<h1>Hello</h1>
</template>
If I search this using
/<template>\_.*template>
How do I yank/cut the selection to put it somewhere else in the file?
Is there a better way to go about doing this?
答案1
得分: 6
以下是翻译好的部分:
事情是,在搜索之后,你有一个匹配,而不是选择。如果你想对这个匹配做一些操作,你必须将这个匹配转换成运动、选择或范围之一。多功能的:help gn
可以帮助处理这三种情况。
匹配到运动
一旦搜索完成,你可以执行:
dgn
来剪切匹配的文本,然后将光标移动到其他地方,按下 p
或 P
将其放在那里。这种方法的问题在于寄存器是字符级的,因此你的片段可能会插入到行的中间,这并不好。你也可以执行类似以下的操作:
:/foo/put=@"
或者:
:6put=@"
这将以行级方式放置文本,因为Ex命令如 :put
都是以行级方式操作。
请参阅 :help gn
、:help :range
和 :help :put
。
匹配到选择
或者,你可以在可视行模式下选择匹配的文本:
Vgn
然后使用 d
剪切它。由于这是在可视行模式下完成的,所以寄存器是行级的,因此你可以在任何地方使用 p
/P
放置你的片段而不太冒风险。
通过以上方法,你在执行每个原子动作时决定要做什么。去这里。拿这个。去那里。做那个。
另一种方法
这绝对没问题,但多年来,我更加欣赏Ex命令在像这样的场景中提供的更高级别的表达能力。
这是我如何做的("将文本移动到最后一行之后",这里):
:/<template/,/<\/template>/m$
请参阅 :help :move
。
匹配到范围
这里还有另一种方法,混合了以上所有的方法/方式以及一个:
/<template>\_.*template><CR>
vgn
:'<,'>m$
其中…
- 你创建了一个匹配,
- 通过将其视为运动,将其转化为选择
- 最后将其用作范围。
全部
顺便说一下,这里以简洁的方式显示了以上所有的方法:
/<template>\_.*template><CR>
dgn
<motion>
p
/<template>\_.*template><CR>
dgn
<motion>
:<address>put=@"
/<template>\_.*template><CR>
Vgn
d
<motion>
p
:/<template/,/<\/template>/m$
英文:
The thing is that, after a search, you have a match, not a selection. If you want to do something with that match, you must turn that match into either a motion, a selection, or a range. The versatile :help gn
can help with all three.
Match to Motion
Once the search is done, you can do:
dgn
to cut the matched text and then move the cursor elsewhere and press p
or P
to put it there. The problem with this is that the register is character-wise, so your snippet might be inserted in the middle of a line, which is not good. You can also do something like:
:/foo/put=@"
or:
:6put=@"
which will put the text in a line-wise way because Ex commands like :put
are all line-wise.
See :help gn
, :help :range
, and :help :put
.
Match to selection
Alternatively, you can select the matched text in visual-line mode:
Vgn
and cut it with d
. Since this was done in visual-line mode, the register is line-wise so you can put your snippet with p
/P
anywhere without too much risk.
With the methods above, you kind of decide what you do as you do it, one atomic action after another. Go there. Take this. Go there. Do that.
A different approach
This is absolutely fine but, over the years, I have come to appreciate the higher level of expressiveness of Ex commands a whole lot more for scenarios like this.
Here is how I would have done it ("move text after last line", here):
:/<template/,/<\/template>/m$
See :help :move
.
Match to range
And here is another one, that mixes all of the methods/approaches above plus one:
/<template>\_.*template><CR>
vgn
:'<,'>m$
Where…
- you make a match,
- you turn it into a selection by treating it as a motion
- and you finally use it as range.
Everything
FWIW, here are all of the above methods displayed in a concise way:
/<template>\_.*template><CR>
dgn
<motion>
p
/<template>\_.*template><CR>
dgn
<motion>
:<address>put=@"
/<template>\_.*template><CR>
Vgn
d
<motion>
p
:/<template/,/<\/template>/m$
/<template>\_.*template><CR>
vgn
:'<,'>m$
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论