Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
80fb918
Reorder and rename many contexts
michaelblyons Dec 4, 2025
85fa6e2
Introduce a statements context
michaelblyons Dec 4, 2025
786aec3
Move comment-like contexts
michaelblyons Dec 4, 2025
c39407e
Tighten attributes context
michaelblyons Dec 4, 2025
6571fd3
Rearrange groups
michaelblyons Dec 4, 2025
d9616c7
Move classes to statements
michaelblyons Dec 4, 2025
e774fa2
Comment out special handling of emails in strings
michaelblyons Dec 4, 2025
967ebaf
Slot hashtables in among groups
michaelblyons Dec 4, 2025
1097d71
Require class stuff to at least be in a block
michaelblyons Dec 4, 2025
33f0aa4
Make a heading for operators
michaelblyons Dec 4, 2025
1240779
Switch to pop: 1
michaelblyons Dec 5, 2025
9ab0460
Move redirection to statements
michaelblyons Dec 5, 2025
2b743d1
Move the source function up to statements
michaelblyons Dec 5, 2025
14cfb9f
Move begin/process/end/clean to script blocks
michaelblyons Dec 5, 2025
9f928fc
Move attributes into groups and script blocks
michaelblyons Dec 5, 2025
c2274d2
Add some formatting
michaelblyons Dec 5, 2025
4ea88b4
Finish named contexts for string content
michaelblyons Dec 5, 2025
43f59db
Activate the prototype context
michaelblyons Dec 5, 2025
c81c02c
Extract string tests to their own file
michaelblyons Dec 5, 2025
b572a9b
Fully qualify the string test assertions
michaelblyons Dec 5, 2025
3c79c99
Test constants
michaelblyons Dec 5, 2025
a1b5619
Call & a "background" operator
michaelblyons Dec 5, 2025
3a05c40
Move ! to symbol operators
michaelblyons Dec 5, 2025
0ed6442
Improve type scopes
michaelblyons Dec 5, 2025
a2a7711
Refactor types
michaelblyons Dec 5, 2025
ea64e63
Extract variable name lists
michaelblyons Dec 5, 2025
76c79ef
Move the members context
michaelblyons Dec 5, 2025
cb44dd9
Extract approved verbs to a variable
michaelblyons Dec 5, 2025
22907c4
Sort function contexts
michaelblyons Dec 5, 2025
a1423b1
Add a dedicated using context
michaelblyons Dec 5, 2025
c35c6f0
Delete TODO for Atom
michaelblyons Dec 5, 2025
46cfcfd
Group commands contexts
michaelblyons Dec 5, 2025
d20ddfc
Add supplemental scopes to some documentation
michaelblyons Dec 5, 2025
6241786
Embed C# in Add-Type strings
michaelblyons Dec 5, 2025
23ec46b
Add context-sensitive functions
michaelblyons Dec 5, 2025
cf2f3c3
Add the PowerShell documentation Class samples
michaelblyons Dec 6, 2025
3f3a963
Improve variable matches
michaelblyons Dec 6, 2025
8b5394f
Allow member access of groups
michaelblyons Dec 6, 2025
d313f4b
Refactor variables
michaelblyons Dec 6, 2025
fa04735
Rename variables-without-members
michaelblyons Dec 6, 2025
ada344c
fixup
michaelblyons Dec 6, 2025
9038901
Add context-sensitive classes
michaelblyons Dec 7, 2025
9c8fbe7
Name the anonymous member contexts
michaelblyons Dec 7, 2025
98fa78d
Organize major syntax sections
michaelblyons Dec 7, 2025
be42068
Change C# context to use indicators
michaelblyons Dec 7, 2025
7daa98a
Add labels
michaelblyons Dec 7, 2025
7d179b3
Move some reserved words to a not-in-use section
michaelblyons Dec 7, 2025
e014fc7
Add data sections
michaelblyons Dec 7, 2025
881aae7
Restrict workflow execution contexts to functions
michaelblyons Dec 7, 2025
c5baa7a
Add null-aware operators and accessors
michaelblyons Dec 7, 2025
1c2adf9
Let script invocation start with a drive letter
michaelblyons Dec 7, 2025
cdacd44
Extract flow-like matches to named contexts
michaelblyons Dec 7, 2025
8b35b0b
Sort the last two reserved words
michaelblyons Dec 7, 2025
f5cbac6
Extract --% to a named context
michaelblyons Dec 7, 2025
8683958
Consolidate variable lookahead
michaelblyons Dec 7, 2025
3a8aae8
Tweak expression execution order
michaelblyons Dec 7, 2025
cba79c8
Move the ternary operator to its rightful place
michaelblyons Dec 7, 2025
2f3144f
Fix data section not popping
michaelblyons Dec 7, 2025
04f8b43
Fix functions not popping fast enough
michaelblyons Dec 7, 2025
915f845
Add naive string placeholder scopes
michaelblyons Dec 7, 2025
1347a55
Drop some unlikely string rules
michaelblyons Dec 8, 2025
649687a
Make straight and curly quotes equivalent
michaelblyons Dec 8, 2025
fa4de92
Extract C# identifiers to a variable
michaelblyons Dec 8, 2025
025c8f9
Add dedicated contexts for DSC
michaelblyons Dec 8, 2025
aec13fa
Add dedicated contexts for workflows
michaelblyons Dec 8, 2025
a9138a4
Use named contexts for group-likes
michaelblyons Dec 8, 2025
d56121f
Update hashtable scopes
michaelblyons Dec 8, 2025
82f5288
Rescope the source operator
michaelblyons Dec 8, 2025
361ad86
Rescope the variable scope colon
michaelblyons Dec 9, 2025
755fdb5
Recognize first statement as a command
michaelblyons Dec 8, 2025
72e580c
Extract command ending sequences to a context
michaelblyons Dec 8, 2025
a180490
Change command identifier for kicks
michaelblyons Dec 8, 2025
eadc61e
Mark scripts as functions after & or .
michaelblyons Dec 8, 2025
a4b0a2e
Stack function scopes over strings
michaelblyons Dec 8, 2025
6c3e17b
Test for background operator
michaelblyons Dec 8, 2025
9fe8439
Test string subexpression property access
michaelblyons Dec 8, 2025
f3090e7
Allow default value in function params
michaelblyons Dec 9, 2025
8e35b8e
Recognize wildcards in unquoted strings
michaelblyons Dec 9, 2025
7dc10a5
Scope command arguments
michaelblyons Dec 9, 2025
e62352f
Allow indented comments in line continuation
michaelblyons Dec 9, 2025
96cae36
Add naive regex in single-quoted strings
michaelblyons Dec 9, 2025
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
1,836 changes: 1,231 additions & 605 deletions PowerShell.sublime-syntax

