星期五, 九月 25, 2020

VIM学习笔记 环绕字符编辑(sandwich)

sandwich 插件可以快速编辑围绕在内容两端的字符(pairs of things surrounding things),比如成对出现的括号、引号,甚至HTML/XML标签等。

sandwich支持vim的文本对象(Text Objects),比如单词、句子和段落等等。同时也支持.重复命令(Dot Command)。

安装配置

推荐您使用vim-plugVundle等插件管理器,来安装GitHub上的sandwich插件。

以下将利用实例来介绍sandwich插件的主要功能,请注意:

  • 在“原始文本”列中,高亮文字表示光标所在位置;
  • 在“命令”列中,为顺序执行的命令序列;
  • 在“更改效果”列中,为命令执行之后的结果。您可以参考实例文件并自行测试。

新增环绕字符

在常规模式和可视化模式下,可以使用sa命令来新增环绕字符:

模式目标
范围
新增
内容
原始文本命令更改效果
常规模式单词字符Hello Worldsaiw*Hello *World*
单词不含标点引号Hello World!saiw'Hello 'World'!
单词包含标点引号Hello World!saiW'Hello 'World!'
单词标签Hello WorldsaiwtstrongHello <strong>World</strong>
单词括号print var1, var2sa3w)print (var1, var2)
行尾括号print var1, var2sa$)print (var1, var2)
查找标签William Shakespeare said,
"Brevity is the soul of wit."
saf"temWilliam Shakespeare said,
<em>"Brevity is the soul of wit."</em>
整行字符Hello World0sa$""Hello World"
整行标签Hello World0sa$tp<p>Hello World</p>
字符可视化模式选中的文本括号print var1, var2veesa)print (var1, var2)
选中的文本标签The passion to save humanity is a
cover for the desire to rule it.
v$jsatp<p>The passion to save humanity is a
cover for the desire to rule it.</p>
行可视化模式整行新行Hello WorldVsa)(
Hello World
)
选中的文本标签
新行
The passion to save humanity is a
cover for the desire to rule it.
Vjsatp<p>
The passion to save humanity is a
cover for the desire to rule it.
</p>
块可视化模式选中的文本标签Item 1
Item 2
Item 3
<Ctrl-Q>$jjsatli<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>

plugin_sandwich_saiwt

从以上屏幕录像中可以看到:

  • 插件提供了友好的视觉反馈。将根据指定的文本对象,自动高亮显示命令将影响的操作范围。例如输入saiw命令时,将高亮显示当前单词;当在可视化模式下操作多行字符时,视觉提示将使用户更加胸有成竹。
  • 命令中的t表示标签,将在屏幕底部显示提示行,在其中输入的标签名称然后按回车键即可(并不需要输入<>);

请注意:

  1. 插入模式下,并没有专门用于输入环绕字符的快捷键。
  2. 可视化模式下的操作:
    • 首先使用快捷键进入不同类型的可视化模式。
      比如在Windows下,使用CTRL-Q键进入块视化模式;
    • 然后使用j等移动命令来选中文本;
    • 最后点击sa键,并输入环绕字符或标签。

修改环绕字符

使用sr命令可以修改环绕字符:

替换内容原始文本命令更改效果注释
引号"Hello World"srb''Hello World'使用标识符b来指代环绕字符
标签'Hello World'srbTp<p>Hello World</p>使用标识符T来输入包含尖括号的完整标签
标签<p>Hello World</p>srtth1<h1>Hello World</h1>使用标识符t来指代尖括号之内的标签名称
标签<h1>Hello World</h1>srT)(Hello World)使用标识符T来指代包含尖括号的完整标签
括号(1,2,3)srb][1,2,3]使用闭括号替换环绕字符
括号及空格(1,2,3)srb[[ 1,2,3 ]使用自定义开括号替换环绕字符并增加间隔空格

从以上sr命令可以看到,并不需要明确指明环绕字符,而可以通过标识符b来指代,既聪明又方便。

随着命令输入,会以高亮显示将被替换的环绕字符,以便在操作之前确认范围是否正确。

plugin_sandwich_srbT

删除环绕字符

使用sd命令可以删除环绕字符:

新增内容原始文本命令更改效果
引号'Hello World'sdbHello World
括号(123+4*56)/2sdb123+4*56/2
标签<div>Hello</div>sdtHello

同样在sd删除命令中,也不需要明确指明环绕字符,而可以通过标识符b来指代,大大减少了命令的复杂度。

HTML标签

假设需要针对以下文本,添加包含多个属性的HTML标签:

Hello World

可以使用以下命令,简化标签的录入:

sa$tp.class1#id1

<p class="class1" id="id1">Hello World</p>

假设需要针对以下文本段落,添加<blockquote>标签:

The passion to save humanity is a
cover for the desire to rule it.

可以使用以下命令,针对整个段落进行操作:

sa}tblockquote

<blockquote>The passion to save humanity is a
cover for the desire to rule it.</blockquote>

自定义快捷键

根据帮助文件,建议在vimrc配置文件中取消当前s键配置:

nmap s <Nop>

xmap s <Nop>

请注意,在日常操作中可以使用cl命令来代替s功能。

如果频繁使用srtt快捷键来修改标签,那么建议映射为较短的srt快捷键:

