Skip to content

Commit 755fdb5

Browse files
committed
Recognize first statement as a command
1 parent 361ad86 commit 755fdb5

File tree

4 files changed

+726
-249
lines changed

4 files changed

+726
-249
lines changed

PowerShell.sublime-syntax

Lines changed: 105 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ contexts:
4646
- include: else-pop
4747

4848
statements:
49-
- include: redirection
5049
- include: classes
5150
- include: functions
5251
- include: workflows
@@ -83,28 +82,43 @@ contexts:
8382
- include: hashtables
8483
- include: arrays
8584

85+
- include: data-blocks
86+
- include: script-blocks
87+
- include: groups
88+
- include: subexpressions
89+
90+
- include: future-reserved-words
91+
92+
- include: operators
8693
- include: commands
8794

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+
88114
- include: data-blocks
89115
- include: script-blocks
90116
- include: groups
91117
- include: subexpressions
92118

93-
# Consume a string with a trailing dot to prevent members with
94-
# particular names from being recognized as keywords.
95-
- match: \b[\w-]+(?=\.)
96-
scope: variable.other.object.powershell
97-
push: members
98-
99-
# "Reserved for future use"
100-
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words
101-
- match: \b(?i:define|from){{kebab_break}}
102-
scope: keyword.control.powershell
103-
- match: \b(?i:var){{kebab_break}}
104-
scope: keyword.declaration.variable.powershell
119+
- include: future-reserved-words
105120

106121
- include: operators
107-
- include: parameters
108122

109123
literal-after:
110124
- match: \B--%\B
@@ -114,6 +128,13 @@ contexts:
114128
- meta_content_scope: string.unquoted.powershell
115129
- include: pop-before-eol
116130

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+
117138
###[ EXCEPTIONS ]##############################################################
118139

119140
exceptions:
@@ -161,6 +182,7 @@ contexts:
161182
scope: keyword.control.conditional.else.powershell
162183
- match: \b(?i:switch){{kebab_break}}
163184
scope: keyword.control.conditional.switch.powershell
185+
push: in-command
164186
- match: \b(?i:default){{kebab_break}}
165187
scope: keyword.control.conditional.default.powershell
166188
- match: \b(?i:where(?!-object)){{kebab_break}}
@@ -189,7 +211,7 @@ contexts:
189211
captures:
190212
1: keyword.other.array.begin.powershell
191213
2: punctuation.section.group.begin.powershell
192-
push: inside-array
214+
push: [members, inside-array]
193215

194216
inside-array:
195217
- meta_scope: meta.group.array-expression.powershell
@@ -203,7 +225,7 @@ contexts:
203225
captures:
204226
1: keyword.other.hashtable.begin.powershell
205227
2: punctuation.section.braces.begin.powershell
206-
push: inside-hashtable
228+
push: [members, inside-hashtable]
207229

208230
inside-hashtable:
209231
- meta_scope: meta.hashtable.powershell
@@ -247,13 +269,14 @@ contexts:
247269
captures:
248270
1: keyword.control.loop.for.powershell
249271
2: punctuation.section.braces.begin.powershell
250-
push: inside-script-block
272+
push: [members, inside-script-block]
251273

252274
inside-script-block:
253275
- meta_scope: meta.block.powershell
254276
- match: \}
255277
scope: punctuation.section.braces.end.powershell
256278
pop: 1
279+
- include: param-block
257280
- include: statements
258281

259282
###[ COMMANDS ]################################################################
@@ -262,6 +285,7 @@ contexts:
262285
- include: commands-verb-noun
263286
- include: commands-reserved
264287
- include: script-invocation
288+
- include: command-freeform
265289

266290
commands-verb-noun:
267291
# The "Verb-Noun" pattern
@@ -273,17 +297,57 @@ contexts:
273297
(?:\.(?i:exe|cmd|bat|ps1))?\b # More path stuff
274298
)
275299
scope: meta.function-call.powershell support.function.powershell
300+
push: in-command
276301
277302
commands-reserved:
278303
# Builtin cmdlets with reserved verbs
279304
- match: \b(?i:(?:ForEach|Where|Sort|Tee)-Object)\b
280305
scope: meta.function-call.powershell support.function.powershell
306+
push: in-command
281307

