├── messages.json
├── HCL.sublime-settings
├── Terraform.sublime-settings
├── Terraform-vars.sublime-settings
├── snippets
├── data.sublime-snippet
├── provider.sublime-snippet
├── output.sublime-snippet
├── resource.sublime-snippet
├── module.sublime-snippet
├── provisioner.sublime-snippet
├── module_path.sublime-snippet
├── module_github.sublime-snippet
├── variable_empty.sublime-snippet
├── module_github_private.sublime-snippet
├── variable_string.sublime-snippet
└── variable_map.sublime-snippet
├── Symbols - Indexed.tmPreferences
├── JSON (Terraform).sublime-syntax
├── Symbols - Local.tmPreferences
├── HCL.sublime-syntax
├── Terraform-vars.sublime-syntax
├── messages
└── 2.0.0.md
├── Indentation Rules.tmPreferences
├── README.md
├── Comments.tmPreferences
├── LICENSE
├── Fold.tmPreferences
├── Terraform Plan.sublime-syntax
├── CHANGELOG.md
└── Terraform.sublime-syntax
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "2.0.0": "messages/2.0.0.md"
3 | }
4 |
--------------------------------------------------------------------------------
/HCL.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | "tab_size": 2,
3 | "translate_tabs_to_spaces": true,
4 | // Move '-' to sub-word separators
5 | "word_separators": "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?",
6 | "sub_word_separators": "_-",
7 | }
8 |
--------------------------------------------------------------------------------
/Terraform.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | "tab_size": 2,
3 | "translate_tabs_to_spaces": true,
4 | // Move '-' to sub-word separators
5 | "word_separators": "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?",
6 | "sub_word_separators": "_-",
7 | }
8 |
--------------------------------------------------------------------------------
/Terraform-vars.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | "tab_size": 2,
3 | "translate_tabs_to_spaces": true,
4 | // Move '-' to sub-word separators
5 | "word_separators": "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?",
6 | "sub_word_separators": "_-",
7 | }
8 |
--------------------------------------------------------------------------------
/snippets/data.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | data
8 | source.terraform
9 | data block
10 |
11 |
--------------------------------------------------------------------------------
/snippets/provider.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | provider
8 | source.terraform
9 | provider block
10 |
11 |
--------------------------------------------------------------------------------
/snippets/output.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | output
8 | source.terraform
9 | output block
10 |
11 |
--------------------------------------------------------------------------------
/snippets/resource.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | resource
8 | source.terraform
9 | resource block
10 |
11 |
--------------------------------------------------------------------------------
/snippets/module.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
8 | module
9 | source.terraform
10 | module block
11 |
12 |
--------------------------------------------------------------------------------
/snippets/provisioner.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
7 | provisioner
8 | source.terraform
9 | provisioner block
10 |
11 |
--------------------------------------------------------------------------------
/snippets/module_path.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
8 | moduleP
9 | source.terraform
10 | module (path)
11 |
12 |
--------------------------------------------------------------------------------
/snippets/module_github.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
8 | moduleG
9 | source.terraform
10 | module (github public)
11 |
12 |
--------------------------------------------------------------------------------
/snippets/variable_empty.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
8 | variableE
9 | source.terraform
10 | variable (empty)
11 |
12 |
--------------------------------------------------------------------------------
/snippets/module_github_private.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
8 | moduleGS
9 | source.terraform
10 | module (github ssh)
11 |
12 |
--------------------------------------------------------------------------------
/snippets/variable_string.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
9 | variableS
10 | source.terraform
11 | variable (string)
12 |
13 |
--------------------------------------------------------------------------------
/snippets/variable_map.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
12 | variableM
13 | source.terraform
14 | variable (map)
15 |
16 |
--------------------------------------------------------------------------------
/Symbols - Indexed.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Local Symbol List
7 | scope
8 |
9 | entity.name.label.terraform
10 |
11 | settings
12 |
13 | showInIndexedSymbolList
14 | 1
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/JSON (Terraform).sublime-syntax:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | ---
3 | # http://www.sublimetext.com/docs/syntax.html
4 | name: JSON (Terraform)
5 | scope: source.json.terraform
6 | version: 2
7 |
8 | extends: Packages/JSON/JSON.sublime-syntax
9 |
10 | file_extensions:
11 | - tfstate
12 |
13 | contexts:
14 | double-quoted-string-body:
15 | - meta_prepend: true
16 | - include: Packages/Terraform/Terraform.sublime-syntax#string-interpolation
17 | - include: Packages/Terraform/Terraform.sublime-syntax#aws-acl
18 |
19 | line-comments:
20 | - meta_append: true
21 | - include: Packages/Terraform/Terraform.sublime-syntax#inline-comments
22 |
--------------------------------------------------------------------------------
/Symbols - Local.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Local Symbol List
7 | scope
8 |
9 | meta.block.head.terraform
10 |
11 | settings
12 |
13 | showInSymbolList
14 | 1
15 | symbolTransformation
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/HCL.sublime-syntax:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | #
3 | # This syntax definition is based on the Terraform guide:
4 | # https://www.terraform.io/docs/configuration/index.html
5 | #
6 | # As well as the HCL Native Syntax Spec:
7 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md
8 | #
9 | # For documentation on the .subline-syntax format:
10 | # https://www.sublimetext.com/docs/syntax.html
11 | #
12 | # Regex's in this file support the Oniguruma regex engine:
13 | # https://raw.githubusercontent.com/kkos/oniguruma/5.9.6/doc/RE
14 | #
15 | ---
16 | name: HCL
17 | scope: source.hcl
18 | version: 2
19 |
20 | extends: Terraform.sublime-syntax
21 |
22 | # File Extensions:
23 | #
24 | # - ".hcl": non-terraform tools often use this HCL syntax, i.e. Vault
25 | # https://www.vaultproject.io/docs/configuration/
26 | file_extensions:
27 | - hcl
28 |
--------------------------------------------------------------------------------
/Terraform-vars.sublime-syntax:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | #
3 | # This syntax definition is based on the Terraform guide:
4 | # https://www.terraform.io/docs/configuration/index.html
5 | #
6 | # As well as the HCL Native Syntax Spec:
7 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md
8 | #
9 | # For documentation on the .subline-syntax format:
10 | # https://www.sublimetext.com/docs/syntax.html
11 | #
12 | # Regex's in this file support the Oniguruma regex engine:
13 | # https://raw.githubusercontent.com/kkos/oniguruma/5.9.6/doc/RE
14 | #
15 | ---
16 | name: Terraform (variables)
17 | scope: source.terraform-vars
18 | version: 2
19 |
20 | extends: Terraform.sublime-syntax
21 |
22 | # File Extensions:
23 | #
24 | # - ".tfvars": variables definitions file
25 | # https://www.terraform.io/docs/configuration/variables.html#variable-definitions-tfvars-files
26 | file_extensions:
27 | - tfvars
28 |
--------------------------------------------------------------------------------
/messages/2.0.0.md:
--------------------------------------------------------------------------------
1 | v2.0.0 - 2025-05-11
2 | -------------------
3 |
4 | The package has been adopted by the SublimeText GitHub org and now lives at
5 | for the community to maintain.
6 | This is accompanied by many changes
7 | to bring the syntax definition up to current standards,
8 | courtesy of @deathaxe, @FichteFoll, and @michaelblyons.
9 |
10 | In summary, the syntax has been aligned with current standards
11 | as they have developed over time for the default syntaxes
12 | and various other third-party syntaxes.
13 | For a detailed list of changes,
14 | please refer to the full changelog at
15 | .
16 |
17 | Note that this release is only compatible with ST builds 4180 and higher.
18 | The old version is still available for installation on older builds
19 | but is not maintained anymore.
20 |
--------------------------------------------------------------------------------
/Indentation Rules.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | scope
5 | source.hcl, source.terraform, source.terraform-vars
6 | settings
7 |
8 | decreaseIndentPattern
9 | ^\s*[])}]
10 | increaseIndentPattern
11 |
19 | indentParens
20 |
21 | indentSquareBrackets
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Terraform
2 |
3 | [Terraform][.tf] configuration file syntax definitions and snippets for [Sublime Text][].
4 |
5 | 
6 |
7 |
8 | ## Installation
9 |
10 | ### Using Package Control
11 |
12 | 1. Install [Package Control][], if needed.
13 | 2. Open the palette by pressing:
14 | - Windows, Linux: Ctrl+Shift+P
15 | - MacOS: Cmd+Shift+P
16 | 3. Select _Package Control: Install Package_.
17 | 4. Select _Terraform_.
18 |
19 | ### Manually
20 |
21 | 1. Open the Sublime Text Packages folder:
22 | - MacOS: `~/Library/Application Support/Sublime Text/Packages/`
23 | - Windows: `%APPDATA%/Sublime Text/Packages/`
24 | - Linux (Ubuntu/Debian): `~/.config/sublime-text/Packages/`
25 | 2. Clone this repo.
26 |
27 | [sublime text]: https://sublimetext.com/
28 | [.tf]: https://developer.hashicorp.com/terraform/language/syntax/configuration
29 | [package control]: https://packagecontrol.io/installation
30 |
--------------------------------------------------------------------------------
/Comments.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Comments
7 | scope
8 | source.terraform, source.terraform-vars, source.hcl
9 | settings
10 |
11 | shellVariables
12 |
13 |
14 | name
15 | TM_COMMENT_START
16 | value
17 | #
18 |
19 |
20 | name
21 | TM_COMMENT_START_2
22 | value
23 | /*
24 |
25 |
26 | name
27 | TM_COMMENT_END_2
28 | value
29 | */
30 |
31 |
32 | name
33 | TM_COMMENT_START_3
34 | value
35 | //
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Alex Louden
4 | Copyright (c) 2024 FichteFoll
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/Fold.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | scope
5 | source.hcl, source.terraform, source.terraform-vars
6 | settings
7 |
8 | indentationFoldingEnabled
9 |
10 | foldScopes
11 |
12 |
13 |
14 | begin
15 | punctuation.section.baces.begin
16 | end
17 | punctuation.section.baces.end
18 | excludeTrailingNewlines
19 |
20 |
21 |
22 | begin
23 | punctuation.section.brackets.begin
24 | end
25 | punctuation.section.brackets.end
26 | excludeTrailingNewlines
27 |
28 |
29 |
30 | begin
31 | punctuation.section.parens.begin
32 | end
33 | punctuation.section.parens.end
34 | excludeTrailingNewlines
35 |
36 |
37 |
38 |
39 |
40 | begin
41 | punctuation.section.block.begin
42 | end
43 | punctuation.section.block.end
44 | excludeTrailingNewlines
45 |
46 |
47 |
48 |
49 |
50 | begin
51 | punctuation.section.mapping.begin
52 | end
53 | punctuation.section.mapping.end
54 | excludeTrailingNewlines
55 |
56 |
57 |
58 | begin
59 | punctuation.section.sequence.begin
60 | end
61 | punctuation.section.sequence.end
62 | excludeTrailingNewlines
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/Terraform Plan.sublime-syntax:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | ---
3 | # http://www.sublimetext.com/docs/syntax.html
4 | # https://github.com/hashicorp/terraform/blob/337bf8e11b75dff87509455cabee60b023dd586e/internal/command/jsonformat/plan.go#L201
5 | name: Terraform Plan
6 | scope: source.diff.terraform
7 | version: 2
8 |
9 | file_extensions:
10 | - tfplan
11 | - tf.plan
12 |
13 | contexts:
14 |
15 | main:
16 | - include: comments
17 | - include: diffs
18 | - include: summary
19 |
20 | comments:
21 | - match: '#'
22 | scope: punctuation.definition.comment.terraform
23 | push:
24 | - meta_scope: comment.line.number-sign.terraform
25 | - include: pop-eol
26 |
27 | diffs:
28 | - match: ^\+/-
29 | scope: punctuation.definition.changed.diff
30 | push: line-created-then-destroyed
31 | - match: ^-/\+
32 | scope: punctuation.definition.changed.diff
33 | push: line-destroyed-then-created
34 | - match: ^!
35 | scope: punctuation.definition.changed.diff
36 | push: line-changed
37 | - match: ^\+
38 | scope: punctuation.definition.inserted.diff
39 | push: line-inserted
40 | - match: ^-
41 | scope: punctuation.definition.deleted.diff
42 | push: line-deleted
43 |
44 | annotations:
45 | - match: ->
46 | scope: keyword.operator.assignment.terraform
47 | - match: \(known after apply\)$
48 | scope: comment.block.terraform
49 | - match: \bnull$
50 | scope: constant.language.null.terraform
51 |
52 | line-deleted:
53 | - meta_scope: markup.deleted.diff
54 | - include: pop-eol
55 | - include: annotations
56 |
57 | line-inserted:
58 | - meta_scope: markup.inserted.diff
59 | - include: pop-eol
60 | - include: annotations
61 |
62 | line-changed:
63 | - meta_scope: markup.changed.updated-in-place.diff
64 | - include: pop-eol
65 | - include: annotations
66 |
67 | line-created-then-destroyed:
68 | - meta_scope: markup.changed.created-then-destroyed.diff
69 | - include: pop-eol
70 | - include: annotations
71 |
72 | line-destroyed-then-created:
73 | - meta_scope: markup.changed.destroyed-then-created.diff
74 | - include: pop-eol
75 | - include: annotations
76 |
77 | line-ignored:
78 | - meta_scope: comment.line.diff
79 | - include: pop-eol
80 | - include: annotations
81 |
82 | summary:
83 | - match: ^(?=Plan:[ ]\d)
84 | push:
85 | - meta_scope: meta.block.summary.terraform
86 | - include: pop-eol
87 | - match: ','
88 | scope: punctuation.separator.sequence.terraform
89 | - match: \.
90 | scope: punctuation.terminator.terraform
91 | - match: (\d+) to add
92 | scope: markup.inserted.terraform
93 | captures:
94 | 1: meta.number.integer.decimal.terraform constant.numeric.value.terraform
95 | - match: (\d+) to change
96 | scope: markup.changed.terraform
97 | captures:
98 | 1: meta.number.integer.decimal.terraform constant.numeric.value.terraform
99 | - match: (\d+) to destroy
100 | scope: markup.deleted.terraform
101 | captures:
102 | 1: meta.number.integer.decimal.terraform constant.numeric.value.terraform
103 |
104 | pop-eol:
105 | - match: \n|$
106 | pop: 1
107 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6 |
7 | ## v2.0.1 - 2025-12-07
8 |
9 | - Fix indexed symbol scope selector leaking into other languages. (@FichteFoll, #99)
10 | - Add support for template literal escape sequence. (@yagizmunger, #97, #98)
11 |
12 | ---
13 |
14 | ## v2.0.0 - 2025-05-11
15 |
16 | The package has been adopted by the SublimeText GitHub org and now lives at
17 | for the community to maintain.
18 | This is accompanied by many changes
19 | to bring the syntax definition up to current standards.
20 |
21 | ### Added
22 |
23 | - Declare hyphens as sub-word separators. (@FichteFoll, #60)
24 | - Special highlighting for `for_each` and `count` meta arguments (`keyword.control`). (@FichteFoll, #59)
25 | - Highlighting of more special language variables: `each`, `count` and `self`. (@FichteFoll, #58)
26 | - Highlighting for `ephemeral` blocks. (@TerminalFi, #70)
27 | - A separate syntax definition for `terraform plan` output (@michaelblyons, #51, #68)
28 | - Special highlighting for AWS ACL resource references in strings. (@michaelblyons, @deathaxe, #69, #76)
29 | - Support JSON-style objects (requires ST 4180). (@michaelblyons, #54, #71)
30 | - Scope-based folding rules. (@deathaxe, #81)
31 | - Consistent indentation rules. (@deathaxe, #82)
32 | - Highlight unclosed strings and stray closing brackets as illegal. (@FichteFoll, #91)
33 |
34 | ### Changed
35 |
36 | - Switched to syntax version 2.
37 | This breaks compatibility with ST builds before 4000,
38 | but the previous version can still be installed on older builds.
39 | (@FichteFoll, #62)
40 | - Adapted and improved many scope names to standards that have been established
41 | over the past years for the default packages:
42 | * String interpolation meta scopes and punctuation (@FichteFoll, #58)
43 | * Keywords (@FichteFoll, @deathaxe, #58, #78, #86)
44 | * Attribute access punctuation (@FichteFoll, #58)
45 | * Punctuation scopes in `for` expressions (@FichteFoll, #58)
46 | * Blocks, including indexing for "name" labels
47 | (@michaelblyons, @FichteFoll, #69, #87)
48 | * Operators (@michaelblyons, #66)
49 | * Numbers (@deathaxe, #77)
50 | * Brackets (@deathaxe, #80)
51 | * Function calls (@deathaxe, #83)
52 | - Updated the built-in function list for highlighting. (@FichteFoll, #59)
53 | - Renamed many contexts and resolved various anonymous contexts
54 | for better extensibility. (@deathaxe, #75, #79)
55 |
56 | ### Removed
57 |
58 | - Removed various files targeting older ST versions,
59 | notably the old `.tmLanguage` syntax definition.
60 | This breaks compatibility with ST 2,
61 | but the previous version can still be installed on older builds.
62 | (@FichteFoll, #63)
63 |
64 | ### Fixed
65 |
66 | - Improved matching of identifiers by adding a scope and properly recognizing hyphens. (@FichteFoll, #60)
67 | - Support identifiers starting with an underscore character (@FichteFoll, #43, #64).
68 |
69 | ---
70 |
71 | ## v1.3.1 - 2024-02-03
72 |
73 | ### Added
74 |
75 | - `.nomad` files are also recognized by the Terraform syntax. (@Quenty, #55)
76 |
77 | ## v1.3.0 - 2024-01-18
78 |
79 | ### Changed
80 |
81 | - Separate HCL syntax into its own file and report it as `source.hcl` (rather than `source.terraform`). (@rchl, #56)
82 | - Update links to official docs on terraform.io. (@totoroot, #53)
83 |
84 | ## v1.2.0 - 2021-06-21
85 |
86 | ### Changed
87 |
88 | - Split the tfvars handling into a separate syntax file. (@rchl, #49)
89 | This improves interoperability with terraform-ls, e.g. via LSP.
90 |
91 | ## v1.1.0 - 2021-05-17
92 |
93 | ### Fixed
94 |
95 | - Removed quotes around variable types in snippets. (@notnmeyer, #42)
96 |
97 | ## v1.0.0 - 2020-01-20
98 |
99 | A huge thanks to @patrickrgaffney for this amazing contribution. (#39)
100 |
101 | ### Added
102 |
103 | - [Syntax tests][tests] have been added.
104 | - `null` constant.
105 | - [Exponents][exponents] in numeric literals.
106 | - [Character escapes][strings] for newline, carriage return, backslash, quote, and unicode points inside string literals.
107 | - [Trim-left and trim-right operators][string-templates] inside string templates.
108 | - [Directives][string-templates] inside string templates.
109 | - Match all valid expressions inside string templates.
110 | - Comparison operators `==`, `!=`, `<`, `>`, `<=`, `>=`.
111 | - Arithmetic operators `+`, `-`, `*`, `/`, `%`.
112 | - Logic operators `&&`, `||`, `!`.
113 | - Conditional operator `p ? e1 : e2`
114 | - Parenthesis matching.
115 | - Tuple list syntax.
116 | - Square-bracket [index notation][indices].
117 | - [Full-splat][splat] operator.
118 | - Comma matching inside function calls, tuples, maps, and for-expressions.
119 | - Attribute-access is matched on named members and the `.` dot operator.
120 | - [Attribute-only splat][splat] operator.
121 | - Allow `-` after first alpha character in identifiers.
122 | - Computed attribute named using parenthesis.
123 | - Allow function-calls outside of string interpolation.
124 | - Match all valid expressions inside function-call parameter lists.
125 | - Match functions unknown to Terraform (for other HCL uses).
126 | - Match [for-expressions][for-exp] inside tuples and maps.
127 | - Map collection syntax.
128 | - Match unknown block names.
129 | - Support for variable number of block labels.
130 | - Nested blocks.
131 | - Inline blocks.
132 | - Terraform [named values][named-values].
133 | - Update list of built-in Terraform functions.
134 | - Built-in block types `locals` and `terraform`.
135 | - Meta-scope `meta.block.terraform` added to all block bodies.
136 | - [Primitive type constants][types].
137 | - Heredocs with the leading-spaces operator `<<-`.
138 | - String interpolation inside heredocs.
139 | - [Import][import] statements.
140 | - JSON highlighting for `*.tfstate` files.
141 |
142 | ### Changed
143 |
144 | - Rename scope `comment.line.number-sign.terraform` to `comment.line.terraform` to better reflect [scope naming standards][scopes].
145 | - Rename scope `constant.numeric.terraform` to `constant.numeric.[integer|float].terraform` to better reflect [scope naming standards][scopes].
146 | - Rename scope `entity.tag.embedded.[begin|end]` to `punctuation.section.interpolation.[begin|end]` to better reflect [scope naming standards][scopes].
147 | - Rename scope `variable.other.assignment.terraform` to `variable.other.readwrite.terraform` to better reflect [scope naming standards][scopes].
148 | - A `meta_scope` of `variable.declaration.terraform` covers the entire attribute definition now.
149 | - Rename scope for `=` in assignments from `keyword.operator` to `keyword.operator.assignment` to better reflect [scope naming standards][scopes].
150 | - Rename scope `keyword.other.function.inline` to `support.function.builtin` to better reflect [scope naming standards][scopes].
151 | - Rename scope for known block types from `storage.type.function.terraform` to `storage.type.terraform` to better reflect [scope naming standards][scopes].
152 | - Rename scope for block labels from `string.value.terraform` to `string.quoted.double.terraform` to better reflect [scope naming standards][scopes].
153 | - Rename meta-scope for block definitions from `meta.block.terraform` to `meta.type.terraform` to better reflect [scope naming standards][scopes].
154 |
155 | ### Removed
156 |
157 | - Invalid constants `yes`, `no`, `on`, and `off`.
158 | - [Unit of measurement suffixes][uom-suffixes].
159 | - [Hexadecimal literals][hex-literals].
160 | - An extra `string.terraform` scope was previously added to all string literals.
161 | - [`atlas` blocks][atlas].
162 |
163 | ### Fixed
164 |
165 | - Remove the `string.*` scope inside string templates.
166 |
167 | ## v0.19.0 - 2019-08-20
168 |
169 | ### Added
170 |
171 | - Symbol indexing for top-level blocks. (@patrickrgaffney - #38)
172 |
173 | ## v0.18.0 - 2019-07-01
174 |
175 | ### Added
176 |
177 | - Update list of built-in functions. (@Tenzer - #37)
178 |
179 | ### Fixed
180 |
181 | - Allow hyphens in names of attributes inside string interpolation. (@Tenzer - #37)
182 |
183 | ## v0.17.0 - 2019-01-25
184 |
185 | ### Added
186 |
187 | - [Sublime syntax][subl-format] format. (@thiagoalmeidasa - #35)
188 |
189 | ### Fixed
190 |
191 | - Better support for parenthesis inside string interpolation. (@NightsPaladin - #33)
192 |
193 | ## v0.16.0 - 2018-08-08
194 |
195 | ### Added
196 |
197 | - Snippet for `data` blocks. (@mschurenko - #32)
198 |
199 | ## v0.15.0 - 2018-02-22
200 |
201 | ### Added
202 |
203 | - Terraform constant `local`. (@digitalfiz - #30)
204 |
205 | ## v0.14.0 - 2017-08-31
206 |
207 | ### Added
208 |
209 | - Update list of built-in functions. (@gburiola - #27)
210 |
211 | ### Removed
212 |
213 | - Built-in function `from`.
214 |
215 | ## v0.13.1 - 2017-08-10
216 |
217 | ### Fixed
218 |
219 | - Allow nested function calls.
220 |
221 | ## v0.13.0 - 2017-06-07
222 |
223 | ### Changed
224 |
225 | - Set default tab size to 2. (@kushmansingh - #25)
226 | - Set default indentation to spaces. (@kushmansingh - #25)
227 |
228 | ## v0.12.2 - 2017-05-08
229 |
230 | ### Fixed
231 |
232 | - Allow whitespace before `<<` when closing heredocs. (@GreatFruitOmsk - #24)
233 |
234 | ## v0.12.1 - 2017-03-31
235 |
236 | ### Fixed
237 |
238 | - Escape hyphens in block labels
239 |
240 | ## v0.12.0 - 2017-03-30
241 |
242 | ### Added
243 |
244 | - Code folding markers.
245 | - Built-in Terraform functions.
246 |
247 | ### Fixed
248 |
249 | - Function calls and attribute access inside string templates.
250 |
251 | ## v0.11.0 - 2017-03-08
252 |
253 | ### Added
254 |
255 | - Heredocs.
256 |
257 | ## v0.10.0 - 2017-02-14
258 |
259 | ### Added
260 |
261 | - `.hcl` file extensions (@akarnani - #19)
262 |
263 | ## v0.9.0 - 2017-02-12
264 |
265 | ### Fixed
266 |
267 | - Handle nested string interpolation.
268 |
269 | ## v0.8.0 - 2017-02-08
270 |
271 | ### Added
272 |
273 | - String interpolation.
274 | - Unquoted block labels.
275 |
276 | ### Fixed
277 |
278 | - De-emphasize variable assignment.
279 |
280 | ## v0.7.0 - 2017-01-10
281 |
282 | ### Added
283 |
284 | - C-style single line comments `//`. (@kerma - #16)
285 |
286 | ## v0.6.0 - 2016-09-08
287 |
288 | ### Added
289 |
290 | - Support for `data` blocks. (@Jonnymcc - #14)
291 |
292 | ## v0.5.0 - 2016-07-05
293 |
294 | ### Added
295 |
296 | - Snippet for `provisioner` blocks. (@ApsOps - #13)
297 |
298 | ## v0.4.0 - 2016-06-08
299 |
300 | ### Added
301 |
302 | - Match opening/closing brackets. (@alexlouden - #12)
303 |
304 | ## v0.3.0 - 2016-06-08
305 |
306 | ### Added
307 |
308 | - Snippets for `module` blocks. (@maplebed - #10)
309 |
310 | ## v0.2.0 - 2016-03-01
311 |
312 | ### Added
313 |
314 | - Blocks comments `/* ... */`. (@bigkraig - #8)
315 |
316 | ## v0.1.0 - 2015-08-04
317 |
318 | Initial release.
319 |
320 | [atlas]: https://www.terraform.io/docs/configuration/terraform-enterprise.html
321 | [exponents]: https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#numeric-literals
322 | [hex-literals]: https://github.com/hashicorp/terraform/issues/20933#issuecomment-480050478
323 | [for-exp]: https://www.terraform.io/docs/configuration/expressions.html#for-expressions
324 | [import]: https://www.terraform.io/docs/import/usage.html
325 | [indices]: https://www.terraform.io/docs/configuration/expressions.html#indices-and-attributes
326 | [named-values]: https://www.terraform.io/docs/configuration/expressions.html#references-to-named-values
327 | [old-splat]: https://www.terraform.io/docs/configuration/expressions.html#legacy-attribute-only-splat-expressions
328 | [scopes]: https://www.sublimetext.com/docs/scope_naming.html
329 | [splat]: https://www.terraform.io/docs/configuration/expressions.html#splat-expressions
330 | [string-templates]: https://www.terraform.io/docs/configuration/expressions.html#string-literals
331 | [strings]: https://www.terraform.io/docs/configuration/expressions.html#string-literals
332 | [subl-format]: https://www.sublimetext.com/docs/syntax.html
333 | [tests]: https://www.sublimetext.com/docs/syntax.html#testing
334 | [types]: https://www.terraform.io/docs/configuration/types.html
335 | [uom-suffixes]: https://github.com/hashicorp/terraform/issues/3287#issuecomment-241560576
336 |
--------------------------------------------------------------------------------
/Terraform.sublime-syntax:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | #
3 | # This syntax definition is based on the Terraform guide:
4 | # https://www.terraform.io/docs/language/index.html
5 | #
6 | # As well as the HCL Native Syntax Spec:
7 | # https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md
8 | # (previously https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md)
9 | #
10 | # For documentation on the .subline-syntax format:
11 | # https://www.sublimetext.com/docs/syntax.html
12 | #
13 | # Regex's in this file support the Oniguruma regex engine:
14 | # https://raw.githubusercontent.com/kkos/oniguruma/5.9.6/doc/RE
15 | #
16 | ---
17 | name: Terraform
18 | scope: source.terraform
19 | version: 2
20 |
21 | # File Extensions:
22 | #
23 | # - ".tf": the standard file extension
24 | # https://www.terraform.io/docs/language/index.html
25 | file_extensions:
26 | - tf
27 | - nomad
28 |
29 | variables:
30 | # Identifiers: ID_Start (ID_Continue | '-')*;
31 | #
32 | # There is an undocumented exception
33 | # that an underscore character is also accepted
34 | # as an id start character.
35 | #
36 | # https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#identifiers
37 | # http://unicode.org/reports/tr31/#Table_Lexical_Classes_for_Identifiers
38 | ID_Start: '[\p{ID_Start}_]'
39 | ID_Continue: '[\p{ID_Continue}-]'
40 | identifier: (?:{{ID_Start}}{{ID_Continue}}*)
41 |
42 | # Exponent: "e" or "E" followed by an optional sign
43 | #
44 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#numeric-literals
45 | exponent: ([Ee][+-]?)
46 |
47 | # Character Escapes:
48 | #
49 | # - \n: newline
50 | # - \r: carriage return
51 | # - \t: tab
52 | # - \": quote
53 | # - \\: backslash
54 | # - \uNNNN: unicode char (NNNN is 4 hex digits)
55 | # - \uNNNNNNNN: unicode char (NNNNNNNN us 8 digits)
56 | #
57 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
58 | char_escapes: \\[nrt"\\]|\\u(\h{8}|\h{4})
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 | # Template literals
67 | #
68 | # https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#template-literals
69 | template_literal: '(?:\$\$|%%)\{'
70 |
71 | # A block label
72 | #
73 | # https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#structural-elements
74 | label: (?:{{identifier}}|{{string_literal}})
75 |
76 | # Terraform Named Values
77 | #
78 | # https://www.terraform.io/docs/language/expressions/references.html
79 | named_values: (?:var|local|module|data|path|terraform|each|count|self)
80 |
81 | # Block types that are known to Terraform.
82 | #
83 | # data: https://developer.hashicorp.com/terraform/language/data-sources
84 | # ephemeral: https://developer.hashicorp.com/terraform/language/resources/ephemeral
85 | # resource: https://developer.hashicorp.com/terraform/language/resources/syntax
86 | terraform_typed_and_named_blocks: (?:data|ephemeral|resource)
87 | # module: https://developer.hashicorp.com/terraform/language/modules/syntax
88 | # output: https://developer.hashicorp.com/terraform/language/values/outputs
89 | # provider: https://developer.hashicorp.com/terraform/language/providers/configuration
90 | # variable: https://developer.hashicorp.com/terraform/language/values/variables
91 | terraform_named_blocks: (?:module|output|provider|variable)
92 | # locals: https://developer.hashicorp.com/terraform/language/values/locals
93 | # terraform: https://developer.hashicorp.com/terraform/language/terraform#terraform-block-syntax
94 | # (Currently unused because they do not have special behavior implemented.)
95 | terraform_other_blocks: (?:locals|terraform)
96 |
97 | # Terraform built-in type keywords
98 | #
99 | # https://www.terraform.io/docs/language/expressions/type-constraints.html#primitive-types
100 | # https://www.terraform.io/docs/language/expressions/type-constraints.html#dynamic-types-the-quot-any-quot-constraint
101 | terraform_type_keywords: (?:any|string|number|bool)
102 |
103 | # Built-In Functions
104 | #
105 | # https://developer.hashicorp.com/terraform/language/functions
106 | builtin_functions: |-
107 | (?x:
108 | # numbers
109 | abs | ceil | floor | log | max | min | parseint | pow | signum
110 | # string
111 | | chomp | endswith | format | formatlist | indent | join | lower | regex
112 | | regexall | replace | split | startswith | strcontains | strrev | substr
113 | | templatestring | title | trim | trimprefix | trimsuffix | trimspace | upper
114 | # collection
115 | | alltrue | anytrue | chunklist | coalesce | coalescelist | compact | concat
116 | | contains | distinct | element | flatten | index | keys | length | list
117 | | lookup | map | matchkeys | merge | one | range | reverse | setintersection
118 | | setproduct | setsubtract | setunion | slice | sort | sum | transpose
119 | | values | zipmap
120 | # encoding
121 | | base64decode | base64encode | base64gzip | csvdecode | jsondecode
122 | | jsonencode | textdecodebase64 | textencodebase64 | urlencode | yamldecode
123 | | yamlencode
124 | # filesystem
125 | | abspath | dirname | pathexpand | basename | file | fileexists | fileset
126 | | filebase64 | templatefile
127 | # date and time
128 | | formatdate | plantimestamp | timeadd | timecmp | timestamp
129 | # hash and crypto
130 | | base64sha256 | base64sha512 | bcrypt | filebase64sha256
131 | | filebase64sha512 | filemd5 | filesha1 | filesha256 | filesha512 | md5
132 | | rsadecrypt | sha1 | sha256 | sha512 | uuid | uuidv5
133 | # ip network
134 | | cidrhost | cidrnetmask | cidrsubnet | cidrsubnets
135 | # type conversion
136 | | can | issensitive | nonsensitive | sensitive | tobool | tolist | tomap
137 | | tonumber | toset | tostring | try | type
138 | # terraform-specific
139 | | provider::terraform::(?:encode_tfvars | decode_tfvars | encode_expr)
140 | # deprecated/old
141 | | filemd1
142 | )
143 |
144 | contexts:
145 | main:
146 | - include: comments
147 | - include: attribute-definition
148 | - include: imports
149 | - include: blocks
150 | - include: expressions
151 |
152 | comments:
153 | - include: inline-comments
154 | - include: block-comments
155 |
156 | # Expressions:
157 | #
158 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#expression-terms
159 | expressions:
160 | - include: literals
161 | - include: operators
162 | - include: brackets
163 | - include: objects
164 | - include: attribute-access
165 | - include: functions
166 | - include: parens
167 | - include: identifiers
168 | - include: illegal-strays
169 |
170 | comma:
171 | - match: \,
172 | comment: Commas - used in certain expressions
173 | scope: punctuation.separator.terraform
174 |
175 | parens:
176 | - match: \(
177 | scope: punctuation.section.parens.begin.terraform
178 | comment: Parens - matched *after* function syntax
179 | push: paren-body
180 |
181 | paren-body:
182 | - meta_scope: meta.parens.terraform
183 | - match: \)
184 | scope: punctuation.section.parens.end.terraform
185 | pop: 1
186 | - include: expressions
187 |
188 | # Literal Values: Numbers, Language Constants, and Strings
189 | #
190 | # Strings are _technically_ part of the "expression sub-language",
191 | # but make the most sense to be part of this stack.
192 | #
193 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#literal-values
194 | literals:
195 | - include: numeric-literals
196 | - include: language-constants
197 | - include: string-literals
198 | - include: heredoc
199 | - include: type-keywords
200 | - include: named-value-references
201 |
202 | named-value-references:
203 | - match: \b{{named_values}}\b
204 | comment: Special variables available only to Terraform.
205 | scope: variable.language.terraform
206 |
207 | type-keywords:
208 | - match: \b{{terraform_type_keywords}}\b
209 | comment: Type keywords known to Terraform.
210 | scope: storage.type.terraform
211 |
212 | # Inline Comments: begin at the operator, end at the end of the line.
213 | #
214 | # https://www.terraform.io/docs/language/syntax/configuration.html#comments
215 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#comments-and-whitespace
216 | inline-comments:
217 | - match: '#|//'
218 | comment: Inline Comments
219 | scope: punctuation.definition.comment.terraform
220 | push: inline-comment-body
221 |
222 | inline-comment-body:
223 | - meta_scope: comment.line.terraform
224 | - match: $\n?
225 | scope: punctuation.definition.comment.terraform
226 | pop: 1
227 |
228 | # Block comments: start and end delimiters for multi-line comments.
229 | #
230 | # https://www.terraform.io/docs/language/syntax/configuration.html#comments
231 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#comments-and-whitespace
232 | block-comments:
233 | - match: /\*
234 | comment: Block comments
235 | scope: punctuation.definition.comment.terraform
236 | push: block-comments-body
237 |
238 | block-comments-body:
239 | - meta_scope: comment.block.terraform
240 | - match: \*/
241 | scope: punctuation.definition.comment.terraform
242 | pop: 1
243 |
244 | # Language Constants: booleans and `null`.
245 | #
246 | # https://www.terraform.io/docs/language/expressions/types.html#literal-expressions
247 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#literal-values
248 | language-constants:
249 | - match: \btrue\b
250 | scope: constant.language.boolean.true.terraform
251 | - match: \bfalse\b
252 | scope: constant.language.boolean.false.terraform
253 | - match: \bnull\b
254 | scope: constant.language.null.terraform
255 |
256 | # Numbers: Integers, fractions and exponents
257 | #
258 | # https://www.terraform.io/docs/language/expressions/types.html
259 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#numeric-literals
260 | numeric-literals:
261 | - match: \b\d+{{exponent}}\d+\b
262 | comment: Integer, no fraction, optional exponent
263 | scope: meta.number.float.decimal.terraform constant.numeric.value.terraform
264 | - match: \b\d+(\.)\d+(?:{{exponent}}\d+)?\b
265 | comment: Integer, fraction, optional exponent
266 | scope: meta.number.float.decimal.terraform constant.numeric.value.terraform
267 | captures:
268 | 1: punctuation.separator.decimal.terraform
269 | - match: \b\d+\b
270 | comment: Integers
271 | scope: meta.number.integer.decimal.terraform constant.numeric.value.terraform
272 |
273 | # Strings:
274 | #
275 | # https://www.terraform.io/docs/language/expressions/types.html
276 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
277 | string-literals:
278 | - match: \"
279 | comment: Strings
280 | scope: punctuation.definition.string.begin.terraform
281 | push: string-body
282 |
283 | string-body:
284 | - meta_scope: meta.string.terraform string.quoted.double.terraform
285 | - match: \"
286 | scope: punctuation.definition.string.end.terraform
287 | pop: 1
288 | - match: \n
289 | scope: invalid.illegal.unclosed-string.terraform
290 | pop: 1
291 | - include: character-escapes
292 | - include: string-interpolation
293 | - include: aws-acl
294 |
295 | character-escapes:
296 | - match: '{{char_escapes}}'
297 | comment: Character Escapes
298 | scope: constant.character.escape.terraform
299 |
300 | template-literals:
301 | - match: '{{template_literal}}'
302 | comment: Template Literal
303 | scope: constant.character.escape.terraform
304 |
305 | aws-acl:
306 | - match: (?=\barn:aws:)
307 | push: aws-acl-body
308 |
309 | aws-acl-body:
310 | - clear_scopes: 1 # Clear the string.* scope.
311 | - meta_scope: variable.language.acl.terraform
312 | - match: ([$%]\{)(~)?
313 | captures:
314 | 1: punctuation.section.interpolation.begin.terraform
315 | 2: keyword.operator.template.trim.left.terraform
316 | push: acl-interpolation-body
317 | - match: :|/
318 | scope: punctuation.separator.sequence.terraform
319 | - match: \*
320 | scope: constant.other.wildcard.asterisk.terraform
321 | - match: (?![\w-])
322 | pop: 1
323 |
324 | acl-interpolation-body:
325 | - meta_scope: meta.interpolation.terraform
326 | - meta_content_scope: source.terraform
327 | - include: string-interpolation-body
328 |
329 | # String Interpolation: ("${" | "${~") Expression ("}" | "~}"
330 | #
331 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#templates
332 | string-interpolation:
333 | - include: template-literals
334 | - match: ([$%]\{)(~)?
335 | captures:
336 | 1: punctuation.section.interpolation.begin.terraform
337 | 2: keyword.operator.template.trim.left.terraform
338 | push: string-interpolation-body
339 |
340 | string-interpolation-body:
341 | - clear_scopes: 1 # Clear the string.* scope.
342 | - meta_scope: meta.interpolation.terraform
343 | - meta_content_scope: source.terraform
344 | - match: (~)?(\})
345 | captures:
346 | 1: keyword.operator.template.trim.right.terraform
347 | 2: punctuation.section.interpolation.end.terraform
348 | pop: 1
349 | - match: \bif\b
350 | scope: keyword.control.conditional.if.terraform
351 | - match: \belse\b
352 | scope: keyword.control.conditional.else.terraform
353 | - match: \bendif\b
354 | scope: keyword.control.conditional.end.terraform
355 | - match: \bfor\b
356 | scope: keyword.control.loop.for.terraform
357 | - match: \bendfor\b
358 | scope: keyword.control.loop.end.terraform
359 | - match: \bin\b
360 | scope: keyword.control.loop.in.terraform
361 | - include: expressions
362 |
363 | # String Heredocs
364 | #
365 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#template-expressions
366 | heredoc:
367 | - match: (\<\<\-?)\s*({{identifier}})\s*$
368 | comment: String Heredoc's
369 | captures:
370 | 1: keyword.operator.heredoc.terraform
371 | 2: keyword.control.heredoc.terraform
372 | push: heredoc-body
373 |
374 | heredoc-body:
375 | - meta_content_scope: meta.string.terraform string.unquoted.heredoc.terraform
376 | - match: ^\s*\2\s*$
377 | comment: The heredoc token identifier (second capture above).
378 | scope: keyword.control.heredoc.terraform
379 | pop: 1
380 | - include: string-interpolation
381 |
382 | # Operators:
383 | #
384 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#operators-and-delimiters
385 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#operations
386 | operators:
387 | - match: \>\= # >=
388 | scope: keyword.operator.comparison.terraform
389 | - match: \<\= # <=
390 | scope: keyword.operator.comparison.terraform
391 | - match: \=\= # ==
392 | scope: keyword.operator.comparison.terraform
393 | - match: \!\= # !=
394 | scope: keyword.operator.comparison.terraform
395 | - match: \+ # +
396 | scope: keyword.operator.arithmetic.terraform
397 | - match: \- # -
398 | scope: keyword.operator.arithmetic.terraform
399 | - match: \* # *
400 | scope: keyword.operator.arithmetic.terraform
401 | - match: \/ # /
402 | scope: keyword.operator.arithmetic.terraform
403 | - match: \% # %
404 | scope: keyword.operator.arithmetic.terraform
405 | - match: \&\& # &&
406 | scope: keyword.operator.logical.terraform
407 | - match: \|\| # ||
408 | scope: keyword.operator.logical.terraform
409 | - match: \! # !
410 | scope: keyword.operator.logical.terraform
411 | - match: \> # >
412 | scope: keyword.operator.comparison.terraform
413 | - match: \< # <
414 | scope: keyword.operator.comparison.terraform
415 | - match: \? # ?
416 | scope: keyword.operator.ternary.terraform
417 | - match: \.\.\. # ...
418 | scope: keyword.operator.terraform
419 | - match: ':' # :
420 | scope: keyword.operator.ternary.terraform
421 |
422 | # Terraform "import" statements
423 | #
424 | # https://www.terraform.io/docs/cli/import/usage.html
425 | imports:
426 | - match: \b(terraform)\s+(import)\b
427 | comment: Importing resources
428 | captures:
429 | 1: support.constant.terraform
430 | 2: keyword.control.import.terraform
431 | push: import-body
432 |
433 | import-body:
434 | - match: \"
435 | comment: String literal label
436 | scope: punctuation.definition.string.begin.terraform
437 | push: literal-label-body
438 | - match: '{{identifier}}'
439 | comment: Identifier label
440 | scope: entity.name.label.terraform
441 | - include: numeric-literals
442 | - include: attribute-access
443 | - match: $\n?
444 | comment: Pop at newline
445 | pop: 1
446 |
447 | literal-label-body:
448 | - meta_scope: meta.string.terraform string.quoted.double.terraform
449 | - match: \"
450 | scope: punctuation.definition.string.end.terraform
451 | pop: 1
452 |
453 | # Brackets: matches tuples and subscript notation
454 | #
455 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#index-operator
456 | brackets:
457 | - match: \[
458 | scope: punctuation.section.brackets.begin.terraform
459 | push: bracket-body
460 |
461 | bracket-body:
462 | - meta_scope: meta.brackets.terraform
463 | - match: (\*)?\]
464 | comment: Full-splat operator
465 | scope: punctuation.section.brackets.end.terraform
466 | captures:
467 | 1: keyword.operator.splat.terraform
468 | pop: 1
469 | - include: comma
470 | - include: comments
471 | - include: tuple-for-expression
472 | - include: expressions
473 |
474 | # Objects: collection values
475 | #
476 | # Allows keys as identifiers, strings, and computed values wrapped in parens.
477 | #
478 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#collection-values
479 | objects:
480 | - match: \{
481 | scope: punctuation.section.braces.begin.terraform
482 | push: object-body
483 |
484 | object-body:
485 | - meta_scope: meta.braces.terraform
486 | - match: \}
487 | scope: punctuation.section.braces.end.terraform
488 | pop: 1
489 | - include: object-for-expression
490 | - include: comments
491 | - match: (?=({{identifier}}|\".*?\")\s*=)
492 | push:
493 | - object-value
494 | - assignment-operator
495 | - object-literal-key
496 | - match: \(
497 | comment: Computed object key (any expression between parens)
498 | scope: punctuation.section.parens.begin.terraform
499 | push:
500 | - object-value
501 | - assignment-operator
502 | - object-computed-key
503 | - include: Packages/Terraform/JSON (Terraform).sublime-syntax#object-body
504 |
505 | object-computed-key:
506 | - meta_scope: meta.mapping.key.terraform meta.parens.terraform
507 | - include: paren-body
508 |
509 | object-literal-key:
510 | - match: '{{identifier}}'
511 | scope: meta.mapping.key.terraform meta.string.terraform string.unquoted.terraform
512 | pop: 1
513 | - match: (\").*?(\")
514 | scope: meta.mapping.key.terraform meta.string.terraform string.quoted.double.terraform
515 | captures:
516 | 1: punctuation.definition.string.begin.terraform
517 | 2: punctuation.definition.string.end.terraform
518 | pop: 1
519 | - include: else-pop
520 |
521 | assignment-operator:
522 | - match: =
523 | scope: keyword.operator.assignment.terraform
524 | pop: 1
525 | - include: else-pop
526 |
527 | # Object key values: pop at comma, newline, and closing-bracket
528 | #
529 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#collection-values
530 | object-value:
531 | - include: comments
532 | - match: \,
533 | comment: Pop scope on comma.
534 | scope: punctuation.separator.terraform
535 | pop: 1
536 | - match: $\n?
537 | comment: Pop scope on EOL.
538 | pop: 1
539 | - match: (?=\})
540 | comment: Lookahead (don't consume) and pop scope on a bracket.
541 | scope: punctuation.section.braces.end.terraform
542 | pop: 1
543 | - include: expressions
544 |
545 | # Attribute Access: "." Identifier
546 | #
547 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#attribute-access-operator
548 | attribute-access:
549 | - match: \.
550 | scope: punctuation.accessor.dot.terraform
551 | push: member
552 |
553 | member:
554 | - include: comments
555 | - match: '{{identifier}}'
556 | comment: Attribute access
557 | scope: variable.other.member.terraform
558 | pop: 1
559 | - match: \d+
560 | comment: Subscript
561 | scope: meta.number.integer.decimal.terraform constant.numeric.value.terraform
562 | pop: 1
563 | - match: \*
564 | comment: Attribute-only splat
565 | scope: keyword.operator.splat.terraform
566 | pop: 1
567 | - include: else-pop
568 |
569 | # Attribute Definition: Identifier "=" Expression Newline
570 | #
571 | # The "=" operator cannot be immediately followed by "="
572 | # ">", as those are other operators, not attr definitions.
573 | #
574 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#attribute-definitions
575 | attribute-definition:
576 | - match: (?=(\()?({{identifier}})(\))?\s*(\=(?![\=\>])))
577 | push:
578 | - assignment-operator
579 | - attribute-key
580 |
581 | attribute-key:
582 | - match: \((?={{identifier}}\))
583 | scope: punctuation.section.parens.begin.terraform
584 | set:
585 | - attribute-key-end
586 | - attribute-key
587 | # https://developer.hashicorp.com/terraform/language/meta-arguments/for_each
588 | - match: for_each\b
589 | scope: variable.declaration.terraform keyword.control.loop.for.terraform
590 | pop: 1
591 | # https://developer.hashicorp.com/terraform/language/meta-arguments/count
592 | - match: count\b
593 | scope: variable.declaration.terraform keyword.control.conditional.terraform
594 | pop: 1
595 | - match: '{{identifier}}'
596 | scope: variable.declaration.terraform variable.other.readwrite.terraform
597 | pop: 1
598 |
599 | attribute-key-end:
600 | - meta_scope: meta.parens.terraform
601 | - match: \)
602 | scope: punctuation.section.parens.end.terraform
603 | pop: 1
604 |
605 | # Functions: Terraform builtins and unknown
606 | #
607 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#functions-and-function-calls
608 | # https://www.terraform.io/docs/language/expressions/function-calls.html
609 | functions:
610 | - match: (?={{builtin_functions}}\()
611 | push: builtin-function-name
612 | - match: (?=(?:{{identifier}}::)*{{identifier}}\()
613 | push: other-function-name
614 |
615 | builtin-function-name:
616 | - meta_content_scope: meta.function-call.identifier.terraform
617 | - include: function-argument-list
618 | - include: namespaces
619 | - match: '{{identifier}}'
620 | scope: support.function.builtin.terraform
621 |
622 | other-function-name:
623 | - meta_content_scope: meta.function-call.identifier.terraform
624 | - include: function-argument-list
625 | - include: namespaces
626 | - match: '{{identifier}}'
627 | scope: variable.function.terraform
628 |
629 | function-argument-list:
630 | - match: \(
631 | scope: punctuation.section.parens.begin.terraform
632 | set: function-argument-list-body
633 |
634 | function-argument-list-body:
635 | - meta_scope: meta.function-call.arguments.terraform meta.parens.terraform
636 | - match: \)
637 | scope: punctuation.section.parens.end.terraform
638 | pop: 1
639 | - include: comments
640 | - include: expressions
641 | - include: comma
642 |
643 | # Tuple for-Expression:
644 | #
645 | # "[" "for" Identifier ("," Identifier)? "in" Expression ":" Expression ("if" Expression)? "]";
646 | #
647 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#for-expressions
648 | # https://www.terraform.io/docs/language/expressions/for.html
649 | tuple-for-expression:
650 | - match: \bfor\b
651 | comment: for expression (arrays)
652 | scope: keyword.control.loop.for.terraform
653 | set: tuple-for-expression-body
654 |
655 | tuple-for-expression-body:
656 | - meta_content_scope: meta.brackets.terraform
657 | - match: \]
658 | scope: meta.brackets.terraform punctuation.section.brackets.end.terraform
659 | pop: 1
660 | - include: for-expression-body
661 |
662 | # Object for-Expression:
663 | #
664 | # "{" "for" Identifier ("," Identifier)? "in" Expression ":" Expression "=>" Expression "..."? ("if" Expression)? "}";
665 | #
666 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#for-expressions
667 | # https://www.terraform.io/docs/language/expressions/for.html
668 | object-for-expression:
669 | - match: \bfor\b
670 | comment: for expression (arrays)
671 | scope: keyword.control.loop.for.terraform
672 | set: object-for-expression-body
673 |
674 | object-for-expression-body:
675 | - meta_content_scope: meta.braces.terraform
676 | - match: \}
677 | scope: meta.braces.terraform punctuation.section.braces.end.terraform
678 | pop: 1
679 | - match: \=\>
680 | scope: punctuation.separator.key-value.terraform
681 | - include: for-expression-body
682 |
683 | # Shared body syntax for tuple and object for-expressions.
684 | # They require different `set` blocks because they are
685 | # pop'd with different characters and objects allow `=>`.
686 | for-expression-body:
687 | - match: \bin\b
688 | scope: keyword.operator.iteration.in.terraform
689 | - match: \bif\b
690 | scope: keyword.control.conditional.terraform
691 | - match: '\:'
692 | scope: punctuation.section.block.loop.for.terraform
693 | - include: expressions
694 | - include: comments
695 | - include: comma
696 |
697 | namespaces:
698 | - match: ({{identifier}})(::)
699 | captures:
700 | 1: variable.namespace.terraform
701 | 2: punctuation.accessor.double-colon.terraform
702 |
703 | identifiers:
704 | - match: '{{identifier}}'
705 | scope: variable.other.readwrite.terraform
706 |
707 | illegal-strays:
708 | - match: '[\])}]'
709 | scope: invalid.illegal.stray.terraform
710 |
711 | # Blocks: Identifier (StringLit|Identifier)* "{" Newline Body "}" Newline;
712 | #
713 | # https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#structural-elements
714 | blocks:
715 | - include: typed-and-named-blocks
716 | - include: named-blocks
717 | - include: generic-blocks
718 |
719 | typed-and-named-blocks:
720 | # Special case for two-label resources,
721 | # where the first denotes the type and the second the name.
722 | - match: (?=\b{{terraform_typed_and_named_blocks}}(\s+{{label}}){2}\s*\{)
723 | push:
724 | - body
725 | - block-name-label
726 | - block-type-label
727 | - block-declaration
728 |
729 | named-blocks:
730 | # Special case for two-label resources,
731 | # where the first denotes the type and the second the name.
732 | - match: (?=\b{{terraform_named_blocks}}\s+{{label}}\s*\{)
733 | push:
734 | - body
735 | - block-name-label
736 | - block-declaration
737 |
738 | generic-blocks:
739 | - match: (?=\b({{identifier}})(\s+{{label}})*\s*\{)
740 | push:
741 | - body
742 | - generic-block-labels
743 | - block-declaration
744 |
745 | block-declaration:
746 | - match: '{{identifier}}'
747 | scope: keyword.declaration.terraform
748 | pop: 1
749 | - include: else-pop
750 |
751 | block-type-label:
752 | - match: \"
753 | scope: punctuation.definition.string.begin.terraform
754 | set: block-type-label-body
755 | - match: '{{identifier}}'
756 | scope: support.type.terraform
757 | pop: 1
758 | - include: else-pop
759 |
760 | block-type-label-body:
761 | - meta_scope: meta.string.terraform
762 | - meta_content_scope: support.type.terraform
763 | - match: \"
764 | scope: punctuation.definition.string.end.terraform
765 | pop: 1
766 | - include: character-escapes
767 |
768 | block-name-label:
769 | - match: \"
770 | scope: punctuation.definition.string.begin.terraform
771 | set: block-name-label-body
772 | - match: '{{identifier}}'
773 | scope: entity.name.label.terraform
774 | pop: 1
775 | - include: else-pop
776 |
777 | block-name-label-body:
778 | - meta_scope: meta.string.terraform
779 | - meta_content_scope: entity.name.label.terraform
780 | - match: \"
781 | scope: punctuation.definition.string.end.terraform
782 | pop: 1
783 | - include: character-escapes
784 |
785 | generic-block-labels:
786 | # Labels probably have a meaning, but we don't know which,
787 | # so we just scope them as (un-)quoted strings.
788 | - match: \"
789 | scope: punctuation.definition.string.begin.terraform
790 | push: generic-block-label-body
791 | - match: '{{identifier}}'
792 | scope: string.unquoted.double.terraform
793 | - include: else-pop
794 |
795 | generic-block-label-body:
796 | - meta_scope: meta.string.terraform string.quoted.double.terraform
797 | - match: \"
798 | scope: punctuation.definition.string.end.terraform
799 | pop: 1
800 | - include: character-escapes
801 |
802 | body:
803 | - meta_content_scope: meta.block.head.terraform
804 | - match: \{
805 | scope: punctuation.section.block.begin.terraform
806 | set: body-body
807 | - include: else-pop
808 |
809 | body-body:
810 | - meta_scope: meta.block.body.terraform
811 | - match: \}
812 | scope: punctuation.section.block.end.terraform
813 | pop: 1
814 | - include: main
815 |
816 | else-pop:
817 | - match: (?=\S)
818 | pop: 1
819 |
--------------------------------------------------------------------------------