Large diffs are not rendered by default.

518 changes: 429 additions & 89 deletions Tests/syntax_test_Class.ps1

Large diffs are not rendered by default.

116 changes: 116 additions & 0 deletions Tests/syntax_test_DSC.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax"

"<- Exit the imports context block"

Configuration MyDscConfiguration {
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^^^^^^^ keyword.declaration.function.powershell
# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell
# ^ punctuation.section.block.begin.powershell
Node "TEST-PC1" {
#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^ keyword.context.block.powershell
# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
# ^ punctuation.section.block.begin.powershell
WindowsFeature MyFeatureInstance {
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^^^^^^^^ keyword.other.powershell
# ^^^^^^^^^^^^^^^^^ entity.name.label.powershell
# ^ meta.block.powershell punctuation.section.braces.begin.powershell
Ensure = 'Present'
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.powershell
# ^ keyword.operator.assignment.powershell
# ^^^^^^^^^ meta.string.powershell string.quoted.single.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
Name = 'RSAT'
}
WindowsFeature My2ndFeatureInstance {
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^^^^^^^^ keyword.other.powershell
# ^^^^^^^^^^^^^^^^^^^^ entity.name.label.powershell
# ^ meta.block.powershell punctuation.section.braces.begin.powershell
Ensure = 'Present'
Name = 'Bitlocker'
}
#^^^^^^^^^^^^ meta.function.powershell meta.block.powershell
# ^ punctuation.section.braces.end.powershell
}
}
MyDscConfiguration


