%YAML 1.2 --- # This file is some kind of internal library which is used to store # common rules which are used by the visible syntax files. name: SSH Common scope: text.ssh.common version: 2 hidden: true contexts: main: - include: comments-number-sign ###[ COMMENTS ]################################################################ comments: - include: comments-number-sign - include: comments-semicolon comments-number-sign: - match: ^\s*(#+) captures: 1: comment.line.number-sign.ssh.common punctuation.definition.comment.ssh.common push: - meta_content_scope: comment.line.number-sign.ssh.common - match: \n scope: comment.line.number-sign.ssh.common pop: true comments-semicolon: - match: ^\s*(;+) captures: 1: comment.line.semi-colon.ssh.common punctuation.definition.comment.ssh.common push: - meta_content_scope: comment.line.semi-colon.ssh.common - include: pop-nl ###[ COMPONENTS ]############################################################## operator-exclamation: - match: '!' scope: keyword.operator.logical.ssh.common wildcards: - match: \* scope: constant.other.wildcard.asterisk.ssh.common - match: \? scope: constant.other.wildcard.questionmark.ssh.common punctuation-comma-sequence: - match: ',' scope: punctuation.separator.sequence.ssh.common punctuation-dot-sequence: - match: \. scope: punctuation.separator.sequence.ssh.common punctuation-at: - match: '@' scope: punctuation.separator.sequence.ssh.common ssh-fingerprint: - match: '{{ssh_fingerprint}}' scope: variable.other.fingerprint.ssh.common ssh-fingerprint-with-label: - match: '{{ssh_fingerprint}}' scope: variable.other.fingerprint.ssh.common push: expect-fingerprint-label expect-fingerprint-label: - include: pop-before-nl - match: (?=\S) push: - meta_scope: meta.annotation.identifier.ssh.common string.unquoted.ssh.common - match: '(?=[ \t]*$)' pop: 1 - include: punctuation-at time-values: # https://man.openbsd.org/sshd_config.5#TIME_FORMATS # seconds, minutes, hours, days, weeks - match: \b(?=[\dsmhdw]*\d[smhdw][\s,"]) push: - meta_scope: meta.constant.time.ssh.common meta.number.integer.decimal.ssh.common - match: (?=[\s,"]) pop: 1 - match: (\d+)([smhdw]) captures: 1: constant.numeric.value.ssh.common 2: constant.numeric.suffix.ssh.common bytes-values: - match: \b(\d+)([KMG])(?=[\s,"]) scope: meta.constant.bytes.ssh.common meta.number.integer.other.ssh.common captures: 1: constant.numeric.value.ssh.common 2: constant.numeric.suffix.ssh.common mac-addresses: - match: (?:[0-9a-fA-F]{2}:){5}(?:[0-9a-fA-F]{2}) scope: entity.name.constant.mac-address.ssh.common ipv4: - match: '\b{{ipv4}}\b' scope: meta.number.integer.other.ssh.common constant.numeric.ip-address.v4.ssh.common ipv6: - match: '{{ipv6}}' scope: meta.number.integer.other.ssh.common constant.numeric.ip-address.v6.ssh.common ipv6-square-bracket: - match: (\[){{ipv6}}(\]) scope: meta.number.integer.other.ssh.common constant.numeric.ip-address.v6.ssh.common captures: 1: punctuation.definition.constant.begin.ssh.common 2: punctuation.definition.constant.end.ssh.common ip-addresses: - include: ipv6 - include: ipv4 ipv4-with-cidr: - match: \b({{ipv4}})(?:(/)({{zero_to_32}}))?\b captures: 1: meta.number.integer.other.ssh.common constant.numeric.ip-address.v4.ssh.common 2: punctuation.separator.sequence.ssh.common 3: constant.other.range.ssh.common ipv6-with-cidr: - match: ({{ipv6}})(?:(/)({{zero_to_128}})\b)? captures: 1: meta.number.integer.other.ssh.common constant.numeric.ip-address.v6.ssh.common 2: punctuation.separator.sequence.ssh.common 3: constant.other.range.ssh.common ip-addresses-with-cidr: - include: ipv6-with-cidr - include: ipv4-with-cidr port-numbers: - match: \b{{zero_to_65535}}(?![\w:]) scope: meta.number.integer.decimal.ssh.common constant.numeric.port-number.ssh.common match-all: - match: '\b(?xi: all )\b' scope: constant.language.boolean.true.ssh.common none: - match: \bnone\b scope: constant.language.null.ssh.common any: - match: \bany\b scope: constant.language.set.ssh.common boolean: - match: \byes\b scope: constant.language.boolean.true.ssh.common - match: \bno\b scope: constant.language.boolean.false.ssh.common boolean-with-typing: - include: boolean # Consume while typing as well, but unscoped - match: \b(?:ye?|n)\b log-level: - match: '\b(?x: QUIET | FATAL | ERROR | INFO | DEBUG[1-3]? )\b' scope: constant.language.log-level.ssh.common possibly-quoted-value: - meta_content_scope: meta.mapping.value.ssh.common - match: '"' scope: punctuation.definition.string.begin.ssh.common push: - meta_scope: string.quoted.double.ssh.common - match: (")(?:\s*(\S.*))? captures: 1: punctuation.definition.string.end.ssh.common 2: invalid.illegal.ssh.common pop: 1 - match: \n|$ scope: invalid.illegal.unclosed-string.ssh.common pop: 2 - match: (?=\S) push: - meta_content_scope: string.unquoted.ssh.common - include: pop-before-nl - include: pop-nl string-patterns: # https://man7.org/linux/man-pages/man5/ssh_config.5.html#PATTERNS # https://man.openbsd.org/ssh_config.5#PATTERNS # https://man7.org/linux/man-pages/man5/sshd_config.5.html#PATTERNS # https://man.openbsd.org/sshd_config.5#PATTERNS - include: punctuation-comma-sequence - include: operator-exclamation - match: '"' scope: punctuation.definition.string.begin.ssh.common push: - meta_content_scope: string.quoted.double.ssh.common - match: '"' scope: punctuation.definition.string.end.ssh.common pop: 1 - include: wildcards - match: (?=\S) push: - meta_content_scope: string.unquoted.ssh.common - match: (?=[,!\s]) pop: 1 - include: wildcards paths: # This is just heuristic. Expect failures. - match: (?=~?[\w.\-?*${}%]*/[\w.\-?*${}%]?) push: - meta_scope: meta.path.ssh.common entity.name.ssh.common - match: (?=[\s,"]) pop: 1 - match: ~[\w\-.]* scope: variable.language.home.ssh.common - match: (/)(?:(\.{1,2})(?=/)|\.(?!/))? captures: 1: punctuation.separator.path.ssh.common 2: constant.other.placeholder.ssh.common - match: \.(?=[\w*?%]) scope: punctuation.separator.sequence.ssh.common - include: wildcards - include: tokens - include: environment-variables none-command-values: - match: \s*(none)\b[ \t]*$ captures: 1: constant.language.null.ssh.common - match: \s*((")(none)("))[ \t]*$ captures: 1: string.quoted.double.ssh.common 2: punctuation.definition.string.begin.ssh.common 3: constant.language.null.ssh.common 4: punctuation.definition.string.end.ssh.common tokens: [] environment-variables: [] ###[ PROTOTYPE ]############################################################### pop-nl: - match: \n pop: 1 pop-before-nl: - match: (?=\n) pop: 1 ############################################################################### variables: base64_char: '[a-zA-Z0-9+/]' ssh_fingerprint: (?:AAAA(?:E2V|[BC]3N){{base64_char}}+={0,3}) # ipv4_basic: (?:(?:\d{1,3}\.){3}\d{1,3}) # ipv6_basic: (?i:(?:[a-f0-9:]+:+)+[a-f0-9]+) 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]) zero_to_65535: (?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[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 :: )