|
4 | 4 | # https://www.terraform.io/docs/language/index.html
|
5 | 5 | #
|
6 | 6 | # As well as the HCL Native Syntax Spec:
|
7 |
| -# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md |
| 7 | +# https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md |
| 8 | +# (previously https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md) |
8 | 9 | #
|
9 | 10 | # For documentation on the .subline-syntax format:
|
10 | 11 | # https://www.sublimetext.com/docs/syntax.html
|
@@ -56,29 +57,43 @@ variables:
|
56 | 57 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
|
57 | 58 | char_escapes: \\[nrt"\\]|\\u(\h{8}|\h{4})
|
58 | 59 |
|
| 60 | + # String literals (basically static and single-line strings) |
| 61 | + # for usage in look-aheads. |
| 62 | + # |
| 63 | + # https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#template-expressions |
| 64 | + string_literal: '"(?:[^"]|{{char_escapes}})*"' |
| 65 | + |
| 66 | + # A block label |
| 67 | + # |
| 68 | + # https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#structural-elements |
| 69 | + label: (?:{{identifier}}|{{string_literal}}) |
| 70 | + |
59 | 71 | # Terraform Named Values
|
60 | 72 | #
|
61 | 73 | # https://www.terraform.io/docs/language/expressions/references.html
|
62 |
| - named_values: var|local|module|data|path|terraform|each|count|self |
| 74 | + named_values: (?:var|local|module|data|path|terraform|each|count|self) |
63 | 75 |
|
64 | 76 | # Block types that are known to Terraform.
|
65 | 77 | #
|
66 | 78 | # data: https://developer.hashicorp.com/terraform/language/data-sources
|
67 | 79 | # ephemeral: https://developer.hashicorp.com/terraform/language/resources/ephemeral
|
68 |
| - # locals: https://developer.hashicorp.com/terraform/language/values/locals |
| 80 | + # resource: https://developer.hashicorp.com/terraform/language/resources/syntax |
| 81 | + terraform_typed_and_named_blocks: (?:data|ephemeral|resource) |
69 | 82 | # module: https://developer.hashicorp.com/terraform/language/modules/syntax
|
70 | 83 | # output: https://developer.hashicorp.com/terraform/language/values/outputs
|
71 | 84 | # provider: https://developer.hashicorp.com/terraform/language/providers/configuration
|
72 |
| - # resource: https://developer.hashicorp.com/terraform/language/resources/syntax |
73 |
| - # terraform: https://developer.hashicorp.com/terraform/language/terraform#terraform-block-syntax |
74 | 85 | # variable: https://developer.hashicorp.com/terraform/language/values/variables
|
75 |
| - terraform_known_blocks: data|ephemeral|locals|module|output|provider|resource|terraform|variable |
| 86 | + terraform_named_blocks: (?:module|output|provider|variable) |
| 87 | + # locals: https://developer.hashicorp.com/terraform/language/values/locals |
| 88 | + # terraform: https://developer.hashicorp.com/terraform/language/terraform#terraform-block-syntax |
| 89 | + # (Currently unused because they do not have special behavior implemented.) |
| 90 | + terraform_other_blocks: (?:locals|terraform) |
76 | 91 |
|
77 | 92 | # Terraform built-in type keywords
|
78 | 93 | #
|
79 | 94 | # https://www.terraform.io/docs/language/expressions/type-constraints.html#primitive-types
|
80 | 95 | # https://www.terraform.io/docs/language/expressions/type-constraints.html#dynamic-types-the-quot-any-quot-constraint
|
81 |
| - terraform_type_keywords: any|string|number|bool |
| 96 | + terraform_type_keywords: (?:any|string|number|bool) |
82 | 97 |
|
83 | 98 | # Built-In Functions
|
84 | 99 | #
|
@@ -126,7 +141,7 @@ contexts:
|
126 | 141 | - include: comments
|
127 | 142 | - include: attribute-definition
|
128 | 143 | - include: imports
|
129 |
| - - include: block |
| 144 | + - include: blocks |
130 | 145 | - include: expressions
|
131 | 146 |
|
132 | 147 | comments:
|
@@ -179,12 +194,12 @@ contexts:
|
179 | 194 | - include: named-value-references
|
180 | 195 |
|
181 | 196 | named-value-references:
|
182 |
| - - match: \b(?:{{named_values}})\b |
| 197 | + - match: \b{{named_values}}\b |
183 | 198 | comment: Special variables available only to Terraform.
|
184 | 199 | scope: variable.language.terraform
|
185 | 200 |
|
186 | 201 | type-keywords:
|
187 |
| - - match: \b(?:{{terraform_type_keywords}})\b |
| 202 | + - match: \b{{terraform_type_keywords}}\b |
188 | 203 | comment: Type keywords known to Terraform.
|
189 | 204 | scope: storage.type.terraform
|
190 | 205 |
|
@@ -264,11 +279,14 @@ contexts:
|
264 | 279 | - match: \"
|
265 | 280 | scope: punctuation.definition.string.end.terraform
|
266 | 281 | pop: 1
|
| 282 | + - include: character-escapes |
| 283 | + - include: string-interpolation |
| 284 | + - include: aws-acl |
| 285 | + |
| 286 | + character-escapes: |
267 | 287 | - match: '{{char_escapes}}'
|
268 | 288 | comment: Character Escapes
|
269 | 289 | scope: constant.character.escape.terraform
|
270 |
| - - include: string-interpolation |
271 |
| - - include: aws-acl |
272 | 290 |
|
273 | 291 | aws-acl:
|
274 | 292 | - match: (?=\barn:aws:)
|
@@ -674,50 +692,105 @@ contexts:
|
674 | 692 | # Blocks: Identifier (StringLit|Identifier)* "{" Newline Body "}" Newline;
|
675 | 693 | #
|
676 | 694 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#structural-elements
|
677 |
| - block: |
678 |
| - # Special case heuristic for the AWS and friends two-term resources |
679 |
| - - match: (\b(resource)\s+(")({{identifier}})(")\s+(")({{identifier}})("))\s*(\{) |
680 |
| - captures: |
681 |
| - 1: meta.type.terraform |
682 |
| - 2: keyword.declaration.terraform |
683 |
| - 3: punctuation.definition.begin.terraform |
684 |
| - 4: support.type.terraform |
685 |
| - 5: punctuation.definition.end.terraform |
686 |
| - 6: punctuation.definition.begin.terraform |
687 |
| - 7: entity.name.type.terraform |
688 |
| - 8: punctuation.definition.end.terraform |
689 |
| - 9: meta.block.terraform punctuation.section.block.begin.terraform |
690 |
| - push: block-body |
691 |
| - # Generic |
692 |
| - - match: (?:\b({{terraform_known_blocks}})\b|({{identifier}}))(?=[-\s\w"]*\{) |
693 |
| - scope: meta.type.terraform |
694 |
| - captures: |
695 |
| - 1: keyword.declaration.terraform |
696 |
| - 2: entity.name.type.terraform |
697 |
| - push: block-name |
| 695 | + blocks: |
| 696 | + - include: typed-and-named-blocks |
| 697 | + - include: named-blocks |
| 698 | + - include: generic-blocks |
| 699 | + |
| 700 | + typed-and-named-blocks: |
| 701 | + # Special case for two-label resources, |
| 702 | + # where the first denotes the type and the second the name. |
| 703 | + - match: (?=\b{{terraform_typed_and_named_blocks}}(\s+{{label}}){2}\s*\{) |
| 704 | + push: |
| 705 | + - body |
| 706 | + - block-name-label |
| 707 | + - block-type-label |
| 708 | + - block-declaration |
| 709 | + |
| 710 | + named-blocks: |
| 711 | + # Special case for two-label resources, |
| 712 | + # where the first denotes the type and the second the name. |
| 713 | + - match: (?=\b{{terraform_named_blocks}}\s+{{label}}\s*\{) |
| 714 | + push: |
| 715 | + - body |
| 716 | + - block-name-label |
| 717 | + - block-declaration |
| 718 | + |
| 719 | + generic-blocks: |
| 720 | + - match: (?=\b({{identifier}})(\s+{{label}})*\s*\{) |
| 721 | + push: |
| 722 | + - body |
| 723 | + - generic-block-labels |
| 724 | + - block-declaration |
| 725 | + |
| 726 | + block-declaration: |
| 727 | + - match: '{{identifier}}' |
| 728 | + scope: keyword.declaration.terraform |
| 729 | + pop: 1 |
| 730 | + - include: else-pop |
698 | 731 |
|
699 |
| - block-name: |
700 |
| - - meta_content_scope: meta.type.terraform |
| 732 | + block-type-label: |
701 | 733 | - match: \"
|
702 | 734 | scope: punctuation.definition.string.begin.terraform
|
703 |
| - push: block-name-body |
| 735 | + set: block-type-label-body |
| 736 | + - match: '{{identifier}}' |
| 737 | + scope: support.type.terraform |
| 738 | + pop: 1 |
| 739 | + - include: else-pop |
| 740 | + |
| 741 | + block-type-label-body: |
| 742 | + - meta_scope: meta.string.terraform |
| 743 | + - meta_content_scope: support.type.terraform |
| 744 | + - match: \" |
| 745 | + scope: punctuation.definition.string.end.terraform |
| 746 | + pop: 1 |
| 747 | + - include: character-escapes |
| 748 | + |
| 749 | + block-name-label: |
| 750 | + - match: \" |
| 751 | + scope: punctuation.definition.string.begin.terraform |
| 752 | + set: block-name-label-body |
704 | 753 | - match: '{{identifier}}'
|
705 | 754 | scope: entity.name.label.terraform
|
706 |
| - - match: \s*(\{) |
707 |
| - captures: |
708 |
| - 1: meta.block.terraform punctuation.section.block.begin.terraform |
709 |
| - set: block-body |
| 755 | + pop: 1 |
| 756 | + - include: else-pop |
710 | 757 |
|
711 |
| - block-name-body: |
| 758 | + block-name-label-body: |
| 759 | + - meta_scope: meta.string.terraform |
| 760 | + - meta_content_scope: entity.name.label.terraform |
| 761 | + - match: \" |
| 762 | + scope: punctuation.definition.string.end.terraform |
| 763 | + pop: 1 |
| 764 | + - include: character-escapes |
| 765 | + |
| 766 | + generic-block-labels: |
| 767 | + # Labels probably have a meaning, but we don't know which, |
| 768 | + # so we just scope them as (un-)quoted strings. |
| 769 | + - match: \" |
| 770 | + scope: punctuation.definition.string.begin.terraform |
| 771 | + push: generic-block-label-body |
| 772 | + - match: '{{identifier}}' |
| 773 | + scope: string.unquoted.double.terraform |
| 774 | + - include: else-pop |
| 775 | + |
| 776 | + generic-block-label-body: |
712 | 777 | - meta_scope: meta.string.terraform string.quoted.double.terraform
|
713 | 778 | - match: \"
|
714 | 779 | scope: punctuation.definition.string.end.terraform
|
715 | 780 | pop: 1
|
| 781 | + - include: character-escapes |
| 782 | + |
| 783 | + body: |
| 784 | + - meta_content_scope: meta.block.head.terraform |
| 785 | + - match: \{ |
| 786 | + scope: punctuation.section.block.begin.terraform |
| 787 | + set: body-body |
| 788 | + - include: else-pop |
716 | 789 |
|
717 |
| - block-body: |
718 |
| - - meta_content_scope: meta.block.terraform |
| 790 | + body-body: |
| 791 | + - meta_scope: meta.block.body.terraform |
719 | 792 | - match: \}
|
720 |
| - scope: meta.block.terraform punctuation.section.block.end.terraform |
| 793 | + scope: punctuation.section.block.end.terraform |
721 | 794 | pop: 1
|
722 | 795 | - include: main
|
723 | 796 |
|
|
0 commit comments