282308
script-invocation:
283309
- match: \b(?i:[a-z]:)?[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b
284-
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
285317

286-
parameters:
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+
349+
350+
cli-parameters:
287351
# Flags/Options/Parameters
288352
- match: \B(--?|[/+])\p{L}(?:[\w-]*\w)?
289353
scope: variable.parameter.option.powershell
@@ -429,9 +493,7 @@ contexts:
429493
scope: punctuation.section.block.end.powershell
430494
pop: 2
431495

432-
- match: \b(?i:(?:Dynamic)?Param){{kebab_break}}
433-
scope: keyword.declaration.parameter.powershell # This scope is not standard
434-
push: expect-param-context
496+
- include: param-block
435497

436498
- match: \b(?i:Begin|Process|End|Clean){{kebab_break}}
437499
scope: keyword.context.block.powershell
@@ -441,6 +503,11 @@ contexts:
441503
- include: workflow-execution-contexts
442504
- include: statements
443505

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+
444511
expect-function-context:
445512
- meta_scope: meta.block.powershell
446513
- match: \{
@@ -650,9 +717,9 @@ contexts:
650717
members:
651718
- match: (?=\.\.)
652719
pop: 1
653-
- match: \?\.(?={{identifier_simple}})
720+
- match: \?\.(?=\$?{{identifier_simple}})
654721
scope: punctuation.accessor.null-coalescing.powershell
655-
- match: \??\.(?={{identifier_simple}})
722+
- match: \??\.(?=\$?{{identifier_simple}})
656723
scope: punctuation.accessor.dot.powershell
657724
- match: ::(?={{identifier_simple}})
658725
scope: punctuation.accessor.double-colon.powershell
@@ -788,10 +855,7 @@ contexts:
788855
scope: keyword.operator.ternary.powershell
789856
- match: ;
790857
scope: punctuation.terminator.statement.powershell
791-
- match: \`(?=\n|$)
792-
scope: punctuation.separator.continuation.line.powershell
793858
- include: comma-separators
794-
# TODO: Distinguish call operator from background operator
795859
- match: '&'
796860
scope: keyword.operator.background.powershell
797861
- match: \.\.(?=\-?\d|\(|\$)
@@ -1124,6 +1188,19 @@ contexts:
11241188

11251189
###[ COMPONENTS ]##############################################################
11261190

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+
11271204
comma-separators:
11281205
- match: ','
11291206
scope: punctuation.separator.sequence.powershell
@@ -1135,7 +1212,7 @@ contexts:
11351212
scope: constant.character.escape.powershell
11361213

11371214
pop-eol:
1138-
- match: $
1215+
- match: $\n?
11391216
pop: 1
11401217

11411218
pop-before-eol:

Tests/syntax_test_Class.ps1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,15 @@ class BookList {
347347
$b.Author -eq $Book.Author -and
348348
$b.PublishDate -eq $Book.PublishDate
349349
}.GetNewClosure()
350+
#^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell
351+
#^^^^^^^^ meta.block.powershell
352+
# ^ punctuation.section.braces.end.powershell
353+
# ^ punctuation.accessor.dot.powershell
354+
# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell
355+
# @@@@@@@@@@@@@ reference
356+
# ^^ meta.function-call.arguments.powershell
357+
# ^ punctuation.section.arguments.begin.powershell
358+
# ^ punctuation.section.arguments.end.powershell
350359
if ([BookList]::Books.Find($FindPredicate)) {
351360
# @@@@ reference
352361
throw "Book '$Book' already in list"
@@ -397,6 +406,16 @@ class BookList {
397406
param($b)
398407
$b.$Property -eq $Value
399408
}.GetNewClosure())
409+
#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell meta.function-call.arguments.powershell
410+
#^^^^^^^^ meta.block.powershell
411+
# ^ punctuation.section.braces.end.powershell
412+
# ^ punctuation.accessor.dot.powershell
413+
# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell
414+
# @@@@@@@@@@@@@ reference
415+
# ^^ meta.function-call.arguments.powershell
416+
# ^ punctuation.section.arguments.begin.powershell
417+
# ^ punctuation.section.arguments.end.powershell
418+
# ^ punctuation.section.arguments.end.powershell
400419
if ($Index -ge 0) {
401420
[BookList]::Books.RemoveAt($Index)
402421
# @@@@@@@@ reference

0 commit comments

Comments
 (0)