sandwich 插件可以快速编辑围绕在内容两端的字符(pairs of things surrounding things),比如成对出现的括号、引号,甚至HTML/XML标签等。
sandwich支持vim的文本对象(Text Objects),比如单词、句子和段落等等。同时也支持.
重复命令(Dot Command)。
安装配置
推荐您使用vim-plug或Vundle等插件管理器,来安装GitHub上的sandwich插件。
以下将利用实例来介绍sandwich插件的主要功能,请注意:
- 在“原始文本”列中,高亮文字表示光标所在位置;
- 在“命令”列中,为顺序执行的命令序列;
- 在“更改效果”列中,为命令执行之后的结果。您可以参考实例文件并自行测试。
新增环绕字符
在常规模式和可视化模式下,可以使用sa
命令来新增环绕字符:
模式 | 目标 范围 | 新增 内容 | 原始文本 | 命令 | 更改效果 |
---|---|---|---|---|---|
常规模式 | 单词 | 字符 | Hello World | saiw* | Hello *World* |
单词不含标点 | 引号 | Hello World! | saiw' | Hello 'World'! | |
单词包含标点 | 引号 | Hello World! | saiW' | Hello 'World!' | |
单词 | 标签 | Hello World | saiwtstrong | Hello <strong>World</strong> | |
单词 | 括号 | print var1, var2 | sa3w) | print (var1, var2) | |
行尾 | 括号 | print var1, var2 | sa$) | print (var1, var2) | |
查找 | 标签 | William Shakespeare said, "Brevity is the soul of wit." | saf"tem | William Shakespeare said, <em>"Brevity is the soul of wit."</em> | |
整行 | 字符 | Hello World | 0sa$" | "Hello World" | |
整行 | 标签 | Hello World | 0sa$tp | <p>Hello World</p> | |
字符可视化模式 | 选中的文本 | 括号 | print var1, var2 | veesa) | 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 World | Vsa) | ( 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> |
从以上屏幕录像中可以看到:
- 插件提供了友好的视觉反馈。将根据指定的文本对象,自动高亮显示命令将影响的操作范围。例如输入saiw命令时,将高亮显示当前单词;当在可视化模式下操作多行字符时,视觉提示将使用户更加胸有成竹。
- 命令中的
t
表示标签,将在屏幕底部显示提示行,在其中输入的标签名称然后按回车键即可(并不需要输入<>);
请注意:
- 插入模式下,并没有专门用于输入环绕字符的快捷键。
- 可视化模式下的操作:
- 首先使用快捷键进入不同类型的可视化模式。
比如在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
来指代,既聪明又方便。
随着命令输入,会以高亮显示将被替换的环绕字符,以便在操作之前确认范围是否正确。
删除环绕字符
使用sd
命令可以删除环绕字符:
新增内容 | 原始文本 | 命令 | 更改效果 |
---|---|---|---|
引号 | 'Hello World' | sdb | Hello World |
括号 | (123+4*56)/2 | sdb | 123+4*56/2 |
标签 | <div>Hello</div> | sdt | Hello |
同样在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 | 删除环绕字符 |