用Vim括在括号中


76

有没有办法在vim中的括号(或大括号)中包含一些文本?

换句话说,您将如何做?

初始字符串:

It is sunny outside.

最终字符串:

It is (sunny) outside.

有趣的是,我只是:w想提出这个问题。

祝您生日快乐,SOCommunity!


似乎宏可以轻松完成工作,但是我不敢特别规定-在VIM中我还是很环保的。但是类似“移至单词开头,插入左括号,移至单词末尾,插入右括号”之类的声音听起来像是在大多数情况下都可以使用的宏……
Triptych

@Triptych-按照您的建议,仅使用映射而不是宏。看我的答案。
鲁克

Answers:



84

一个词,我一直在使用:

bcw()<Esc>P

也就是说,转到单词的开头,剪切单词并进入插入模式,键入方括号,然后退出插入模式并将单词粘贴回。

请记住,这将覆盖您的猛拉寄存器。

当然,您可以将bcw替换为所需的任何移动和选择类型,例如

5cc{<Enter>}<Esc>P

22
当我的扬子被覆盖时,我讨厌它。
d1str0

1
无需插件。大。老实说,在round.vim中,您必须按下相同数量的按键,所以为什么要使用插件?
哈米德

vim的优势在于其光标控制语言!谢谢!将其记录到脚本中并使其成为宏很容易。qbcw()<Esc>Pq然后@q快速重做单词。
汤姆森·科默

4
@ d1str0,您仍然可以在寄存器中找到您的"0
扬子

切线,但确实应该将yanks堆栈起来,就像撤消一样。
hraban

46

下面是使用的例子surround.vim。在vim正常模式下,将光标置于所需单词上(在这种情况下为晴天),然后键入:

ysiw

然后输入 )

所以:

初始字符串:

It is sunny outside.

最终字符串:

It is (sunny) outside.

多余的空间: 使用开括号或括号,例如ysiw(用括号包围,并在括号和单词的开头和结尾之间留一个空格)

在视觉模式下更容易 按进入视觉模式v。现在,如果您输入S(,则单词将被空格包围。但是,如果您使用闭包)代替S),它将不会被空格包围。

这不仅适用于所有括号对的环境,而且还适用<> [] {} ()()。的行为S<是这样的,它期望使用标签封装,因此只能S>将括起来 <>

更多:

键入,ysiw然后}对卷发进行相同的操作