nmap srt <Plug>(operator-sandwich-replace)<Plug>(textobj-sandwich-query-a)tt

如果希望使用surround风格的快捷键,那么可以参照surround keymappings进行配置。

自定义环绕字符

通过自定义receipe,可以设置用户特有的环绕字符。例如在vimrc文件中增加以下命令,以使用 ( [ { 来指定在括号之后附带一个间隔空格:

" if you have not copied default recipes
let g:sandwich#recipes = deepcopy(g:sandwich#default_recipes)

" add spaces inside bracket
let g:sandwich#recipes += [
      \   {'buns': ['{ ', ' }'], 'nesting': 1, 'match_syntax': 1, 'kind': ['add', 'replace'], 'action': ['add'], 'input': ['{']},
      \   {'buns': ['[ ', ' ]'], 'nesting': 1, 'match_syntax': 1, 'kind': ['add', 'replace'], 'action': ['add'], 'input': ['[']},
      \   {'buns': ['( ', ' )'], 'nesting': 1, 'match_syntax': 1, 'kind': ['add', 'replace'], 'action': ['add'], 'input': ['(']},
      \   {'buns': ['{\s*', '\s*}'],   'nesting': 1, 'regex': 1, 'match_syntax': 1, 'kind': ['delete', 'replace', 'textobj'], 'action': ['delete'], 'input': ['{']},
      \   {'buns': ['\[\s*', '\s*\]'], 'nesting': 1, 'regex': 1, 'match_syntax': 1, 'kind': ['delete', 'replace', 'textobj'], 'action': ['delete'], 'input': ['[']},
      \   {'buns': ['(\s*', '\s*)'],   'nesting': 1, 'regex': 1, 'match_syntax': 1, 'kind': ['delete', 'replace', 'textobj'], 'action': ['delete'], 'input': ['(']},
      \ ]
	

使用:help textobj-sandwich命令,可以查看sandwich文本对象的帮助信息,使用:help operator-sandwich命令,可以查看sandwich操作符的帮助信息。

使用以下命令,可以查看插件的帮助文件:

:help sandwich

使用感受

一,相较surround重新发明一系列新概念,sandwich更多地重用了已经存在的元素,比如Vim的文本对象(Text Objects)重复命令(Dot Command),以此保证操作的一致性,并大大降低学习成本。

二,sandwich提供了非常友好的视觉辅助。对于相隔较远或者多层嵌套的环绕字符,随着命令的输入将会高亮显示被影响的字符,这使用户在执行操作之前,能有机会确认命令执行范围是否准确。

我个人更喜欢sandwich的举重若轻,而不是surround的举轻若重。此诚为一家之言,还请自行斟酌。

命令小结
sa添加环绕字符
sr修改环绕字符
sd删除环绕字符

Ver: 2.0 | YYQ<上一篇 | 目录 下一篇>

星期三, 九月 16, 2020

VIM学习笔记 匹配成对字符(Match Pairs)

motion_Ninja
Originally from Practical Vim by Drew Neal

'matchpairs'选项

matchpairs选项,用来控制哪些字符可以通过%命令进行匹配。此选项的默认值如下:

:set matchpairs=(:),{:},[:]

也就是说,在开括号“(,{,[”上点击%键,将会自动跳转到对应的闭括号“),},]”上;同理,在闭括号上点击%键,也会跳转回到对应的开括号上;同时,匹配跳转也能够正确处理括号嵌套的情况。

如果当前光标下并非括号,那么点击%键,将自动在本行内向前查找并定位到括号之上。

matchit-vim-example
Source: https://catonmat.net/vim-plugins-matchit-vim

如果需要新增匹配类型,例如增加对于HTML文件中的尖括号的匹配,那么可以使用以下命令:

:set mps+=<:>

利用自动命令(autocmd),可以针对特定文件类型设置匹配字符。例如针对C和Java代码,增加对于“=”和“;”的匹配:

:au FileType c,cpp,java set mps+==:;

'showmatch'选项

如果希望在输入闭括号时,短暂地跳转到与之匹配的开括号,那么可以设置以下选项:

:set showmatch

'matchtime'选项

'matchtime'选项,用于控制显示配对括号的时间,其单位为0.1秒,默认值为5,即0.5秒。

如果希望持续显示配对括号1.5秒,那么可以使用以下命令:

:set matchtime=15

matchit插件

matchit插件扩展了%命令的功能,支持if/else/endif语法结构;支持HTML标签。使用:help matchit-languages命令,可以查看当前支持的所有语言列表。

从Vim 6.0开始,matchit插件伴随vim发行,内置于$VIMRUNTIME\pack\dist\opt\matchit目录中,并不需要单独安装。

vimrc配置文件中增加以下命令,可以启用matchit插件:

packadd! matchit

在HTML标签中,点击%键,将移动到关闭标签上:

matchit-vim-example
Source: https://catonmat.net/vim-plugins-matchit-vim

使用以下命令,可以查看更多帮助信息:

:help matchit

命令小结
%跳转到匹配字符
:set matchpairs设置形成配对的字符
:set showmatch设置是否短暂跳转到匹配括号
:set matchtime设置显示配对括号的时间长度

Ver: 2.0 | YYQ<上一篇 | 目录 下一篇>