Vim 中的片段与缩写
Snippets vs. Abbreviations in Vim
使用 "snippets" 插件有什么优点 and/or 缺点,例如snipmate, ultisnips, for VIM as opposed to simply using the builtin "abbreviations" 功能?
是否有声明 iabbr
、cabbr
等的特定用例。缺乏 一些 主要片段插件提供的功能?我未能找到这两个 "features" 及其各自实现之间的彻底比较。
正如@peter-rincker 在评论中指出的那样:
It should be noted that abbreviations can execute code as well. Often via <c-r>=
or via an expression abbreviation (<expr>)
. Example which expands @@ to the current file's path: :iabbrev @@ <c-r>=expand('%:p')<cr>
作为 python 的示例,让我们比较 Vim 中的一个 snipmate 片段和一个缩写,用于为 class 声明插入行。
Snipmate
# New Class
snippet cl
class ${1:ClassName}(${2:object}):
"""${3:docstring for }"""
def __init__(self, ${4:arg}):
${5:super(, self).__init__()}
self. =
Vim脚本
au FileType python :iabbr cl class ClassName(object):<CR><Tab>"""docstring for ClassName"""<CR>def __init__(self, arg):<CR><Tab>super(ClassName, self).__init__()<CR>self.arg = arg
当 Vim 的 abbr
和 :help template
时,我是否遗漏了 "snippets" 的一些基本功能,或者我假设它们在大多数情况下是矫枉过正的?模板能够做 所有 大部分 的片段吗?
我认为实现代码片段更容易,而且它们提供了额外的 aesthetic/visual 功能。例如,如果我在 Vim 中使用 abbr
并在 vim 中使用其他插件 running/testing python 代码——例如syntastic, pytest, ropevim, pep8,等等——我是否错过了代码片段提供的一些关键功能?
片段更强大。
根据实施情况,片段可以让您更改(或接受默认值)多个占位符,甚至可以在片段展开时执行代码。
例如 ultisnips,你可以让它执行 shell 命令,vimscript 和 Python 代码。
一个(ultisnips)例子:
snippet hdr "General file header" b
# file: `!v expand('%:t')`
# vim:fileencoding=utf-8:ft=`!v &filetype`
#
#
# Author: ${2:J. Doe} ${3:<jdoe@gmail.com>}
# Created: `!v strftime("%F %T %z")`
# Last modified: `!v strftime("%F %T %z")`
endsnippet
这会为您提供三个要填写的占位符(它为其中两个提供默认值),并设置文件名、文件类型和当前日期和时间。
单词"snippet"之后,起始行包含三项;
- 触发字符串,
- 描述和
- 片段选项。
我个人主要使用 b
选项,其中片段在行首展开,而 w
选项在触发字符串从单词开头展开时展开片段.
请注意,您必须键入触发字符串 和 ,然后输入实际触发扩展的键或组合键。因此,除非您希望 .
,否则片段不会展开
此外,片段可以按文件类型专门化。假设您要定义四级标题,h1
.. h4
。您可以对相同的名称进行不同的扩展,例如HTML、markdown、LaTeX 或重组文本文件。
片段
Vim 的本地缩写的粗略超集。以下是要点:
- 仅在按键时触发
- 使用用户可以在其间跳转的占位符
- 只存在于插入模式
- 动态扩展
缩写
非常适合常见的拼写错误和小片段。
- Vim 原生,因此不需要插件
- 通常在空格或
<c-]>
处展开
- 触发文本的一些特殊规则(参见
:h abbreviations
)
- 可以通过
:cabbrev
在命令模式下使用(通常用于创建命令别名)
- 没有占位符
- 动态扩展
结论
在大多数情况下,片段更强大,并提供其他编辑器喜欢的许多功能,但您可以同时使用这两种功能,而且很多人都在使用。缩写享有本地化的优势,这对远程环境很有用。缩写还有另一个明显的优势,那就是可以在命令模式下使用。
片段就像类固醇的内置:abbreviate
,通常有:
- 参数插入:您可以在片段内的不同位置插入(键入或select)文本片段。缩写只展开一次。
- 镜像:参数可能会在代码段的其他地方重复(甚至可能以转换的方式),通常会在您键入时更新。
- multiple stops inside: 你可以在片段中从一个点跳到另一个点,有时甚至递归地在一个片段中扩展片段。
snippet plugin的评价有三点:一是snippet engine本身的特性,二是作者或他人提供的snippet的质量和广度;第三,添加新片段是多么容易。
任何可以用代码片段完成的事情都可以用缩写来完成,反之亦然。你可以有(镜像或不镜像)带有缩写的占位符,你可以有上下文相关的片段。
有两个重要区别:
- 当输入缩写文本并点击非单词字符(或 esc)时,会触发缩写。片段按需触发,可以使用快捷方式(无需键入
while
+ tab。w
+ tab 可能就足够了)。
- 定义新片段(或维护旧片段)比定义缩写要容易得多。使用缩写,a lot of boiler plate code is required when we want to do neat things.
还有一些其他差异。例如,缩写总是在任何地方触发。在注释或字符串上下文中看到 for
扩展为 for(placeholder) {\n}
肯定不是最终用户所期望的。使用片段,这不再是问题:我们可以期望最终用户在要求扩展片段时知道他在做什么。不过,我们可以建议 context-aware snippets 在评论中将 throw
扩展为 @throw {domain::exception} {explanation}
,或在其他地方扩展为 throw domain::exception({message});
。
使用 "snippets" 插件有什么优点 and/or 缺点,例如snipmate, ultisnips, for VIM as opposed to simply using the builtin "abbreviations" 功能?
是否有声明 iabbr
、cabbr
等的特定用例。缺乏 一些 主要片段插件提供的功能?我未能找到这两个 "features" 及其各自实现之间的彻底比较。
正如@peter-rincker 在评论中指出的那样:
It should be noted that abbreviations can execute code as well. Often via
<c-r>=
or via an expression abbreviation(<expr>)
. Example which expands @@ to the current file's path::iabbrev @@ <c-r>=expand('%:p')<cr>
作为 python 的示例,让我们比较 Vim 中的一个 snipmate 片段和一个缩写,用于为 class 声明插入行。
Snipmate
# New Class
snippet cl
class ${1:ClassName}(${2:object}):
"""${3:docstring for }"""
def __init__(self, ${4:arg}):
${5:super(, self).__init__()}
self. =
Vim脚本
au FileType python :iabbr cl class ClassName(object):<CR><Tab>"""docstring for ClassName"""<CR>def __init__(self, arg):<CR><Tab>super(ClassName, self).__init__()<CR>self.arg = arg
当 Vim 的 abbr
和 :help template
时,我是否遗漏了 "snippets" 的一些基本功能,或者我假设它们在大多数情况下是矫枉过正的?模板能够做 所有 大部分 的片段吗?
我认为实现代码片段更容易,而且它们提供了额外的 aesthetic/visual 功能。例如,如果我在 Vim 中使用 abbr
并在 vim 中使用其他插件 running/testing python 代码——例如syntastic, pytest, ropevim, pep8,等等——我是否错过了代码片段提供的一些关键功能?
片段更强大。
根据实施情况,片段可以让您更改(或接受默认值)多个占位符,甚至可以在片段展开时执行代码。
例如 ultisnips,你可以让它执行 shell 命令,vimscript 和 Python 代码。
一个(ultisnips)例子:
snippet hdr "General file header" b
# file: `!v expand('%:t')`
# vim:fileencoding=utf-8:ft=`!v &filetype`
#
#
# Author: ${2:J. Doe} ${3:<jdoe@gmail.com>}
# Created: `!v strftime("%F %T %z")`
# Last modified: `!v strftime("%F %T %z")`
endsnippet
这会为您提供三个要填写的占位符(它为其中两个提供默认值),并设置文件名、文件类型和当前日期和时间。
单词"snippet"之后,起始行包含三项;
- 触发字符串,
- 描述和
- 片段选项。
我个人主要使用 b
选项,其中片段在行首展开,而 w
选项在触发字符串从单词开头展开时展开片段.
请注意,您必须键入触发字符串 和 ,然后输入实际触发扩展的键或组合键。因此,除非您希望 .
,否则片段不会展开此外,片段可以按文件类型专门化。假设您要定义四级标题,h1
.. h4
。您可以对相同的名称进行不同的扩展,例如HTML、markdown、LaTeX 或重组文本文件。
片段
Vim 的本地缩写的粗略超集。以下是要点:
- 仅在按键时触发
- 使用用户可以在其间跳转的占位符
- 只存在于插入模式
- 动态扩展
缩写
非常适合常见的拼写错误和小片段。
- Vim 原生,因此不需要插件
- 通常在空格或
<c-]>
处展开
- 触发文本的一些特殊规则(参见
:h abbreviations
) - 可以通过
:cabbrev
在命令模式下使用(通常用于创建命令别名) - 没有占位符
- 动态扩展
结论
在大多数情况下,片段更强大,并提供其他编辑器喜欢的许多功能,但您可以同时使用这两种功能,而且很多人都在使用。缩写享有本地化的优势,这对远程环境很有用。缩写还有另一个明显的优势,那就是可以在命令模式下使用。
片段就像类固醇的内置:abbreviate
,通常有:
- 参数插入:您可以在片段内的不同位置插入(键入或select)文本片段。缩写只展开一次。
- 镜像:参数可能会在代码段的其他地方重复(甚至可能以转换的方式),通常会在您键入时更新。
- multiple stops inside: 你可以在片段中从一个点跳到另一个点,有时甚至递归地在一个片段中扩展片段。
snippet plugin的评价有三点:一是snippet engine本身的特性,二是作者或他人提供的snippet的质量和广度;第三,添加新片段是多么容易。
任何可以用代码片段完成的事情都可以用缩写来完成,反之亦然。你可以有(镜像或不镜像)带有缩写的占位符,你可以有上下文相关的片段。
有两个重要区别:
- 当输入缩写文本并点击非单词字符(或 esc)时,会触发缩写。片段按需触发,可以使用快捷方式(无需键入
while
+ tab。w
+ tab 可能就足够了)。 - 定义新片段(或维护旧片段)比定义缩写要容易得多。使用缩写,a lot of boiler plate code is required when we want to do neat things.
还有一些其他差异。例如,缩写总是在任何地方触发。在注释或字符串上下文中看到 for
扩展为 for(placeholder) {\n}
肯定不是最终用户所期望的。使用片段,这不再是问题:我们可以期望最终用户在要求扩展片段时知道他在做什么。不过,我们可以建议 context-aware snippets 在评论中将 throw
扩展为 @throw {domain::exception} {explanation}
,或在其他地方扩展为 throw domain::exception({message});
。