%YAML 1.2
---
# Vue single-file components. Template markup is highlighted here; the
# contents of <script> and <style> blocks are deliberately left unstyled
# raw regions scoped `meta.embedded.block.{script,style}.vue`, with the
# `lang` attribute value scoped `constant.other.language-name.vue` — the
# highlight engine's embedded-language-region mechanism (see
# docs/internal/embedded-language-highlighting.md) parses those regions
# with the named language's grammar (default: js / css).
name: Vue
file_extensions: [vue]
scope: text.html.vue
contexts:
  main:
    - include: comments
    - include: template_tag
    - include: script_tag
    - include: style_tag
    - include: html_tags
  comments:
    - match: '<!--'
      push: [{meta_scope: comment.block.html.vue}, {match: '-->', pop: true}]
  template_tag:
    - match: '(<)(template)\b'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
  script_tag:
    - match: '(<)(script)\b'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
      push: script_tag_attrs
  script_tag_attrs:
    - meta_scope: meta.embedded.block.script.vue
    - match: 'lang=(["''])([\w.+-]+)\1'
      captures:
        2: constant.other.language-name.vue
    - match: '/>'
      scope: punctuation.definition.tag.end.vue
      pop: true
    - match: '>'
      scope: punctuation.definition.tag.end.vue
      set: script_content
    - include: html_attributes
  script_content:
    - meta_scope: meta.embedded.block.script.vue
    - match: '(</)(script)\s*(>)'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
        3: punctuation.definition.tag.end.vue
      pop: true
  style_tag:
    - match: '(<)(style)\b'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
      push: style_tag_attrs
  style_tag_attrs:
    - meta_scope: meta.embedded.block.style.vue
    - match: 'lang=(["''])([\w.+-]+)\1'
      captures:
        2: constant.other.language-name.vue
    - match: '/>'
      scope: punctuation.definition.tag.end.vue
      pop: true
    - match: '>'
      scope: punctuation.definition.tag.end.vue
      set: style_content
    - include: html_attributes
  style_content:
    - meta_scope: meta.embedded.block.style.vue
    - match: '(</)(style)\s*(>)'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
        3: punctuation.definition.tag.end.vue
      pop: true
  html_tags:
    - match: '(</)(\w[\w-]*)(>)'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
        3: punctuation.definition.tag.end.vue
    - match: '(<)(\w[\w-]*)'
      captures:
        1: punctuation.definition.tag.begin.vue
        2: entity.name.tag.vue
      push:
        - match: '>'
          scope: punctuation.definition.tag.end.vue
          pop: true
        - include: html_attributes
    - match: '\{\{([^}]+)\}\}'
      scope: variable.interpolation.vue
  html_attributes:
    - match: '[@:v-][\w\-\.]+'
      scope: entity.other.attribute-name.vue
    - match: '\w[\w-]*'
      scope: entity.other.attribute-name.vue
    - match: '"[^"]*"'
      scope: string.quoted.double.vue
    - match: "'[^']*'"
      scope: string.quoted.single.vue
