在 VS Code 中试用

Visual Studio Code 中的 Emmet

Visual Studio Code 内置了对 Emmet 代码片段和扩展的支持,无需安装扩展Emmet 2.0 支持大多数 Emmet 操作,包括展开 Emmet 缩写和代码片段

如何扩展 Emmet 缩写和代码片段

Emmet 缩写和代码片段扩展在 htmlhamlpugslimjsxxmlxslcssscsssasslessstylus 文件中默认启用,对于继承自上述任何语言的语言(如 handlebarsphp)也同样启用。

Emmet in suggestion/auto-completion list

当您开始输入 Emmet 缩写时,您将在建议列表中看到缩写。如果您打开了建议文档弹出框,您将在输入时看到扩展的预览。如果您在样式表文件中,扩展的缩写会出现在建议列表中,与其它 CSS 建议一起排序。

使用 Tab 键进行 Emmet 扩展

如果您想使用 Tab 键来展开 Emmet 缩写,请添加以下设置:

"emmet.triggerExpansionOnTab": true

此设置允许在文本不是 Emmet 缩写时使用 Tab 键进行缩进。

快速建议禁用时的 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.includeLanguagesemmet.syntaxProfiles 仅用于自定义最终输出

带有多光标的 Emmet

您也可以将大多数 Emmet 操作与多光标一起使用:

Emmet with multi cursors

使用过滤器

过滤器是一种特殊的后处理器,它在将扩展的缩写输出到编辑器之前对其进行修改。使用过滤器有两种方式:全局通过 emmet.syntaxProfiles 设置,或者直接在当前缩写中使用。

下面是使用第一种方法,通过 emmet.syntaxProfiles 设置将 bem 过滤器应用于 HTML 文件中所有缩写的示例:

"emmet.syntaxProfiles": {
  "html": {
    "filters": "bem"
  }
}

要仅为当前缩写提供过滤器,请将过滤器附加到您的缩写。例如,div#page|c 将把 comment 过滤器应用于 div#page 缩写。

BEM 过滤器 (bem)

如果您使用 块元素修饰符 (BEM) 的方式编写 HTML,那么 bem 过滤器对您来说非常方便。要了解如何使用 bem 过滤器,请阅读 Emmet 中的 BEM 过滤器

您可以通过使用 Emmet Preferences 中记录的 bem.elementSeparatorbem.modifierSeparator 首选项来自定义此过滤器。

注释过滤器 (c)

此过滤器在重要标签周围添加注释。默认情况下,“重要标签”是指带有 id 和/或 class 属性的标签。

例如,div>div#page>p.title+p|c 将被扩展为:

<div>
    <div id="page">
        <p class="title"></p>
        <!-- /.title -->
        <p></p>
    </div>
    <!-- /#page -->
</div>

您可以通过使用 Emmet Preferences 中记录的 filter.commentTriggerfilter.commentAfterfilter.commentBefore 首选项来自定义此过滤器。

在 VS Code Emmet 2.0 中,filter.commentAfter 首选项的格式有所不同。

例如,您不是使用:

"emmet.preferences": {
  "filter.commentAfter": "\n<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->"
}

在 VS Code 中,您将使用更简单的:

"emmet.preferences": {
  "filter.commentAfter": "\n<!-- /[#ID][.CLASS] -->"
}

修剪过滤器 (t)

此过滤器仅在为 Emmet: Wrap with Abbreviation 命令提供缩写时适用。它移除被包装行的行标记。

使用自定义 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}"
    }
  }
}

通过 snippets.json 文件编写 Emmet 2.0 中的自定义代码片段与旧方法相比有几个方面不同:

主题 旧版 Emmet Emmet 2.0
代码片段与缩写 支持 snippetsabbreviations 两个独立的属性 两者合并为一个属性,称为 snippets。参见默认的 HTML 代码片段CSS 代码片段
CSS 代码片段名称 可以包含 : 定义代码片段名称时不使用 :。当 Emmet 尝试将给定的缩写与某个代码片段进行模糊匹配时,它用于分隔属性名和值。
CSS 代码片段值 可以以 ; 结尾 不在代码片段值末尾添加 ;。Emmet 将根据文件类型 (css/less/scss vs sass/stylus) 或为 css.propertyEndsass.propertyEndstylus.propertyEnd 设置的 emmet 首选项添加末尾的 ;
光标位置 可以使用 ${cursor}| 仅使用类似 ${1} 的 textmate 语法来表示制表位和光标位置

HTML Emmet 代码片段

HTML 自定义代码片段适用于所有其他标记语言,例如 hamlpug。当代码片段值是缩写而不是实际 HTML 时,可以应用适当的转换以根据语言类型获得正确的输出。

例如,对于带有列表项的无序列表,如果您的代码片段值是 ul>li,您可以在 htmlhamlpugslim 中使用相同的代码片段,但如果您的代码片段值是 <ul><li></li></ul>,那么它将仅在 html 文件中有效。

如果您想要一个用于纯文本的代码片段,则用 {} 括起来。

CSS Emmet 代码片段

CSS Emmet 代码片段的值应是一个完整的属性名和值对。

CSS 自定义代码片段适用于所有其他样式表语言,例如 scsslesssass。因此,不要在代码片段值末尾包含末尾的 ;。Emmet 将根据语言是否需要来添加它。

请勿在代码片段名称中使用 :。当 Emmet 尝试将缩写与某个代码片段进行模糊匹配时,: 用于分隔属性名和值。