Configuration MyDscConfiguration
{
param
#^^^^^^^^^^^^ meta.function.powershell
# ^^^^^ keyword.declaration.parameter.powershell
(
[string[]]$ComputerName='localhost'
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^ storage.type.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^ punctuation.section.brackets.end.powershell
# ^^^^^^^^^^^^^ variable.other.readwrite.powershell
# ^ punctuation.definition.variable.powershell
# ^ keyword.operator.assignment.powershell
# ^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
)

Node $ComputerName
{
WindowsFeature MyFeatureInstance
{
Ensure = 'Present'
Name = 'RSAT'
}

WindowsFeature My2ndFeatureInstance
{
Ensure = 'Present'
Name = 'Bitlocker'
}
}
}
MyDscConfiguration


Configuration MyDscConfiguration
{
Node @('localhost', 'Server01')
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^ keyword.context.block.powershell
# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.array-expression.powershell
# ^ keyword.other.array.begin.powershell
# ^ punctuation.section.group.begin.powershell
# ^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
# ^ punctuation.separator.sequence.powershell
# ^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
# ^ punctuation.section.group.end.powershell
{
WindowsFeature MyFeatureInstance
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^^^^^^^^ keyword.other.powershell
# ^^^^^^^^^^^^^^^^^ entity.name.label.powershell
{
Ensure = 'Present'
Name = 'RSAT'
}

WindowsFeature My2ndFeatureInstance
{
Ensure = 'Present'
Name = 'Bitlocker'
}
}
}
MyDscConfiguration
147 changes: 99 additions & 48 deletions Tests/syntax_test_Function.ps1
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax"

using module Microsoft.Management
# <- keyword.control.using
# ^ keyword.other
# ^ variable.parameter
#^^^^ keyword.control.import.powershell
# ^^^^^^ keyword.control.import.powershell
# ^^^^^^^^^^^^^^^^^^^^ meta.path.powershell
# ^ punctuation.accessor.dot.powershell
# ^^^^^^^^^^ support.type.powershell

function Test-Path {}
# @@@@@@@@@ definition
Expand Down Expand Up @@ -49,16 +51,34 @@ function Test-Path {}
# <- punctuation.definition.keyword
# ^ keyword.other.documentation
The functionality that best describes this cmdlet
.ForwardHelpCategory Alias
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.powershell comment.documentation.embedded.powershell
# ^ punctuation.definition.keyword.documentation.powershell
# ^^^^^^^^^^^^^^^^^^^ keyword.other.documentation.powershell
# ^^^^^ support.type.powershell

.parameter foo
#^^^^^^^^^^^^^^^^^ comment.block.powershell comment.documentation.embedded.powershell
# ^ punctuation.definition.keyword.documentation.powershell
# ^^^^^^^^^ keyword.other.documentation.param.powershell
# ^^^ variable.parameter.powershell

.LINK https://example.com
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.powershell comment.documentation.embedded.powershell
# ^ punctuation.definition.keyword.documentation.powershell
# ^^^^ keyword.other.documentation.powershell
# ^^^^^^^^^^^^^^^^^^^ markup.underline.link.powershell

