PowerShell / EditorSyntax

PowerShell syntax highlighting for editors (VS Code, Atom, SublimeText, TextMate, etc.) and GitHub!
MIT License
132 stars 43 forks source link

Decide on scope names for all language constructs #8

Open gravejester opened 8 years ago

gravejester commented 8 years ago

I'd like to have a discussion where we decide on the "correct" scope names for all PowerShell language constructs. This will mean much less work when doing updates to the tmLanguage file in the future, as the scopes (as well as the color(!) of each) are checked by a Travis CI build job on the vscode repo.

General

As we decide, we can fill out this table:

Language construct Scope Name Comments/Examples
Line comment comment.line.number-sign # comments
Block comment comment.block <# comments #>
Help directives comment.documentation.embedded Meta scope
Help directives - keywords keyword.operator.documentation .SYNOPSIS
Help directives - keyword value constant.string.documentation 'ParameterName' in .PARAMETER ParameterName
#Requires statement keywords.operator.documentation 'Requires' in #Requires -Version 3.0
#Requires statement - parameter constant.string.documentation '-Version 3.0' in #Requires -Version 3.0
String - double quoted string.quoted.double "string"
String - single quoted string.quoted.single 'string'
String - escape characters constant.character.escape 't' in"onettwo"
String - heredoc double quoted string.quoted.double.heredoc
String - heredoc single quoted string.quoted.single.heredoc
ScriptBlock meta.scriptblock { ... }
SubExpression meta.subexpression $( ... )
Hashtable meta.hashtable @{ ... }
Array meta.array @(1,2,3) & (1,2,3)
Property/Member entity.other.attribute-name 'property' in (Invoke-Something).property & 'property' in $var.property
Numeric Constant - real constant.numeric.real +.5
Numeric Constant - integer constant.numeric.integer 5
Numeric Constant - hexadecimal constant.numeric.hexadecimal 0x20
Type entity.name.type 'string' in [string]
Type - static method meta.method '::MinValue' in [int]::MinValue
Parameter decorator entity.name.type 'Parameter' in [Parameter(Position = 1)]
Parameter decorator - property entity.other.attribute-name 'Position' in [Parameter(Position = 1)]
Function meta.function Meta scope
Function - keyword storage.type 'function' in function script:Invoke-Something { ... }
Function - scope storage.modifier.scope 'script' in function script:Invoke-Something { ... }
Function - name entity.name.function 'Invoke-Something' in function script:Invoke-Something { ... }
Command meta.command Meta scope
Command - keyword support.function 'Invoke-Something' in Invoke-Something -p1 'v1'
Command - parameter variable.parameter '-p1' in Invoke-Something -p1 'v1'
Reserved words keyword.other configuration
Control words keyword.control break
Enum - keyword storage.type 'enum' in enum myEnum { ... }
Enum - name entity.name.function 'myEnum' in enum myEnum { ... }
Class meta.class Meta scope
Class - keyword storage.type 'class' in class myClass : inheritedClass { ... }
Class - name entity.name.function 'myClass' in class myClass : inheritedClass { ... }
Class - inheritance entity.other.inherited-class 'inheritedClass' in class myClass : inheritedClass { ... }
Class - reserved words keyword.other hidden & static
Class - control words keyword.control.class 'base' in : base( ... )
Operator - redirection keyword.operator.redirection 2>&1
Operator - comparison keyword.operator.comparison -gt
Operator - bitwise keyword.operator.bitwise -band
Operator - logical keyword.operator.logical -and
Operator - format keyword.operator.format -f
Operator - assignment keyword.operator.assignment +=
Operator - logical not keyword.operator.logical-not -not & !
Operator - multiplicative keyword.operator.multiplicative / & *
Operator - unary plus keyword.operator.unary-plus +
Operator - unary minus keyword.operator.unary-minus -
Operator - additive keyword.operator.additive + & -
Operator - range keyword.operator.range ..
Operator - command invocation keyword.operator.other &
Operator - stop parsing keyword.operator --%
Switch - keyword keyword.control 'switch' in switch -regex ($var) { ... }
Switch - parameter variable.parameter '-regex' in switch -regex ($var) { ... }
Switch - reserved word keyword.other default
Illegal invalid.illegal Space after backtick
Variable - $ keyword.other '$' in $variable
Variable - ${..} keyword.other '${' and '}' in ${variable}
Variable - automatic constant.language $_ & $error
Variable - scope storage.modifier.scope 'script' in $script:variable
Variable - name variable.other.readwrite 'variable' in $script:variable

I have started by filling out the scope names as I have used them in my refactored language file.