自定义代码片段中的制表位和光标

自定义 Emmet 代码片段中制表位的语法遵循 Textmate 代码片段语法

  • 使用 ${1}${2} 表示制表位,使用 ${1:placeholder} 表示带有占位符的制表位。
  • 以前,|${cursor} 用于表示自定义 Emmet 代码片段中的光标位置。这不再受支持。请改用 ${1}

Emmet 配置

以下是您可以用来在 VS Code 中自定义 Emmet 体验的 Emmet 设置

  • emmet.includeLanguages

    使用此设置添加您选择的语言与 Emmet 支持的语言之间的映射,以便在前一种语言中使用后一种语言的语法启用 Emmet。请确保映射的两侧都使用语言 ID。

    例如:

    "emmet.includeLanguages": {
      "javascript": "javascriptreact",
      "plaintext": "pug"
    }
    
  • emmet.excludeLanguages

    如果您不想在某些语言中看到 Emmet 扩展,请将其添加到此设置中,该设置接受一个语言 ID 字符串数组。

  • emmet.syntaxProfiles

    请参阅 Emmet 输出配置文件自定义 以了解如何自定义 HTML 缩写的输出。

    例如:

    "emmet.syntaxProfiles": {
      "html": {
        "attr_quotes": "single"
      },
      "jsx": {
        "self_closing_tag": true
      }
    }
    
  • emmet.variables

    自定义 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 代码片段的建议,例如 linklink:csslink:favicon 等。这有助于您学习那些您可能从未知道存在的 Emmet 代码片段,除非您完全记住了 Emmet 速查表

    在样式表中或当 emmet.showExpandedAbbreviation 设置为 never 时不适用。

  • emmet.extensionsPath

    提供包含 snippets.json 文件的目录位置,该文件包含您的自定义代码片段。

  • emmet.triggerExpansionOnTab

    将其设置为 true 可使用 Tab 键展开 Emmet 缩写。当没有缩写可展开时,我们使用此设置来提供适当的回退以提供缩进。

  • emmet.showSuggestionsAsSnippets

    如果设置为 true,则 Emmet 建议将与其他代码片段一起分组,使您可以根据 editor.snippetSuggestions 设置对其进行排序。将此设置为 true 并将 editor.snippetSuggestions 设置为 top,以确保 Emmet 建议始终显示在其他建议的顶部。

  • emmet.preferences

    您可以使用此设置自定义 Emmet,如 Emmet Preferences 中所述。目前支持以下自定义项:

    • 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

    在 Emmet 2.0 中,filter.commentAfter 首选项的格式有所不同,并且更简单。

    例如,您将使用:

    "emmet.preferences": {
      "filter.commentAfter": "\n<!-- /<%= attr('id', '#') %><%= attr('class', '.') %> -->"
    }
    

    而不是旧格式:

    "emmet.preferences": {
      "filter.commentAfter": "\n<!-- /[#ID][.CLASS] -->"
    }
    

    如果您需要支持 Emmet Preferences 中记录的任何其他首选项,请提交 功能请求

后续步骤

Emmet 只是 VS Code 中众多出色的 Web 开发功能之一。请继续阅读以了解:

  • HTML - VS Code 通过智能感知、闭合标签和格式化支持 HTML。
  • CSS - 我们为 CSS、SCSS 和 Less 提供了丰富的支持。

疑难解答

自定义标签未在建议列表中展开

当自定义标签用于表达式(如 MyTag>YourTagMyTag.someclass)时,它们确实会出现在建议列表中。但当它们单独使用(如 MyTag)时,它们不会出现在建议列表中。这是为了避免建议列表中的干扰,因为每个词都是潜在的自定义标签。

添加以下设置以使用 tab 键启用 Emmet 缩写扩展,这将始终扩展自定义标签:

"emmet.triggerExpansionOnTab": true

我的以 + 结尾的 HTML 代码片段无效

Emmet 速查表 中以 + 结尾的 HTML 代码片段(如 select+ul+)不受支持。这是 Emmet 2.0 中的一个已知问题 Issue: emmetio/html-matcher#1。一种解决方法是为此类场景创建您自己的自定义 Emmet 代码片段

缩写无法展开

首先,检查您是否正在使用自定义代码片段(即是否有 snippets.json 文件正在被 emmet.extensionsPath 设置指定)。自定义代码片段的格式在 VS Code 1.53 版本中发生了变化。请使用 ${1}${2} 等标记来表示光标位置,而不是使用 |。来自 emmetio/emmet 仓库的默认 CSS 代码片段文件展示了新的光标位置格式示例。

如果缩写仍然无法展开:

  • 检查内置扩展以查看 Emmet 是否已被禁用。
  • 尝试通过在命令面板中运行 Developer: Restart Extension Host (workbench.action.restartExtensionHost) 命令来重启扩展主机。

我在哪里可以设置 Emmet preferences 中记录的所有首选项?

您可以使用设置 emmet.preferences 来设置首选项。Emmet preferences 中记录的首选项只有一部分可以自定义。请阅读Emmet 配置下的首选项部分。

有什么提示和技巧吗?

当然!

  • 在 CSS 缩写中,当您使用 : 时,左侧部分用于模糊匹配 CSS 属性名,右侧部分用于匹配 CSS 属性值。充分利用这一点,使用像 pos:ftrf:rxfw:b 等缩写。
  • 探索 Emmet Actions 中记录的所有其他 Emmet 功能。
  • 不要犹豫创建您自己的自定义 Emmet 代码片段