View raw

1 { 2 "scopeName": "source.hcl.terraform", 3 "name": "HashiCorp Terraform", 4 "uuid": "d9db10d3-db70-48aa-8d44-f96ccbaa29f3", 5 "fileTypes": [ 6 "tf", 7 "tfvars" 8 ], 9 "patterns": [ 10 { 11 "include": "#comments" 12 }, 13 { 14 "include": "#attribute_definition" 15 }, 16 { 17 "include": "#block" 18 }, 19 { 20 "include": "#expressions" 21 } 22 ], 23 "repository": { 24 "attribute_access": { 25 "begin": "\\.(?!\\*)", 26 "end": "[[:alpha:]][\\w-]*|\\d*", 27 "comment": "Matches traversal attribute access such as .attr", 28 "beginCaptures": { 29 "0": { 30 "name": "keyword.operator.accessor.hcl" 31 } 32 }, 33 "endCaptures": { 34 "0": { 35 "patterns": [ 36 { 37 "match": "(?!null|false|true)[[:alpha:]][\\w-]*", 38 "comment": "Attribute name", 39 "name": "variable.other.member.hcl" 40 }, 41 { 42 "match": "\\d+", 43 "comment": "Optional attribute index", 44 "name": "constant.numeric.integer.hcl" 45 } 46 ] 47 } 48 } 49 }, 50 "attribute_definition": { 51 "name": "variable.declaration.hcl", 52 "match": "(\\()?(\\b(?!null\\b|false\\b|true\\b)[[:alpha:]][[:alnum:]_-]*)(\\))?\\s*(\\=(?!\\=|\\>))\\s*", 53 "comment": "Identifier \"=\" with optional parens", 54 "captures": { 55 "1": { 56 "name": "punctuation.section.parens.begin.hcl" 57 }, 58 "2": { 59 "name": "variable.other.readwrite.hcl" 60 }, 61 "3": { 62 "name": "punctuation.section.parens.end.hcl" 63 }, 64 "4": { 65 "name": "keyword.operator.assignment.hcl" 66 } 67 } 68 }, 69 "attribute_splat": { 70 "begin": "\\.", 71 "end": "\\*", 72 "comment": "Legacy attribute-only splat", 73 "beginCaptures": { 74 "0": { 75 "name": "keyword.operator.accessor.hcl" 76 } 77 }, 78 "endCaptures": { 79 "0": { 80 "name": "keyword.operator.splat.hcl" 81 } 82 } 83 }, 84 "block": { 85 "name": "meta.block.hcl", 86 "begin": "([\\w][\\-\\w]*)([\\s\\\"\\-\\w]*)(\\{)", 87 "end": "\\}", 88 "comment": "This will match Terraform blocks like `resource \"aws_instance\" \"web\" {` or `module {`", 89 "beginCaptures": { 90 "1": { 91 "patterns": [ 92 { 93 "match": "\\bdata|check|import|locals|module|output|provider|resource|terraform|variable\\b", 94 "comment": "Known block type", 95 "name": "entity.name.type.terraform" 96 }, 97 { 98 "match": "\\b(?!null|false|true)[[:alpha:]][[:alnum:]_-]*\\b", 99 "comment": "Unknown block type", 100 "name": "entity.name.type.hcl" 101 } 102 ] 103 }, 104 "2": { 105 "patterns": [ 106 { 107 "match": "[\\\"\\-\\w]+", 108 "comment": "Block label", 109 "name": "variable.other.enummember.hcl" 110 } 111 ] 112 }, 113 "3": { 114 "name": "punctuation.section.block.begin.hcl" 115 }, 116 "5": { 117 "name": "punctuation.section.block.begin.hcl" 118 } 119 }, 120 "endCaptures": { 121 "0": { 122 "name": "punctuation.section.block.end.hcl" 123 } 124 }, 125 "patterns": [ 126 { 127 "include": "#comments" 128 }, 129 { 130 "include": "#attribute_definition" 131 }, 132 { 133 "include": "#block" 134 }, 135 { 136 "include": "#expressions" 137 } 138 ] 139 }, 140 "block_inline_comments": { 141 "name": "comment.block.hcl", 142 "begin": "/\\*", 143 "end": "\\*/", 144 "comment": "Inline comments start with the /* sequence and end with the */ sequence, and may have any characters within except the ending sequence. An inline comment is considered equivalent to a whitespace sequence", 145 "captures": { 146 "0": { 147 "name": "punctuation.definition.comment.hcl" 148 } 149 } 150 }, 151 "brackets": { 152 "begin": "\\[", 153 "end": "\\]", 154 "beginCaptures": { 155 "0": { 156 "name": "punctuation.section.brackets.begin.hcl" 157 } 158 }, 159 "endCaptures": { 160 "0": { 161 "name": "punctuation.section.brackets.end.hcl" 162 } 163 }, 164 "patterns": [ 165 { 166 "name": "keyword.operator.splat.hcl", 167 "match": "\\*", 168 "comment": "Splat operator" 169 }, 170 { 171 "include": "#comma" 172 }, 173 { 174 "include": "#comments" 175 }, 176 { 177 "include": "#inline_for_expression" 178 }, 179 { 180 "include": "#inline_if_expression" 181 }, 182 { 183 "include": "#expressions" 184 }, 185 { 186 "include": "#local_identifiers" 187 } 188 ] 189 }, 190 "char_escapes": { 191 "name": "constant.character.escape.hcl", 192 "match": "\\\\[nrt\"\\\\]|\\\\u(\\h{8}|\\h{4})", 193 "comment": "Character Escapes" 194 }, 195 "comma": { 196 "name": "punctuation.separator.hcl", 197 "match": "\\,", 198 "comment": "Commas - used in certain expressions" 199 }, 200 "comments": { 201 "patterns": [ 202 { 203 "include": "#hash_line_comments" 204 }, 205 { 206 "include": "#double_slash_line_comments" 207 }, 208 { 209 "include": "#block_inline_comments" 210 } 211 ] 212 }, 213 "double_slash_line_comments": { 214 "name": "comment.line.double-slash.hcl", 215 "begin": "//", 216 "end": "$\\n?", 217 "comment": "Line comments start with // sequence and end with the next newline sequence. A line comment is considered equivalent to a newline sequence", 218 "captures": { 219 "0": { 220 "name": "punctuation.definition.comment.hcl" 221 } 222 } 223 }, 224 "expressions": { 225 "patterns": [ 226 { 227 "include": "#literal_values" 228 }, 229 { 230 "include": "#operators" 231 }, 232 { 233 "include": "#tuple_for_expression" 234 }, 235 { 236 "include": "#object_for_expression" 237 }, 238 { 239 "include": "#brackets" 240 }, 241 { 242 "include": "#objects" 243 }, 244 { 245 "include": "#attribute_access" 246 }, 247 { 248 "include": "#attribute_splat" 249 }, 250 { 251 "include": "#functions" 252 }, 253 { 254 "include": "#parens" 255 } 256 ] 257 }, 258 "for_expression_body": { 259 "patterns": [ 260 { 261 "name": "keyword.operator.word.hcl", 262 "match": "\\bin\\b", 263 "comment": "in keyword" 264 }, 265 { 266 "name": "keyword.control.conditional.hcl", 267 "match": "\\bif\\b", 268 "comment": "if keyword" 269 }, 270 { 271 "name": "keyword.operator.hcl", 272 "match": "\\:" 273 }, 274 { 275 "include": "#expressions" 276 }, 277 { 278 "include": "#comments" 279 }, 280 { 281 "include": "#comma" 282 }, 283 { 284 "include": "#local_identifiers" 285 } 286 ] 287 }, 288 "functions": { 289 "name": "meta.function-call.hcl", 290 "begin": "([:\\-\\w]+)(\\()", 291 "end": "\\)", 292 "comment": "Built-in function calls", 293 "beginCaptures": { 294 "1": { 295 "patterns": [ 296 { 297 "match": "\\b(core::)?(abs|abspath|alltrue|anytrue|base64decode|base64encode|base64gzip|base64sha256|base64sha512|basename|bcrypt|can|ceil|chomp|chunklist|cidrhost|cidrnetmask|cidrsubnet|cidrsubnets|coalesce|coalescelist|compact|concat|contains|csvdecode|dirname|distinct|element|endswith|file|filebase64|filebase64sha256|filebase64sha512|fileexists|filemd5|fileset|filesha1|filesha256|filesha512|flatten|floor|format|formatdate|formatlist|indent|index|join|jsondecode|jsonencode|keys|length|log|lookup|lower|matchkeys|max|md5|merge|min|nonsensitive|one|parseint|pathexpand|plantimestamp|pow|range|regex|regexall|replace|reverse|rsadecrypt|sensitive|setintersection|setproduct|setsubtract|setunion|sha1|sha256|sha512|signum|slice|sort|split|startswith|strcontains|strrev|substr|sum|templatefile|textdecodebase64|textencodebase64|timeadd|timecmp|timestamp|title|tobool|tolist|tomap|tonumber|toset|tostring|transpose|trim|trimprefix|trimspace|trimsuffix|try|upper|urlencode|uuid|uuidv5|values|yamldecode|yamlencode|zipmap)\\b", 298 "name": "support.function.builtin.terraform" 299 }, 300 { 301 "match": "\\bprovider::[[:alpha:]][\\w_-]*::[[:alpha:]][\\w_-]*\\b", 302 "name": "support.function.provider.terraform" 303 } 304 ] 305 }, 306 "2": { 307 "name": "punctuation.section.parens.begin.hcl" 308 } 309 }, 310 "endCaptures": { 311 "0": { 312 "name": "punctuation.section.parens.end.hcl" 313 } 314 }, 315 "patterns": [ 316 { 317 "include": "#comments" 318 }, 319 { 320 "include": "#expressions" 321 }, 322 { 323 "include": "#comma" 324 } 325 ] 326 }, 327 "hash_line_comments": { 328 "name": "comment.line.number-sign.hcl", 329 "begin": "#", 330 "end": "$\\n?", 331 "comment": "Line comments start with # sequence and end with the next newline sequence. A line comment is considered equivalent to a newline sequence", 332 "captures": { 333 "0": { 334 "name": "punctuation.definition.comment.hcl" 335 } 336 } 337 }, 338 "hcl_type_keywords": { 339 "name": "storage.type.hcl", 340 "match": "\\b(any|string|number|bool|list|set|map|tuple|object)\\b", 341 "comment": "Type keywords known to HCL." 342 }, 343 "heredoc": { 344 "name": "string.unquoted.heredoc.hcl", 345 "begin": "(\\<\\<\\-?)\\s*(\\w+)\\s*$", 346 "end": "^\\s*\\2\\s*$", 347 "comment": "String Heredoc", 348 "beginCaptures": { 349 "1": { 350 "name": "keyword.operator.heredoc.hcl" 351 }, 352 "2": { 353 "name": "keyword.control.heredoc.hcl" 354 } 355 }, 356 "endCaptures": { 357 "0": { 358 "name": "keyword.control.heredoc.hcl" 359 } 360 }, 361 "patterns": [ 362 { 363 "include": "#string_interpolation" 364 } 365 ] 366 }, 367 "inline_for_expression": { 368 "match": "(for)\\b(.*)\\n", 369 "captures": { 370 "1": { 371 "name": "keyword.control.hcl" 372 }, 373 "2": { 374 "patterns": [ 375 { 376 "match": "\\=\\>", 377 "name": "storage.type.function.hcl" 378 }, 379 { 380 "include": "#for_expression_body" 381 } 382 ] 383 } 384 } 385 }, 386 "inline_if_expression": { 387 "begin": "(if)\\b", 388 "end": "\\n", 389 "beginCaptures": { 390 "1": { 391 "name": "keyword.control.conditional.hcl" 392 } 393 }, 394 "patterns": [ 395 { 396 "include": "#expressions" 397 }, 398 { 399 "include": "#comments" 400 }, 401 { 402 "include": "#comma" 403 }, 404 { 405 "include": "#local_identifiers" 406 } 407 ] 408 }, 409 "language_constants": { 410 "name": "constant.language.hcl", 411 "match": "\\b(true|false|null)\\b", 412 "comment": "Language Constants" 413 }, 414 "literal_values": { 415 "patterns": [ 416 { 417 "include": "#numeric_literals" 418 }, 419 { 420 "include": "#language_constants" 421 }, 422 { 423 "include": "#string_literals" 424 }, 425 { 426 "include": "#heredoc" 427 }, 428 { 429 "include": "#hcl_type_keywords" 430 }, 431 { 432 "include": "#named_value_references" 433 } 434 ] 435 }, 436 "local_identifiers": { 437 "name": "variable.other.readwrite.hcl", 438 "match": "\\b(?!null|false|true)[[:alpha:]][[:alnum:]_-]*\\b", 439 "comment": "Local Identifiers" 440 }, 441 "named_value_references": { 442 "name": "variable.other.readwrite.terraform", 443 "match": "\\b(var|local|module|data|path|terraform)\\b", 444 "comment": "Constant values available only to Terraform." 445 }, 446 "numeric_literals": { 447 "patterns": [ 448 { 449 "name": "constant.numeric.float.hcl", 450 "match": "\\b\\d+([Ee][+-]?)\\d+\\b", 451 "comment": "Integer, no fraction, optional exponent", 452 "captures": { 453 "1": { 454 "name": "punctuation.separator.exponent.hcl" 455 } 456 } 457 }, 458 { 459 "name": "constant.numeric.float.hcl", 460 "match": "\\b\\d+(\\.)\\d+(?:([Ee][+-]?)\\d+)?\\b", 461 "comment": "Integer, fraction, optional exponent", 462 "captures": { 463 "1": { 464 "name": "punctuation.separator.decimal.hcl" 465 }, 466 "2": { 467 "name": "punctuation.separator.exponent.hcl" 468 } 469 } 470 }, 471 { 472 "name": "constant.numeric.integer.hcl", 473 "match": "\\b\\d+\\b", 474 "comment": "Integers" 475 } 476 ] 477 }, 478 "object_for_expression": { 479 "begin": "(\\{)\\s?(for)\\b", 480 "end": "\\}", 481 "beginCaptures": { 482 "1": { 483 "name": "punctuation.section.braces.begin.hcl" 484 }, 485 "2": { 486 "name": "keyword.control.hcl" 487 } 488 }, 489 "endCaptures": { 490 "0": { 491 "name": "punctuation.section.braces.end.hcl" 492 } 493 }, 494 "patterns": [ 495 { 496 "name": "storage.type.function.hcl", 497 "match": "\\=\\>" 498 }, 499 { 500 "include": "#for_expression_body" 501 } 502 ] 503 }, 504 "object_key_values": { 505 "patterns": [ 506 { 507 "include": "#comments" 508 }, 509 { 510 "include": "#literal_values" 511 }, 512 { 513 "include": "#operators" 514 }, 515 { 516 "include": "#tuple_for_expression" 517 }, 518 { 519 "include": "#object_for_expression" 520 }, 521 { 522 "include": "#heredoc" 523 }, 524 { 525 "include": "#functions" 526 } 527 ] 528 }, 529 "objects": { 530 "name": "meta.braces.hcl", 531 "begin": "\\{", 532 "end": "\\}", 533 "beginCaptures": { 534 "0": { 535 "name": "punctuation.section.braces.begin.hcl" 536 } 537 }, 538 "endCaptures": { 539 "0": { 540 "name": "punctuation.section.braces.end.hcl" 541 } 542 }, 543 "patterns": [ 544 { 545 "include": "#comments" 546 }, 547 { 548 "include": "#objects" 549 }, 550 { 551 "include": "#inline_for_expression" 552 }, 553 { 554 "include": "#inline_if_expression" 555 }, 556 { 557 "match": "\\b((?!null|false|true)[[:alpha:]][[:alnum:]_-]*)\\s*(\\=\\>?)\\s*", 558 "comment": "Literal, named object key", 559 "captures": { 560 "1": { 561 "name": "meta.mapping.key.hcl variable.other.readwrite.hcl" 562 }, 563 "2": { 564 "name": "keyword.operator.assignment.hcl", 565 "patterns": [ 566 { 567 "match": "\\=\\>", 568 "name": "storage.type.function.hcl" 569 } 570 ] 571 } 572 } 573 }, 574 { 575 "match": "\\b((\").*(\"))\\s*(\\=)\\s*", 576 "comment": "String object key", 577 "captures": { 578 "0": { 579 "patterns": [ 580 { 581 "include": "#named_value_references" 582 } 583 ] 584 }, 585 "1": { 586 "name": "meta.mapping.key.hcl string.quoted.double.hcl" 587 }, 588 "2": { 589 "name": "punctuation.definition.string.begin.hcl" 590 }, 591 "3": { 592 "name": "punctuation.definition.string.end.hcl" 593 }, 594 "4": { 595 "name": "keyword.operator.hcl" 596 } 597 } 598 }, 599 { 600 "name": "meta.mapping.key.hcl", 601 "begin": "^\\s*\\(", 602 "end": "(\\))\\s*(=|:)\\s*", 603 "comment": "Computed object key (any expression between parens)", 604 "beginCaptures": { 605 "0": { 606 "name": "punctuation.section.parens.begin.hcl" 607 } 608 }, 609 "endCaptures": { 610 "1": { 611 "name": "punctuation.section.parens.end.hcl" 612 }, 613 "2": { 614 "name": "keyword.operator.hcl" 615 } 616 }, 617 "patterns": [ 618 { 619 "include": "#named_value_references" 620 }, 621 { 622 "include": "#attribute_access" 623 } 624 ] 625 }, 626 { 627 "include": "#object_key_values" 628 } 629 ] 630 }, 631 "operators": { 632 "patterns": [ 633 { 634 "name": "keyword.operator.hcl", 635 "match": "\\>\\=" 636 }, 637 { 638 "name": "keyword.operator.hcl", 639 "match": "\\<\\=" 640 }, 641 { 642 "name": "keyword.operator.hcl", 643 "match": "\\=\\=" 644 }, 645 { 646 "name": "keyword.operator.hcl", 647 "match": "\\!\\=" 648 }, 649 { 650 "name": "keyword.operator.arithmetic.hcl", 651 "match": "\\+" 652 }, 653 { 654 "name": "keyword.operator.arithmetic.hcl", 655 "match": "\\-" 656 }, 657 { 658 "name": "keyword.operator.arithmetic.hcl", 659 "match": "\\*" 660 }, 661 { 662 "name": "keyword.operator.arithmetic.hcl", 663 "match": "\\/" 664 }, 665 { 666 "name": "keyword.operator.arithmetic.hcl", 667 "match": "\\%" 668 }, 669 { 670 "name": "keyword.operator.logical.hcl", 671 "match": "\\&\\&" 672 }, 673 { 674 "name": "keyword.operator.logical.hcl", 675 "match": "\\|\\|" 676 }, 677 { 678 "name": "keyword.operator.logical.hcl", 679 "match": "\\!" 680 }, 681 { 682 "name": "keyword.operator.hcl", 683 "match": "\\>" 684 }, 685 { 686 "name": "keyword.operator.hcl", 687 "match": "\\<" 688 }, 689 { 690 "name": "keyword.operator.hcl", 691 "match": "\\?" 692 }, 693 { 694 "name": "keyword.operator.hcl", 695 "match": "\\.\\.\\." 696 }, 697 { 698 "name": "keyword.operator.hcl", 699 "match": "\\:" 700 }, 701 { 702 "name": "keyword.operator.hcl", 703 "match": "\\=\\>" 704 } 705 ] 706 }, 707 "parens": { 708 "begin": "\\(", 709 "end": "\\)", 710 "comment": "Parens - matched *after* function syntax", 711 "beginCaptures": { 712 "0": { 713 "name": "punctuation.section.parens.begin.hcl" 714 } 715 }, 716 "endCaptures": { 717 "0": { 718 "name": "punctuation.section.parens.end.hcl" 719 } 720 }, 721 "patterns": [ 722 { 723 "include": "#comments" 724 }, 725 { 726 "include": "#expressions" 727 } 728 ] 729 }, 730 "string_interpolation": { 731 "name": "meta.interpolation.hcl", 732 "begin": "(?<![%$])([%$]{)", 733 "end": "\\}", 734 "comment": "String interpolation", 735 "beginCaptures": { 736 "1": { 737 "name": "keyword.other.interpolation.begin.hcl" 738 } 739 }, 740 "endCaptures": { 741 "0": { 742 "name": "keyword.other.interpolation.end.hcl" 743 } 744 }, 745 "patterns": [ 746 { 747 "name": "keyword.operator.template.left.trim.hcl", 748 "match": "\\~\\s", 749 "comment": "Trim left whitespace" 750 }, 751 { 752 "name": "keyword.operator.template.right.trim.hcl", 753 "match": "\\s\\~", 754 "comment": "Trim right whitespace" 755 }, 756 { 757 "name": "keyword.control.hcl", 758 "match": "\\b(if|else|endif|for|in|endfor)\\b", 759 "comment": "if/else/endif and for/in/endfor directives" 760 }, 761 { 762 "include": "#expressions" 763 }, 764 { 765 "include": "#local_identifiers" 766 } 767 ] 768 }, 769 "string_literals": { 770 "name": "string.quoted.double.hcl", 771 "begin": "\"", 772 "end": "\"", 773 "comment": "Strings", 774 "beginCaptures": { 775 "0": { 776 "name": "punctuation.definition.string.begin.hcl" 777 } 778 }, 779 "endCaptures": { 780 "0": { 781 "name": "punctuation.definition.string.end.hcl" 782 } 783 }, 784 "patterns": [ 785 { 786 "include": "#string_interpolation" 787 }, 788 { 789 "include": "#char_escapes" 790 } 791 ] 792 }, 793 "tuple_for_expression": { 794 "begin": "(\\[)\\s?(for)\\b", 795 "end": "\\]", 796 "beginCaptures": { 797 "1": { 798 "name": "punctuation.section.brackets.begin.hcl" 799 }, 800 "2": { 801 "name": "keyword.control.hcl" 802 } 803 }, 804 "endCaptures": { 805 "0": { 806 "name": "punctuation.section.brackets.end.hcl" 807 } 808 }, 809 "patterns": [ 810 { 811 "include": "#for_expression_body" 812 } 813 ] 814 } 815 } 816 } 817