Visual Studio Code 中的片段
代码片段是模板,用于更容易地输入重复的代码模式,例如循环或条件语句。
在Visual Studio Code中,片段会在IntelliSense(⌃Space(Windows, Linux Ctrl+Space))中出现,与其它建议混合显示,同时也会出现在专门的片段选择器(命令面板中的Insert Snippet)。此外,还支持标签补全:通过以下方式启用:"editor.tabCompletion": "on",输入 a 片段前缀(触发文本),然后按 Tab 插入片段。
片段语法遵循 TextMate片段语法,但有‘插值的 shell 代码’和使用 的例外情况输入:两者都不支持。

内置片段
VS Code 内置了许多语言的片段,例如:JavaScript、TypeScript、Markdown 和 PHP。

您可以通过在命令面板中运行插入片段命令来查看当前文件所在语言的可用片段列表。但是,请记住,此列表也包括您定义的用户片段以及您已安装的扩展提供的任何片段。
从市场安装片段
许多扩展在VS Code 市场中包含片段。您可以在扩展视图中搜索包含片段的扩展 (⇧⌘X (Windows, Linux Ctrl+Shift+X)),使用@类别: "片段"过滤器。

如果你找到一个你想使用的扩展,安装它,然后重启 VS Code,新的片段将可用。
创建你自己的片段
您可以通过任何扩展轻松定义自己的代码片段。要创建或编辑自己的代码片段,请选择配置代码片段,在文件 > 首选项下,然后选择代码片段应出现的语言(通过语言标识符),或者如果它们应出现在所有语言中,请选择新的全局代码片段文件 选项。VS Code 会为您管理底层代码片段文件的创建和刷新。

