-
Notifications
You must be signed in to change notification settings - Fork 119
Description
Regarding microsoft/vscode#57831, using VS Code 1.27.2,
syntax (JSON) as simplified:
{
"name": "PowerShell",
"scopeName": "source.powershell",
"patterns": [
{
"include": "#variable"
},
{
"include": "#operators"
}
],
"repository": {
"operators": {
"patterns": [
{
"match": "(?:\\G|(?<!\\p{L}|!))-(?i:is(?:not)?|as)(?!\\p{L})",
"name": "keyword.operator.comparison.powershell"
},
{
"match": "(?:\\G|(?<!\\p{L}|!))-(?i:[ic]?(?:eq|ne|[gl][te]|(?:not)?(?:like|match|contains|in)|replace))(?!\\p{L})",
"name": "keyword.operator.comparison.powershell"
},
{
"match": "(?:\\G|(?<!\\p{L}|!))-(?i:join|split)(?!\\p{L})|--|\\+\\+",
"name": "keyword.operator.unary.powershell"
},
{
"match": "(?:\\G|(?<!\\p{L}|!))-(?i:and|or|not|xor)(?!\\p{L})|!",
"name": "keyword.operator.logical.powershell"
},
{
"match": "(?:\\G|(?<!\\p{L}|!))-(?i:band|bor|bnot|bxor|shl|shr)(?!\\p{L})",
"name": "keyword.operator.bitwise.powershell"
},
{
"match": "(?:\\G|(?<!\\p{L}|!))-(?i:f)(?!\\p{L})",
"name": "keyword.operator.string-format.powershell"
},
{
"match": "[+%*/-]?=|[+/*%]|-(?!\\p{L}|-%)",
"name": "keyword.operator.assignment.powershell"
},
{
"match": "\\|\\||&&|;",
"name": "punctuation.terminator.statement.powershell"
},
{
"match": "&|(?<!\\p{L}|!)(?<!\\.)\\.(?=\\s)|,|\\|",
"name": "keyword.operator.other.powershell"
},
{
"comment": "This is very imprecise, is there a syntax for 'must come after...' ",
"match": "(?<!^)\\s*\\.\\.\\s*(?=\\-?\\d|\\(|\\$)",
"name": "keyword.operator.range.powershell"
}
]
},
"variable": {
"patterns": [
{
"captures": {
"0": {
"name": "variable.other.readwrite.powershell"
},
"1": {
"name": "punctuation.definition.variable.powershell"
}
},
"begin": "(\\$)(?:\\p{L}|\\d|[_?])+",
"patterns": [
{
"include": "#operators"
}
],
"name": "meta.test",
"end": "(?!\\G)",
"applyEndPatternLast": 1
}
]
}
}
}
applyEndPatternLast was an experiment. Had no affect as either 1 or "1" or not present.
A test set as
# Operators
if (10 -cgt 100) { }
$a -is $b
$b -contains $c
$x -notcontains $c
$a -match $b
$a-notmatch $b
$x -like $c
100-and 0
$a-ceq 4 -and $a-ine $d-or
$c -is [Type]
$c -isnot [Type]
$c -as [Type]
$k = $y -bor $k
$x = $y -and $x-and $z
$x = $y-and $x-and $z-split
$z = -bnot $x
$k = $y -xor $b
$k = $y -bxor $b
$a -icontains $c-or
$a-ccontains $c
$a-iNotContains $c
$a-cNotContains $c
$a-cmatch $c
$x-iMatch $c
$x -iNotMatch $c
$a -iLike $b
$b -cLike $c
"hey" -cgt "Hey"
"Hey" -igt "hey"
"hey" -cge "Hey"
"Hey" -ige "hey"
"HEY" -clt "hey"
"HEY" -ilt "hey"
"HEY" -cle "hey"
"HEY" -ile "hey"
A variable that starts the line can always match the operator immediately behind it, but after that, I cannot seem to find a reason for why it sometimes matches, sometimes doesn't. It specifically deals with the operators that, if they were immediately following a command name, would be possibly an extension of the command name, so a lookbehind is used to verify the last digit isn't alpha, when in reality, what needs to be checked is the last scope, so I am trying to use the anchor \G (as an alternate), as all these operators can immediately follow a variable. I have been looking for a way to support the operators following items where the '-' is a separator, so that a space is not required (since PowerShell doesn't require a space). I have more ideas how to handle this, but I really think there is something going wrong with the rule parsing, probably around the anchor. I'll probably try separating the operators from the lookbehind, so that in this case, I can just recursively call the base operators, but please keep in mind I am just editing the original VS Code language file attempting to make it work better.
Unexpectedly the scope 'meta.test' is showing up on the spaces after the variable matches, and on the failed operator matches, the 'meta.test' scope shows up on the '-' only. However, if I change the end match to (?=.|$)
then that doesn't happen, but everything is still exactly the same for the matching of the operators. Interesting note, when it normally works, the operator immediately following the variable will be included in 'meta.test' as expected, but when a part that isn't working, is edited (remove spaces from places on the same line) and suddenly starts working, the operator matches that suddenly start working are NOT in the 'meta.test' scope as it would have been expected!