Vim - 如何捕获斜杠之间的内容?

12

有没有一种方法可以捕获在/\之间的文本?我知道还有其他符号的方法 ---

ci" - 捕获"text"中的'text'

vi( - 在foo(int var)内部捕获int var

di[ - 删除[word]单词并保留[]

我唯一能找到的解决方法是使用Vim Surround插件,并将其用于将周围的\更改为"(cs\"),然后从那里开始工作。但是,不仅这种方法很繁琐,而且该插件只支持反斜杠,而不支持正斜杠。


1
我可能已经编辑了一百次我的答案,但它目前适用于任何模式(例如单个字符、单词、正则表达式等等…),并且在多行上运作(_在适度测试之后_)。好问题! - jahroy
4个回答

9
你可以很容易地编写自己的文本对象。
onoremap <silent> i/ :<C-U>normal! T/vt/<CR> " inside /
onoremap <silent> a/ :<C-U>normal! F/vf/<CR> " around /

要使其在可视化模式下工作:

xnoremap <silent> i/ :<C-U>normal! T/vt/<CR> " inside /
xnoremap <silent> a/ :<C-U>normal! F/vf/<CR> " around /

同样地,你也可以为\做同样的操作。
编辑:添加了信息注释。

我认为这个答案肯定是最干净的,尽管我有点难以理解它在做什么。不过用一点谷歌搜索就可以搞清楚了。 :)非常感谢! - dook
只是跟进一下,我想在匹配正则表达式时也需要同样的操作。对于 "around" 风格,我真的希望能够进一步匹配正则表达式标志,因此我想出了这个版本:xnoremap <silent> a/ :<C-U>normal! F/vf/h<CR>/\/[gim]*/e<CR>目前看起来运行良好! - Andrew
再进行一次更新,在完成操作后,添加“y”标志并清除搜索高亮:xnoremap <silent> a/ :<C-U>normal! F/vf/h<CR>/\/[gimy]*/e<CR>:<C-U>noh<CR>gv - Andrew

3

这是一种使用映射的方法:

  nnoremap H mal??e+1<Enter>mb//<Enter>y`b`a

这个映射将拷贝最后一次搜索模式之间的所有内容。将其放置在你的.vimrc文件中,以使其永久化。
使用方法如下:
  • 搜索正斜杠: /\/(注意反斜杠转义字符)
  • 将光标定位在两个斜杠之间(或在第二个斜杠上)
  • 按下H
最后一个/和下一个/之间的所有内容都会被拷贝。
解释如下:
  nnoremap H mal??e+1<Enter>mb//<Enter>y`b`a

 - nnoremap H      map H in normal mode, ignoring other mappings    
 - ma              place a mark (named a) at the current cursor location
 - l               move the cursor one char to the right
 - ??e+1<Enter>    move to 1 character after END of prev occurrence of last search pattern
 - mb              place a mark (named b) at the current cursor location
 - //<Enter>       go to the beginning of the next occurrence of the last search pattern
 - y`b             yank to the location of the mark named x (note: ` = "back tick")
 - `a              go to the mark named `a`

示例输入:

This is a *funky* string
  • 搜索 *
  • 将光标置于两个星号之间(或在第二个星号上)
  • 按下 H

单词funky将被复制到缓冲区。

您可以使用单词作为定界符!

示例输入:

<br>
Capture all this text.
<br>
  • 搜索<br>
  • 在正常模式下,在<br>之间(或第二个<br>上)按下H

您也可以使用正则表达式!

示例输入:

<p>
Capture this paragraph.
</p>
  • 搜索<.\?p>(或<\/\{,1}p>更加准确)
  • 在段落中普通模式下按H键(或在关闭<p>标签时)

...

一个更好的方法是使用寄存器来记住分隔符,这样你就可以快速和/或重复地使用这个映射。换句话说,你可以将/\<\?p>存储在寄存器中,并使用它来快速捕获存储分隔符之间的文本。


1
这是一个非常详尽的回答!它超出了我所询问的范围,但我喜欢它可以捕捉任何可搜索的表达式。我将来一定会使用它。 :) - dook
1
@bark - 很高兴能够帮助!我在编写答案时也学到了很多,所以感谢你提出这个问题! - jahroy
是否可以将映射与现有的 Vim 常规对齐?ci/ - 更改斜杠之间的内容 di, - 删除逗号内的内容 va% - 在 % 之间(包括%)进行可视化选择 - SenG

2

目前没有内置支持 slash 的文本对象。不过有些插件支持自定义文本对象,例如:targets


这可能并没有完全回答我的问题,但是非常感谢您提供的插件链接。我已经尝试了一下,玩起来还真有点乐趣。 - dook

2

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