片段文件以JSON编写,支持C风格注释,并可以定义任意数量的片段。片段支持大多数TextMate语法以实现动态行为,根据插入上下文智能格式化空白字符,并允许轻松的多行编辑。
以下是示例对于JavaScript 循环片段:
// 在文件 'Code/User/snippets/javascript.json' 中
{
"For Loop": {
"prefix": ["for", "for-const"],
"body": ["for (const ${2:element} of ${1:array}) {", "\t$0", "}"],
"description": "一个 for 循环。"
}
}
在上面的例子中:
- "For Loop" 是片段名称。如果没有任何内容,它将通过IntelliSense显示。
描述提供。 前缀定义一个或多个触发词以在IntelliSense中显示片段。前缀匹配用于子字符串,因此在这种情况下,"fc" 可以匹配 "for-const"。身体是一行或多行内容,在插入时将被连接为多行。新行和嵌入的制表符将根据片段插入的上下文进行格式化。描述是IntelliSense显示片段的可选描述。
此外,身体上面示例有三个占位符(按遍历顺序列出):${1:数组},${2:元素},和$0。你可以用Tab快速跳转到下一个占位符,此时你可以编辑该占位符或跳转到下一个。冒号后面的字符串输入:(如果有的话)是默认文本,例如元素在${2:元素}占位符遍历顺序按数字升序排列,从1开始;0是可选的特殊 case,总是排在最后,并在光标位于指定位置时退出片段模式。
文件模板片段
你可以添加是否是文件模板 如果片段的目的是填充或替换文件的内容,请将此属性添加到片段的定义中。文件模板片段在您在新文件或现有文件中运行 Snippets: Fill File with Snippet 命令时会显示在下拉菜单中。
片段范围
代码片段的范围仅建议相关的片段。片段可以通过以下方式之一进行范围限制:
- 这些片段所涉及的语言(可能全部)
- 这些项目片段所涉及的(可能全部)
语言片段范围
每个片段都针对一种、几种或所有(“全局”)语言,具体取决于它是在以下位置定义的:
- 一个语言片段文件
- 一个全局片段文件
单语言用户定义的片段在特定语言的片段文件中定义(例如javascript.json),您可以通过语言标识符访问 片段:配置片段。片段仅在编辑定义它的语言时可见。
多语言和全局用户定义的片段都定义在“global”片段文件中(文件后缀为JSON)。代码片段),也可以通过 片段:配置片段进行访问。在一个全局片段文件中,片段定义可能会有一个额外的 范围 属性接受一个或多个 语言标识符,这使得片段仅对指定的语言可用。如果没有任何 范围 如果提供了属性,那么全局片段在 所有 语言中可用。
大多数用户定义的代码片段都限制在一个语言内,并且在特定语言的代码片段文件中定义。
项目片段范围
你也可以有一个全局片段文件(JSON文件,带有文件后缀代码片段) 限制在您的项目中。项目文件夹片段是通过 “New Snippets”文件为 “'<folder-name>'”... 选项在 片段:配置片段 下拉菜单中创建的,并且位于项目根目录下的 .vscode文件夹。项目片段文件对所有在该项目中工作的用户共享片段很有用。项目文件夹中的片段类似于全局片段,并且可以通过特定语言进行限定。范围财产。
文件模式范围
您可以通过使用可选的来进一步控制片段何时出现包含和排除用于指定文件模式的属性。这些属性适用于语言特定和全局片段文件,并且可以与范围属性,以更精确地控制片段建议。
包含- 通配符模式或通配符模式数组,用于指定片段应出现在哪些文件中。排除- 一个 glob 模式或 glob 模式的数组,用于指定片段不应出现在哪些文件中。
模式匹配的工作原理如下:
- 仅文件名模式(例如,
*.test.ts) 基于文件名进行匹配,而不考虑文件在项目中的位置。 - 基于路径的模式(例如,
**/*.test.ts或**/dist/**) 匹配整个文件路径。 - 如果一个文件同时符合
包含和排除模式,排除模式优先。 - 如果未指定任何属性,该片段将出现在所有适用的文件中,基于
范围财产。
示例
示例:测试片段
此片段仅出现在TypeScript测试文件中:
{
"Test Block": {
"prefix": "test",
"body": ["test('${1:description}', () => {", "\t${0}", "});"],
"description": "Insert a test block",
"scope": "typescript",
"include": ["**/*.test.ts", "**/*.spec.ts"]
}
}
Example: Excluding directories
This snippet appears in all JavaScript files except those in dist or node_modules directories:
{
"Console Log": {
"prefix": "log",
"body": "console.log(${0});",
"description": "Insert console.log",
"scope": "javascript",
"exclude": ["**/dist/**", "**/node_modules/**"]
}
}
Example: Configuration file snippet
This snippet only appears in travis.yml files, using a filename-only pattern:
{
"Travis CI Node": {
"前缀": "travis-node",
"主体": ["语言: node_js", "node_js:", " - ${1:18}"],
"描述": "Travis CI Node.js 配置",
"范围": "yaml",
"包含": ["travis.yml"]
}
}
使用包含和排除模式有助于通过仅在相关位置显示片段来减少 IntelliSense 中的杂乱。
片段语法
该身体片段可以使用特殊构造来控制光标和插入的文本。以下是一些支持的功能及其语法:
制表位
使用制表位,您可以让编辑器光标在片段内部移动。使用$1,$2用于指定光标位置。该数字是标签停止被访问的顺序,而$0表示最终光标位置。多个相同的制表位出现时是相互关联并同时更新的。
占位符
占位符是带有值的制表位,例如${1:foo}占位符文本将被插入和选择,以便可以轻松更改。占位符可以嵌套,例如${1:另一个 ${2:占位符}}输入:.
选择
占位符可以有多个选择作为值。语法是用逗号分隔的值列表,用竖线字符包围,例如${1|一,二,三|}当片段插入并选择占位符时,提示将要求用户选择一个值。
变量
有$name或${name:默认},您可以插入变量的值。当变量未设置时,插入默认值或空字符串。当变量未知(即其名称未定义)时,插入变量的名称并将其转换为占位符。
以下变量可以使用:
TM_选择的文本当前选择的文本或空字符串TM_CURRENT_LINE当前行的内容TM_当前单词光标下的单词或空字符串TM_LINE_INDEX基于零索引的行号TM_行号基于1索引的行号TM_FILENAME当前文档的文件名TM_FILENAME_BASE当前文档的文件名(不包括扩展名)TM_DIRECTORY当前文档的目录TM 文件路径当前文档的完整文件路径相对文件路径当前文档相对于打开的工作区或文件夹的相对文件路径剪贴板剪贴板中的内容工作区名称打开的工作区或文件夹的名称工作区文件夹打开的工作区或文件夹的路径光标索引基于零索引的光标编号光标编号基于单索引的光标编号
插入当前日期和时间:
当前年份当前年份当前年份(简写)今年的最后两位数字当前月份月份以两位数字表示(例如 '02')当前月份名称完整的月份名称(例如 '七月')当前月份名称简写该月的简称(例如 'Jul')当前日期月份中的日期,两位数字(例如 '08')当前日期名称星期的名称(例如 '星期一')当前日期名称简写星期的简称(例如 'Mon')当前小时当前的小时(24小时制)当前分钟当前分钟的两位数字表示当前秒当前秒作为两位数当前秒数(Unix)自 Unix 时代的秒数当前时区偏移量当前的 UTC 时间区偏移量为+时:分或-时:分(示例-07:00)。
用于插入随机值:
随机6个随机的十进制数字随机十六进制6个随机的十六进制数字通用唯一识别码版本 4 的 UUID
用于插入行或块注释,遵循当前语言:
块注释开始示例输出:在 PHP 中/*或在HTML中块注释结束示例输出:在 PHP 中* /或在HTML中-->行注释示例输出:在 PHP 中输入://
下面的片段插入/* Hello World */在JavaScript文件中和在HTML文件中:
{
"你好": {
"范围": "javascript,html",
"前缀": "你好",
"主体": "$BLOCK_COMMENT_START Hello World $BLOCK_COMMENT_END"
}
}
变量转换
转换允许您在插入之前修改变量的值。转换的定义包括三个部分:
- 正则表达式,用于与变量的值进行匹配,或者当变量无法解析时为空字符串。
- 一个“格式字符串”,允许从正则表达式中引用匹配组。格式字符串允许条件插入和简单修改。
- 传递给正则表达式的选项。
以下示例插入当前文件的名称而不带其扩展名,因此从foo.txt它使输入:foo输入:.
${TM_FILENAME/(.*)\\..+$/$1/}
| | | |
| | | |-> 无选项
| | |
| | |-> 引用第一个捕获组的内容
| |
| |
| |-> 正则表达式捕获在
| 最后的`.suffix`之前的所有内容
|
|-> 解析为文件名
占位符-转换
就像变量转换一样,占位符的转换允许在移动到下一个制表位时更改插入文本的占位符。 插入的文本与正则表达式匹配,匹配或多个匹配(取决于选项)将被指定的替换格式文本替换。 每个占位符可以使用第一个占位符的值独立地定义自己的转换。 占位符转换的格式与变量转换相同。
转换示例
示例使用双引号显示,因为它们会在片段体内出现,以说明某些字符需要双转义。示例转换和文件名的结果输出示例-123.456-测试.js输入:.
| 示例 | 输出 | 解释 |
|---|---|---|
"${TM_FILENAME/[\\.]/_/}" |
example-123_456-TEST.js |
替换第一个输入:.与输入:_ |
"${TM_FILENAME/[\\.-]/_/g}" |
示例_123_456_测试_js |
替换每个输入:.或输入:-与输入:_ |
"${TM_FILENAME/(.*)/${1:/upcase}/}" |
EXAMPLE-123.456-TEST.JS |
转换为全大写 |
"${TM_FILENAME/[^0-9a-z]//gi}" |
示例123456测试js |
移除非字母数字字符 |
语法
以下是片段的EBNF (扩展的Backus-Naur形式)。使用 输入:(反斜杠),你可以转义输入:$,},和输入:在选择元素中,反斜杠也转义逗号和管道字符。只能转义需要转义的字符,因此输入:$这些结构内部不应转义,并且也不应输入:$或}应该在选择结构内部进行转义。
any ::= tabstop | placeholder | choice | variable | text
tabstop ::= '$' int
| '${' int '}'
| '${' int transform '}'
placeholder ::= '${' int ':' any '}'
choice ::= '${' int '|' text (',' text)* '|}'
variable ::= '$' var | '${' var '}'
| '${' var ':' any '}'
| '${' var transform '}'
transform ::= '/' regex '/' (format | text)+ '/' options
format ::= '$' int | '${' int '}'
| '${' int ':' '/upcase' | '/downcase' | '/capitalize' | '/camelcase' | '/pascalcase' | '/snakecase' | '/kebabcase' '}'
| '${' int ':+' if '}'
| '${' int ':?' if ':' else '}'
| '${' int ':-' else '}' | '${' int ':' else '}'
regex ::= JavaScript Regular Expression 值 (ctor-string)
options ::= JavaScript Regular Expression 选项 (ctor-options)
var ::= [_a-zA-Z] [_a-zA-Z0-9]*
int ::= [0-9]+
text ::= .*
if ::= text
else ::= text
使用 TextMate 模板
你也可以在 VS Code 中使用现有的 TextMate 模板 (.tmSnippets)。请参阅使用 TextMate 模板主题以了解更多信息。
为片段分配键盘快捷键
您可以创建自定义键盘快捷键以插入特定片段。打开keybindings.json (偏好设置:打开键盘快捷键文件), 定义了所有的键盘快捷键,并添加一个键盘快捷键通过"片段"作为额外参数:
{
"键": "cmd+k 1",
"命令": "editor.action.insertSnippet",
"条件": "editorTextFocus",
"参数": {
"片段": "console.log($1)$0"
}
}
键盘快捷键将调用插入片段命令,但与其提示您选择片段,它将插入提供的片段。您像往常一样定义自定义键绑定,使用键盘快捷键、命令 ID 和可选的当条件上下文来启用键盘快捷键。
此外,与其使用片段要在线定义您的代码片段,可以使用引用现有代码片段的参数值语言ID和名字参数。语言ID参数选择片段所表示的语言名字插入,例如下面的示例选择我的收藏片段那有可用的C#-文件。
{
"键": "cmd+k 1",
"命令": "editor.action.insertSnippet",
"条件": "editorTextFocus",
"参数": {
"langId": "csharp",
"名称": "myFavSnippet"
}
}
下一步
- 命令行 - VS Code 具有丰富的命令行界面,可以打开或比较文件并安装扩展。
- 扩展 API - 了解其他扩展 VS Code 的方式。
- 片段指南 - 您可以将片段打包以在 VS Code 中使用。
常见问题
如果我想从 .tmSnippet 文件中使用现有的 TextMate 模板,怎么办?
您可以轻松地将 TextMate 摘录文件打包用于 VS Code 中的使用。请参阅在我们的扩展 API 文档中使用 TextMate 摘录。
如何在粘贴的脚本中将片段放置在变量的位置?
要在粘贴的脚本中使用变量,您需要转义'$'$变量名称以便在片段扩展阶段不被解析。
"变量片段":{
"前缀": "_Var",
"主体": "\\$MyVar = 2",
"描述": "一个基本的片段,将变量放置在脚本中,并带有 $ 前缀"
}
这导致粘贴片段如下:
$MyVar = 2
我可以从IntelliSense中移除片段吗?
是的,您可以通过选择隐藏在IntelliSense(完成列表)中按钮来隐藏特定片段在插入片段命令下拉菜单中的显示。

您仍然可以使用插入片段命令选择片段,但隐藏的片段不会在IntelliSense中显示。