Visual Studio Code 中的 Emmet
Visual Studio Code 内置了对 Emmet 片段和展开的支持,无需额外扩展。Emmet 2.0 支持大部分 Emmet 操作,包括展开 Emmet 缩写和片段。
如何展开 Emmet 缩写和代码片段
Emmet 缩写和代码片段展开功能在 html
、haml
、pug
、slim
、jsx
、xml
、xsl
、css
、scss
、sass
、less
和 stylus
文件中默认启用,同时也适用于任何继承自上述语言的语言,如 handlebars
和 php
。
当你开始输入 Emmet 缩写时,你会在建议列表中看到该缩写。如果你打开了建议文档浮出窗口,你会在输入时看到展开的预览。如果你在样式表文件中,展开的缩写会显示在建议列表中,并与其他 CSS 建议一起排序。
使用 Tab 键进行 Emmet 展开
如果你想使用 Tab 键来展开 Emmet 缩写,请添加以下设置
"emmet.triggerExpansionOnTab": true
当文本不是 Emmet 缩写时,此设置允许使用 Tab 键进行缩进。
当 quickSuggestions 禁用时使用 Emmet
如果你禁用了 editor.quickSuggestions 设置,你将不会在输入时看到建议。你仍然可以通过按 ⌃Space (Windows、Linux 为 Ctrl+Space) 手动触发建议并查看预览。
在建议中禁用 Emmet
如果你完全不希望在建议中看到 Emmet 缩写,请使用以下设置
"emmet.showExpandedAbbreviation": "never"
你仍然可以使用 Emmet: Expand Abbreviation 命令来展开你的缩写。你也可以将任何键盘快捷键绑定到命令 ID editor.emmet.action.expandAbbreviation
。
Emmet 建议排序
为确保 Emmet 建议始终位于建议列表的顶部,请添加以下设置
"emmet.showSuggestionsAsSnippets": true,
"editor.snippetSuggestions": "top"
在其他文件类型中使用 Emmet 缩写
要在默认不支持 Emmet 缩写展开的文件类型中启用它,请使用 emmet.includeLanguages 设置。请确保在映射的两边都使用语言标识符,右侧是 Emmet 支持的语言的标识符(参见上面的列表)。
例如
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"razor": "html",
"plaintext": "pug"
}
Emmet 对这些新语言一无所知,因此可能会在非 HTML/CSS 上下文中显示 Emmet 建议。为避免这种情况,你可以使用以下设置。
"emmet.showExpandedAbbreviation": "inMarkupAndStylesheetFilesOnly"
注意:如果你以前使用 emmet.syntaxProfiles 来映射新的文件类型,从 VS Code 1.15 版本开始,你应该改用 emmet.includeLanguages 设置。emmet.syntaxProfiles 仅用于自定义最终输出。
Emmet 与多光标
你也可以将大多数 Emmet 操作与多光标一起使用
使用过滤器
过滤器是特殊的后处理器,它在展开的缩写输出到编辑器之前对其进行修改。有两种使用过滤器的方法;一种是通过 emmet.syntaxProfiles 设置全局使用,另一种是直接在当前缩写中使用。
下面是第一种方法的示例,使用 emmet.syntaxProfiles 设置为 HTML 文件中的所有缩写应用 bem
过滤器
"emmet.syntaxProfiles": {
"html": {
"filters": "bem"
}
}
要为当前缩写提供过滤器,请将过滤器附加到你的缩写之后。例如,div#page|c
将对 div#page
缩写应用 comment
过滤器。
BEM 过滤器 (bem)
如果你使用 块元素修饰符 (BEM) 的方式编写 HTML,那么 bem
过滤器对你来说非常方便。要了解更多关于如何使用 bem
过滤器的信息,请阅读 Emmet 中的 BEM 过滤器。
你可以通过使用 bem.elementSeparator
和 bem.modifierSeparator
首选项来自定义此过滤器,具体文档请见 Emmet 首选项。
注释过滤器 (c)
此过滤器在重要标签周围添加注释。默认情况下,“重要标签”是那些带有 id 和/或 class 属性的标签。
例如,div>div#page>p.title+p|c
将被展开为
<div>
<div id="page">
<p class="title"></p>
<!-- /.title -->
<p></p>
</div>
<!-- /#page -->
</div>
你可以通过使用 filter.commentTrigger
、filter.commentAfter
和 filter.commentBefore
首选项来自定义此过滤器,具体文档请见 Emmet 首选项。
filter.commentAfter
首选项的格式在 VS Code Emmet 2.0 中有所不同。
例如,替代
"emmet.preferences": {
"filter.commentAfter": "\n<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->"
}
在 VS Code 中,你会使用一个更简单的
"emmet.preferences": {
"filter.commentAfter": "\n<!-- /[#ID][.CLASS] -->"
}
修剪过滤器 (t)
此过滤器仅在为 Emmet: 使用缩写包裹 命令提供缩写时适用。它会从被包裹的行中移除行标记。
使用自定义 Emmet 代码片段
自定义 Emmet 代码片段需要在一个名为 snippets.json
的 json 文件中定义。emmet.extensionsPath 设置应包含此文件所在目录的路径。
以下是这个 snippets.json
文件内容的示例。
{
"html": {
"snippets": {
"ull": "ul>li[id=${1} class=${2}]*2{ Will work with html, pug, haml and slim }",
"oll": "<ol><li id=${1} class=${2}> Will only work in html </ol>",
"ran": "{ Wrap plain text in curly braces }"
}
},
"css": {
"snippets": {
"cb": "color: black",
"bsd": "border: 1px solid ${1:red}",
"ls": "list-style: ${1}"
}
}
}
在 Emmet 2.0 中通过 snippets.json
文件编写自定义代码片段与旧方式有几点不同
主题 | 旧版 Emmet | Emmet 2.0 |
---|---|---|
代码片段 vs 缩写 | 在两个独立的属性 snippets 和 abbreviations 中都支持 |
两者已合并为一个名为 snippets 的属性。请参阅默认的 HTML 代码片段 和 CSS 代码片段 |
CSS 代码片段名称 | 可以包含 : |
定义代码片段名称时不要使用 : 。当 Emmet 尝试将给定的缩写与其中一个片段进行模糊匹配时,它用于分隔属性名和值。 |
CSS 代码片段值 | 可以以 ; 结尾 |
不要在代码片段值的末尾添加 ; 。Emmet 将根据文件类型 (css/less/scss vs sass/stylus) 或为 css.propertyEnd 、sass.propertyEnd 、stylus.propertyEnd 设置的 emmet 首选项添加结尾的 ; |
光标位置 | 可以使用 ${cursor} 或 | |
仅使用 Textmate 语法,如 ${1} 用于制表位和光标位置 |
HTML Emmet 代码片段
HTML 自定义代码片段适用于所有其他标记语言,如 haml
或 pug
。当代码片段的值是缩写而不是实际的 HTML 时,可以应用适当的转换以根据语言类型获得正确的输出。
例如,对于一个带有列表项的无序列表,如果你的代码片段值是 ul>li
,你可以在 html
、haml
、pug
或 slim
中使用相同的代码片段,但如果你的代码片段值是 <ul><li></li></ul>
,那么它将只在 html
文件中有效。
如果你想要一个纯文本的代码片段,请用 {}
将文本括起来。
CSS Emmet 代码片段
CSS Emmet 代码片段的值应该是一个完整的属性名和值对。
CSS 自定义代码片段适用于所有其他样式表类型,如 scss
、less
或 sass
。因此,不要在代码片段值的末尾包含结尾的 ;
。Emmet 会根据语言是否需要来添加它。
不要在代码片段名称中使用 :
。当 Emmet 尝试将缩写与其中一个代码片段进行模糊匹配时,:
用于分隔属性名和值。
自定义代码片段中的制表位和光标
自定义 Emmet 代码片段中制表位的语法遵循 Textmate 代码片段语法。
- 使用
${1}
、${2}
表示制表位,使用${1:placeholder}
表示带占位符的制表位。 - 以前,
|
或${cursor}
用于表示自定义 Emmet 代码片段中的光标位置。这已不再支持。请改用${1}
。
Emmet 配置
以下是你可以用来在 VS Code 中自定义 Emmet 体验的 Emmet 设置。
-
使用此设置在你选择的语言和 Emmet 支持的语言之间添加映射,以便在前者中使用后者的语法启用 Emmet。确保在映射的两边都使用语言 ID。
例如
"emmet.includeLanguages": { "javascript": "javascriptreact", "plaintext": "pug" }
-
如果你不希望在某种语言中看到 Emmet 展开,请将其添加到此设置中,该设置接受一个语言 ID 字符串数组。
-
请参阅 Emmet 输出配置文件的自定义,了解如何自定义 HTML 缩写的输出。
例如
"emmet.syntaxProfiles": { "html": { "attr_quotes": "single" }, "jsx": { "self_closing_tag": true } }
-
自定义 Emmet 代码片段使用的变量。
例如
"emmet.variables": { "lang": "de", "charset": "UTF-16" }
-
emmet.showExpandedAbbreviation
控制在建议/完成列表中显示的 Emmet 建议。
设置值 描述 never
从不在任何语言的建议列表中显示 Emmet 缩写。 inMarkupAndStylesheetFilesOnly
仅在纯标记和样式表语言('html', 'pug', 'slim', 'haml', 'xml', 'xsl', 'css', 'scss', 'sass', 'less', 'stylus')中显示 Emmet 建议。 always
在所有 Emmet 支持的模式以及在 emmet.includeLanguages 设置中有映射的语言中显示 Emmet 建议。 注意:在
always
模式下,新的 Emmet 实现不是上下文感知的。例如,如果你正在编辑一个 JavaScript React 文件,你不仅在编写标记时会得到 Emmet 建议,在编写 JavaScript 时也会得到。 -
emmet.showAbbreviationSuggestions
将可能的 emmet 缩写显示为建议。默认为
true
。例如,当你输入
li
时,你会得到所有以li
开头的 emmet 片段的建议,如link
、link:css
、link:favicon
等。这有助于学习你可能不知道存在的 Emmet 片段,除非你熟记 Emmet 速查表。在样式表或当 emmet.showExpandedAbbreviation 设置为
never
时不适用。 -
提供包含
snippets.json
文件的目录位置,该文件包含你的自定义代码片段。 -
设置为 true 以启用使用 Tab 键展开 Emmet 缩写。我们使用此设置在没有缩写可展开时提供适当的回退以进行缩进。
-
emmet.showSuggestionsAsSnippets
如果设置为
true
,Emmet 建议将与其他代码片段分组,允许你根据 editor.snippetSuggestions 设置对它们进行排序。将此设置为true
并将 editor.snippetSuggestions 设置为top
,以确保 Emmet 建议始终显示在其他建议之上。 -
你可以使用此设置来自定义 Emmet,如 Emmet 首选项 中所记录。目前支持以下自定义
css.propertyEnd
css.valueSeparator
sass.propertyEnd
sass.valueSeparator
stylus.propertyEnd
stylus.valueSeparator
css.unitAliases
css.intUnit
css.floatUnit
bem.elementSeparator
bem.modifierSeparator
filter.commentBefore
filter.commentTrigger
filter.commentAfter
format.noIndentTags
format.forceIndentationForTags
profile.allowCompactBoolean
css.fuzzySearchMinScore
filter.commentAfter
首选项的格式在 Emmet 2.0 中更简单。例如,代替旧格式
"emmet.preferences": { "filter.commentAfter": "\n<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->" }
你将使用
"emmet.preferences": { "filter.commentAfter": "\n<!-- /[#ID][.CLASS] -->" }
后续步骤
Emmet 只是 VS Code 中众多优秀 Web 开发功能之一。继续阅读以了解
故障排除
自定义标签未在建议列表中展开
当在表达式如 MyTag>YourTag
或 MyTag.someclass
中使用自定义标签时,它们会显示在建议列表中。但当它们单独使用如 MyTag
时,它们不会出现在建议列表中。这样设计是为了避免建议列表中的噪音,因为每个单词都可能是一个潜在的自定义标签。
添加以下设置以启用使用 tab 键展开 Emmet 缩写,这将在所有情况下展开自定义标签。
"emmet.triggerExpansionOnTab": true
我的以 +
结尾的 HTML 代码片段无法工作
以 +
结尾的 HTML 片段,如来自 Emmet 速查表的 select+
和 ul+
,是不被支持的。这是 Emmet 2.0 中的一个已知问题 问题:emmetio/html-matcher#1。一个变通方法是为这种情况创建你自己的自定义 Emmet 片段。
缩写无法展开
首先,检查你是否正在使用自定义代码片段(如果 emmet.extensionsPath 设置正在读取一个 snippets.json
文件)。自定义代码片段的格式在 VS Code 1.53 版本中发生了变化。现在不再使用 |
来指示光标位置,而是使用 ${1}
、${2}
等标记。来自 emmetio/emmet
仓库的默认 CSS 代码片段文件展示了新光标位置格式的示例。
如果缩写仍然无法展开
- 检查内置扩展,看看 Emmet 是否被禁用。
- 尝试通过在命令面板中运行 Developer: Restart Extension Host (
workbench.action.restartExtensionHost
) 命令来重启扩展主机。
我可以在哪里设置 Emmet 首选项中记录的所有首选项?
你可以使用 emmet.preferences 设置来设置首选项。只有 Emmet 首选项中记录的部分首选项可以自定义。请阅读Emmet 配置下的首选项部分。
有什么提示和技巧吗?
当然!
- 在 CSS 缩写中,当你使用
:
时,左侧部分用于与 CSS 属性名进行模糊匹配,右侧部分用于与 CSS 属性值进行匹配。充分利用这一点,使用像pos:f
、trf:rx
、fw:b
等缩写。 - 探索 Emmet 操作中记录的所有其他 Emmet 功能。
- 不要犹豫,创建你自己的自定义 Emmet 片段。