mirror of
https://github.com/danbulant/mdsvexrs
synced 2026-05-19 04:08:47 +00:00
552 lines
No EOL
20 KiB
YAML
552 lines
No EOL
20 KiB
YAML
%YAML 1.2
|
|
#
|
|
# This syntax definition is based on the Terraform guide:
|
|
# https://www.terraform.io/docs/configuration/index.html
|
|
#
|
|
# As well as the HCL Native Syntax Spec:
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md
|
|
#
|
|
# For documentation on the .subline-syntax format:
|
|
# https://www.sublimetext.com/docs/3/syntax.html
|
|
#
|
|
# Regex's in this file support the Oniguruma regex engine:
|
|
# https://raw.githubusercontent.com/kkos/oniguruma/5.9.6/doc/RE
|
|
#
|
|
---
|
|
name: Terraform
|
|
|
|
# File Extensions:
|
|
#
|
|
# - ".tf": the standard file extension
|
|
# https://www.terraform.io/docs/configuration/index.html#code-organization
|
|
#
|
|
# - ".tfvars": variables definitions file
|
|
# https://www.terraform.io/docs/configuration/variables.html#variable-definitions-tfvars-files
|
|
#
|
|
# - ".hcl": non-terraform tools often use this HCL syntax, i.e. Vault
|
|
# https://www.vaultproject.io/docs/configuration/
|
|
file_extensions:
|
|
- tf
|
|
- tfvars
|
|
- hcl
|
|
scope: source.terraform
|
|
|
|
variables:
|
|
# Identifiers: (UTF-8) (ID_Continue | '-')*;
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#identifiers
|
|
identifer: \b(?!null|false|true)[[:alpha:]][[:alnum:]_-]*\b
|
|
|
|
# Exponent: "e" or "E" followed by an optional sign
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#numeric-literals
|
|
exponent: ([Ee][+-]?)
|
|
|
|
# Character Escapes:
|
|
#
|
|
# - \n: newline
|
|
# - \r: carriage return
|
|
# - \t: tab
|
|
# - \": quote
|
|
# - \\: backslash
|
|
# - \uNNNN: unicode char (NNNN is 4 hex digits)
|
|
# - \uNNNNNNNN: unicode char (NNNNNNNN us 8 digits)
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
|
|
char_escapes: \\[nrt"\\]|\\u(\h{8}|\h{4})
|
|
|
|
# Terraform Named Values
|
|
#
|
|
# https://www.terraform.io/docs/configuration/expressions.html#references-to-named-values
|
|
named_values: var|local|module|data|path|terraform
|
|
|
|
# Block types that are known to Terraform.
|
|
#
|
|
# resource: https://www.terraform.io/docs/configuration/resources.html
|
|
# provider: https://www.terraform.io/docs/configuration/providers.html
|
|
# variable: https://www.terraform.io/docs/configuration/variables.html
|
|
# output: https://www.terraform.io/docs/configuration/outputs.html
|
|
# locals: https://www.terraform.io/docs/configuration/locals.html
|
|
# module: https://www.terraform.io/docs/configuration/modules.html
|
|
# data: https://www.terraform.io/docs/configuration/data-sources.html
|
|
# terraform: https://www.terraform.io/docs/configuration/terraform.html#terraform-block-syntax
|
|
terraform_known_blocks: resource|provider|variable|output|locals|module|data|terraform
|
|
|
|
# Terraform built-in type keywords
|
|
#
|
|
# https://www.terraform.io/docs/configuration/types.html#primitive-types
|
|
# https://www.terraform.io/docs/configuration/types.html#dynamic-types-the-quot-any-quot-constraint
|
|
terraform_type_keywords: any|string|number|bool
|
|
|
|
# Built-In Functions
|
|
#
|
|
# https://www.terraform.io/docs/configuration/functions.html
|
|
predeclared_funcs: abs|ceil|floor|log|max|min|pow|signum|chomp|format|formatlist|indent|join|lower|regex|regexall|replace|split|strrev|substr|title|trimspace|upper|chunklist|coalesce|coalescelist|compact|concat|contains|distinct|element|flatten|index|keys|length|list|lookup|map|matchkeys|merge|range|reverse|setintersection|setproduct|setunion|slice|sort|transpose|values|zipmap|base64decode|base64encode|base64gzip|csvdecode|jsondecode|jsonencode|urlencode|yamldecode|yamlencode|abspath|dirname|pathexpand|basename|file|fileexists|fileset|filebase64|templatefile|formatdate|timeadd|timestamp|base64sha256|base64sha512|bcrypt|filebase64sha256|filebase64sha512|filemd5|filemd1|filesha256|filesha512|md5|rsadecrypt|sha1|sha256|sha512|uuid|uuidv5|cidrhost|cidrnetmask|cidrsubnet|tobool|tolist|tomap|tonumber|toset|tostring
|
|
|
|
contexts:
|
|
main:
|
|
- include: comments
|
|
- include: attribute_definition
|
|
- include: imports
|
|
- include: block
|
|
- include: expressions
|
|
|
|
comments:
|
|
- include: inline_comments
|
|
- include: block_comments
|
|
|
|
# Expressions:
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#expression-terms
|
|
expressions:
|
|
- include: literal_values
|
|
- include: operators
|
|
- include: brackets
|
|
- include: objects
|
|
- include: attribute_access
|
|
- include: functions
|
|
- include: parens
|
|
|
|
comma:
|
|
- match: \,
|
|
comment: Commas - used in certain expressions
|
|
scope: punctuation.separator.terraform
|
|
|
|
parens:
|
|
- match: \(
|
|
scope: punctuation.section.parens.begin.terraform
|
|
comment: Parens - matched *after* function syntax
|
|
push:
|
|
- match: \)
|
|
scope: punctuation.section.parens.end.terraform
|
|
pop: true
|
|
- include: expressions
|
|
- match: "{{identifer}}"
|
|
comment: Local Identifiers
|
|
scope: variable.other.readwrite.terraform
|
|
|
|
# Literal Values: Numbers, Language Constants, and Strings
|
|
#
|
|
# Strings are _technically_ part of the "expression sub-language",
|
|
# but make the most sense to be part of this stack.
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#literal-values
|
|
literal_values:
|
|
- include: numeric_literals
|
|
- include: language_constants
|
|
- include: string_literals
|
|
- include: heredoc
|
|
- include: type_keywords
|
|
- include: named_value_references
|
|
|
|
named_value_references:
|
|
- match: '\b({{named_values}})\b'
|
|
comment: Constant values available only to Terraform.
|
|
scope: support.constant.terraform
|
|
|
|
type_keywords:
|
|
- match: '\b({{terraform_type_keywords}})\b'
|
|
comment: Type keywords known to Terraform.
|
|
scope: storage.type.terraform
|
|
|
|
# Inline Comments: begin at the operator, end at the end of the line.
|
|
#
|
|
# https://www.terraform.io/docs/configuration/syntax.html#comments
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#comments-and-whitespace
|
|
inline_comments:
|
|
- match: '#|//'
|
|
comment: Inline Comments
|
|
scope: punctuation.definition.comment.terraform
|
|
push:
|
|
- meta_scope: comment.line.terraform
|
|
- match: $\n?
|
|
scope: punctuation.definition.comment.terraform
|
|
pop: true
|
|
|
|
# Block comments: start and end delimiters for multi-line comments.
|
|
#
|
|
# https://www.terraform.io/docs/configuration/syntax.html#comments
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#comments-and-whitespace
|
|
block_comments:
|
|
- match: /\*
|
|
comment: Block comments
|
|
scope: punctuation.definition.comment.terraform
|
|
push:
|
|
- meta_scope: comment.block.terraform
|
|
- match: \*/
|
|
scope: punctuation.definition.comment.terraform
|
|
pop: true
|
|
|
|
# Language Constants: booleans and `null`.
|
|
#
|
|
# https://www.terraform.io/docs/configuration/expressions.html#literal-expressions
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#literal-values
|
|
language_constants:
|
|
- match: \b(true|false|null)\b
|
|
comment: Language Constants
|
|
scope: constant.language.terraform
|
|
|
|
# Numbers: Integers, fractions and exponents
|
|
#
|
|
# https://www.terraform.io/docs/configuration/expressions.html#types-and-values
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#numeric-literals
|
|
numeric_literals:
|
|
- match: \b\d+({{exponent}})\d+\b
|
|
comment: Integer, no fraction, optional exponent
|
|
scope: constant.numeric.float.terraform
|
|
captures:
|
|
1: punctuation.separator.exponent.terraform
|
|
- match: \b\d+(\.)\d+(?:({{exponent}})\d+)?\b
|
|
comment: Integer, fraction, optional exponent
|
|
scope: constant.numeric.float.terraform
|
|
captures:
|
|
1: punctuation.separator.decimal.terraform
|
|
2: punctuation.separator.exponent.terraform
|
|
- match: \b\d+\b
|
|
comment: Integers
|
|
scope: constant.numeric.integer.terraform
|
|
|
|
# Strings:
|
|
#
|
|
# https://www.terraform.io/docs/configuration/expressions.html#types-and-values
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
|
|
string_literals:
|
|
- match: '"'
|
|
comment: Strings
|
|
scope: punctuation.definition.string.begin.terraform
|
|
push:
|
|
- meta_scope: string.quoted.double.terraform
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.terraform
|
|
pop: true
|
|
- include: string_interpolation
|
|
- match: '{{char_escapes}}'
|
|
comment: Character Escapes
|
|
scope: constant.character.escape.terraform
|
|
|
|
# String Interpolation: ("${" | "${~") Expression ("}" | "~}"
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#templates
|
|
string_interpolation:
|
|
- match: (\$|\%)\{
|
|
comment: String interpolation
|
|
scope: keyword.other.interpolation.begin.terraform
|
|
push:
|
|
- meta_scope: meta.interpolation.terraform
|
|
- clear_scopes: 1 # Clear the string.* scope.
|
|
- match: \}
|
|
scope: keyword.other.interpolation.end.terraform
|
|
pop: true
|
|
- match: \~\s
|
|
comment: Trim left whitespace
|
|
scope: keyword.operator.template.left.trim.terraform
|
|
- match: \s\~
|
|
comment: Trim right whitespace
|
|
scope: keyword.operator.template.right.trim.terraform
|
|
- match: \b(if|else|endif|for|in|endfor)\b
|
|
comment: if/else/endif and for/in/endfor directives
|
|
scope: keyword.control.terraform
|
|
- include: expressions
|
|
|
|
# String Heredocs
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
|
|
heredoc:
|
|
- match: (\<\<\-?)\s*({{identifer}})\s*$
|
|
comment: String Heredoc's
|
|
captures:
|
|
1: keyword.operator.heredoc.terraform
|
|
2: keyword.control.heredoc.terraform
|
|
push:
|
|
- meta_content_scope: string.unquoted.heredoc.terraform
|
|
- match: ^\s*\2\s*$
|
|
comment: The heredoc token identifier (second capture above).
|
|
scope: keyword.control.heredoc.terraform
|
|
pop: true
|
|
- include: string_interpolation
|
|
|
|
# Operators:
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#operators-and-delimiters
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#operations
|
|
operators:
|
|
- match: \>\= # >=
|
|
scope: keyword.operator.terraform
|
|
- match: \<\= # <=
|
|
scope: keyword.operator.terraform
|
|
- match: \=\= # ==
|
|
scope: keyword.operator.terraform
|
|
- match: \!\= # !=
|
|
scope: keyword.operator.terraform
|
|
- match: \+ # +
|
|
scope: keyword.operator.arithmetic.terraform
|
|
- match: \- # -
|
|
scope: keyword.operator.arithmetic.terraform
|
|
- match: \* # *
|
|
scope: keyword.operator.arithmetic.terraform
|
|
- match: \/ # /
|
|
scope: keyword.operator.arithmetic.terraform
|
|
- match: \% # %
|
|
scope: keyword.operator.arithmetic.terraform
|
|
- match: \&\& # &&
|
|
scope: keyword.operator.logical.terraform
|
|
- match: \|\| # ||
|
|
scope: keyword.operator.logical.terraform
|
|
- match: \! # !
|
|
scope: keyword.operator.logical.terraform
|
|
- match: \> # >
|
|
scope: keyword.operator.terraform
|
|
- match: \< # <
|
|
scope: keyword.operator.terraform
|
|
- match: \? # ?
|
|
scope: keyword.operator.terraform
|
|
- match: \.\.\. # ...
|
|
scope: keyword.operator.terraform
|
|
- match: "\\:" # :
|
|
scope: keyword.operator.terraform
|
|
|
|
# Terraform "import" statements
|
|
#
|
|
# https://www.terraform.io/docs/import/usage.html
|
|
imports:
|
|
- match: \s*(terraform)\s*(import)\s*
|
|
comment: Importing resources
|
|
captures:
|
|
1: support.constant.terraform
|
|
2: keyword.control.import.terraform
|
|
push:
|
|
- match: \"
|
|
comment: String literal label
|
|
scope: punctuation.definition.string.begin.terraform
|
|
push:
|
|
- meta_scope: string.quoted.double.terraform
|
|
- match: \"
|
|
scope: punctuation.definition.string.end.terraform
|
|
pop: true
|
|
- match: "{{identifer}}"
|
|
comment: Identifer label
|
|
scope: entity.name.label.terraform
|
|
- include: numeric_literals
|
|
- include: attribute_access
|
|
- match: $\n?
|
|
comment: Pop at newline
|
|
pop: true
|
|
|
|
# Brackets: matches tuples and subscript notation
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#index-operator
|
|
brackets:
|
|
- match: \[
|
|
scope: punctuation.section.brackets.begin.terraform
|
|
push:
|
|
- match: \]
|
|
scope: punctuation.section.brackets.end.terraform
|
|
pop: true
|
|
- match: (\*)\]
|
|
comment: Full-splat operator
|
|
scope: punctuation.section.brackets.end.terraform
|
|
captures:
|
|
1: keyword.operator.splat.terraform
|
|
pop: true
|
|
- include: comma
|
|
- include: comments
|
|
- include: expressions
|
|
- include: tuple_for_expression
|
|
|
|
# Objects: collection values
|
|
#
|
|
# Allows keys as identifiers, strings, and computed values wrapped in parens.
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#collection-values
|
|
objects:
|
|
- match: \{
|
|
scope: punctuation.section.braces.begin.terraform
|
|
push:
|
|
- meta_scope: meta.braces.terraform
|
|
- match: \}
|
|
scope: punctuation.section.braces.end.terraform
|
|
pop: true
|
|
- include: object_for_expression
|
|
- include: comments
|
|
- match: '\s*({{identifer}})\s*(\=)\s*'
|
|
comment: Literal, named object key
|
|
captures:
|
|
1: meta.mapping.key.terraform string.unquoted.terraform
|
|
2: keyword.operator.terraform
|
|
push: object_key_values
|
|
- match: '((\").*(\"))\s*(\=)\s*'
|
|
comment: String object key
|
|
captures:
|
|
1: meta.mapping.key.terraform string.quoted.double.terraform
|
|
2: punctuation.definition.string.begin.terraform
|
|
3: punctuation.definition.string.end.terraform
|
|
4: keyword.operator.terraform
|
|
push: object_key_values
|
|
- match: \(
|
|
comment: Computed object key (any expression between parens)
|
|
scope: punctuation.section.parens.begin.terraform
|
|
push:
|
|
- meta_scope: meta.mapping.key.terraform
|
|
- match: '(\))\s*(\=)\s*'
|
|
captures:
|
|
1: punctuation.section.parens.end.terraform
|
|
2: keyword.operator.terraform
|
|
set: object_key_values
|
|
- include: expressions
|
|
|
|
# Object key values: pop at comma, newline, and closing-bracket
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#collection-values
|
|
object_key_values:
|
|
- include: comments
|
|
- include: expressions
|
|
- match: \,
|
|
comment: Pop scope on comma.
|
|
scope: punctuation.separator.terraform
|
|
pop: true
|
|
- match: $\n?
|
|
comment: Pop scope on EOL.
|
|
pop: true
|
|
- match: (?=\})
|
|
comment: Lookahead (don't consume) and pop scope on a bracket.
|
|
scope: punctuation.section.braces.end.terraform
|
|
pop: true
|
|
|
|
# Attribute Access: "." Identifier
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#attribute-access-operator
|
|
attribute_access:
|
|
- match: \.
|
|
scope: keyword.operator.accessor.terraform
|
|
push:
|
|
- match: "{{identifer}}"
|
|
comment: Attribute access
|
|
scope: variable.other.member.terraform
|
|
pop: true
|
|
- match: \d+
|
|
comment: Subscript
|
|
scope: constant.numeric.integer.terraform
|
|
pop: true
|
|
- match: \*
|
|
comment: Attribute-only splat
|
|
scope: keyword.operator.splat.terraform
|
|
pop: true
|
|
|
|
# Attribute Definition: Identifier "=" Expression Newline
|
|
#
|
|
# The "=" operator cannot be immediately followed by "="
|
|
# ">", as those are other operators, not attr definitions.
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#attribute-definitions
|
|
attribute_definition:
|
|
- match: (\()?({{identifer}})(\))?\s*(\=[^\=|\>])\s*
|
|
comment: Identifier "=" with optional parens
|
|
scope: variable.declaration.terraform
|
|
captures:
|
|
1: punctuation.section.parens.begin.terraform
|
|
2: variable.other.readwrite.terraform
|
|
3: punctuation.section.parens.end.terraform
|
|
4: keyword.operator.assignment.terraform
|
|
|
|
# Functions: Terraform builtins and unknown
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#functions-and-function-calls
|
|
# https://www.terraform.io/docs/configuration/expressions.html#function-calls
|
|
functions:
|
|
- match: (({{predeclared_funcs}})|\b({{identifer}})\b)(\()
|
|
comment: Built-in function calls
|
|
captures:
|
|
2: support.function.builtin.terraform
|
|
3: variable.function.terraform
|
|
4: punctuation.section.parens.begin.terraform
|
|
push:
|
|
- meta_scope: meta.function-call.terraform
|
|
- match: \)
|
|
scope: punctuation.section.parens.end.terraform
|
|
pop: true
|
|
- include: comments
|
|
- include: expressions
|
|
- include: comma
|
|
|
|
# Tuple for-Expression:
|
|
#
|
|
# "[" "for" Identifier ("," Identifier)? "in" Expression ":" Expression ("if" Expression)? "]";
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#for-expressions
|
|
# https://www.terraform.io/docs/configuration/expressions.html#for-expressions
|
|
tuple_for_expression:
|
|
- match: \bfor\b
|
|
comment: for expression (arrays)
|
|
scope: keyword.control.terraform
|
|
set:
|
|
- include: for_expression_body
|
|
- match: \]
|
|
scope: punctuation.section.brackets.end.terraform
|
|
pop: true
|
|
|
|
# Object for-Expression:
|
|
#
|
|
# "{" "for" Identifier ("," Identifier)? "in" Expression ":" Expression "=>" Expression "..."? ("if" Expression)? "}";
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#for-expressions
|
|
# https://www.terraform.io/docs/configuration/expressions.html#for-expressions
|
|
object_for_expression:
|
|
- match: \bfor\b
|
|
comment: for expression (arrays)
|
|
scope: keyword.control.terraform
|
|
set:
|
|
- match: \=\>
|
|
scope: storage.type.function.terraform
|
|
- include: for_expression_body
|
|
- match: \}
|
|
scope: punctuation.section.braces.end.terraform
|
|
pop: true
|
|
|
|
# Shared body syntax for tuple and object for-expressions.
|
|
# They require different `set` blocks because they are
|
|
# pop'd with different characters and objects allow `=>`.
|
|
for_expression_body:
|
|
- match: \bin\b
|
|
comment: in keyword
|
|
scope: keyword.operator.word.terraform
|
|
- match: \bif\b
|
|
comment: if keyword
|
|
scope: keyword.control.conditional.terraform
|
|
- match: '\:'
|
|
scope: keyword.operator.terraform
|
|
- include: expressions
|
|
- include: comments
|
|
- include: comma
|
|
- match: "{{identifer}}"
|
|
comment: Local Identifiers
|
|
scope: variable.other.readwrite.terraform
|
|
|
|
# Blocks: Identifier (StringLit|Identifier)* "{" Newline Body "}" Newline;
|
|
#
|
|
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#structural-elements
|
|
block:
|
|
- match: '(\b({{terraform_known_blocks}})\b|({{identifer}}))(?=[\s\"\-[:word:]]*(\{))'
|
|
captures:
|
|
2: storage.type.terraform
|
|
3: entity.name.type.terraform
|
|
push:
|
|
- meta_scope: meta.type.terraform
|
|
- match: \"
|
|
comment: String literal label
|
|
scope: punctuation.definition.string.begin.terraform
|
|
push:
|
|
- meta_scope: string.quoted.double.terraform
|
|
- match: \"
|
|
scope: punctuation.definition.string.end.terraform
|
|
pop: true
|
|
- match: "{{identifer}}"
|
|
comment: Identifer label
|
|
scope: entity.name.label.terraform
|
|
- match: \{
|
|
scope: punctuation.section.block.begin.terraform
|
|
set:
|
|
- meta_scope: meta.block.terraform
|
|
- include: main
|
|
- match: \}
|
|
scope: punctuation.section.block.end.terraform
|
|
pop: true |