还可以在此处添加更多示例:

  • 键入cs('到[C]焊割[S] urroundings从(为'

  • cs'( 从“”环境更改为()

  • ds(.为[d] elete ([S] urroundings共

更:

为什么不引用Tpope页面的其余部分,以免我们单击链接?

//开始报价:

用示例最容易解释。

cs"'

“你好,世界!” 更改为

'Hello world!'

-

现在按cs'<q>将其更改为

<q>Hello world!</q>

-

走了一圈,按cst"获得

"Hello world!"

-

要完全删除定界符,请按 ds".

Hello world!

-

现在将光标放在“ Hello”上,按ysiw](iw是文本对象)。

[Hello] world!

让我们做大括号并添加一些空间(使用}代替{表示无空格): cs]{

{ Hello } world!

-

现在,用yssb或将整个行用括号括起来yss)

({ Hello } world!)

-

恢复为原始文本: ds{ds)

Hello world!

-

强调你好: ysiw<em>

<em>Hello</em> world!

-

最后,让我们尝试视觉模式。按大写V字母(用于逐行可视模式),然后按S<p class="important">

<p class="important">
  <em>Hello</em> world!
</p>

这个插件对于HTML和XML编辑非常强大,这是一个小众市场,目前在Vim领域似乎还不足。(与许多插件可用的HTML / XML插入相反)。同时添加,更改和删除标记对是一件轻而易举的事情。

.命令将工作dscs以及yss如果你安装repeat.vim


1
为什么我们需要ysiw中的y?
Jwan622 '20

8

您可以为该排序事件定义一个简单的映射。这应该做到。在正常模式下,键入z可以用括号将单词括起来。

:nnoremap <leader>z viw<esc>a)<esc>hbi(<esc>lel

太棒了 只需按2个按钮“ leader + z”。这是我最喜欢的答案
Darren Haynes

为什么要以视图模式传递?似乎更简单的举动:nnoremap <leader>( bi(<esc>eli)<esc>还是我错过了什么?顺便说一句很好的答案。
Titou


6

为什么不使用:s//搜索和替换)?

例如:

:s/sunny/(&)/

您可能还有其他想法,但是从您的问题中我无法分辨出它是什么。

&是匹配文本的缩写)


5
因为您最终要键入两次已写入的单词,所以您需要选择它并加上括号。
Titou

2

您可以使用以下命令:

cw(<C-r><C-o>")<ESC>

好处是您可以使用dot命令对不同的单词重复此操作。这也适用于自定义包围,例如:

更改之前:

word

然后使用以下命令:

cw\enquote{<C-r><C-o>"}<ESC>

最后结果:

\enquote{word}

太好了 您也可以用标记文本,v然后c(<C-r><C-o>")<ESC>明显地使用。将包含最后一个delete或yank(请参见:help i_^r)文本的默认或未命名寄存器粘贴到游标(:help ^o)的最后位置,并立即插入一个右括号非常方便。
AdamKalisz

1

我不想使用任何插件,并且希望将所有内容都限制在我的dotfile中,以便于移植。我能想到的最简单的方法是简单地记录并重放它。如果您打算在各个会话中更频繁地使用它,则也可以在.vimrc中映射该键,但是我不需要这样做(而且我真的很想找出要映射到哪个键)。

假设您对vim有一个新手级别的了解,假设我有一条(为简单起见)要用方括号括起来的直线。例如

hello world

进入普通模式。q1开始录制。现在执行以下操作

ESC ^i[ ESC $a] ESC

这将保留当前行的括号。现在您可以选择任何行,然后按@1以重复它。

例如,如果您希望将当前单词括起来,则只需记录并回放以下配方:

ESC bi[ ESC ea] ESC

您当然可以尝试针对击键进行优化,但这目前对我有用。


1

我知道这是一个古老的问题,但是此处尚未提及类似的复杂解决方案,并且我相信它可以帮助某人。在我的.vimrc文件中,有这样一行:

xnoremap <silent> ( <ESC>:let p = &paste<CR>:set paste<CR>:let a = line2byte(line('.')) + col('.')<CR>gvc()<ESC>:if getregtype() ==# 'V'<CR>call setreg('"', substitute(@", '\n$', '', ''), 'c')<CR>endif<CR>P:exe "goto ".a<CR>:exe "let &paste=".p<CR>

在可视模式下选择一些文本并按即可 (。此映射还适用于逐行和逐行可视模式。

它是如何工作的?

<ESC> 退出视觉模式

:let p = &paste<CR>:set paste<CR>...:exe "let &paste=".p<CR> 将确保宏将以粘贴模式执行(因为自动缩进和类似的改进可能会包含一些我们不希望的额外空间),而宏之后的粘贴状态将保持与执行宏之前相同

:let a = line2byte(line('.')) + col('.')<CR> 将找到当前字节偏移量(从1开始)

gv 将重新选择之前选择的文本

c 将删除选择并带我们进入插入模式以替换选择

()<ESC> 将放入我们想要的括号并退出插入模式

:if getregtype()==#'V'<CR>call setreg('"',substitute(@",'\n$','',''),'c')<CR>endif<CR>\n从未命名的(")寄存器中并将其类型更改为字符型,但前提是之前是逐行的(以便可以从注册表中将其粘贴到括号中)

P 将先前替换的文本粘贴在括号内

:exe "goto ".a<CR>将光标移回上一个位置(goto使用从0开始的偏移量,因此,由于插入了左括号,因此我们不必将以前记录的位置增加一个)


0

对于这样的事情,使用范围和组可能比使用外部插件更好:

:%s~\v(\w{5}) ~(\1) ~g

上面的代码搜索了一个5个字母的单词,后跟一个空格,使用()对匹配项进行分组,并用分组的匹配项周围的括号将其替换。


0

我还没有在其他答案中看到另一个有用的花絮:

在映射,使用expand("<cword>")(或任何其它类似的<cWORD><cexpr>等)。这使您可以访问“光标下的单词”。

例如,用括号内的版本替换“光标下的单词”当前行上的所有出现:

nnoremap <leader>( :execute "s!" . expand("<cword>") . "!(&)!g"<CR>

有一些缺点:

  • 如果其中<cword>带有感叹号,则会中断(s///当然,您可以选择其他字符)。
  • 您不能替换光标下的单个单词。您可以在一行中执行第一个操作(默认设置),也可以在一行中进行所有操作(如上所述,带有/g标志)。您甚至可以使用来处理文件中的所有事件%s...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.