About scopes and highlighting

If, in the theme, there are colorization rules only for the scope constant.operator, both constant.operator and constant.operator.range will be colorized the same.

If there isn't any colorization rules for a scope, it will be colorized with the "root" color of the current scope. Meaning if the word 'test' only belong to the source scope (or have a scope name that is not defined in the current theme), it will be colorized with the default background color. If the word 'test' is found inside another scope, for instance a string, it will be colorized with the color for the string scope.

Colorization rules may differ between editors. For instance the background parameter. This is supported on Sublime Text, but not in VSCode.

A matched set of characters can be (and more often than not are) assigned multiple scopes. So for example the word variable in function MyFunction {"this is $("a $variable")"} have the following scopes: source, string.quoted.double, meta.subexpression, string.quoted.double and lastly variable.other.readwrite. Only the last one is used for colorization.

About the default themes in VSCode

There are five themes that are defined as default themes in Visual Studio Code:

The themes supports nesting, and:

The following scopes are defined in the plus-themes:

The following scopes are defined in the "old" default themes:

Scope names on the same line, means they are defined in the same colorization rule.

daviwil commented 8 years ago

This is a great start! Curious to see what feedback @aeschli might have.

gravejester commented 8 years ago

Yeah, I have started by just filling out the scope names as I have used them. Hopefully we get some feedback from others in the community so we can decide/make changes as we agree on them :)

vors commented 8 years ago

What are good sources for existing scope names?

gravejester commented 8 years ago

Language files for other languages I guess. I tried looking at the built-in for c# that came with Sublime Text. That one was horrible :(

aeschli commented 8 years ago

https://manual.macromates.com/en/language_grammars is the textmate spec. I also found http://www.apeth.com/nonblog/stories/textmatebundle.html useful.

gravejester commented 8 years ago

@aeschli I looked at the TextMate documentation, but it's not always easy to figure out what scope name to use, so it would be good to have a discussion to come to some kind of agreement, regarding PowerShell as a language.

AdjectiveAllison commented 8 years ago

NOTE: This is attempting to colorize powershell syntax correctly and is not attempting to assign the technically correct scopes at all.

These are the main issues that I ran into that I think should be changed:

Variable - $ keyword.other '$' in $variable Variable - ${..} keyword.other '${' and '}' in ${variable} Variable - automatic constant.language $_ & $error Variable - scope storage.modifier.scope 'script' in $script:variable Variable - name variable.other.readwrite 'variable' in $script:variable

Having all of these as different scopes causes a huge amount of variation between themes that I tested vs powershell ISE. From what I can tell the color of variable.other.readwrite is the color that powershell ISE uses for all of the above variables in every theme that I found. That would mean changing all of the above to variable.other.whatever would be a great way to keep coloring consistent across all themes and editors.

Examples: $script:muffins $_.muffins ${global:muffins} $false All of these would be colored correctly with the above changes.


Keyword.other.* and keyword.operator.* :

Most of the time these are using the default text color in Powershell ISE(read as every theme I tested). If the editor theme includes keyword.operator or keyword.other specifically it sets the color to the default text color. The issue is when many themes do not have these specified, and you end up with tons of operators being the colors of the keywords, which in ISE this color is mainly just used for keyword.control. This was rather frustrating as I could not find a consistent way to represent these as just the simple text color across multiple themes, is there anything they could be set to that would consistently set them to the default text color? If not this might be something that requires updating themes instead of updating scopes.

Examples: any operator is affected "+ - = == =+ * / | - -match -replace -le ++ etc." items labeled as other that were not asked to be changed to variable above already "@() () "


Things I know are wrong but don't know how to fix yet:

[string] $muffins[0] "[ and ]" I am not exactly sure what brackets are being classified as but they are not working well with themes. They are the same as the operators above where they are always the default text color in ISE, but often cause a ton of color contrast for no reason with the other editors.

AdjectiveAllison commented 8 years ago

Making all of those changes(still don't know how to edit the brackets) makes the following difference.

Current syntax in VSCode default

Powershell ISE highlighting powershell-ise

Proposed changes in VScode monokai-edited

As you can see it looks much much better. I have tried it in several different themes and compared with similar results.

Satak commented 7 years ago

Very good demonstration Allieway! My number one reason that I'm not using the VSCode for Powershell projects is the confusing and distracting highlighting. It really should be consistent with ISE.

omniomi commented 6 years ago

We need to reopen this discussion. In my recent changes I followed https://www.sublimetext.com/docs/3/scope_naming.html and compared to some other language syntaxes.

Should we continue here or start fresh?