From dd1791b2182c547df85d22702b0c9bda232b8463 Mon Sep 17 00:00:00 2001 From: msftrncs Date: Tue, 15 Oct 2019 21:33:51 -0500 Subject: [PATCH] Squash to a single commit, See https://github.com/msftrncs/PowerShell.tmLanguage/blob/argumentmode_2ndtry/powershell.tmLanguage.json for details. --- PowerShellSyntax.tmLanguage | 7655 ++++++++++++++++++++++++++++++----- 1 file changed, 6692 insertions(+), 963 deletions(-) diff --git a/PowerShellSyntax.tmLanguage b/PowerShellSyntax.tmLanguage index 60dd69d..1f8bfa7 100644 --- a/PowerShellSyntax.tmLanguage +++ b/PowerShellSyntax.tmLanguage @@ -13,197 +13,4356 @@ patterns + comment + type without accessor or attribute needed in statement mode, mostly for [flags()] before an `enum`. begin - <# - beginCaptures - - 0 - - name - punctuation.definition.comment.block.begin.powershell - - + (?=\[) end - #> - endCaptures - - 0 - - name - punctuation.definition.comment.block.end.powershell - - - name - comment.block.powershell + (?=[\n;)}\]]) patterns + + comment + if type advanced, test for attribute qualified keywords + begin + (?!\G)(?![\n;)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #advanceToToken + + + include + #attributeStatement + + + include + #expression_mode + + + include - #commentEmbeddedDocs + #type + + + comment + if not a type or attribute, try finishing in command mode + begin + (?![\n;)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #command_mode + + - - match - [2-6]>&1|>>|>|<<|<|>|>\||[1-6]>|[1-6]>> - name - keyword.operator.redirection.powershell - - - include - #commands - - - include - #commentLine - - - include - #variable - - - include - #interpolatedStringContent - - - include - #function - - - include - #attribute - - - include - #UsingDirective - - - include - #type - - - include - #hashtable - - - include - #doubleQuotedString - include - #scriptblock + #RequiresDirective comment - Needed to parse stuff correctly in 'argument mode'. (See about_parsing.) - include - #doubleQuotedStringEscapes - - + `;` resume's in statement mode. begin - (?<!')' + ; beginCaptures 0 name - punctuation.definition.string.begin.powershell + punctuation.terminator.statement.powershell end - '(?!') - endCaptures - - 0 - - name - punctuation.definition.string.end.powershell - - - name - string.quoted.single.powershell + (?=[\n;)}\]]) patterns - match - '' - name - constant.character.escape.powershell + comment + $self may have been combined with other includes, this will insure its just $self now + include + $self - begin - \@"(?=$) - end - ^"@ - name - string.quoted.double.heredoc.powershell + include + #statements + + + repository + + attributeStatement + patterns - include - #variableNoProperty - - - include - #doubleQuotedStringEscapes + begin + (?i:class)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.declaration.class.powershell + + + end + }|(?=\S) + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + applyEndPatternLast + + patterns + + + begin + [\p{L}_]\w*(?=[\s\[{(,;&|)}:#<>]|`\s) + beginCaptures + + 0 + + name + entity.name.type.class.powershell + + + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + : + beginCaptures + + 0 + + name + punctuation.separator.colon.powershell + + + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + (?!`)((?>[\p{L}_`][\w#`+]*)(?=[<>.,\s])(?:\.\g<1>?)?) + beginCaptures + + 0 + + patterns + + + include + #type_keywords + + + match + [^\.]+ + name + entity.other.inherited-class.powershell + + + match + \. + name + punctuation.accessor.type.powershell + + + + + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + , + beginCaptures + + 0 + + name + punctuation.separator.comma.powershell + + + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + (?!`)([\p{L}_`][\w#`+]*(?:\.#*\g<1>?)?) + beginCaptures + + 0 + + patterns + + + include + #type_keywords + + + match + [^\.]+ + name + entity.other.inherited-class.powershell + + + match + \. + name + punctuation.accessor.type.powershell + + + + + end + (?=\S) + applyEndPatternLast + + patterns + + + include + #notCode + + + + + include + #notCode + + + + + include + #notCode + + + + + include + #notCode + + + + + include + #notCode + + + + + begin + { + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + (?=}) + contentName + meta.class.powershell + patterns + + + match + ((?i:hidden|static))(?=[\s{(,;&|)}]) + name + storage.modifier.powershell + + + begin + (?=[\p{L}_]) + end + }|(?=[\S\n]) + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + applyEndPatternLast + + name + meta.method.powershell + patterns + + + match + `\n + name + constant.character.escape.powershell + + + begin + \G([\p{L}_]\w*) + beginCaptures + + 1 + + name + entity.name.function.powershell + + + end + (?=[\S\n]) + applyEndPatternLast + + patterns + + + begin + (?=\() + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + : + beginCaptures + + 0 + + name + punctuation.separator.colon.powershell + + + end + (?=[;{]) + patterns + + + begin + (?i:base)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + variable.language.super.powershell + + + end + (?=[;{]) + patterns + + + include + #declarationParameterSet + + + + + + + include + #declarationParameterSet + + + begin + { + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + (?=}) + contentName + meta.method-body.powershell + patterns + + + include + $self + + + + + include + #notCode + + + + + include + #notCode + + + + + include + #notCode + + + + + include + #variableNoProperty + + + include + #type + + + comment + default assignment for a property + begin + (?==) + end + (?!\G) + patterns + + + include + #expression_mode + + + + + include + #notCode + + + + + include + #notCode + + - include - #interpolation + begin + ((?i:enum))(?=[\s{(,;&|)}]) + beginCaptures + + 1 + + name + keyword.declaration.enum.powershell + + + end + }|(?=\S) + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + applyEndPatternLast + + patterns + + + begin + ([\p{L}_]\w*)(?=[\s\[{(,;&|)}:#<>]) + beginCaptures + + 1 + + name + entity.name.type.enum.powershell + + + end + (?=\S) + applyEndPatternLast + + patterns + + + comment + optional user specified type, PowerShell Core >= 6.2.0 + begin + : + beginCaptures + + 0 + + name + punctuation.separator.colon.powershell + + + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + (?!`)((?>[\p{L}_`][\w`+]*)(?=[.\s])(?:\.\g<1>?)?) + beginCaptures + + 0 + + patterns + + + include + #type_Disolve + + + + + end + (?=\S) + applyEndPatternLast + + patterns + + + include + #notCode + + + + + include + #notCode + + + + + include + #notCode + + + + + begin + { + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + (?=}) + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + contentName + meta.enumeration-definition.powershell + patterns + + + match + ; + name + punctuation.terminator.assignment.enum-member.powershell + + + begin + ([\p{L}_]\w*) + beginCaptures + + 1 + + name + entity.name.variable.enum-member.powershell + + + end + (?=[#;&|}\n]) + patterns + + + begin + = + beginCaptures + + 0 + + name + keyword.operator.assignment.enum-member.powershell + + + end + (?=[#;&|}\n]) + patterns + + + comment + begin at the first token in the expression, to test for numeric and unary operators + begin + (?![\s#]|<#|`\n)(?![\n;&|)}\]]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + comment + allow for possibility that numeric value or unary operators match first, before resuming in expression mode + begin + (?!\G)(?![\n;&|)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #expression_mode + + + + + include + #numericConstant + + + include + #operators_preUnary + + + comment + if neither numeric or a pre-unary operator, just finish in expression mode + begin + (?![\n;&|)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #expression_mode + + + + + + + include + #commentBlock + + + comment + normally provided by command mode, but thats not available here + match + `\n + name + constant.character.escape.powershell + + + + + include + #notCode + + + + + comment + `,`, `&` and `|` not permitted here + match + [,&|] + name + invalid.source.powershell + + + include + #notCode + + + + + include + #notCode + + + statements - begin - \@'(?=$) - end - ^'@ - name - string.quoted.single.heredoc.powershell patterns - match - '' - name - constant.character.escape.powershell - - - - - include - #numericConstant - - - begin - (@)(\() - beginCaptures - - 1 - - name - keyword.other.array.begin.powershell + include + #attributeStatement - 2 - name - punctuation.section.group.begin.powershell - - - end - \) - endCaptures + begin + (?i:function|filter|workflow)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.declaration.$0.powershell + + + end + }|(?=\S) + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + applyEndPatternLast + + patterns + + + begin + (?:(global|local|script|private)(`)?(:)(?=[^\s{(,;&)}])|(?=[^`'"\x{2018}-\x{201E}\s{(,;&)}<>$@#]|`(?!\s))) + beginCaptures + + 1 + + name + storage.modifier.scope.powershell + + 2 + + name + invalid.character.escape.powershell + + 3 + + name + punctuation.separator.colon.powershell + + + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + \G + end + (?=[\s{(,;&)}])|\G] + name + entity.name.function.powershell + patterns + + + comment + function names that start with `:` are treated differently + match + \G(?<!:):\p{L}\w*[^\s{(,;&)}]? + + + include + #functionName + + + + + begin + (?!\G)(?!}) + end + (?=\S) + applyEndPatternLast + + patterns + + + begin + { + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + (?=}) + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + contentName + meta.function-body.powershell + patterns + + + include + $self + + + + + include + #declarationParameterSet + + + include + #notCode + + + + + + + include + #notCode + + + + + comment + do,for,foreach,switch,while: allow a `:label` that must start the statement; A `:label` before a loop looks just like a function, and its possible to put the loop keyword on a later line! Here we just see if a valid label appears to be the only useful thing on a single line + match + (?>(:)([\p{L}_]\w*)(?=[\s{(,;&|)}]))(?=(?>(?:`\s|\s*<#.*?#>)*)\s*(?:(?i:do|for(?:each)?|switch|while)(?=[\s{(,;&|)}])|#|<#.*$|`?$)) + captures + + 1 + + name + punctuation.definition.label.powershell + + 2 + + name + entity.name.label.powershell + + 3 + + patterns + + + include + #commentBlock + + + + + + + comment + break,continue: permit a label following, then revert back to statement mode + begin + (?i:break|continue)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.$0.powershell + + + end + [\p{L}_]\w*|(?=$\n|\S) + endCaptures + + 0 + + name + entity.name.label.powershell + + + applyEndPatternLast + + patterns + + + include + #commentBlock + + + + + begin + (?i:exit|return|throw)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.$0.powershell + + + end + (?=[\n;)}\]]) + patterns + + + include + #command_mode + + + + + begin + (?i:foreach)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.foreach.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + (?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + name + meta.foreach-set.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + patterns + + + begin + (?i:in) + beginCaptures + + 0 + + name + keyword.control.foreach-in.powershell + + + end + (?=[;)]) + patterns + + + include + #command_mode + + + + + include + #variableNoProperty + + + include + #type + + + comment + `;` not permitted here + match + ; + name + invalid.terminator.statement.powershell + + + include + #notCode + + + + + begin + (?<=\))(?![,)}]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.foreach-loop.powershell + patterns + + + include + $self + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<![})])(?=[\n,})\]]) + patterns + + + include + $self + + + + + + + + + + + comment + only allow foreach arguments before the `(` + begin + \G(?=[\s#\x{2013}-\x{2015}-]|<#) + end + (?![\s#\x{2013}-\x{2015}-]|<#) + patterns + + + comment + -parallel parameter can only be used in a workflow, consider using meta scopes, and an injection to properly catch this + match + (?i:([\x{2013}-\x{2015}-])parallel)(?:(:)|(?=[\s\[{(,;&|)}])) + beginCaptures + + 1 + + name + entity.name.parameter.foreach-parallel.powershell + + 2 + + name + punctuation.definition.parameter.powershell + + 3 + + name + punctuation.separator.parameter-value.powershell + + + + + include + #notCode + + + + + comment + `,`, `<` and `>` not permitted here + match + [,<>] + name + invalid.source.powershell + + + include + #notCode + + + + + begin + (?i:while)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.while.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<![)}])(?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + name + meta.while-condition.powershell + patterns + + + comment + `;` not permitted here + match + ; + name + invalid.source.powershell + + + include + #command_mode + + + + + begin + (?<=\))(?=[\s#]|<#|`\s|{) + end + (?<=})|$(?!\G) + patterns + + + include + #advanceToToken + + + begin + (?<!})(?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.while-loop.powershell + patterns + + + include + $self + + + + + + + include + #notCode + + + + + + + + + begin + (?i:for)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.for.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<![})])(?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + name + meta.for-condition.powershell + patterns + + + comment + `;` here resumes in command mode + match + ; + name + punctuation.terminator.statement.powershell + + + include + #command_mode + + + + + begin + (?<=\))(?![,)}]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<!})(?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.for-loop.powershell + patterns + + + include + $self + + + + + + + include + #notCode + + + + + + + + + comment + until/while (condition) ends do {statements} + begin + (?i:do)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.do.powershell + + + end + (?<=\))|$(?!\G) + patterns + + + include + #advanceToToken + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.do-loop.powershell + patterns + + + include + $self + + + + + begin + (?<=})(?![,;&|)}]) + beginCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + end + (?<=\))|$(?!\G) + patterns + + + include + #advanceToToken + + + begin + (?i:while)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.do-while.powershell + + + end + (?<=\))|$(?!\G) + patterns + + + include + #advanceToToken + + + begin + (?<!\))(?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + name + meta.while-condition.powershell + patterns + + + comment + `;` not permitted here + match + ; + name + invalid.source.powershell + + + include + #command_mode + + + + + + + include + #notCode + + + + + begin + (?i:until)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.do-until.powershell + + + end + (?<=\))|$(?!\G) + patterns + + + include + #advanceToToken + + + begin + (?<!\))(?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + name + meta.until-condition.powershell + patterns + + + comment + `;` not permitted here + match + ; + name + invalid.source.powershell + + + include + #command_mode + + + + + + + include + #notCode + + + + + include + #notCode + + + + + + + include + #notCode + + + + + comment + else,elseif: only after if,elseif + begin + (?i)(?=if[\s{(,;&|)}]) + end + (?!\G) + applyEndPatternLast + + patterns + + + include + #ifStatement + + + begin + (?i:else)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.if-else.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<!}){ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.if-else-condition.powershell + patterns + + + include + $self + + + + + begin + (?<=})(?![;)}\]\n]) + end + (?=[;)}\]\n]) + patterns + + + include + $self + + + + + + + + + begin + (?i:switch)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.switch.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + (?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G + contentName + meta.switch-value.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + patterns + + + comment + `;` not permitted here + match + ; + name + invalid.source.powershell + + + include + #command_mode + + + + + begin + (?<=\))(?![,)}]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + include + #switchConditions + + + include + #notCode + + + comment + very limited what is permitted here + ignore + [^\s{] + name + invalid.source.powershell + + + + + + + + + include + #switchConditions + + + comment + only allow switch arguments before the `(` or `{` + begin + \G(?=[\s#\x{2013}-\x{2015}-]|<#) + end + (?![\s#\x{2013}-\x{2015}-]|<#) + patterns + + + match + ((?i:([\x{2013}-\x{2015}-])(regex|wildcard|exact|casesensitive)))(?:(:)|(?=[\s\[{(,;&|)}])) + captures + + 1 + + name + entity.name.parameter.switch-$2.powershell + + 3 + + name + punctuation.definition.parameter.powershell + + 4 + + name + punctuation.separator.parameter-value.powershell + + + + + comment + -file is special case, needs file argument, no condition expression + begin + ((?i:([\x{2013}-\x{2015}-])file))(?:(:)|(?=[\s\[{(,;&|)}])) + beginCaptures + + 1 + + name + entity.name.parameter.switch-file.powershell + + 2 + + name + punctuation.definition.parameter.powershell + + 3 + + name + punctuation.separator.parameter-value.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G(?![,;&|)}<>]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<=[\s>]|\G|^)(?![\s#,;&|)}<>]|<#|$) + end + (?!\G) + name + meta.argument.switch-file.powershell + patterns + + + include + #argument + + + + + + + + + include + #notCode + + + + + comment + `,`, `<` and `>` not permitted here + match + [,<>] + name + invalid.source.powershell + + + include + #notCode + + + + + begin + (?i:trap)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.trap.powershell + + + end + (?=\S|$) + applyEndPatternLast + + patterns + + + comment + only one [exception] argument before the `{` + begin + \G(?=[\s#\[]|<#) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?=\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + (?<=])(?![,)}]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.trap.powershell + patterns + + + include + $self + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<![}\]])(?=[\n,})\]]) + patterns + + + include + $self + + + + + + + comment + `,`, `<` and `>` not permitted here + match + [,\(\[\]<>] + name + invalid.source.powershell + + + + + include + #type + + + + + ignore + #notCode + + + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.trap.powershell + patterns + + + include + $self + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<![}\]])(?=[\n,})\]]) + patterns + + + include + $self + + + + + + + comment + `,`, `<` and `>` not permitted here + match + [,\(\[\]<>] + name + invalid.source.powershell + + + include + #notCode + + + + + comment + catch/finally only after try + begin + (?i:try)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.try.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.try.powershell + patterns + + + include + $self + + + + + begin + (?<=})(?![,;&|)}]) + beginCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #catchClause + + + + + + + include + #notCode + + + + + comment + data: parameter `-supportedCommand` is array of cmdlets (function names) + begin + (?i:data)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.$0.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + comment + only allow data parameters before the `{` + begin + \G(?=[\s#\x{2013}-\x{2015}-]|<#) + end + (?![\s#\x{2013}-\x{2015}-]|<#) + patterns + + + comment + -supportedcommand is special case, array of arguments + begin + ((?i:([\x{2013}-\x{2015}-])supportedcommand))(?:(:)|(?=[\s\[{(,;&|)}])) + beginCaptures + + 1 + + name + entity.name.parameter.data-supportedcommand.powershell + + 2 + + name + punctuation.definition.parameter.powershell + + 3 + + name + punctuation.separator.parameter-value.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + match + , + name + punctuation.separator.powershell + + + begin + (?:\G|(?<=,))(?![;&|)}<>]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<=[\s>]|\G|^)(?![\s#,;&|)}<>]|<#|$) + end + (?!\G) + name + meta.argument.data-supportedcommand.powershell + patterns + + + include + #argument + + + + + + + + + include + #notCode + + + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.data-section.powershell + patterns + + + include + $self + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<!})(?=[\n,})\]]) + patterns + + + include + $self + + + + + comment + very limited what is permitted here + ignore + [^\s{}] + name + invalid.source.powershell + + + + + comment + `,`, `<` and `>` not permitted here + match + [,\[\]<>] + name + invalid.source.powershell + + + include + #notCode + + + + + comment + inlinescript,parallel,sequence: only in workflow; + begin + (?i:begin|dispose|dynamicparam|end|inlinescript|parallel|process|sequence)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.$0.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statement-block.powershell + patterns + + + include + $self + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<!})(?=[\n,})\]]) + patterns + + + include + $self + + + + + comment + very limited what is permitted here + ignore + [^\s{}] + name + invalid.source.powershell + + + + + comment + `,`, `<` and `>` not permitted here + match + [,\[\]<>] + name + invalid.source.powershell + + + include + #notCode + + + + + comment + the argument is permitted to be quoted; TODO + match + (?i:(using))\s+(?i:(assembly|namespace|module))\s+((?>[\p{L}_][\w#]*(?:\.#*)?)+(?=[<>.,+\s\[\]])) + captures + + 1 + + name + keyword.control.using.powershell + + 2 + + name + keyword.other.powershell + + 3 + + patterns + + + include + #type_Disolve + + + + + + + comment + from,var,define are reserved; configuration is TODO, needs significant syntax structure work. + match + (?i:configuration|define|from|var)(?=[\s{(,;&|)}]) + name + invalid.reserved.keyword.control.$0.powershell + + + comment + param: only in main body or a function main body, and only if followed by parameter declaration + match + (?i:param)(?=[\s{(,;&|)}]) + name + keyword.control.$0.powershell + + + include + #command_mode + + + + command_mode + + patterns + + + include + #terminators + + + comment + (dot) source operator, requires trailing space, or invoke operator + begin + &|\.(?=[\s{(,;&|)}'"\x{2018}-\x{201E}$@]) + beginCaptures + + 0 + + name + keyword.operator.invoke-or-source.powershell + + + end + (?=[\n;)}\]]) + patterns + + + comment + Next token needs to be an operand for the operator, not the actual command, but an expression or unquoted expandable string that describes the command's name. + begin + \G(?![,;&|)}<>])|\G(?=<|[1-6]>&[12]|\*>&1|[1-6*]?>>?) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + comment + at the begining of a command name, `<`, `>` or `>>` are the entire command name. + match + (?:<|[1-6]>&[12]|\*>&1|[1-6*]?>>?) + name + entity.name.function.powershell + + + begin + (?<=[\s>]|\G|^)(?![\s#,;&|)}<>]|<#|$) + end + (?!\G) + name + meta.argument.invoke-or-source.powershell + patterns + + + include + #argument + + + + + + + comment + Next token needs to be an operand for the operator, not the actual command, but an expression or unquoted expandable string that describes the command's name. + begin + (?![\n;)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #argument_mode + + + + + + + comment + could be a numeric constant or a limited list of unary operators, that we should switch to expression mode + begin + (?=[.,!+\x{2013}-\x{2015}-]|\d(?!>&[12])) + end + (?=[\n;)}\]]) + patterns + + + comment + if unary operators/numeric constant advanced, switch to expression mode + begin + (?!\G)(?![\n;)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #expression_mode + + + + + include + #numericConstant + + + include + #operators_preUnary + + + comment + if neither numeric or a pre-unary operator, try finishing command mode with a command name + begin + (?![\n;)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #command_name + + + + + + + comment + patterns that indicate an expression, might be able to simplify this to include expression_mode and then see if the cursor advanced, sorta, don't forget about 'notCode', maybe check operand/operator only first, as redirect could also be a problem. + begin + (?=[$@][{(\w:$^?]|[({\[,]|@?['"\x{2018}-\x{201E}]|[\x{2013}-\x{2015}-][\s{(,;|)}#<>.!+%*/='"\x{2018}-\x{201E}\x{2013}-\x{2015}-]) + end + (?=[\n;)}\]]) + patterns + + + include + #expression_mode + + + + + match + `\n + name + constant.character.escape.powershell + + + match + `\s + name + invalid.character.escape.powershell + + + match + \| + name + invalid.empty-pipe.powershell + + + include + #command_name + + + comment + catch that which didn't match elsewhere + match + [^\s] + name + invalid.source.powershell + + + + command_name + + patterns + + + include + #commentBlock + + + include + #commentLine + + + include + #commands + + + comment + command names are allowed to start with < or >, without a backtick, but `function` requires a backtick. See below! + begin + (?:(global|local|script|private)(`)?(:)(?![\s{(,;&|)}])|(?=[^`'"\x{2018}-\x{201E}\s{(,;&)}@#]|`(?!\s))) + beginCaptures + + 1 + + name + storage.modifier.scope.powershell + + 2 + + name + invalid.character.escape.powershell + + 3 + + name + punctuation.separator.colon.powershell + + + end + (?!\G) + applyEndPatternLast + + patterns + + + comment + at the begining of a command name, `]`, `<`, `>` or `>>` are the entire command name. + match + \G(?:]|<|\*>&1|\*?>>?|[1-6]>&[12]) + name + entity.name.function.powershell + + + begin + \G(?=[^\n{(,;&|)}]) + end + (?=[\s{(,;&|)}]) + name + entity.name.function.powershell + patterns + + + comment + function names that start with `:` are treated differently + match + \G(?<!:):\p{L}\w*[^\s{(,;&|)}]? + + + include + #functionName + + + + + begin + (?![\n;)}]) + end + (?=[\n;)}]) + patterns + + + include + #argument_mode + + + + + + + + argument + + patterns + + + include + #scriptblock + + + include + #expressionGroup + + + include + #hashtable + + + include + #array + + + include + #quotedStrings_Members + + + include + #numericConstant_argumentMode + + + comment + could be variable reference, if it doesn't have member reference, its the start of an unquoted expandable string + begin + (?=\$[{\w:$^?]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + comment + check out the first variable reference + begin + \G(?=\$) + end + (?!\G) + patterns + + + include + #variableNoProperty + + + + + comment + if a member access doesn't occur after variable, finish as an unquoted expandable string argument. + begin + (?![\s{(,;&|)}])(?!\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #unquotedArgument + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + comment + attempt another argument after member access + include + #argument + + + + + + + include + #substatement + + + comment + splatting cannot have members and certain characters following, including no line comment + match + (?>@(?:[$^?]|(?>[\w][\w?]*:(?!:)|:)?(?:[\w?]|:(?!:))+|:))(?![~`!@#$%^*<>\]\\/'"\x{2018}-\x{201E}+-]) + captures + + 0 + + patterns + + + include + #variable_inner + + + + + + + comment + splatting cannot have members and certain characters following, including no line comment + match + @(?![$^?:\w]) + name + invalid.splat.powershell + + + include + #unquotedArgument + + + + argument_mode + + patterns + + + include + #redirection + + + comment + `,` just continues current mode, after advancing to next token + begin + , + beginCaptures + + 0 + + name + punctuation.separator.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + + include + #commentBlock + + + include + #commentLine + + + begin + (?<!\w)(--%)(?!\w) + beginCaptures + + 1 + + name + keyword.control.verbatim-argument.powershell + + + end + $|(?=\|) + patterns + + + match + [^"\x{201C}-\x{201E}]+? + name + string.unquoted.verbatim-argument.powershell + + + begin + (?:["\x{201C}-\x{201E}]) + beginCaptures + + 0 + + name + punctuation.definition.string.begin.powershell + + + end + (?:["\x{201C}-\x{201E}])|$ + applyEndPatternLast + + endCaptures + + 0 + + name + punctuation.definition.string.end.powershell + + + name + string.quoted.double.powershell + + + + + match + (([\x{2013}-\x{2015}-])\p{L}[^:\s\[{(,;&|)}'"\x{2018}-\x{201E}]*)(?:(:)|(?=[\s\[{(,;&|)}])) + captures + + 1 + + name + entity.name.parameter.powershell + + 2 + + name + punctuation.definition.parameter.powershell + + 3 + + name + punctuation.separator.parameter-value.powershell + + + + + include + #argument + + + + unquotedArgument + + patterns + + + match + `(?!\n)\s + name + invalid.character.escape.powershell + + + match + \.(?=['"\x{2018}-\x{201E}\s{(,;&|)}$]) + name + string.unquoted.argument.powershell + + + begin + (?![\s{(,;&|)}]) + alternateBegin + (?=[^'"\x{2018}-\x{201E}\s\[{(,;&|)}$@])|(?<=\S)(?=[$@<>]) + end + (?=[\s{(,;&|)}]) + contentName + string.unquoted.argument.powershell + patterns + + + match + \G`[\x{2013}-\x{2015}-] + name + constant.character.escape.powershell + + + include + #unquotedStrings_text + + + + + + expression_mode + + comment + Keep in mind, before begining expression mode, check for prefixed unary operators, but check for numeric constants before that! This is done for each area that forwards to expression mode. + patterns + + + include + #redirection + + + comment + normally operands win matches first, but numeric constant and operators share common first characters, and their matching needs to be alternated such that after any operand matches, a check for operators should occur before a numeric value is checked for again. Operators needs to have first priority of a match after a numeric constant. + include + #operand + + + comment + Once an operator has matched, subsequently #operators_preunary should be checked first until the next non operator token is found. However, an operator might have matched before we've even gotten here (pre-unary) + include + #operators + + + match + `\n + name + constant.character.escape.powershell + + + ignore + ` + name + invalid.character.escape.powershell + + + include + #notCode + + + + operand + + patterns + + + comment + preunary operators are technically part of an operand expression + include + #operators_preUnary + + + include + #type + + + include + #variable + + + include + #expressionGroup + + + include + #hashtable + + + include + #scriptblock + + + include + #numericConstant + + + include + #array + + + include + #substatement + + + include + #quotedStrings_Members + + + + array + + begin + (?=@\() + end + (?!\G) + applyEndPatternLast + + patterns + + + begin + \G(@)(\() + beginCaptures + + 1 + + name + keyword.other.array.begin.powershell + + 2 + + name + punctuation.section.group.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + name + meta.group.array-expression.powershell + patterns + + + include + $self + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + + catchClause + + patterns + + + include + #advanceToToken + + + begin + (?i:catch)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.try-catch.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.try-catch.powershell + patterns + + + include + $self + + + + + begin + (?<=})(?![,)}]|$) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #catchClause + + + + + comment + very limited what is permitted here + ignore + [^\s{}] + name + invalid.source.powershell + + + + + comment + only [exception] arguments before the `{` + begin + \G(?=[\s#\[]|<#) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?=\[) + end + (?![\s#\[,]|<#) + patterns + + + match + , + name + punctuation.separator.powershell + + + include + #type + + + include + #notCode + + + + + include + #notCode + + + + + comment + `,`, `<` and `>` not permitted here + match + [,<>] + name + invalid.source.powershell + + + include + #notCode + + + + + begin + (?i:finally)(?=[\s{(,;&|)}]) + beginCaptures + + 0 + + name + keyword.control.try-finally.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.try-finally.powershell + patterns + + + include + $self + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<![}\]])(?=[\n,})\]]) + patterns + + + include + $self + + + + + comment + very limited what is permitted here + ignore + [^\s{}] + name + invalid.source.powershell + + + + + + + comment + next statement, return when safe to exit + begin + (?![,)}\]]|$) + end + (?<![}\]])(?=[\n,})\]]) + patterns + + + include + $self + + + + + + commentBlock + + begin + <# + beginCaptures + + 0 + + name + punctuation.definition.comment.block.begin.powershell + + + end + #> + endCaptures + + 0 + + name + punctuation.definition.comment.block.end.powershell + + + name + comment.block.powershell + patterns + + + comment + capture remainder of comment block, preventing #commentEmbeddedDocs from consuming to end of line + match + .+?(?=#>) + captures + + 0 + + patterns + + + comment + restore the anchor point + begin + (?=.) + end + $ + patterns + + + include + #commentEmbeddedDocs + + + + + + + + + include + #commentEmbeddedDocs + + + + commentLine + + begin + (#)#* + captures + + 1 + + name + punctuation.definition.comment.powershell + + + end + $(?=(\n)?) + endCaptures + + 1 + + name + comment.line.powershell + + + name + comment.line.powershell + patterns + + + include + #commentEmbeddedDocs + + + + argumentModeEscapes + + patterns + + + match + `[`0abefnrtv'"\x{2018}-\x{201E}$@{(,;&|)}#<>\n] + name + constant.character.escape.powershell + + + include + #unicodeEscape + + + match + ` + name + invalid.character.escape.powershell + + + + commands + + patterns + + + comment + Verb-Noun pattern: + begin + (?i:Add|Approve|Assert|Backup|Block|Build|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Deploy|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Mount|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Write)-(?:`.|[^\s{(,;&)}])+?(?:\.(?i:exe|cmd|bat|ps1))?(?=[\s{(,;&)}]) + beginCaptures + + 0 + + name + support.function.powershell + + + end + (?=[\n;)}\]]) + patterns + + + include + #argument_mode + + + + + comment + Builtin cmdlets with reserved verbs, trailing negative lookahead needs work + begin + (?i:(?:foreach|where|sort|tee)-object)(?=[\s{(,;&)}]) + beginCaptures + + 0 + + name + support.function.$0.powershell + + + end + (?=[\n;)}\]]) + patterns + + + include + #argument_mode + + + + + + commentEmbeddedDocs + + patterns + + + captures + + 1 + + name + constant.string.documentation.powershell + + 2 + + name + keyword.operator.documentation.powershell + + + match + (?:^|\G)(?i:\s*(\.)(COMPONENT|DESCRIPTION|EXAMPLE|FUNCTIONALITY|INPUTS|LINK|NOTES|OUTPUTS|ROLE|SYNOPSIS))(?:\s*$) + name + comment.documentation.embedded.powershell + + + captures + + 1 + + name + constant.string.documentation.powershell + + 2 + + name + keyword.operator.documentation.powershell + + 3 + + name + constant.character.documentation.powershell + + + match + (?:^|\G)(?i:\s*(\.)(EXTERNALHELP)\s+(.+)) + name + comment.documentation.embedded.powershell + + + captures + + 1 + + name + constant.string.documentation.powershell + + 2 + + name + keyword.operator.documentation.powershell + + 3 + + name + variable.other.documentation.powershell + + + match + (?:^|\G)(?i:\s*(\.)(REMOTEHELPRUNSPACE)\s+(.+)) + name + comment.documentation.embedded.powershell + + + captures + + 1 + + name + constant.string.documentation.powershell + + 2 + + name + keyword.operator.documentation.powershell + + 3 + + name + variable.other.property.documentation.powershell + + + match + (?:^|\G)(?i:\s*(\.)(FORWARDHELPCATEGORY)\s+(Alias|Cmdlet|HelpFile|Function|General|Provider|FAQ|Glossary|ScriptCommand|ExternalScript|Filter|All)\s*$) + name + comment.documentation.embedded.powershell + + + captures + + 1 + + name + constant.string.documentation.powershell + + 2 + + name + keyword.operator.documentation.powershell + + 3 + + name + entity.name.function.documentation.powershell + + + match + (?:^|\G)(?i:\s*(\.)(FORWARDHELPTARGETNAME)\s+(.+)) + name + comment.documentation.embedded.powershell + + + captures + + 1 + + name + constant.string.documentation.powershell + + 2 + + name + keyword.operator.documentation.powershell + + 3 + + name + entity.name.parameter.documentation.powershell + + + match + (?:^|\G)(?i:\s*(\.)(PARAMETER)\s+(.+)) + name + comment.documentation.embedded.powershell + + + + unicodeEscape + + comment + `u{x} added in PowerShell 6.0 (x=1-6 hex digits, value ranging 0-10FFFF) + patterns + + + match + `u\{(?:(?:10)\h{1,4}|0?\h{1,5})} + name + constant.character.escape.powershell + + + match + `u(?:\{\h{,6}.)? + name + invalid.character.escape.powershell + + + + doubleQuotedStringEscapes + + patterns + + + match + `[`0abefnrtv"\x{201C}-\x{201E}$] + name + constant.character.escape.powershell + + + include + #unicodeEscape + + + match + ` + name + invalid.character.escape.powershell + + + match + (?:["\x{201C}-\x{201E}]){2} + name + constant.character.escape.powershell + + + + doubleQuotedHereStringEscapes + + patterns + + + match + `[`0abefnrtv]|^`["\x{201C}-\x{201E}](?=@) + name + constant.character.escape.powershell + + + include + #unicodeEscape + + + match + ` + name + invalid.character.escape.powershell + + + + declarationParameterSet + + begin + \( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + name + meta.parameters.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + patterns + + + begin + = + beginCaptures + + 0 + + name + keyword.operator.assignment.parameter-default.powershell + + + end + (?=[,)])|(?=\n)(?!\G) + patterns + + + include + #advanceToToken + + + comment + begin at the first token in the expression, to test for numeric and unary operators + begin + (?![\n,;&|)}\]]) + end + (?=[\n,;&|)}\]]) + patterns + + + include + #expression_mode + + + + + + + match + , + name + punctuation.separator.comma.powershell + + + include + #variableNoProperty + + + include + #type + + + include + #notCode + + + + expressionGroup + + begin + (?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + name + meta.group.subexpression.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + patterns + + + include + #command_mode + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + + ifStatement + + comment + else,elseif: only after if,elseif + begin + \G(?i:(if)|(elseif))(?=[\s{(,;&|)}]) + beginCaptures + + 1 + + name + keyword.control.if.powershell + + 2 + + name + keyword.control.if-elseif.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<![)}])(?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.section.group.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + name + meta.if-condition.powershell + patterns + + + comment + `;` not permitted here + match + ; + name + invalid.source.powershell + + + include + #command_mode + + + + + begin + (?<=\))(?=[\s#]|<#|`\s|{) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<!})(?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\{ + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.statements.if-condition.powershell + patterns + + + include + $self + + + + + begin + (?<=})(?=[\s#]|<#|`\s) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?i)(?=elseif[\s{(,;&|)}]) + end + (?!\G) + patterns + + + include + #ifStatement + + + + + + + + + + + + + + substatement + + begin + (?=\$\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + (\$)(\() + beginCaptures + + 1 + + name + keyword.other.substatement.powershell + + 2 + + name + punctuation.section.group.begin.powershell + + + contentName + meta.group.substatement-expression.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell + + + patterns + + + include + $self + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + + substatementEmbedded + + begin + (\$)(\() + beginCaptures - 0 + 1 name - punctuation.section.group.end.powershell + keyword.other.substatement.powershell punctuation.section.embedded.begin.powershell + + 2 + + name + punctuation.section.group.begin.powershell punctuation.section.embedded.begin.powershell name - meta.group.array-expression.powershell + meta.embedded.substatement.powershell interpolated.complex.source.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.group.end.powershell punctuation.section.embedded.end.powershell + + patterns @@ -212,1354 +4371,2924 @@ + numericConstant + + patterns + + + begin + (?>(?i:[+\x{2013}-\x{2015}-]?(?:0(?:x\h+|b[01]+)|(?:\d+(?:\.(?!\.)\d*)?|\.\d+)(?:e[+\x{2013}-\x{2015}-]?\d+)?)(?:u?[lsy]|[dnu])?(?:[kmgtp]b)?))(?=[\s{(,;&|)}#\]<>.!+%*/=\x{2013}-\x{2015}-]) + beginCaptures + + 0 + + patterns + + + include + #numericConstant_capture + + + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #numeric_post + + + + + comment + capture negative invalid constant construct + name + invalid.numeric-constant.powershell + match + ([\x{2013}-\x{2015}-]\.(?i:(?:e[+\x{2013}-\x{2015}-]?\d+)?(?:[dlsyn]|u[lsy]?)?))((?i:[kmgtp]b))?(?=[\s{(,;&|)}#\]<>.!+%*/=\x{2013}-\x{2015}-]) + + + repository + + numeric_post + + patterns + + + begin + \G(?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + begin + \G(?=[\s.+\x{2013}-\x{2015}-]|<#|`\n)(?![\x{2013}-\x{2015}-]\p{L}|\n) + end + \.\.|\+\+?|[\x{2013}-\x{2015}-](?!\p{L})[\x{2013}-\x{2015}-]?|(?=\n)|(?![\s]|<#|`\n|$) + endCaptures + + 0 + + patterns + + + include + #operators + + + + + patterns + + + match + `\n + name + constant.character.escape.powershell + + + include + #commentBlock + + + + + + + + numericConstant_capture + + patterns + + + captures + + 1 + + name + constant.numeric.hex.powershell + + 2 + + name + storage.modifier.powershell + + 3 + + name + constant.language.powershell + + + match + ([+\x{2013}-\x{2015}-]?0(?i:x\h+(u?[lsy]|[nu])?))((?i:[kmgtp]b))?$ + + + captures + + 1 + + name + constant.numeric.binary.powershell + + 2 + + name + storage.modifier.powershell + + 3 + + name + constant.language.powershell + + + match + ([+\x{2013}-\x{2015}-]?0(?i:b[01]+(u?[lsy]|[dnu])?))((?i:[kmgtp]b))?$ + + + captures + + 1 + + name + constant.numeric.decimal.powershell + + 2 + + name + storage.modifier.decimal.powershell + + 5 + + name + constant.language.powershell + + + match + ([+\x{2013}-\x{2015}-]?(?i:\d+(?:(?:(d)|(?:(e[+\x{2013}-\x{2015}-]?\d+)\g<2>?))|\.\d*(\g<3>?\g<2>?))|\.\d+\g<4>))((?i:[kmgtp]b))?$ + + + captures + + 1 + + name + constant.numeric.integer.powershell + + 3 + + name + storage.modifier.powershell + + 4 + + name + constant.language.powershell + + + match + ([+\x{2013}-\x{2015}-]?(?:\d+(?i:(?:\.\d*)?((?:e[+\x{2013}-\x{2015}-]?\d+)?(u?[lsy]|[un])))?|(?:\.\d+)\g<2>))((?i:[kmgtp]b))?$ + + + + numericConstant_argumentMode + + match + (?>(?i:(?:0(?:x\h+|b[01]+)|(?:\d+(?:\.(?!\.)\d*)?|\.\d+)(?:e[+\x{2013}-\x{2015}-]?\d+)?)(?:u?[lsy]|[dnu])?(?:[kmgtp]b)?))(?=[\s{(,;&|)}]) + captures + + 0 + + patterns + + + include + #numericConstant_capture + + + + + + scriptblock + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + { + beginCaptures + + 0 + + name + punctuation.section.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.section.braces.end.powershell + + + name + meta.scriptblock.powershell + patterns + + + include + $self + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + + type + comment + This is used by both type and attribute references. begin - (\$)(\() - beginCaptures - - 1 - - name - punctuation.definition.variable.powershell - - 2 + (?=\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + begin + \G\[ + beginCaptures + + 0 + + name + punctuation.section.bracket.begin.powershell + + + end + ]|(?=\n) + endCaptures + + 0 + + name + punctuation.section.bracket.end.powershell + + + applyEndPatternLast + name - punctuation.section.group.begin.powershell + meta.attribute-or-type-reference.powershell + patterns + + + include + #advanceToToken + + + match + (?i)(?:(?:cmdletbinding|alias|flags|outputtype|parameter|validate(?:not(?:null(?:orempty)?)|count|set|script|range|pattern|length)|allow(?:null|empty(?:collection|string))|supportswildcards|dsc(?:resource|property)|psdefaultvalue)(?![.\w+`-])) + name + support.function.attribute.powershell + + + begin + (?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \G\( + beginCaptures + + 0 + + name + punctuation.group.attribute-argument-set.begin.powershell + + + end + \) + endCaptures + + 0 + + name + punctuation..group.attribute-argument-set.end.powershell + + + applyEndPatternLast + + name + meta.attribute-argument-set.powershell + patterns + + + include + #advanceToToken + + + begin + \b([\p{L}_]\w*) + beginCaptures + + 1 + + name + variable.parameter.attribute.powershell + + + end + (?=[\n,;&|)}\]]) + patterns + + + begin + = + beginCaptures + + 0 + + name + keyword.operator.assignment.attribute-argument.powershell + + + end + (?=[,;&|)}\]]) + patterns + + + include + #advanceToToken + + + comment + begin at the first token in the expression, to test for numeric and unary operators + begin + (?!$|[,;|)}\]]) + end + (?=$|[,;|)}\]]) + patterns + + + include + #expression_mode + + + + + include + #notCode + + + + + include + #notCode + + + + + comment + this makes `=` invalid without an argument name + match + = + name + invalid.source.powershell + + + comment + `,` just continues current mode, after advancing to next token + begin + , + beginCaptures + + 0 + + name + keyword.operator.attribute-argument-separator.comma.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + + comment + this gets expressions without argument names + include + #expression_mode + + + + + begin + (?<=\))(?![;&|)}\]]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + + + + include + #type_SubType + + - - comment - TODO: move to repo; make recursive. - end - \) - endCaptures - - 0 - name - punctuation.section.group.end.powershell + comment + index access is not permitted here + begin + (?=\.(?!\.)|::) + beginCaptures + + 0 + + name + punctuation.section.bracket.end.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + begin + (?!\G)(?![\n;)}\]]) + end + (?=[\n;)}\]]) + patterns + + + include + #expression_mode + + + + - - name - meta.group.complex.subexpression.powershell + + + type_Disolve + patterns include - $self + #type_keywords + + + match + [^\.+]+ + name + storage.type.powershell - - - - match - (\b(([A-Za-z0-9\-_\.]+)\.(?i:exe|com|cmd|bat))\b) - name - support.function.powershell - - - match - (?<!\w|-|\.)((?i:begin|break|catch|continue|data|default|define|do|dynamicparam|else|elseif|end|exit|finally|for|from|if|in|inlinescript|parallel|param|process|return|sequence|switch|throw|trap|try|until|var|while)|%|\?)(?!\w) - name - keyword.control.powershell - - - match - (?<!\w|-|[^\)]\.)((?i:(foreach|where)(?!-object))|%|\?)(?!\w) - name - keyword.control.powershell - - - begin - (?<!\w)(--%)(?!\w) - beginCaptures - - 1 + match + \. name - keyword.control.powershell + punctuation.accessor.type.powershell.powershell - - end - $ - patterns - match - .+ + \+ name - string.unquoted.powershell + keyword.operator.type.powershell - comment - This should be moved to the repository at some point. - - - comment - This should only be relevant inside a class but will require a rework of how classes are matched. This is a temp fix. - match - (?<!\w)((?i:hidden|static))(?!\w) - name - storage.modifier.powershell + type_SubType - captures - - 1 + patterns + + begin + (\[) + beginCaptures + + 0 + + name + punctuation.section.bracket.begin.powershell + + + end + (])|[^\s\p{L},] + endCaptures + + 0 + + name + punctuation.section.bracket.end.powershell + + + applyEndPatternLast + name - storage.type.powershell + meta.type-reference.powershell + patterns + + + include + #type_SubType + + + match + , + name + punctuation.separator.comma.powershell + + + match + [^\s\[\]+,]+ + name + invalid.character.powershell + + - 2 - name - entity.name.function + begin + (?!`)((?>[\p{L}_`][\w#`+]*)(?=[<>.,+\s(\[\]])(?:\.#*\g<1>?)?) + beginCaptures + + 0 + + patterns + + + include + #type_Disolve + + + + + end + (?=[^\s]|\n)|(?<=]) + applyEndPatternLast + + patterns + + + match + ((?i:Version|Culture|PublicKeyToken))(=)([^,\[\]]*) + captures + + 1 + + name + variable.parameter.attribute.powershell + + 2 + + name + keyword.operator.assignment.powershell + + 3 + + name + constant.character.powershell + + + name + invalid.character.powershell + + + include + #type_SubType + + + match + , + name + punctuation.separator.comma.powershell + + + match + (?<!])[^\s\[\]\(+,]+ + name + invalid.character.powershell + + - - comment - capture should be entity.name.type, but it doesn't provide a good color in the default schema. - match - (?<!\w|-)((?i:class)|%|\?)(?:\s)+((?:\p{L}|\d|_|-|)+)\b - - - match - (?<!\w)-(?i:is(?:not)?|as)\b - name - keyword.operator.comparison.powershell - - - match - (?<!\w)-(?i:[ic]?(?:eq|ne|[gl][te]|(?:not)?(?:like|match|contains|in)|replace))(?!\p{L}) - name - keyword.operator.comparison.powershell - - - match - (?<!\w)-(?i:join|split)(?!\p{L})|! - name - keyword.operator.unary.powershell - - - match - (?<!\w)-(?i:and|or|not|xor)(?!\p{L})|! - name - keyword.operator.logical.powershell - - - match - (?<!\w)-(?i:band|bor|bnot|bxor|shl|shr)(?!\p{L}) - name - keyword.operator.bitwise.powershell - - - match - (?<!\w)-(?i:f)(?!\p{L}) - name - keyword.operator.string-format.powershell - - - match - [+%*/-]?=|[+/*%-] - name - keyword.operator.assignment.powershell - - - match - \|{2}|&{2}|; - name - punctuation.terminator.statement.powershell + + include + #commentBlock + + + include + #commentLine + + + type_keywords - match - &|(?<!\w)\.(?= )|`|,|\| - name - keyword.operator.other.powershell + comment + primitive types and base classes often used + patterns + + + comment: + [short], [ushort], [uint], [ulong] added PowerShell Core 6.2; + match + (?<![.\w-])(?i:(?:value)?type|void|switch|(?:ps(?:custom)?)?object|pscredential|psmoduleinfo|hashtable|scriptblock|string|single|float|double|decimal|s?byte|bool(?:ean)?|char|datetime|array|bigint|u?int(?:32|16|64)?|u?long|u?short)(?![.\w#+`-]) + name + keyword.type.powershell + + + match + (?<![.\w-])(?i:system|math|text|convert|regex|xml|enum)(?![\w#-]) + name + support.class.powershell + + + match + (?<![.\w-])(?i:ordered)(?![.\w#+`\[-]) + name + support.function.attribute.powershell + + + match + (?<![.\w-])(?i:ref)(?![.\w#+`\[-]) + name + storage.modifier.powershell + + + advanceToArgument comment - This is very imprecise, is there a syntax for 'must come after...' - match - (?<!\s|^)\.\.(?=\-?\d|\(|\$) - name - keyword.operator.range.powershell + consume spaces and comments (but not unescaped line ends) until the next token appears + begin + \G(?=[\s]|<#|`\s) + end + (?!\s)(?!$)|(?=\n) + applyEndPatternLast + + patterns + + + match + `\n + name + constant.character.escape.powershell + + + comment + useless escape, and doesn't count as a token + match + `\s + name + invalid.character.escape.powershell + + + include + #commentBlock + + - - repository - - commentLine + advanceToToken + comment + consume spaces and comments and line ends until the next token appears begin - (?<![`\\-])# - captures - - 0 + \G(?=[\s#]|<#|`\s) + end + (?!\s)(?!$) + applyEndPatternLast + + patterns + + comment + useless escape, and doesn't count as a token + match + `\s name - punctuation.definition.comment.powershell + invalid.character.escape.powershell - - end - $\n? - name - comment.line.powershell + + include + #commentLine + + + include + #commentBlock + + + + accessors + patterns + + begin + \G(?:\.(?!\.)|(?<!:)::) + beginCaptures + + 0 + + name + punctuation.accessor.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #members + + + include + #commentLine + + + include + #commentBlock + + + include + #advanceToToken + + + + + begin + \G(?=\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \[ + beginCaptures + + 0 + + name + punctuation.section.bracket.begin.powershell + + + end + ] + endCaptures + + 0 + + name + punctuation.section.bracket.end.powershell + + + name + meta.index.powershell + patterns + + + comment + should only be an expression, no assignment operators + include + #expression_mode + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + include - #commentEmbeddedDocs + #commentLine include - #RequiresDirective + #commentBlock - attribute + members - begin - (\[)\s*\b(?i)(cmdletbinding|alias|outputtype|parameter|validatenotnull|validatenotnullorempty|validatecount|validateset|allownull|allowemptycollection|allowemptystring|validatescript|validaterange|validatepattern|validatelength|supportswildcards)\b - beginCaptures - - 1 + patterns + - name - punctuation.section.bracket.begin.powershell + begin + (?<![\])])(?:(?i:(foreach|where)(?=[\({]))|([\p{L}_]\w*(?=\())) + captures + + 1 + + name + support.function.$1.powershell + + 2 + + name + entity.name.function.method.powershell + + + end + (?!\G)|(?=\)) + patterns + + + begin + \G(?=\() + end + (?=.|$) + applyEndPatternLast + + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.section.method-arguments.begin.powershell + + + contentName + meta.method-arguments.powershell + end + \) + endCaptures + + 0 + + name + punctuation.section.method-arguments.end.powershell + + + patterns + + + include + #expression_mode + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + + + + begin + \G(?=\{) + end + (?!\G) + patterns + + + include + #scriptblock + + + + - 2 - name - support.function.attribute.powershell + begin + (?<![\])])[\p{L}_]\w*(?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + beginCaptures + + 0 + + name + variable.other.object.property.powershell + + + patterns + + + include + #accessors + + - - end - (\]) - endCaptures - - 1 + match + (?<![\])])[\p{L}_]\w* name - punctuation.section.bracket.end.powershell + variable.other.property.powershell - - name - meta.attribute.powershell + + comment + need to wrap a begin block around this using \G + include + #quotedStrings_Members + + + + switchConditions + + begin + (?={) + end + (?=.|$) + applyEndPatternLast + patterns begin - \( + \G\{ beginCaptures 0 name - punctuation.section.group.begin.powershell + punctuation.section.braces.begin.powershell end - \) + } endCaptures 0 name - punctuation.section.group.end.powershell + punctuation.section.braces.end.powershell + name + meta.switch-conditions.powershell patterns - include - $self + begin + (?:\G|(?<=\}))(?![,;&|)}]) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + begin + (?<=[\s>]|\G|^)(?![\s#,;&|)}<>]|<#) + end + (?!\G) + name + meta.argument.switch-condition.powershell + patterns + + + comment + default: only in switch + match + (?i:default)(?=[\s{(,;&|)}]) + name + keyword.control.switch-default.powershell + + + include + #argument + + + + - match - (?i)\b(mandatory|valuefrompipeline|valuefrompipelinebypropertyname|valuefromremainingarguments|position|parametersetname|defaultparametersetname|supportsshouldprocess|supportspaging|positionalbinding|helpuri|confirmimpact|helpmessage)\b(?:\s+)?(=)? - captures + begin + { + beginCaptures - 1 + 0 name - variable.parameter.attribute.powershell + punctuation.section.braces.begin.powershell - 2 + + end + } + endCaptures + + 0 name - keyword.operator.assignment.powershell + punctuation.section.braces.end.powershell + name + meta.statements.switch-condition.powershell + patterns + + + include + $self + + + + + include + #notCode + + + comment + very limited what is permitted here + match + [^\s{()}] + name + invalid.source.powershell + + + + + comment + next statement, return when safe to exit + begin + (?<=})(?![,)}\]]) + end + (?<!})(?=[\n,})\]]) + patterns + + + include + $self - commands + variable_inner + comment + separate the parts of the variable name and scope them, character validation has already been done patterns + match + (?:\G|[$@])(?:[^`:]|`[^:])*`?:$ + name + invalid.variable.powershell + + + captures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + name + storage.modifier.scope.powershell + + 3 + + name + invalid.character.escape.powershell + + 4 + + name + punctuation.separator.colon.powershell + + comment - Verb-Noun pattern: + These are special constants. match - (?:(\p{L}|\d|_|-|\\|\:)*\\)?\b(?i:Add|Approve|Assert|Backup|Block|Build|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Deploy|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Mount|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Write)\-.+?(?:\.(?i:exe|cmd|bat|ps1))?\b + (?:\G|([$@]))(?i:(?:(global|local|private|script|using|workflow)?(`)?(:))?(?:False|Null|True))$ name - support.function.powershell + constant.language.powershell + captures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + name + storage.modifier.scope.powershell + + 3 + + name + invalid.character.escape.powershell + + 4 + + name + punctuation.separator.colon.powershell + + comment - Builtin cmdlets with reserved verbs + These are the other built-in constants. match - (?<!\w)(?i:foreach-object)(?!\w) + (?:\G|([$@]))(?i:(?:(global|local|private|script|using|workflow)?(`)?(:))?(?:Error|ExecutionContext|Is(?:CoreCLR|Linux|MacOS|Windows)|Host|Home|PID|PSHome|PSVersionTable|ShellID)$) name - support.function.powershell + variable.language.builtin.powershell - comment - Builtin cmdlets with reserved verbs + captures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + name + storage.modifier.scope.powershell + + 3 + + name + invalid.character.escape.powershell + + 4 + + name + punctuation.separator.colon.powershell + + match - (?<!\w)(?i:where-object)(?!\w) + (?:\G|([$@]))(?i:(?:(global|local|private|script|using|workflow)?(`)?(:))?(?:[$^?_]|Args|ConsoleFileName|Event|EventArgs|EventSubscriber|ForEach|Input|LastExitCode|Matches|MyInvocation|NestedPromptLevel|Profile|PSBoundParameters|PSCmdlet|PSCulture|PSDebugContext|PSItem|PSCommandPath|PSScriptRoot|PSUICulture|Pwd|Sender|SourceArgs|SourceEventArgs|StackTrace|Switch|This)$) name - support.function.powershell + variable.language.builtin.powershell + captures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + name + storage.modifier.scope.powershell + + 3 + + name + invalid.character.escape.powershell + + 4 + + name + punctuation.separator.colon.powershell + + comment - Builtin cmdlets with reserved verbs + Style preference variables as language variables so that they stand out. match - (?<!\w)(?i:sort-object)(?!\w) + (?:\G|([$@]))(?i:(?:(global|local|private|script|using|workflow)?(`)?(:))?(?:ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|InformationPreference|Log(?:Command|Engine|Provider)(?:HealthEvent|LifecycleEvent)|Maximum(?:AliasCount|DriveCount|ErrorCount|FunctionCount|HistoryCount|VariableCount)|OFS|OutputEncoding|ProgressPreference|PsCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoLoadingPreference|PSSenderInfo|PSSession(?:ApplicationName|ConfigurationName|Option)|VerbosePreference|WarningPreference|WhatIfPreference)$) name - support.function.powershell + variable.language.powershell + captures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + patterns + + + include + #variable_scopeOrDrive + + + + 3 + + patterns + + + include + #variable_escapes + + + + comment - Builtin cmdlets with reserved verbs + capture all other seemingly valid normal variables match - (?<!\w)(?i:tee-object)(?!\w) + (?:\G|([$@]))(?:([^:]*`?:))?(.*) name - support.function.powershell + variable.other.readwrite.powershell - commentEmbeddedDocs + variable_scopeOrDrive patterns + comment + workflow scope only available in workflow + match + ((?i:global|local|private|script|using|workflow))(`)?(:) captures 1 name - constant.string.documentation.powershell + storage.modifier.scope.powershell 2 name - keyword.operator.documentation.powershell + invalid.character.escape.powershell + + 3 + + name + punctuation.separator.colon.powershell - match - ^(?i:(?:\s?|#)+(\.)(COMPONENT|DESCRIPTION|EXAMPLE|EXTERNALHELP|FORWARDHELPCATEGORY|FORWARDHELPTARGETNAME|FUNCTIONALITY|INPUTS|LINK|NOTES|OUTPUTS|REMOTEHELPRUNSPACE|ROLE|SYNOPSIS)) - name - comment.documentation.embedded.powershell + match + (?i:(Alias|Cert|Env|Function|HKCU|HKLM|Variable|WSMan))(`)?(:) captures 1 name - constant.string.documentation.powershell + keyword.type.drive.powershell 2 name - keyword.operator.documentation.powershell + invalid.character.escape.powershell 3 name - keyword.operator.documentation.powershell + punctuation.separator.colon.powershell - match - (?i:\s?(\.)(PARAMETER|FORWARDHELPTARGETNAME|FORWARDHELPCATEGORY|REMOTEHELPRUNSPACE|EXTERNALHELP)\s+([a-z0-9-_]+)) - name - comment.documentation.embedded.powershell - - - - doubleQuotedStringEscapes - - patterns - - - match - `[`0abefnrtv"'$] - name - constant.character.escape.powershell - - - include - #unicodeEscape - match - "" + comment + Unknown drive + begin + (?=.) + end + : + endCaptures + + 0 + + name + punctuation.separator.colon.powershell + + name - constant.character.escape.powershell + storage.type.drive.powershell + patterns + + + include + #variable_escapes + + - unicodeEscape + variable_bracketed_inside - comment - `u{xxxx} added in PowerShell 6.0 patterns + comment + capture a complete variable reference that appears on a single line and attempt to scope language variables match - `u\{(?:(?:10)?([0-9a-fA-F]){1,4}|0?\g<1>{1,5})} - name - constant.character.escape.powershell + \G(?:[^`}:]*`?:)?[^`}]*(?=}) + captures + + 0 + + patterns + + + begin + (?=.) + end + (?!\G) + patterns + + + include + #variable_inner + + + + + + + comment + this captures up to the first colon, and then matches up the capture match - `u(?:\{[0-9a-fA-F]{,6}.)? - name - invalid.character.escape.powershell - - - - function - - begin - ^(?:\s*+)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) - beginCaptures - - 0 - - name - meta.function.powershell - - 1 - - name - storage.type.powershell - - 2 - - name - storage.modifier.scope.powershell - - 3 - - name - entity.name.function.powershell - - - end - (?=\{|\() - patterns - - - include - #commentLine - - - - interpolatedStringContent - - begin - \( - beginCaptures - - 0 - - name - punctuation.section.group.begin.powershell - - - contentName - interpolated.simple.source.powershell - end - \) - endCaptures - - 0 - - name - punctuation.section.group.end.powershell - - - patterns - - - include - $self - - - include - #interpolation - - - include - #interpolatedStringContent - - - - interpolation - - begin - (\$)(\() - beginCaptures - - 1 - - name - punctuation.definition.variable.powershell - - 2 - - name - punctuation.section.group.begin.powershell - - - contentName - interpolated.complex.source.powershell - end - \) - endCaptures - - 0 + \G(?:[^`}:]|`[^:])*`?: + captures + + 0 + + patterns + + + include + #variable_scopeOrDrive + + + + + - name - punctuation.section.group.end.powershell + include + #variable_escapes - + + + variable_escapes + patterns - include - $self + match + `(?:[`0abefnrtv{}\n]) + name + constant.character.escape.powershell include - #interpolation + #unicodeEscape - include - #interpolatedStringContent + match + ` + name + invalid.character.escape.powershell + + + match + { + name + invalid.character.powershell - numericConstant + variable patterns - captures - - 1 + begin + (?=\$[{\w:$^?]) + end + (?!\G) + patterns + - name - constant.numeric.hex.powershell + begin + \G\$(?:[$^?]|(?>[\w][\w?]*:(?!:)|:)?(?:[\w?]|:(?!:))+)(?=\.(?!\.)|::|\[) + beginCaptures + + 0 + + patterns + + + include + #variable_inner + + + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + - 2 - name - keyword.other.powershell + match + \G\$(?:[$^?]|(?>[\w][\w?]*:(?!:)|:)?(?:[\w?]|:(?!:))+|:) + captures + + 0 + + patterns + + + include + #variable_inner + + + + - - match - (?<!\w)([-+]?0(?:x|X)[0-9a-fA-F_]+(?:U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?)((?i:[kmgtp]b)?)\b - - - captures - - 1 + match + \$\{} name - constant.numeric.integer.powershell + invalid.variable.powershell - 2 - name - keyword.other.powershell + begin + (?=\$\{) + end + (?!\G) + applyEndPatternLast + + patterns + + + begin + (\$)(\{) + beginCaptures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + name + punctuation.definition.variable.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.definition.variable.braces.end.powershell + + + name + variable.other.readwrite.powershell + patterns + + + include + #variable_bracketed_inside + + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + + + - + + + + comment + splatting cannot be used outside of argument mode, result is invalid source. match - (?<!\w)([-+]?(?:[0-9_]+)?\.[0-9_]+(?:(?:e|E)[0-9]+)?(?:F|f|D|d|M|m)?)((?i:[kmgtp]b)?)\b + (?>@(?:[$^?]|(?>[\w][\w?]*:(?!:)|:)?(?:[\w?]|:(?!:))+|:)) + name + invalid.splat.powershell + + + variableNoProperty + + begin + (?=\$[{\w:$^?]) + end + (?!\G) + name + meta.embedded.interpolated.powershell + patterns + + match + \G\$(?:[$^?]|(?>[\w][\w?]*:(?!:)|:)?(?:[\w?]|:(?!:))+|:) captures - 1 - - name - constant.numeric.octal.powershell - - 2 + 0 - name - keyword.other.powershell + patterns + + + include + #variable_inner + + - match - (?<!\w)([-+]?0(?:b|B)[01_]+(?:U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?)((?i:[kmgtp]b)?)\b - captures - - 1 + begin + (?=\$\{) + end + (?!\G) + applyEndPatternLast + + patterns + + begin + (\$)(\{) + beginCaptures + + 1 + + name + punctuation.definition.variable.powershell + + 2 + + name + punctuation.definition.variable.braces.begin.powershell + + + end + } + endCaptures + + 0 + + name + punctuation.definition.variable.braces.end.powershell + + name - constant.numeric.integer.powershell + variable.other.readwrite.powershell + patterns + + + include + #variable_bracketed_inside + + - 2 + + + + + RequiresDirective + + comment + requires directive must be on single line, so capture and tokenize, current PS <= 6.2 allow `requires` keyword without delimiter, but the parameters must follow with a delimiter! + match + ^\s*(#)((?i:requires))(.?)(.*)$ + captures + + 1 + + name + punctuation.definition.comment.powershell + + 2 + + name + keyword.control.requires.powershell + + 3 + + patterns + + match + \S name - keyword.other.powershell + invalid.source.powershell - - match - (?<!\w)([-+]?[0-9_]+(?:e|E)(?:[0-9_])?+(?:F|f|D|d|M|m)?)((?i:[kmgtp]b)?)\b + + 4 - captures - - 1 + patterns + + + match + (([\x{2013}-\x{2015}-])(?i:Modules|PSSnapin|PSEdition|RunAsAdministrator|ShellId|Version)\b)(:)? + captures + + 1 + + name + entity.name.parameter.powershell + + 2 + + name + punctuation.definition.parameter.powershell + + 3 + + name + punctuation.separator.parameter-value.powershell + + + + comment + needs custom argument handler, single line quoted or unquoted arguments + match + (?<!\x{2013}-\x{2015}-)\b\p{L}+|\d+(?:\.\d+)* name - constant.numeric.integer.powershell + variable.parameter.powershell - 2 + match + , name - keyword.other.powershell + punctuation.separator.powershell - - match - (?<!\w)([-+]?[0-9_]+\.(?:e|E)(?:[0-9_])?+(?:F|f|D|d|M|m)?)((?i:[kmgtp]b)?)\b + + comment + needs custom hashtable that does not auto continue to next line + include + #hashtable + + + include + #notCode + + + + name + comment.line.powershell meta.requires.powershell + + hashtable + + begin + (?=@\{) + end + (?=.|$) + applyEndPatternLast + + patterns + - captures + begin + (@)(\{) + beginCaptures 1 name - constant.numeric.integer.powershell + keyword.other.hashtable.begin.powershell 2 name - keyword.other.powershell + punctuation.section.braces.begin.powershell - match - (?<!\w)([-+]?[0-9_]+[\.]?(?:F|f|D|d|M|m))((?i:[kmgtp]b)?)\b - - - captures + end + \} + endCaptures - 1 + 0 name - constant.numeric.integer.powershell + punctuation.section.braces.end.powershell - 2 + + name + meta.hashtable.powershell + patterns + - name - keyword.other.powershell + include + #hashtableAssignment - - match - (?<!\w)([-+]?[0-9_]+[\.]?(?:U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?)((?i:[kmgtp]b)?)\b + + + + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #accessors + + - scriptblock + hashtableAssignment - begin - \{ - beginCaptures - - 0 + patterns + + match + \b([\p{L}_]\w*)(?=\s*=) name - punctuation.section.braces.begin.powershell + entity.name.variable.property.powershell - - end - \} - endCaptures - - 0 - name - punctuation.section.braces.end.powershell + comment + #type - - name - meta.scriptblock.powershell - patterns - - include - $self + comment + #variable + + + comment + #quotedStrings_Members - - - type - - begin - \[ - beginCaptures - - 0 - name - punctuation.section.bracket.begin.powershell + include + #operand - - end - \] - endCaptures - - 0 - name - punctuation.section.bracket.end.powershell + begin + (=) + beginCaptures + + 1 + + name + keyword.operator.assignment.hashtable-member.powershell + + + end + (?=[;}])|$(?!\G) + patterns + + + include + #advanceToToken + + + begin + (?![;}\n]) + end + (?=[;}\n]) + patterns + + + begin + \G + end + (?!\G) + patterns + + + include + #statements + + + + + include + #hashtableAssignment + + + + - - patterns - match - (?!\d+|\.)(?:\p{L}|\p{N}|\.)+ + ; name - storage.type.powershell + punctuation.terminator.assignment.hashtable-member.powershell include - $self + #notCode - variable + quotedStrings_Members + comment + detect all quoted strings (arguments or expressions) starting here + begin + (?=@?['"\x{2018}-\x{201E}]) + end + (?!\G) + applyEndPatternLast + patterns - captures + comment + single quoted strings + begin + \G['\x{2018}-\x{201B}] + beginCaptures 0 name - constant.language.powershell - - 1 - - name - punctuation.definition.variable.powershell + punctuation.definition.string.begin.powershell - comment - These are special constants. - match - (\$)(?i:(False|Null|True))\b - - - captures + end + ['\x{2018}-\x{201B}] + applyEndPatternLast + + endCaptures 0 name - support.constant.variable.powershell - - 1 - - name - punctuation.definition.variable.powershell + punctuation.definition.string.end.powershell - 3 + + name + string.quoted.single.powershell + patterns + + match + ['\x{2018}-\x{201B}]{2} name - variable.other.member.powershell + constant.character.escape.powershell - - comment - These are the other built-in constants. - match - (\$)(?i:(Error|ExecutionContext|Host|Home|PID|PsHome|PsVersionTable|ShellID))((?:\.(?:\p{L}|\d|_)+)*\b)?\b + - captures + comment + double quoted here-strings + begin + \G@["\x{201C}-\x{201E}] + beginCaptures 0 name - support.variable.automatic.powershell + string.quoted.double.heredoc.powershell punctuation.definition.heredoc.begin.powershell + + end + ^(["\x{201C}-\x{201E}]@)|\G((?:\s*\S+)+)(?:(?!\n)\s)*$ + endCaptures + 1 name - punctuation.definition.variable.powershell + string.quoted.double.heredoc.powershell punctuation.definition.heredoc.end.powershell - 3 + 2 - name - variable.other.member.powershell + patterns + + + match + \S+ + name + invalid.source.powershell + + - comment - Automatic variables are not constants, but they are read-only. In monokai (default) color schema support.variable doesn't have color, so we use constant. - match - (\$)((?:[$^?])|(?i:_|Args|ConsoleFileName|Event|EventArgs|EventSubscriber|ForEach|Input|LastExitCode|Matches|MyInvocation|NestedPromptLevel|Profile|PSBoundParameters|PsCmdlet|PsCulture|PSDebugContext|PSItem|PSCommandPath|PSScriptRoot|PsUICulture|Pwd|Sender|SourceArgs|SourceEventArgs|StackTrace|Switch|This)\b)((?:\.(?:\p{L}|\d|_)+)*\b)? - - - captures - - 0 + contentName + string.quoted.double.heredoc.powershell + patterns + - name - variable.language.powershell + include + #variableNoProperty - 1 - name - punctuation.definition.variable.powershell + include + #doubleQuotedHereStringEscapes - 3 - name - variable.other.member.powershell + include + #substatementEmbedded - - comment - Style preference variables as language variables so that they stand out. - match - (\$)(?i:(ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|InformationPreference|LogCommandHealthEvent|LogCommandLifecycleEvent|LogEngineHealthEvent|LogEngineLifecycleEvent|LogProviderHealthEvent|LogProviderLifecycleEvent|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount|MaximumHistoryCount|MaximumVariableCount|OFS|OutputEncoding|PSCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoLoadingPreference|PSModuleAutoloadingPreference|PSSenderInfo|PSSessionApplicationName|PSSessionConfigurationName|PSSessionOption|ProgressPreference|VerbosePreference|WarningPreference|WhatIfPreference))((?:\.(?:\p{L}|\d|_)+)*\b)?\b + - captures + comment + single quoted here-strings + begin + \G@['\x{2018}-\x{201B}] + beginCaptures 0 name - variable.other.readwrite.powershell + string.quoted.single.heredoc.powershell punctuation.definition.heredoc.begin.powershell + + end + ^(['\x{2018}-\x{201B}]@)|\G((?:\s*\S+)+)(?:(?!\n)\s)*$ + endCaptures + 1 name - punctuation.definition.variable.powershell + string.quoted.single.heredoc.powershell punctuation.definition.heredoc.end.powershell 2 - name - storage.modifier.scope.powershell - - 4 - - name - variable.other.member.powershell + patterns + + + match + \S+ + name + invalid.source.powershell + + - match - (?i:(\$|@)(global|local|private|script|using|workflow):((?:\p{L}|\d|_)+))((?:\.(?:\p{L}|\d|_)+)*\b)? + contentName + string.quoted.single.heredoc.powershell - captures + comment + double quoted strings + begin + \G(?:["\x{201C}-\x{201E}]) + beginCaptures 0 name - variable.other.readwrite.powershell - - 1 - - name - punctuation.definition.variable.powershell + punctuation.definition.string.begin.powershell - 2 + + end + (?:["\x{201C}-\x{201E}]) + applyEndPatternLast + + endCaptures + + 0 name - punctuation.section.braces.begin.powershell + punctuation.definition.string.end.powershell - 3 + + name + string.quoted.double.powershell + patterns + - name - storage.modifier.scope.powershell + include + #variableNoProperty - 5 - name - punctuation.section.braces.end.powershell + include + #doubleQuotedStringEscapes - 6 - name - variable.other.member.powershell + include + #substatementEmbedded - - match - (?i:(\$)(\{)(global|local|private|script|using|workflow):([^}]*[^}`])(\}))((?:\.(?:\p{L}|\d|_)+)*\b)? + - captures - - 0 - - name - variable.other.readwrite.powershell - - 1 - - name - punctuation.definition.variable.powershell - - 2 - - name - support.variable.drive.powershell - - 4 + begin + (?=\.(?!\.)|::|\[) + end + (?=.|$) + applyEndPatternLast + + patterns + - name - variable.other.member.powershell + include + #accessors - + + + + + functionName + + patterns + + match - (?i:(\$|@)((?:\p{L}|\d|_)+:)?((?:\p{L}|\d|_)+))((?:\.(?:\p{L}|\d|_)+)*\b)? + `(?!\n)\s + name + constant.character.escape.powershell - captures - - 0 + include + #argumentModeEscapes + + + begin + ['\x{2018}-\x{201B}] + end + ['\x{2018}-\x{201B}] + applyEndPatternLast + + patterns + + match + ['\x{2018}-\x{201B}]{2} name - variable.other.readwrite.powershell + constant.character.escape.powershell - 1 + + + + begin + ["\x{201C}-\x{201E}] + end + ["\x{201C}-\x{201E}] + applyEndPatternLast + + patterns + - name - punctuation.definition.variable.powershell + include + #doubleQuotedStringEscapes - 2 - name - punctuation.section.braces.begin.powershell + begin + \$\( + end + \) + patterns + + + include + #functionName + + - 3 + + + + begin + \$\( + end + \) + patterns + - name - support.variable.drive.powershell + include + #functionName - 5 + + + + begin + \$\{ + end + } + patterns + - name - punctuation.section.braces.end.powershell + match + \$ - 6 - name - variable.other.member.powershell + include + #functionName - - match - (?i:(\$)(\{)((?:\p{L}|\d|_)+:)?([^}]*[^}`])(\}))((?:\.(?:\p{L}|\d|_)+)*\b)? + - UsingDirective + unquotedStrings_text - match - (?<!\w)(?i:(using))\s+(?i:(namespace|module))\s+(?i:((?:\w+(?:\.)?)+)) - captures - - 1 + patterns + + match + `(?!\n)\s name - keyword.control.using.powershell + constant.character.escape.powershell - 2 - name - keyword.other.powershell + include + #argumentModeEscapes - 3 - name - variable.parameter.powershell + include + #variableNoProperty - - - RequiresDirective - - begin - (?<=#)(?i:(requires))\s - beginCaptures - - 0 - name - keyword.control.requires.powershell + include + #quotedStrings_Members - - end - $ - name - meta.requires.powershell + + include + #substatementEmbedded + + + + unquotedStrings_text_interpolatedString + + comment + !!!!!!!!!!!!!!!!!!WIP!!! patterns match - \-(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) + `(?!\n)\s name - keyword.other.powershell + constant.character.escape.powershell - match - (?<!-)\b\p{L}+|\d+(?:\.\d+)* - name - variable.parameter.powershell + include + #argumentModeEscapes - include - #hashtable + begin + ['\x{2018}-\x{201B}] + end + ['\x{2018}-\x{201B}] + applyEndPatternLast + + patterns + + + match + ['\x{2018}-\x{201B}]{2} + name + constant.character.escape.powershell + + + + + begin + ["\x{201C}-\x{201E}] + end + ["\x{201C}-\x{201E}] + applyEndPatternLast + + patterns + + + include + #doubleQuotedStringEscapes + + + begin + \$\( + end + \) + patterns + + + include + #unquotedStrings_text + + + + + + + begin + \$\( + end + \) + patterns + + + include + #unquotedStrings_text + + - variableNoProperty + terminators + + patterns + + + comment + `||` and `&&` conditional terminators are reserved. + match + \|\||&& + name + invalid.reserved.powershell + + + + operators_post + comment + expression mode operators that follow operands mutually exclusive of each other. patterns + match + (\+\+)|([\x{2013}-\x{2015}-]{2}) captures - 0 + 1 name - constant.language.powershell + keyword.operator.arithmetic.postfix.unary.increment.powershell - 1 + 2 name - punctuation.definition.variable.powershell + keyword.operator.arithmetic.postfix.unary.decrement.powershell - comment - These are special constants. - match - (\$)(?i:(False|Null|True))\b - captures + comment + the range operator is only available after an operand (but is a binary operator) + begin + (?<!^)\s*(\.\.) + beginCaptures - 0 + 1 name - support.constant.variable.powershell + keyword.operator.range.powershell - 1 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - punctuation.definition.variable.powershell + include + #advanceToToken - 3 + + + + begin + (?:[+%*/\x{2013}-\x{2015}-]|\?\?)?= + beginCaptures + + 0 name - variable.other.member.powershell + keyword.operator.assignment.powershell - comment - These are the other built-in constants. - match - (\$)(?i:(Error|ExecutionContext|Host|Home|PID|PsHome|PsVersionTable|ShellID))\b + end + (?=\n)(?!\G)|(?=[,;&)}\]]) + patterns + + + include + #advanceToToken + + + include + $self + + + + + operators_preUnary + + comment + expression mode unary operators that precede operands. + patterns + - captures + comment + `,` just continues current mode, after advancing to next token + begin + , + beginCaptures 0 name - support.variable.automatic.powershell + keyword.operator.unary.array-element-separator.comma.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + begin + (\+\+)|([\x{2013}-\x{2015}-]{2}) + beginCaptures + 1 name - punctuation.definition.variable.powershell + keyword.operator.arithmetic.prefix.unary.increment.powershell - 3 + 2 name - variable.other.member.powershell + keyword.operator.arithmetic.prefix.unary.decrement.powershell - comment - Automatic variables are not constants, but they are read-only... - match - (\$)((?:[$^?])|(?i:_|Args|ConsoleFileName|Event|EventArgs|EventSubscriber|ForEach|Input|LastExitCode|Matches|MyInvocation|NestedPromptLevel|Profile|PSBoundParameters|PsCmdlet|PsCulture|PSDebugContext|PSItem|PSCommandPath|PSScriptRoot|PsUICulture|Pwd|Sender|SourceArgs|SourceEventArgs|StackTrace|Switch|This)\b) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + - captures + begin + [\x{2013}-\x{2015}-]((?i:join|[ic]?(?:split)))(?!\p{L}) + beginCaptures 0 name - variable.language.powershell + keyword.operator.unary.string-$1.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + begin + (?:(?=[\x{2013}-\x{2015}-])(?i:(.not)|(.bnot)|(.)(?![\d.]))|(!))(?!\p{L})|(\+)(?![\d.]) + beginCaptures + 1 name - punctuation.definition.variable.powershell + keyword.operator.logical.unary.not.powershell + + 2 + + name + keyword.operator.bitwise.unary.bnot.powershell 3 name - variable.other.member.powershell + keyword.operator.arithmetic.unary.negate.powershell + + 4 + + name + keyword.operator.logical.unary.not.powershell + + 5 + + name + keyword.operator.arithmetic.unary.positive.powershell - comment - Style preference variables as language variables so that they stand out. - match - (\$)(?i:(ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|InformationPreference|LogCommandHealthEvent|LogCommandLifecycleEvent|LogEngineHealthEvent|LogEngineLifecycleEvent|LogProviderHealthEvent|LogProviderLifecycleEvent|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount|MaximumHistoryCount|MaximumVariableCount|OFS|OutputEncoding|PSCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoLoadingPreference|PSModuleAutoloadingPreference|PSSenderInfo|PSSessionApplicationName|PSSessionConfigurationName|PSSessionOption|ProgressPreference|VerbosePreference|WarningPreference|WhatIfPreference))\b + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + + operators + + patterns + - captures + include + #operators_post + + + comment + `,` just continues current mode, after advancing to next token + begin + , + beginCaptures 0 name - variable.other.readwrite.powershell + keyword.operator.array-element-separator.comma.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + begin + (?=[\x{2013}-\x{2015}-])(?i:(.is(?:not)?)|(.as))(?!\p{L}) + beginCaptures + 1 name - punctuation.definition.variable.powershell + keyword.operator.comparison.type.powershell 2 name - storage.modifier.scope.powershell + keyword.operator.type-cast.powershell - 4 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - variable.other.member.powershell + include + #advanceToToken - - match - (?i:(\$)(global|local|private|script|using|workflow):((?:\p{L}|\d|_)+)) + - captures + begin + [\x{2013}-\x{2015}-]((?i:[ic]?(?:eq|ne|[gl][te]|(?:not)?(?:like|match|contains|in))))(?!\p{L}) + beginCaptures 0 name - variable.other.readwrite.powershell - - 1 - - name - punctuation.definition.variable.powershell + keyword.operator.comparison.$1.powershell - 2 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - storage.modifier.scope.powershell + include + #advanceToToken - 4 + + + + begin + [\x{2013}-\x{2015}-]((?i:join|[ic]?(?:split|replace)))(?!\p{L}) + beginCaptures + + 0 name - keyword.other.powershell + keyword.operator.string-$1.powershell - 5 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - variable.other.member.powershell + include + #advanceToToken - - match - (?i:(\$)(\{)(global|local|private|script|using|workflow):([^}]*[^}`])(\})) + - captures + begin + [\x{2013}-\x{2015}-]((?i:and|or|xor))(?!\p{L}) + beginCaptures 0 name - variable.other.readwrite.powershell + keyword.operator.logical.$1.powershell - 1 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - punctuation.definition.variable.powershell + include + #advanceToToken - 2 + + + + begin + [\x{2013}-\x{2015}-]((?i:band|bor|bxor|shl|shr))(?!\p{L}) + beginCaptures + + 0 name - support.variable.drive.powershell + keyword.operator.bitwise.$1.powershell - 4 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - variable.other.member.powershell + include + #advanceToToken - - match - (?i:(\$)((?:\p{L}|\d|_)+:)?((?:\p{L}|\d|_)+)) + - captures + begin + [\x{2013}-\x{2015}-](?i:f)(?!\p{L}) + beginCaptures 0 name - variable.other.readwrite.powershell + keyword.operator.string-format.powershell - 1 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - punctuation.definition.variable.powershell + include + #advanceToToken - 2 + + + + begin + [+%*/]|[\x{2013}-\x{2015}-](?![\p{L}\x{2013}-\x{2015}-]) + beginCaptures + + 0 name - punctuation.section.braces.begin + keyword.operator.arithmetic.powershell - 3 + + end + (?=.|$) + applyEndPatternLast + + patterns + - name - support.variable.drive.powershell + include + #advanceToToken - 5 + + + + begin + \?\? + beginCaptures + + 0 name - punctuation.section.braces.end + keyword.operator.null-coalesce.powershell - match - (?i:(\$)(\{)((?:\p{L}|\d|_)+:)?([^}]*[^}`])(\})) + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToToken + + + + + comment + included last only because preunary also includes the negate `!` and `-b?not` operators, but we didn't want the `-` negate operator replacing `-` subtract. + old include + #operators_preUnary - hashtable + notCode - begin - (@)(\{) - beginCaptures - - 1 + patterns + + match + `(?!\n)\s name - keyword.other.hashtable.begin.powershell + invalid.character.escape.powershell - 2 - name - punctuation.section.braces.begin.powershell + include + #commentBlock - - end - (\}) - endCaptures - - 1 - name - punctuation.section.braces.end.powershell + include + #commentLine - - name - meta.hashtable.powershell + + comment + when nothing else matches in usual tokenizing, consume it to prevent other patterns from striking in the middle of what might be a command name. + begin + (?=[^\[\s{(,;&|)}]) + end + (?=[\s{(,;&|)}]) + contentName + invalid.source.powershell + patterns + + + include + #unquotedStrings_text + + + + + + redirection + patterns - captures + include + #terminators + + + comment + `&` resume's in statement mode, added PowerShell 6 (previously reserved) + begin + & + beginCaptures - 1 + 0 name - punctuation.definition.string.begin.powershell + punctuation.terminator.job.powershell - 2 + + end + (?=[\n;)}\]]) + patterns + - name - variable.other.readwrite.powershell + include + $self - 3 + + + + comment + `|` resume's in command mode + begin + \|(?!\|) + beginCaptures + + 0 name - punctuation.definition.string.end.powershell + keyword.operator.other.pipe.powershell - 4 + + end + (?=\n)(?!\G)|(?=[;&)}\]]) + patterns + - name - keyword.operator.assignment.powershell + include + #advanceToToken - - match - \b((?:\'|\")?)(\w+)((?:\'|\")?)(?:\s+)?(=)(?:\s+)? - name - meta.hashtable.assignment.powershell - - - include - #scriptblock - - - include - $self - - - - doubleQuotedString - - begin - (?<!(?<!`)")" - beginCaptures - - 0 - - name - punctuation.definition.string.begin.powershell + + include + #command_mode + + - - end - "(?!") - endCaptures - - 0 + match + <(?!#)|[1-6]>&2 name - punctuation.definition.string.end.powershell + invalid.reserved.redirection.powershell - - name - string.quoted.double.powershell - patterns - match - (?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b - - - include - #variableNoProperty - - - include - #doubleQuotedStringEscapes - - - include - #interpolation + [2-6*]>&1 + name + keyword.operator.redirection.to-stdout.powershell - match - `\s*$ - name - keyword.other.powershell + begin + [1-6*]?>>? + beginCaptures + + 0 + + name + keyword.operator.redirection.powershell + + + end + (?=.|$) + applyEndPatternLast + + patterns + + + include + #advanceToArgument + + + begin + (?<=[\s>]|\G|^)(?![\s#;&|)}]|<#|$|`\s) + end + (?!\G) + name + meta.argument.redirect-file.powershell + patterns + + + comment + `,`, `<` and `>` not permitted here + match + [,<>] + name + invalid.source.powershell + + + include + #argument + + + +