Skip to content

Add IPs and CIDR in strings #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions Terraform.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,29 @@ variables:
| filemd1
)

# IPs and CIDR
## IPv6 pattern stolen lovingly from https://github.com/tijn/hosts.tmLanguage,
## where Michael Lyons adapted them from David M. Szydek https://stackoverflow.com/a/17871737.
zero_to_32: (?:3[0-2]|[12][0-9]|[0-9])
zero_to_128: (?:12[0-8]|1[01][0-9]|[1-9][0-9]|[0-9])
zero_to_255: (?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9][0-9])|(?:[1-9][0-9])|[0-9])
ipv4: (?:(?:{{zero_to_255}}\.){3}{{zero_to_255}})
ipv6: |-
(?xi:
(?:::(?:ffff(?::0{1,4}){0,1}:){0,1}{{ipv4}}) # ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|(?:(?:[0-9a-f]{1,4}:){1,4}:{{ipv4}}) # 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
|(?:fe80:(?::[0-9a-f]{1,4}){0,4}%[0-9a-z]{1,}) # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
|(?:(?:[0-9a-f]{1,4}:){7,7} [0-9a-f]{1,4}) # 1:2:3:4:5:6:7:8
| (?:[0-9a-f]{1,4}: (?::[0-9a-f]{1,4}){1,6}) # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|(?:(?:[0-9a-f]{1,4}:){1,2}(?::[0-9a-f]{1,4}){1,5}) # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|(?:(?:[0-9a-f]{1,4}:){1,3}(?::[0-9a-f]{1,4}){1,4}) # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|(?:(?:[0-9a-f]{1,4}:){1,4}(?::[0-9a-f]{1,4}){1,3}) # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|(?:(?:[0-9a-f]{1,4}:){1,5}(?::[0-9a-f]{1,4}){1,2}) # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|(?:(?:[0-9a-f]{1,4}:){1,6} :[0-9a-f]{1,4}) # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|(?:(?:[0-9a-f]{1,4}:){1,7} :) # 1:: 1:2:3:4:5:6:7::
|(?::(?:(?::[0-9a-f]{1,4}){1,7}|:)) # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
)

contexts:
main:
- include: comments
Expand Down Expand Up @@ -294,6 +317,8 @@ contexts:
scope: constant.character.escape.terraform
- include: string-interpolation
- include: aws-acl
- include: ip-addresses-with-cidr-at-start
- include: ipv6-square-bracket-at-start

aws-acl:
- match: (?=\barn:aws:)
Expand All @@ -319,6 +344,43 @@ contexts:
- meta_content_scope: source.terraform
- include: string-interpolation-body

ipv4-at-start:
- match: \G{{ipv4}}\b
Copy link
Member

@FichteFoll FichteFoll May 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\G means it matches after any previously consumed token, i.e. you could have multiple IPs within a single string or have an IP after an escape sequence. A more consistent approach would be to have two different string body contexts where the IP patterns are only applied for the very first character and any other following character switches to the other string context.

image

scope: meta.number.integer.other.terraform constant.numeric.ip-address.v4.terraform

ipv6-at-start:
- match: \G{{ipv6}}
scope: meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform

ipv6-square-bracket-at-start:
- match: \G(\[){{ipv6}}(\])
scope: meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform
captures:
1: punctuation.definition.constant.begin.terraform
2: punctuation.definition.constant.end.terraform

ip-addresses-at-start:
- include: ipv6-at-start
- include: ipv4-at-start

ipv4-with-cidr-at-start:
- match: \G({{ipv4}})(?:(/)({{zero_to_32}}))?\b
captures:
1: meta.number.integer.other.terraform constant.numeric.ip-address.v4.terraform
2: punctuation.separator.sequence.terraform
3: constant.other.range.terraform

ipv6-with-cidr-at-start:
- match: \G({{ipv6}})(?:(/)({{zero_to_128}})\b)?
captures:
1: meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform
2: punctuation.separator.sequence.terraform
3: constant.other.range.terraform

ip-addresses-with-cidr-at-start:
- include: ipv6-with-cidr-at-start
- include: ipv4-with-cidr-at-start

# String Interpolation: ("${" | "${~") Expression ("}" | "~}"
#
# https://github.com/hashicorp/hcl2/blob/master/hcl/hclsyntax/spec.md#templates
Expand Down
56 changes: 56 additions & 0 deletions tests/syntax_test_scope.tf
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,62 @@
# ^^^^^^^^^^ constant.character.escape.terraform
# ^ punctuation.definition.string.end.terraform


/////
// Matches IPs and CIDR
/////

"1.2.3.4"
# ^^^^^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^^^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v4.terraform
# ^ punctuation.definition.string.end.terraform

"1.2.3.4/32"
# ^^^^^^^^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^^^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v4.terraform
# ^ punctuation.separator.sequence.terraform
# ^^ constant.other.range.terraform
# ^ punctuation.definition.string.end.terraform

"1.2.3.4/33"
# ^^^^^^^^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^^^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v4.terraform
# ^^^ - constant - punctuation
# ^ punctuation.definition.string.end.terraform

"256.2.3.4"
# ^^^^^^^^^^^ - constant

"::1"
# ^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform
# ^ punctuation.definition.string.end.terraform

"1:2:3:4:5:6:7:8"
# ^^^^^^^^^^^^^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^^^^^^^^^^^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform
# ^ punctuation.definition.string.end.terraform

"1:2:3:4:5:6:7:8/128"
# ^^^^^^^^^^^^^^^^^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^^^^^^^^^^^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform
# ^ punctuation.separator.sequence.terraform
# ^^^ constant.other.range.terraform
# ^ punctuation.definition.string.end.terraform

"1:2:3:4:5:6:7:8/129"
# ^^^^^^^^^^^^^^^^^^^^^ meta.string.terraform string.quoted.double.terraform
# ^ punctuation.definition.string.begin.terraform
# ^^^^^^^^^^^^^^^ meta.number.integer.other.terraform constant.numeric.ip-address.v6.terraform
# ^^^^ - constant - punctuation
# ^ punctuation.definition.string.end.terraform

/////////////////////////////////////////////////////////////////////
// Identifiers
/////////////////////////////////////////////////////////////////////
Expand Down