@@ -46,21 +46,23 @@ contexts:
4646 - include : else-pop
4747
4848 statements :
49- - include : redirection
5049 - include : classes
51- - include : expressions
5250 - include : functions
5351 - include : workflows
5452 - include : desired-state-configurations
5553
56- - match : \B\.(?= )
57- scope : support.function.source.powershell
58-
5954 - include : exceptions
6055 - include : loops
6156 - include : flow
6257 - include : conditionals
6358
59+ - match : \B\.(?= )
60+ scope : support.function.source.powershell
61+ - match : \&
62+ scope : keyword.operator.call.powershell
63+
64+ - include : expressions
65+
6466 expressions :
6567 # Meta
6668 - include : labels
@@ -80,28 +82,43 @@ contexts:
8082 - include : hashtables
8183 - include : arrays
8284
85+ - include : data-blocks
86+ - include : script-blocks
87+ - include : groups
88+ - include : subexpressions
89+
90+ - include : future-reserved-words
91+
92+ - include : operators
8393 - include : commands
8494
95+ expressions-without-commands :
96+ # Meta
97+ - include : labels
98+ - include : regions
99+ - include : requires-directives
100+
101+ - include : escape-sequences
102+ - include : literal-after
103+
104+ # Normal code
105+ - include : types
106+ - include : strings
107+ - include : numbers
108+ - include : constants
109+ - include : variables
110+
111+ - include : hashtables
112+ - include : arrays
113+
85114 - include : data-blocks
86115 - include : script-blocks
87116 - include : groups
88117 - include : subexpressions
89118
90- # Consume a string with a trailing dot to prevent members with
91- # particular names from being recognized as keywords.
92- - match : \b[\w-]+(?=\.)
93- scope : variable.other.object.powershell
94- push : members
95-
96- # "Reserved for future use"
97- # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words
98- - match : \b(?i:define|from){{kebab_break}}
99- scope : keyword.control.powershell
100- - match : \b(?i:var){{kebab_break}}
101- scope : keyword.declaration.variable.powershell
119+ - include : future-reserved-words
102120
103121 - include : operators
104- - include : parameters
105122
106123 literal-after :
107124 - match : \B--%\B
@@ -111,6 +128,13 @@ contexts:
111128 - meta_content_scope : string.unquoted.powershell
112129 - include : pop-before-eol
113130
131+ future-reserved-words :
132+ # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words
133+ - match : \b(?i:define|from){{kebab_break}}
134+ scope : keyword.control.powershell
135+ - match : \b(?i:var){{kebab_break}}
136+ scope : keyword.declaration.variable.powershell
137+
114138# ##[ EXCEPTIONS ]##############################################################
115139
116140 exceptions :
@@ -158,6 +182,7 @@ contexts:
158182 scope : keyword.control.conditional.else.powershell
159183 - match : \b(?i:switch){{kebab_break}}
160184 scope : keyword.control.conditional.switch.powershell
185+ push : in-command
161186 - match : \b(?i:default){{kebab_break}}
162187 scope : keyword.control.conditional.default.powershell
163188 - match : \b(?i:where(?!-object)){{kebab_break}}
@@ -186,7 +211,7 @@ contexts:
186211 captures :
187212 1 : keyword.other.array.begin.powershell
188213 2 : punctuation.section.group.begin.powershell
189- push : inside-array
214+ push : [members, inside-array]
190215
191216 inside-array :
192217 - meta_scope : meta.group.array-expression.powershell
@@ -200,7 +225,7 @@ contexts:
200225 captures :
201226 1 : keyword.other.hashtable.begin.powershell
202227 2 : punctuation.section.braces.begin.powershell
203- push : inside-hashtable
228+ push : [members, inside-hashtable]
204229
205230 inside-hashtable :
206231 - meta_scope : meta.hashtable.powershell
@@ -244,13 +269,14 @@ contexts:
244269 captures :
245270 1 : keyword.control.loop.for.powershell
246271 2 : punctuation.section.braces.begin.powershell
247- push : inside-script-block
272+ push : [members, inside-script-block]
248273
249274 inside-script-block :
250275 - meta_scope : meta.block.powershell
251276 - match : \}
252277 scope : punctuation.section.braces.end.powershell
253278 pop : 1
279+ - include : param-block
254280 - include : statements
255281
256282# ##[ COMMANDS ]################################################################
@@ -259,6 +285,7 @@ contexts:
259285 - include : commands-verb-noun
260286 - include : commands-reserved
261287 - include : script-invocation
288+ - include : command-freeform
262289
263290 commands-verb-noun :
264291 # The "Verb-Noun" pattern
@@ -270,17 +297,57 @@ contexts:
270297 (?:\.(?i:exe|cmd|bat|ps1))?\b # More path stuff
271298 )
272299 scope: meta.function-call.powershell support.function.powershell
300+ push: in-command
273301
274302 commands-reserved :
275303 # Builtin cmdlets with reserved verbs
276304 - match : \b(?i:(?:ForEach|Where|Sort|Tee)-Object)\b
277305 scope : meta.function-call.powershell support.function.powershell
306+ push : in-command
278307
279308 script-invocation :
280309 - match : \b(?i:[a-z]:)?[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b
281- scope : variable.function.powershell
310+ scope : meta.function-call.powershell variable.function.powershell
311+ push : in-command
312+
313+ command-freeform :
314+ - match : ' {{identifier_function}}'
315+ scope : meta.function-call.powershell variable.function.powershell
316+ push : in-command
317+
318+ in-command :
319+ # - meta_scope: region.pinkish
320+ - include : line-continuations
321+ - include : pop-eol
322+ - match : (?=[)}])
323+ pop : 1
324+ - match : ' ;'
325+ scope : punctuation.terminator.statement.powershell
326+ pop : 1
327+ - match : (\|)\s*\n
328+ captures :
329+ 1 : keyword.operator.logical.pipe.powershell
330+ push :
331+ - match : ^
332+ pop : 2
333+ - match : \|
334+ scope : keyword.operator.logical.pipe.powershell
335+ pop : 1
336+ - include : redirection
337+ - include : cli-parameters
338+ - include : expressions-without-commands
339+ - match : (?=\S)
340+ push :
341+ - meta_include_prototype : false
342+ - meta_scope : string.unquoted.powershell
343+ - match : (?=[\s#|>;,]|$)
344+ pop : 1
345+ - match : ' [\\/:.]'
346+ scope : punctuation.separator.powershell
347+ - include : escape-sequences
348+
282349
283- parameters :
350+ cli- parameters :
284351 # Flags/Options/Parameters
285352 - match : \B(--?|[/+])\p{L}(?:[\w-]*\w)?
286353 scope : variable.parameter.option.powershell
@@ -426,9 +493,7 @@ contexts:
426493 scope : punctuation.section.block.end.powershell
427494 pop : 2
428495
429- - match : \b(?i:(?:Dynamic)?Param){{kebab_break}}
430- scope : keyword.declaration.parameter.powershell # This scope is not standard
431- push : expect-param-context
496+ - include : param-block
432497
433498 - match : \b(?i:Begin|Process|End|Clean){{kebab_break}}
434499 scope : keyword.context.block.powershell
@@ -438,6 +503,11 @@ contexts:
438503 - include : workflow-execution-contexts
439504 - include : statements
440505
506+ param-block :
507+ - match : \b(?i:(?:Dynamic)?Param){{kebab_break}}
508+ scope : keyword.declaration.parameter.powershell # This scope is not standard
509+ push : expect-param-context
510+
441511 expect-function-context :
442512 - meta_scope : meta.block.powershell
443513 - match : \{
@@ -647,9 +717,9 @@ contexts:
647717 members :
648718 - match : (?=\.\.)
649719 pop : 1
650- - match : \?\.(?={{identifier_simple}})
720+ - match : \?\.(?=\$? {{identifier_simple}})
651721 scope : punctuation.accessor.null-coalescing.powershell
652- - match : \??\.(?={{identifier_simple}})
722+ - match : \??\.(?=\$? {{identifier_simple}})
653723 scope : punctuation.accessor.dot.powershell
654724 - match : ::(?={{identifier_simple}})
655725 scope : punctuation.accessor.double-colon.powershell
@@ -785,10 +855,7 @@ contexts:
785855 scope : keyword.operator.ternary.powershell
786856 - match : ;
787857 scope : punctuation.terminator.statement.powershell
788- - match : \`(?=\n|$)
789- scope : punctuation.separator.continuation.line.powershell
790858 - include : comma-separators
791- # TODO: Distinguish call operator from background operator
792859 - match : ' &'
793860 scope : keyword.operator.background.powershell
794861 - match : \.\.(?=\-?\d|\(|\$)
@@ -1121,6 +1188,19 @@ contexts:
11211188
11221189# ##[ COMPONENTS ]##############################################################
11231190
1191+ line-continuations :
1192+ - match : (`)\n
1193+ captures :
1194+ 1 : punctuation.separator.continuation.line.powershell
1195+ push : line-continuation-body
1196+ - match : ' `(\s+)\n'
1197+ captures :
1198+ 1 : invalid.illegal.unexpected-whitespace.powershell
1199+
1200+ line-continuation-body :
1201+ - match : ^
1202+ pop : 1
1203+
11241204 comma-separators :
11251205 - match : ' ,'
11261206 scope : punctuation.separator.sequence.powershell
@@ -1132,7 +1212,7 @@ contexts:
11321212 scope : constant.character.escape.powershell
11331213
11341214 pop-eol :
1135- - match : $
1215+ - match : $\n?
11361216 pop : 1
11371217
11381218 pop-before-eol :
0 commit comments