This should not be considered documentaton -> .role
# ^ - keyword.operator.documentation
#>
# <- punctuation.definition.comment.block.end
function Verb-Noun {
#^^^^^^^^^^^^^^^^^ meta.function
#^^^^^^^ storage.type
# ^^^^^^^^^ entity.name.function
#^^^^^^^^^^^^^^^^^^^ meta.function.powershell
#^^^^^^^ keyword.declaration.function.powershell
# ^^^^^^^^^ entity.name.function.powershell
# @@@@@@@@@ definition
# ^ punctuation.section.block.begin.powershell
[CmdletBinding(DefaultParameterSetName = 'Parameter Set 1',
# <- meta.attribute punctuation.section.brackets.begin
# ^ meta.attribute support.function.attribute
Expand Down Expand Up @@ -93,18 +113,22 @@ function Verb-Noun {
# ^ meta.attribute punctuation.section.group.end
# ^ meta.attribute punctuation.section.brackets.end
[OutputType([String])]
# <- meta.attribute punctuation.section.brackets.begin
# ^ meta.attribute support.function.attribute
# ^ meta.attribute punctuation.section.group.begin
# ^ meta.attribute punctuation.section.brackets.begin
# ^^^^^^ meta.attribute storage.type
# ^ meta.attribute punctuation.section.brackets.end
# ^ meta.attribute punctuation.section.group.end
# ^ meta.attribute punctuation.section.brackets.end
#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^^^^^ support.function.attribute.powershell
# ^ punctuation.section.group.begin.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^ support.type.powershell
# ^ punctuation.section.brackets.end.powershell
# ^ punctuation.section.group.end.powershell
# ^ punctuation.section.brackets.end.powershell
Param
#^^^^^ keyword.declaration.parameter
#^^^^^^^^ meta.function.powershell
# ^^^^^ keyword.declaration.parameter.powershell
(
# <- punctuation.section.group.begin
#^^^^ meta.function.powershell
# ^ punctuation.section.block.begin.powershell
# Param1 help description
# <- comment.line punctuation.definition.comment
# ^^^^^^^^^^^^^^^^^^^^^^^ comment.line
Expand Down Expand Up @@ -264,13 +288,15 @@ function Verb-Noun {
# ^ punctuation.section.group.end
# ^ punctuation.section.brackets.end
[int32]
# <- punctuation.section.brackets.begin
#^^^^^ storage.type
# ^ punctuation.section.brackets.end
#^^^^^^^^^^^^^^ meta.function.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^ storage.type.powershell
# ^ punctuation.section.brackets.end.powershell
$Param2,
# <- punctuation.definition.variable
# ^ variable.other.readwrite
# ^ punctuation.separator
#^^^^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^ variable.other.readwrite.powershell
# ^ punctuation.definition.variable.powershell
# ^ punctuation.separator.sequence.powershell

# Param3 help description
# <- comment.line punctuation.definition.comment
Expand Down Expand Up @@ -302,9 +328,10 @@ function Verb-Noun {
# ^ meta.attribute punctuation.section.group.end
# ^ meta.attribute punctuation.section.brackets.end
[String]
# <- punctuation.section.brackets.begin
#^^^^^^ storage.type
# ^ punctuation.section.brackets.end
#^^^^^^^^^^^^^^^ meta.function.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^ support.type.powershell
# ^ punctuation.section.brackets.end.powershell
$Param3,
# <- punctuation.definition.variable
#^^^^^^ variable.other.readwrite
Expand Down Expand Up @@ -335,9 +362,10 @@ function Verb-Noun {
# ^ meta.attribute punctuation.section.group.end
# ^ meta.attribute punctuation.section.brackets.end
[string]
# <- punctuation.section.brackets.begin
# ^ storage.type
# ^ punctuation.section.brackets.end
#^^^^^^^^^^^^^^^ meta.function.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^ storage.type.powershell
# ^ punctuation.section.brackets.end.powershell
$Param4,
# <- punctuation.definition.variable
# ^ variable.other.readwrite
Expand Down Expand Up @@ -365,38 +393,61 @@ function Verb-Noun {
# ^ comment.line punctuation.definition.comment
# ^ comment.line
[string]
# <- punctuation.section.brackets.begin
# ^ storage.type
# ^ punctuation.section.brackets.end
#^^^^^^^^^^^^^^^ meta.function.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^ storage.type.powershell
# ^ punctuation.section.brackets.end.powershell
$Param5
# <- punctuation.definition.variable
# ^ variable.other.readwrite
)
# <- punctuation.section.group.end
)
#^^^^ meta.function.powershell
# ^ punctuation.section.block.end.powershell

Begin
#^^^^^ keyword.context.block.begin
#^^^^^^^^ meta.function.powershell
# ^^^^^ keyword.context.block.powershell
{
#^^^^ meta.function.powershell
# ^ punctuation.section.block.begin.powershell
}
Process {
# <- keyword.context.block.process
#^^^^^^^^^^^^ meta.function.powershell
# ^^^^^^^ keyword.context.block.powershell
# ^ punctuation.section.block.begin.powershell
if ($pscmdlet.ShouldProcess("Target", "Operation")) {
# <- keyword.control
# ^ punctuation.section.group.begin
# ^ punctuation.definition.variable
# ^^^^^^^^ variable.language
# ^^^^^^^^^^^^^ variable.function
# @@@@@@@@@@@@@ reference
# ^ punctuation.section.arguments.begin
# ^^^^^^^^ string.quoted.double
# ^ punctuation.separator
# ^^^^^^^^^^^ string.quoted.double
# ^ punctuation.section.arguments.end
# ^ punctuation.section.group.end
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell
# ^^ keyword.control.conditional.if.powershell
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.powershell
# ^ punctuation.section.group.begin.powershell
# ^^^^^^^^^ variable.language.powershell
# ^ punctuation.definition.variable.powershell
# ^ punctuation.accessor.dot.powershell
# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell
# @@@@@@@@@@@@@ reference
# ^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell
# ^ punctuation.section.arguments.begin.powershell
# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
# ^ punctuation.separator.sequence.powershell
# ^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
# ^ punctuation.section.arguments.end.powershell
# ^ punctuation.section.group.end.powershell
# ^ meta.block.powershell punctuation.section.braces.begin.powershell
}
}
End {
#^^^ keyword.context.block.end
#^^^^^^^^ meta.function.powershell
# ^^^ keyword.context.block.powershell
# ^ punctuation.section.block.begin.powershell

}
clean { }
#^^^^^^^^^^^^ meta.function.powershell
# ^^^^^ keyword.context.block.powershell
# ^ punctuation.section.block.begin.powershell
# ^ punctuation.section.block.end.powershell
}
61 changes: 61 additions & 0 deletions Tests/syntax_test_Pester.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax"

BeforeAll {
# your function
function Get-Planet ([string]$Name='*')
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell meta.function.powershell
# ^^^^^^^^ keyword.declaration.function.powershell
# ^^^^^^^^^^ entity.name.function.powershell
# ^ punctuation.section.parameters.begin.powershell
# ^ punctuation.section.brackets.begin.powershell
# ^^^^^^ storage.type.powershell
# ^ punctuation.section.brackets.end.powershell
# ^^^^^ variable.parameter.powershell
# ^ punctuation.definition.variable.begin.powershell
# ^ keyword.operator.assignment.powershell
# ^^^ meta.string.powershell string.quoted.single.powershell
# ^ punctuation.definition.string.begin.powershell
# ^ punctuation.definition.string.end.powershell
# ^ punctuation.section.parameters.end.powershell
{
$planets = @(
@{ Name = 'Mercury' }
@{ Name = 'Venus' }
@{ Name = 'Earth' }
@{ Name = 'Mars' }
@{ Name = 'Jupiter' }
@{ Name = 'Saturn' }
@{ Name = 'Uranus' }
@{ Name = 'Neptune' }
) | foreach { [PSCustomObject]$_ }

$planets | where { $_.Name -like $Name }
}
}

# Pester tests
Describe 'Get-Planet' {
It "Given no parameters, it lists all 8 planets" {
$allPlanets = Get-Planet
$allPlanets.Count | Should -Be 8
}

Context "Filtering by Name" {
It "Given valid -Name '<Filter>', it returns '<Expected>'" -TestCases @(
@{ Filter = 'Earth'; Expected = 'Earth' }
@{ Filter = 'ne*' ; Expected = 'Neptune' }
@{ Filter = 'ur*' ; Expected = 'Uranus' }
@{ Filter = 'm*' ; Expected = 'Mercury', 'Mars' }
) {
param ($Filter, $Expected)

$planets = Get-Planet -Name $Filter
$planets.Name | Should -Be $Expected
}

It "Given invalid parameter -Name 'Alpha Centauri', it returns `$null" {
$planets = Get-Planet -Name 'Alpha Centauri'
$planets | Should -Be $null
}
}
}
Loading