the home site for me: also iteration 3 or 4 of my site
1%YAML 1.2
2---
3# This file is some kind of internal library which is used to store
4# common rules which are used by the visible syntax files.
5name: SSH Common
6scope: text.ssh.common
7version: 2
8hidden: true
9
10contexts:
11 main:
12 - include: comments-number-sign
13
14###[ COMMENTS ]################################################################
15
16 comments:
17 - include: comments-number-sign
18 - include: comments-semicolon
19
20 comments-number-sign:
21 - match: ^\s*(#+)
22 captures:
23 1: comment.line.number-sign.ssh.common punctuation.definition.comment.ssh.common
24 push:
25 - meta_content_scope: comment.line.number-sign.ssh.common
26 - match: \n
27 scope: comment.line.number-sign.ssh.common
28 pop: true
29
30 comments-semicolon:
31 - match: ^\s*(;+)
32 captures:
33 1: comment.line.semi-colon.ssh.common punctuation.definition.comment.ssh.common
34 push:
35 - meta_content_scope: comment.line.semi-colon.ssh.common
36 - include: pop-nl
37
38###[ COMPONENTS ]##############################################################
39
40 operator-exclamation:
41 - match: '!'
42 scope: keyword.operator.logical.ssh.common
43
44 wildcards:
45 - match: \*
46 scope: constant.other.wildcard.asterisk.ssh.common
47 - match: \?
48 scope: constant.other.wildcard.questionmark.ssh.common
49
50 punctuation-comma-sequence:
51 - match: ','
52 scope: punctuation.separator.sequence.ssh.common
53
54 punctuation-dot-sequence:
55 - match: \.
56 scope: punctuation.separator.sequence.ssh.common
57
58 punctuation-at:
59 - match: '@'
60 scope: punctuation.separator.sequence.ssh.common
61
62 ssh-fingerprint:
63 - match: '{{ssh_fingerprint}}'
64 scope: variable.other.fingerprint.ssh.common
65
66 ssh-fingerprint-with-label:
67 - match: '{{ssh_fingerprint}}'
68 scope: variable.other.fingerprint.ssh.common
69 push: expect-fingerprint-label
70
71 expect-fingerprint-label:
72 - include: pop-before-nl
73 - match: (?=\S)
74 push:
75 - meta_scope: meta.annotation.identifier.ssh.common
76 string.unquoted.ssh.common
77 - match: '(?=[ \t]*$)'
78 pop: 1
79 - include: punctuation-at
80
81 time-values:
82 # https://man.openbsd.org/sshd_config.5#TIME_FORMATS
83 # seconds, minutes, hours, days, weeks
84 - match: \b(?=[\dsmhdw]*\d[smhdw][\s,"])
85 push:
86 - meta_scope: meta.constant.time.ssh.common
87 meta.number.integer.decimal.ssh.common
88 - match: (?=[\s,"])
89 pop: 1
90 - match: (\d+)([smhdw])
91 captures:
92 1: constant.numeric.value.ssh.common
93 2: constant.numeric.suffix.ssh.common
94
95 bytes-values:
96 - match: \b(\d+)([KMG])(?=[\s,"])
97 scope: meta.constant.bytes.ssh.common
98 meta.number.integer.other.ssh.common
99 captures:
100 1: constant.numeric.value.ssh.common
101 2: constant.numeric.suffix.ssh.common
102
103 mac-addresses:
104 - match: (?:[0-9a-fA-F]{2}:){5}(?:[0-9a-fA-F]{2})
105 scope: entity.name.constant.mac-address.ssh.common
106
107 ipv4:
108 - match: '\b{{ipv4}}\b'
109 scope: meta.number.integer.other.ssh.common constant.numeric.ip-address.v4.ssh.common
110
111 ipv6:
112 - match: '{{ipv6}}'
113 scope: meta.number.integer.other.ssh.common constant.numeric.ip-address.v6.ssh.common
114
115 ipv6-square-bracket:
116 - match: (\[){{ipv6}}(\])
117 scope: meta.number.integer.other.ssh.common constant.numeric.ip-address.v6.ssh.common
118 captures:
119 1: punctuation.definition.constant.begin.ssh.common
120 2: punctuation.definition.constant.end.ssh.common
121
122 ip-addresses:
123 - include: ipv6
124 - include: ipv4
125
126 ipv4-with-cidr:
127 - match: \b({{ipv4}})(?:(/)({{zero_to_32}}))?\b
128 captures:
129 1: meta.number.integer.other.ssh.common constant.numeric.ip-address.v4.ssh.common
130 2: punctuation.separator.sequence.ssh.common
131 3: constant.other.range.ssh.common
132
133 ipv6-with-cidr:
134 - match: ({{ipv6}})(?:(/)({{zero_to_128}})\b)?
135 captures:
136 1: meta.number.integer.other.ssh.common constant.numeric.ip-address.v6.ssh.common
137 2: punctuation.separator.sequence.ssh.common
138 3: constant.other.range.ssh.common
139
140 ip-addresses-with-cidr:
141 - include: ipv6-with-cidr
142 - include: ipv4-with-cidr
143
144 port-numbers:
145 - match: \b{{zero_to_65535}}(?![\w:])
146 scope: meta.number.integer.decimal.ssh.common
147 constant.numeric.port-number.ssh.common
148
149 match-all:
150 - match: '\b(?xi: all )\b'
151 scope: constant.language.boolean.true.ssh.common
152
153 none:
154 - match: \bnone\b
155 scope: constant.language.null.ssh.common
156
157 any:
158 - match: \bany\b
159 scope: constant.language.set.ssh.common
160
161 boolean:
162 - match: \byes\b
163 scope: constant.language.boolean.true.ssh.common
164 - match: \bno\b
165 scope: constant.language.boolean.false.ssh.common
166
167 boolean-with-typing:
168 - include: boolean
169 # Consume while typing as well, but unscoped
170 - match: \b(?:ye?|n)\b
171
172 log-level:
173 - match: '\b(?x: QUIET | FATAL | ERROR | INFO | DEBUG[1-3]? )\b'
174 scope: constant.language.log-level.ssh.common
175
176 possibly-quoted-value:
177 - meta_content_scope: meta.mapping.value.ssh.common
178 - match: '"'
179 scope: punctuation.definition.string.begin.ssh.common
180 push:
181 - meta_scope: string.quoted.double.ssh.common
182 - match: (")(?:\s*(\S.*))?
183 captures:
184 1: punctuation.definition.string.end.ssh.common
185 2: invalid.illegal.ssh.common
186 pop: 1
187 - match: \n|$
188 scope: invalid.illegal.unclosed-string.ssh.common
189 pop: 2
190 - match: (?=\S)
191 push:
192 - meta_content_scope: string.unquoted.ssh.common
193 - include: pop-before-nl
194 - include: pop-nl
195
196 string-patterns:
197 # https://man7.org/linux/man-pages/man5/ssh_config.5.html#PATTERNS
198 # https://man.openbsd.org/ssh_config.5#PATTERNS
199 # https://man7.org/linux/man-pages/man5/sshd_config.5.html#PATTERNS
200 # https://man.openbsd.org/sshd_config.5#PATTERNS
201 - include: punctuation-comma-sequence
202 - include: operator-exclamation
203 - match: '"'
204 scope: punctuation.definition.string.begin.ssh.common
205 push:
206 - meta_content_scope: string.quoted.double.ssh.common
207 - match: '"'
208 scope: punctuation.definition.string.end.ssh.common
209 pop: 1
210 - include: wildcards
211 - match: (?=\S)
212 push:
213 - meta_content_scope: string.unquoted.ssh.common
214 - match: (?=[,!\s])
215 pop: 1
216 - include: wildcards
217
218 paths:
219 # This is just heuristic. Expect failures.
220 - match: (?=~?[\w.\-?*${}%]*/[\w.\-?*${}%]?)
221 push:
222 - meta_scope: meta.path.ssh.common
223 entity.name.ssh.common
224 - match: (?=[\s,"])
225 pop: 1
226 - match: ~[\w\-.]*
227 scope: variable.language.home.ssh.common
228 - match: (/)(?:(\.{1,2})(?=/)|\.(?!/))?
229 captures:
230 1: punctuation.separator.path.ssh.common
231 2: constant.other.placeholder.ssh.common
232 - match: \.(?=[\w*?%])
233 scope: punctuation.separator.sequence.ssh.common
234 - include: wildcards
235 - include: tokens
236 - include: environment-variables
237
238 none-command-values:
239 - match: \s*(none)\b[ \t]*$
240 captures:
241 1: constant.language.null.ssh.common
242 - match: \s*((")(none)("))[ \t]*$
243 captures:
244 1: string.quoted.double.ssh.common
245 2: punctuation.definition.string.begin.ssh.common
246 3: constant.language.null.ssh.common
247 4: punctuation.definition.string.end.ssh.common
248
249 tokens: []
250 environment-variables: []
251
252###[ PROTOTYPE ]###############################################################
253
254 pop-nl:
255 - match: \n
256 pop: 1
257
258 pop-before-nl:
259 - match: (?=\n)
260 pop: 1
261
262###############################################################################
263
264variables:
265 base64_char: '[a-zA-Z0-9+/]'
266 ssh_fingerprint: (?:AAAA(?:E2V|[BC]3N){{base64_char}}+={0,3})
267 # ipv4_basic: (?:(?:\d{1,3}\.){3}\d{1,3})
268 # ipv6_basic: (?i:(?:[a-f0-9:]+:+)+[a-f0-9]+)
269 zero_to_32: (?:3[0-2]|[12][0-9]|[0-9])
270 zero_to_128: (?:12[0-8]|1[01][0-9]|[1-9][0-9]|[0-9])
271 zero_to_255: (?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9][0-9])|(?:[1-9][0-9])|[0-9])
272 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])
273 ipv4: (?:(?:{{zero_to_255}}\.){3}{{zero_to_255}})
274 ipv6: |-
275 (?xi:
276 (?:::(?: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)
277 |(?:(?:[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)
278 |(?: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)
279 |(?:(?:[0-9a-f]{1,4}:){7,7} [0-9a-f]{1,4}) # 1:2:3:4:5:6:7:8
280 | (?:[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
281 |(?:(?:[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
282 |(?:(?:[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
283 |(?:(?:[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
284 |(?:(?:[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
285 |(?:(?:[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
286 |(?:(?:[0-9a-f]{1,4}:){1,7} :) # 1:: 1:2:3:4:5:6:7::
287 |(?::(?:(?::[0-9a-f]{1,4}){1,7}|:)) # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
288 )