From 00b21a7eccebdd9e074354af6ab7d13cb91a16d9 Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:26:02 -0500 Subject: [PATCH 001/133] Disable ANSI escape colors in build output (#193) --- Support/Powershell.sublime-build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Support/Powershell.sublime-build b/Support/Powershell.sublime-build index c9021510..f27af30e 100644 --- a/Support/Powershell.sublime-build +++ b/Support/Powershell.sublime-build @@ -1,6 +1,9 @@ { "cmd": ["pwsh", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], "selector": "source.powershell", + "env": { + "TERM": "dumb", + }, "windows": { "cmd": ["powershell.exe", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], From ce16d6d24627765d96d18e3a2c81dab986e0d734 Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:45:30 -0500 Subject: [PATCH 002/133] Test stable ST version (#194) --- .github/workflows/syntax.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/syntax.yml b/.github/workflows/syntax.yml index 19da5411..7531ebe3 100644 --- a/.github/workflows/syntax.yml +++ b/.github/workflows/syntax.yml @@ -1,7 +1,7 @@ name: Syntax Tests +# https://github.com/sublimetext/syntax-test-action on: - push: branches: - '**' @@ -10,33 +10,36 @@ on: paths: - '.github/workflows/syntax.yml' - '**.sublime-syntax' - - '**/syntax_test*' + - '**/syntax_test_*' - '**.tmPreferences' pull_request: paths: - '.github/workflows/syntax.yml' - '**.sublime-syntax' - - '**/syntax_test*' + - '**/syntax_test_*' - '**.tmPreferences' types: - - "opened" - - "reopened" - - "synchronize" + - 'opened' + - 'reopened' + - 'synchronize' workflow_dispatch: jobs: main: name: Syntax Tests (${{ matrix.build }}) + runs-on: ubuntu-latest + timeout-minutes: 15 strategy: matrix: include: - - build: 4107 - packages: v4107 - build: latest packages: master - runs-on: ubuntu-latest + - build: stable + packages: binary + - build: 4107 + packages: binary steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: SublimeText/syntax-test-action@v2 with: build: ${{ matrix.build }} From fc2013d92890f4596827696917d93862e852737d Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Wed, 19 Nov 2025 14:16:33 -0500 Subject: [PATCH 003/133] Bump license --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 0a8767aa..513b0e8f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ Copyright (c) 2011-2015 Guillermo López-Anglada - 2020-2021 Michael Lyons + 2020-2025 Michael Lyons Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: From 860ab2a9fdfe07f0493131386c7fe61204b8a8e2 Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Mon, 1 Dec 2025 11:53:40 -0500 Subject: [PATCH 004/133] Drop defunct publish script (#195) --- .gitattributes | 1 - bin/Publish.ps1 | 52 ------------------------------------------------- 2 files changed, 53 deletions(-) delete mode 100644 bin/Publish.ps1 diff --git a/.gitattributes b/.gitattributes index 7e37a585..d2580af3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,5 +5,4 @@ CONTRIBUTING.md export-ignore # Project and Dev Assets -/bin/ export-ignore *.sublime-project export-ignore diff --git a/bin/Publish.ps1 b/bin/Publish.ps1 deleted file mode 100644 index 3dac4059..00000000 --- a/bin/Publish.ps1 +++ /dev/null @@ -1,52 +0,0 @@ -<# - .DESCRIPTION - Publishes to 'master' after deleting dev files. -#> - -param([string]$Tag) - -function AbortIfProcessFailed { - param([string]$message) - if ($LASTEXITCODE) { throw $message } - exit $LASTEXITCODE -} - -function AbortIfDirtyWorkingDirectory { - if (@(git status --short).Count -ne 0) { - throw "uncommited changes " - exit 1 - } -} - -function AbortIfGitNotAvailable { - get-command git -erroraction stop > $null -} - -function AbortIfNotOnMaster { - if (@(git branch | select-string "* master" -simplematch).Count -eq 0) { - throw "not on 'master' branch" - exit 1 - } -} - -$toDelete = @( - "manifest.json", - "tests", - "bin" -) - -AbortIfGitNotAvailable -AbortIfDirtyWorkingDirectory -AbortIfNotOnMaster - -try { - push-location $PSScriptRoot\.. - - remove-item -recurse $toDelete -exclude "Publish.ps1" -whatif - - write-warning "commit the files, tag and push upstream" -} -finally { - pop-location -} - From 4e67ae9304bb2401199e82604fadcd432cb3cba7 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 1 Dec 2025 11:40:27 -0500 Subject: [PATCH 005/133] Move indentation and fold rules to Support --- Fold.tmPreferences => Support/Fold.tmPreferences | 0 Indentation.tmPreferences => Support/Indentation.tmPreferences | 1 - 2 files changed, 1 deletion(-) rename Fold.tmPreferences => Support/Fold.tmPreferences (100%) rename Indentation.tmPreferences => Support/Indentation.tmPreferences (78%) diff --git a/Fold.tmPreferences b/Support/Fold.tmPreferences similarity index 100% rename from Fold.tmPreferences rename to Support/Fold.tmPreferences diff --git a/Indentation.tmPreferences b/Support/Indentation.tmPreferences similarity index 78% rename from Indentation.tmPreferences rename to Support/Indentation.tmPreferences index 5759b67d..3014a7db 100644 --- a/Indentation.tmPreferences +++ b/Support/Indentation.tmPreferences @@ -1,5 +1,4 @@ - name From 6c166381b77d7a7e83571cc18e4982a71050a6c6 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 1 Dec 2025 11:56:58 -0500 Subject: [PATCH 006/133] Update ReadMe. Drop Contributing.md --- .gitattributes | 1 - CONTRIBUTING.md | 50 ------------------------------------------------- README.md | 19 ++++++++++--------- 3 files changed, 10 insertions(+), 60 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/.gitattributes b/.gitattributes index d2580af3..70df0c49 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,7 +2,6 @@ /.github/ export-ignore /.gitattributes export-ignore /.gitignore export-ignore -CONTRIBUTING.md export-ignore # Project and Dev Assets *.sublime-project export-ignore diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 1660549a..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -## Contributing - -Thanks for taking an interest in contributing to the PowerShell package for -Sublime Text 3! - - -### Development - -Development happens on the **dev** branch. Please send your PRs against that -branch only. - - -### Building Development Versions - -To build development versions, first you need a configuration file in -`~\sublime-package-dev.json`. - -This file must contain the following information: - -``` json -{ - "pathToSublimeText": "...\\sublime_text.exe", - "pathToSublimeTextData": "...\\" -} -``` - - -#### Using Sublime Text - -1. Press Ctrl+Shift+B to open the build systems menu. -2. Select 'PowerShell: Build Dev Version' - - -#### Using the Command Line - -From the project's root: - -``` pwsh -.\bin\BuildFolder.ps1 -verbose -``` - -#### Running Tests - -If you are adding functionality or making substantial changes to existing -code, please add tests and ensure that existing tests pass. - -Currently, we have very few tests and they aren't easy to run... :-( - -If you feel lazy about writing tests, this is the right time to contribute -- -we'll turn a blind eye more often now than later on! ;-) diff --git a/README.md b/README.md index c35ed0ae..6098cc5d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PowerShell Package for Sublime Text 3 +# PowerShell Package for Sublime Text [![Join the chat at https://gitter.im/SublimeText/PowerShell](https://badges.gitter.im/SublimeText/PowerShell.svg)](https://gitter.im/SublimeText/PowerShell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -6,21 +6,22 @@ Adds support for the MS PowerShell programming language. ### Installing -1. Install [package control][package_control] for Sublime Text. +1. Install [Package Control]] for Sublime Text. 1. Install the **PowerShell** package: - 1. Press Ctrl+Shift+P (Cmd+Shift+P on Mac) - 1. Select 'Install Package' - 1. Select 'PowerShell' + 1. Press Ctrl+Shift+P + (Cmd+Shift+P on Mac) + 1. Select **Install Package**. + 1. Select **PowerShell**. ### Developing -You want to contribute? Awesome! Take a look at [CONTRIBUTING.md](CONTRIBUTING.md). +You want to contribute? Awesome! Send us a PR. ### EditorSyntax -Syntax highlighting is adapted from the [EditorSyntax][] project. +Syntax highlighting was originally adapted from the [EditorSyntax][] project. -[package_control]: https://sublime.wbond.net/installation -[EditorSyntax]: https://github.com/PowerShell/EditorSyntax +[package control]: https://sublime.wbond.net/installation +[editorsyntax]: https://github.com/PowerShell/EditorSyntax From 35b8522209439e23f5ea798b09967f7db420220c Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 1 Dec 2025 12:21:46 -0500 Subject: [PATCH 007/133] Fix ReadMe typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6098cc5d..f62821e4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Adds support for the MS PowerShell programming language. ### Installing -1. Install [Package Control]] for Sublime Text. +1. Install [Package Control][] for Sublime Text. 1. Install the **PowerShell** package: 1. Press Ctrl+Shift+P From ae1b785eaae774545f25184f741352fdb229b5be Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 11:53:36 -0500 Subject: [PATCH 008/133] Remove word_wrap setting Re-applies #173 that got lost in a merge --- Support/PowerShell.sublime-settings | 1 - 1 file changed, 1 deletion(-) diff --git a/Support/PowerShell.sublime-settings b/Support/PowerShell.sublime-settings index 77a3a3b6..eb30a80e 100644 --- a/Support/PowerShell.sublime-settings +++ b/Support/PowerShell.sublime-settings @@ -1,5 +1,4 @@ { - "word_wrap": false, "translate_tabs_to_spaces": true, // Skip `-` in word separators "word_separators": "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?", From 2c3f9514eff095733f4212ded3b4478037ffea9e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 13:37:35 -0500 Subject: [PATCH 009/133] Fix build file indentation --- Support/Powershell.sublime-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Support/Powershell.sublime-build b/Support/Powershell.sublime-build index f27af30e..d18a8950 100644 --- a/Support/Powershell.sublime-build +++ b/Support/Powershell.sublime-build @@ -2,7 +2,7 @@ "cmd": ["pwsh", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], "selector": "source.powershell", "env": { - "TERM": "dumb", + "TERM": "dumb", }, "windows": { From 53163285000daa9544b62f2b5bbe2f0938716a6a Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 16:41:25 -0500 Subject: [PATCH 010/133] Reorder and rename many contexts --- PowerShell.sublime-syntax | 487 ++++++++++++++++--------------- Tests/syntax_test_PowerShell.ps1 | 2 +- 2 files changed, 258 insertions(+), 231 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 6372d331..7a4d3f94 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1,6 +1,6 @@ %YAML 1.2 --- -# http://www.sublimetext.com/docs/3/syntax.html +# http://www.sublimetext.com/docs/syntax.html name: PowerShell scope: source.powershell version: 2 @@ -16,23 +16,9 @@ first_line_match: |- | ^\# \s* -\*- [^*]* mode: \s* powershell [^*]* -\*- ) -variables: - dec_exponent: (?:[eE][-+]?\d*) - dec_suffix: '[dD]' - float_suffix: '[dDlL]' - int_suffix: (?i:u[lsy]?|[lnsy]) - unit_suffix: (?i:[kmgtp]b\b) - kebab_break: (?![\w-]) - contexts: - - pop-before-newline: - - match: (?=\n|$) - pop: true - - pop-at-newline: - - match: \n|$ - pop: true + # prototype: + # - include: comments main: - include: regions @@ -42,18 +28,18 @@ contexts: expressions: - include: redirection - include: commands - - include: variable - - include: group - - include: function - - include: attribute - - include: using-directive - - include: type - - include: hashtable + - include: variables + - include: groups + - include: functions + - include: attributes + - include: using-directives + - include: types + - include: hashtables - include: strings - - include: script-block - - include: escape-characters - - include: numeric-constant - - include: class-method + - include: script-blocks + - include: escape-sequences + - include: numbers + - include: class-methods - match: (@)(\() captures: 1: keyword.other.array.begin.powershell @@ -144,7 +130,7 @@ contexts: scope: keyword.control.powershell push: - meta_content_scope: string.unquoted.powershell - - include: pop-before-newline + - include: pop-before-eol - match: \b(?i:hidden|static)\b # This should only be relevant inside a class but will require a rework of how classes are matched. This is a temp fix. scope: storage.modifier.powershell @@ -217,10 +203,6 @@ contexts: # This is very imprecise. Is there a syntax for 'must come after...'? scope: keyword.operator.range.powershell - comments: - - include: comment-block - - include: comment-line - redirection: # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection - match: ([2-6*])(>&)(1) @@ -237,7 +219,7 @@ contexts: # - match: <+ # scope: invalid.illegal.powershell - requires-directive: + requires-directives: # TODO: add back `(?<=#)`-equivalent match - match: (#)((?i:requires))\s captures: @@ -245,8 +227,8 @@ contexts: 2: keyword.control.import.require.powershell push: - meta_scope: meta.requires.powershell - - include: pop-at-newline - - include: hashtable + - include: pop-eol + - include: hashtables - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) scope: variable.parameter.option.powershell captures: @@ -254,14 +236,14 @@ contexts: - match: ',' scope: punctuation.separator.powershell - using-directive: + using-directives: - match: \b(?i:(using))\s+(?i:(namespace|module))\s+(?i:((?:\w+(?:\.)?)+)) captures: 1: keyword.control.using.powershell 2: keyword.other.powershell 3: variable.parameter.powershell - attribute: + attributes: - match: |- (?xi: (\[)\s* @@ -288,14 +270,14 @@ contexts: - match: \) scope: punctuation.section.group.end.powershell pop: true - - include: variable - - include: variable-no-property - - include: hashtable - - include: script-block - - include: escape-characters - - include: double-quoted-string - - include: type - - include: numeric-constant + - include: variables + - include: variables-without-property + - include: hashtables + - include: script-blocks + - include: escape-sequences + - include: double-quoted-strings + - include: types + - include: numbers - include: main - match: |- (?xi: @@ -349,54 +331,6 @@ contexts: - match: \b(?i:(?:foreach|where|sort|tee)-object)\b scope: support.function.powershell - comment-block: - - match: <# - scope: punctuation.definition.comment.block.begin.powershell - push: - - meta_scope: comment.block.powershell - - match: '#>' - scope: punctuation.definition.comment.block.end.powershell - pop: true - - include: comment-embedded-docs - - comment-embedded-docs: - # TODO - # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help - - match: |- - (?xi: - ^\s*(\.) - ( - Component | Description | Example | ExternalHelp | ForwardHelpCategory | ForwardHelpTargetName - | Functionality | Inputs | Link | Notes | Outputs | Parameter | RemoteHelpRunSpace - | Role | Synopsis - ) - ) - scope: comment.documentation.embedded.powershell - captures: - 1: punctuation.definition.keyword.documentation.powershell - 2: keyword.other.documentation.powershell - - match: ^\s*(\.)(?i:(Parameter)\s+([a-z0-9-_]+)) - scope: comment.documentation.embedded.powershell - captures: - 1: punctuation.definition.keyword.documentation.powershell - 2: keyword.other.documentation.param.powershell - 3: variable.parameter.powershell - - match: ^\s*(\.)(?i:(ForwardHelpTargetName|ForwardHelpCategory|ExternalHelp|Link)\s+([a-z0-9-_]+)) - scope: comment.documentation.embedded.powershell - captures: - 1: punctuation.definition.keyword.documentation.powershell - 2: keyword.other.documentation.powershell - 3: markup.underline.link.powershell - - comment-line: - - include: requires-directive - - match: '#' - scope: punctuation.definition.comment.powershell - push: - - meta_scope: comment.line.powershell - - include: pop-at-newline - - include: comment-embedded-docs - static-members: # - meta_content_scope: debug.in.static-members - match: '::' @@ -432,62 +366,7 @@ contexts: - match: '' pop: true - strings: - - include: double-quoted-string - - include: single-quoted-string - - match: \@"(?=$) - scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell - - match: ^"@ - scope: punctuation.definition.string.end.powershell - pop: true - - include: escape-characters - - include: interpolation - - match: \@'(?=$) - scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell - - match: ^'@ - scope: punctuation.definition.string.end.powershell - pop: true - - match: "''" - scope: constant.character.escape.powershell - - single-quoted-string: - - match: \' - scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: meta.string.powershell string.quoted.single.powershell - - match: "''" - scope: constant.character.escape.powershell - - match: \' - scope: punctuation.definition.string.end.powershell - pop: true - - double-quoted-string: - - match: '"' - scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: meta.string.powershell string.quoted.double.powershell - - match: '""' - scope: constant.character.escape.powershell - - include: escape-characters - - match: '"' - scope: punctuation.definition.string.end.powershell - pop: true - - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' - - include: interpolation - - match: '`\s*$' - scope: keyword.other.powershell - - escape-characters: - - match: '`[0abenfrvt"''$`]' - scope: constant.character.escape.powershell - - match: '`u\{\h+\}' - scope: constant.character.escape.powershell - - function: + functions: - match: ^(?:\s*)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) scope: meta.function.powershell captures: @@ -499,7 +378,7 @@ contexts: pop: true - include: comment-line - hashtable: + hashtables: - match: (@)(\{) captures: 1: keyword.other.hashtable.begin.powershell @@ -516,10 +395,10 @@ contexts: 2: variable.other.readwrite.powershell 3: punctuation.definition.string.end.powershell 4: keyword.operator.assignment.powershell - - include: script-block + - include: script-blocks - include: main - group: + groups: - match: \( scope: punctuation.section.group.begin.powershell push: @@ -529,79 +408,7 @@ contexts: pop: true - include: main - interpolation: - - match: \$\( - scope: punctuation.section.interpolation.begin.powershell - push: - - clear_scopes: 1 - - meta_scope: meta.interpolation.powershell - - meta_content_scope: source.powershell.embedded - - match: \) - scope: punctuation.section.interpolation.end.powershell - pop: true - - include: main - - match: (?=\$) - push: - - clear_scopes: 1 - - meta_scope: meta.interpolation.powershell - - include: variable-no-property - - include: variable - - match: '' - pop: true - - numeric-constant: - - match: \b(0[bB])([01]*)({{int_suffix}}?{{unit_suffix}}?) - scope: meta.number.integer.binary.powershell - captures: - 1: constant.numeric.base.powershell - 2: constant.numeric.value.powershell - 3: constant.numeric.suffix.powershell - push: members - - match: \b(0[xX])(\h*)({{int_suffix}}?{{unit_suffix}}?) - scope: meta.number.integer.hexadecimal.powershell - captures: - 1: constant.numeric.base.powershell - 2: constant.numeric.value.powershell - 3: constant.numeric.suffix.powershell - push: members - - match: |- - (?x) - ( - # .10 .10e5 - (\.)\d+{{dec_exponent}}? - # 1.2 1.2e-3 1.e2 1e2 - | \d+ (?: (\.) \d+ {{dec_exponent}}? | (\.)? {{dec_exponent}} ) - ) - ( {{float_suffix}}? {{unit_suffix}}? ) - | - # 10.l 10.lGB 10.GB - ( \d+ (\.) ) - ( {{float_suffix}} {{unit_suffix}}? | {{unit_suffix}} ) - scope: meta.number.float.decimal.powershell - captures: - 1: constant.numeric.value.powershell - 2: punctuation.separator.decimal.powershell - 3: punctuation.separator.decimal.powershell - 4: punctuation.separator.decimal.powershell - 5: constant.numeric.suffix.powershell - 6: constant.numeric.value.powershell - 7: punctuation.separator.decimal.powershell - 8: constant.numeric.suffix.powershell - push: members - - match: \b(\d+)({{dec_suffix}}{{unit_suffix}}?) - scope: meta.number.float.decimal.powershell - captures: - 1: constant.numeric.value.powershell - 2: constant.numeric.suffix.powershell - push: members - - match: \b(\d+)({{int_suffix}}?{{unit_suffix}}?) - scope: meta.number.integer.decimal.powershell - captures: - 1: constant.numeric.value.powershell - 2: constant.numeric.suffix.powershell - push: members - - script-block: + script-blocks: - match: (%)?(\{) captures: 1: keyword.control.loop.for.powershell @@ -613,7 +420,7 @@ contexts: pop: true - include: main - type: + types: # TODO: push a maybe-static-members context - match: \[ scope: punctuation.section.brackets.begin.powershell @@ -628,7 +435,7 @@ contexts: scope: storage.type.powershell - include: main - variable: + variables: - match: (\$)(?i:True|False|Null)\b scope: constant.language.powershell captures: @@ -716,7 +523,7 @@ contexts: 6: punctuation.section.braces.end.powershell push: members - variable-no-property: + variables-without-property: - match: (\$)(?i:True|False|Null)\b scope: constant.language.powershell captures: @@ -796,7 +603,7 @@ contexts: 4: variable.other.readwrite.powershell 5: punctuation.section.braces.end - class-method: + class-methods: - match: ^(?:\s*)(?i)(hidden|static)?\s*(\[)((?!\d+|\.)[\p{L}\p{N}.]+)(\])\s*((?:\p{L}|\d|_|-|\.)+)\s*(?=\() scope: meta.function.powershell captures: @@ -824,3 +631,223 @@ contexts: 2: punctuation.definition.comment.powershell 3: keyword.other.region.end.powershell 4: meta.fold.end.powershell + +###[ LITERALS ]################################################################ + + literals: + - include: strings + - include: numbers + + strings: + - include: double-quoted-strings + - include: single-quoted-strings + - match: \@"(?=$) + scope: punctuation.definition.string.begin.powershell + push: + - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell + - match: ^"@ + scope: punctuation.definition.string.end.powershell + pop: true + - include: escape-sequences + - include: string-interpolations + - match: \@'(?=$) + scope: punctuation.definition.string.begin.powershell + push: + - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell + - match: ^'@ + scope: punctuation.definition.string.end.powershell + pop: true + - match: "''" + scope: constant.character.escape.powershell + + single-quoted-strings: + - match: \' + scope: punctuation.definition.string.begin.powershell + push: + - meta_scope: meta.string.powershell string.quoted.single.powershell + - match: "''" + scope: constant.character.escape.powershell + - match: \' + scope: punctuation.definition.string.end.powershell + pop: true + + double-quoted-strings: + - match: '"' + scope: punctuation.definition.string.begin.powershell + push: + - meta_scope: meta.string.powershell string.quoted.double.powershell + - match: '""' + scope: constant.character.escape.powershell + - include: escape-sequences + - match: '"' + scope: punctuation.definition.string.end.powershell + pop: true + - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' + - include: string-interpolations + - match: '`\s*$' + scope: keyword.other.powershell + + string-interpolations: + - match: \$\( + scope: punctuation.section.interpolation.begin.powershell + push: + - clear_scopes: 1 + - meta_scope: meta.interpolation.powershell + - meta_content_scope: source.powershell.embedded + - match: \) + scope: punctuation.section.interpolation.end.powershell + pop: true + - include: main + - match: (?=\$) + push: + - clear_scopes: 1 + - meta_scope: meta.interpolation.powershell + - include: variables-without-property + - include: variables + - include: immediately-pop + + numbers: + # Binary numbers + - match: \b(0[bB])([01]*)({{int_suffix}}?{{unit_suffix}}?) + scope: meta.number.integer.binary.powershell + captures: + 1: constant.numeric.base.powershell + 2: constant.numeric.value.powershell + 3: constant.numeric.suffix.powershell + push: members + # Hexadecimal numbers + - match: \b(0[xX])(\h*)({{int_suffix}}?{{unit_suffix}}?) + scope: meta.number.integer.hexadecimal.powershell + captures: + 1: constant.numeric.base.powershell + 2: constant.numeric.value.powershell + 3: constant.numeric.suffix.powershell + push: members + # Floats + - match: |- + (?x) + ( + # .10 .10e5 + (\.)\d+{{dec_exponent}}? + # 1.2 1.2e-3 1.e2 1e2 + | \d+ (?: (\.) \d+ {{dec_exponent}}? | (\.)? {{dec_exponent}} ) + ) + ( {{float_suffix}}? {{unit_suffix}}? ) + | + # 10.l 10.lGB 10.GB + ( \d+ (\.) ) + ( {{float_suffix}} {{unit_suffix}}? | {{unit_suffix}} ) + scope: meta.number.float.decimal.powershell + captures: + 1: constant.numeric.value.powershell + 2: punctuation.separator.decimal.powershell + 3: punctuation.separator.decimal.powershell + 4: punctuation.separator.decimal.powershell + 5: constant.numeric.suffix.powershell + 6: constant.numeric.value.powershell + 7: punctuation.separator.decimal.powershell + 8: constant.numeric.suffix.powershell + push: members + # "Decimal" numbers + - match: \b(\d+)({{dec_suffix}}{{unit_suffix}}?) + scope: meta.number.float.decimal.powershell + captures: + 1: constant.numeric.value.powershell + 2: constant.numeric.suffix.powershell + push: members + # Integers + - match: \b(\d+)({{int_suffix}}?{{unit_suffix}}?) + scope: meta.number.integer.decimal.powershell + captures: + 1: constant.numeric.value.powershell + 2: constant.numeric.suffix.powershell + push: members + +###[ COMMENTS ]################################################################ + + comments: + - include: comment-block + - include: comment-line + + comment-block: + - match: <# + scope: punctuation.definition.comment.block.begin.powershell + push: + - meta_scope: comment.block.powershell + - match: '#>' + scope: punctuation.definition.comment.block.end.powershell + pop: true + - include: comment-embedded-docs + + comment-embedded-docs: + # TODO + # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help + - match: |- + (?xi: + ^\s*(\.) + ( + Component | Description | Example | ExternalHelp | ForwardHelpCategory | ForwardHelpTargetName + | Functionality | Inputs | Link | Notes | Outputs | Parameter | RemoteHelpRunSpace + | Role | Synopsis + ) + ) + scope: comment.documentation.embedded.powershell + captures: + 1: punctuation.definition.keyword.documentation.powershell + 2: keyword.other.documentation.powershell + - match: ^\s*(\.)(?i:(Parameter)\s+([a-z0-9-_]+)) + scope: comment.documentation.embedded.powershell + captures: + 1: punctuation.definition.keyword.documentation.powershell + 2: keyword.other.documentation.param.powershell + 3: variable.parameter.powershell + - match: ^\s*(\.)(?i:(ForwardHelpTargetName|ForwardHelpCategory|ExternalHelp|Link)\s+([a-z0-9-_]+)) + scope: comment.documentation.embedded.powershell + captures: + 1: punctuation.definition.keyword.documentation.powershell + 2: keyword.other.documentation.powershell + 3: markup.underline.link.powershell + + comment-line: + # TODO: Is requires-directive really a thing here? + - include: requires-directives + - match: '#' + scope: punctuation.definition.comment.powershell + push: + - meta_scope: comment.line.powershell + - include: pop-eol + - include: comment-embedded-docs + +###[ COMPONENTS ]############################################################## + + escape-sequences: + - match: '`[0abenfrvt"''$`]' + scope: constant.character.escape.powershell + - match: '`u\{\h+\}' + scope: constant.character.escape.powershell + + pop-eol: + - match: $ + pop: true + + pop-before-eol: + - match: (?=$) + pop: true + + immediately-pop: + - match: '' + pop: true + + else-pop: + - match: (?=\S) + pop: true + +############################################################################### + +variables: + dec_exponent: (?:[eE][-+]?\d*) + dec_suffix: '[dD]' + float_suffix: '[dDlL]' + int_suffix: (?i:u[lsy]?|[lnsy]) + unit_suffix: (?i:[kmgtp]b\b) + kebab_break: (?![\w-]) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index bb9d932a..d9154142 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -5,7 +5,7 @@ using namespace System.Management.Automation # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter #Requires -PSSnapin DiskSnapin -Version 1.2 # <- punctuation.definition.keyword -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.requires +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.requires #^^^^^^^^ keyword.control.import.require # ^^^^^^^^^ variable.parameter # ^^^^^^^^ variable.parameter From 1aaf5587a9fac064b9aab600ff472778b7a937fc Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 17:15:18 -0500 Subject: [PATCH 011/133] Introduce a statements context --- PowerShell.sublime-syntax | 252 +++++++++++++++++-------------- Tests/syntax_test_PowerShell.ps1 | 1 - 2 files changed, 139 insertions(+), 114 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 7a4d3f94..352a0d99 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -17,57 +17,15 @@ first_line_match: |- ) contexts: - # prototype: - # - include: comments + prototype: + - include: comments main: - - include: regions + - include: statements + + statements: - include: comments - include: expressions - - expressions: - - include: redirection - - include: commands - - include: variables - - include: groups - - include: functions - - include: attributes - - include: using-directives - - include: types - - include: hashtables - - include: strings - - include: script-blocks - - include: escape-sequences - - include: numbers - - include: class-methods - - match: (@)(\() - captures: - 1: keyword.other.array.begin.powershell - 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.array-expression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: true - - include: main - - match: (\$)(\() - # TODO: move to repo; make recursive. - captures: - 1: keyword.other.variable.definition.powershell - 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.complex.subexpression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: true - - include: main - - match: \b[\w.-]+\.(?i:exe|com|cmd|bat)\b - scope: variable.function.powershell - # Consume a string with a trailing dot - # to prevent members with particular names from being recognized as keywords. - - match: \b[\w-]+(?=\.) - scope: variable.other.object.powershell - push: members # Exceptions - match: \b(?i:throw){{kebab_break}} scope: keyword.control.exception.raise.powershell @@ -77,19 +35,6 @@ contexts: scope: keyword.control.exception.catch.powershell - match: \b(?i:finally){{kebab_break}} scope: keyword.control.exception.finally.powershell - # Conditionals - - match: \b(?i:if){{kebab_break}} - scope: keyword.control.conditional.if.powershell - - match: \b(?i:elseif){{kebab_break}} - scope: keyword.control.conditional.elseif.powershell - - match: \b(?i:else){{kebab_break}} - scope: keyword.control.conditional.else.powershell - - match: \b(?i:switch){{kebab_break}} - scope: keyword.control.conditional.switch.powershell - - match: \? - scope: keyword.control.conditional.select.powershell - - match: \b(?i:where(?!-object)){{kebab_break}} - scope: keyword.control.conditional.select.powershell # Begin/End - match: \b(?i:begin){{kebab_break}} scope: keyword.context.block.begin.powershell @@ -117,12 +62,69 @@ contexts: scope: keyword.control.flow.exit.powershell - match: \b(?i:return){{kebab_break}} scope: keyword.control.flow.return.powershell + # Conditionals + - match: \b(?i:if){{kebab_break}} + scope: keyword.control.conditional.if.powershell + - match: \b(?i:elseif){{kebab_break}} + scope: keyword.control.conditional.elseif.powershell + - match: \b(?i:else){{kebab_break}} + scope: keyword.control.conditional.else.powershell + - match: \b(?i:switch){{kebab_break}} + scope: keyword.control.conditional.switch.powershell + - match: \? + scope: keyword.control.conditional.select.powershell + - match: \b(?i:where(?!-object)){{kebab_break}} + scope: keyword.control.conditional.select.powershell # Declaration - match: \b(?i:var){{kebab_break}} # scope: storage.type.variable.powershell scope: keyword.declaration.variable.powershell - match: \b(?i:(?:dynamic)?param){{kebab_break}} scope: keyword.declaration.parameter.powershell # This scope is not standard + + expressions: + - include: redirection + - include: commands + - include: variables + - include: groups + - include: functions + - include: attributes + - include: using-directives + - include: types + - include: hashtables + - include: strings + - include: script-blocks + - include: escape-sequences + - include: numbers + - include: class-methods + - match: (@)(\() + captures: + 1: keyword.other.array.begin.powershell + 2: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.array-expression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: true + - include: statements + - match: (\$)(\() + # TODO: move to repo; make recursive. + captures: + 1: keyword.other.variable.definition.powershell + 2: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.complex.subexpression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: true + - include: statements + - match: \b[\w.-]+\.(?i:exe|com|cmd|bat)\b + scope: variable.function.powershell + # Consume a string with a trailing dot + # to prevent members with particular names from being recognized as keywords. + - match: \b[\w-]+(?=\.) + scope: variable.other.object.powershell + push: members # Uncategorized keywords - match: \b(?i:data|default|define|from|in|inlinescript|parallel|sequence){{kebab_break}} scope: keyword.control.powershell @@ -138,7 +140,17 @@ contexts: captures: 1: storage.type.class.powershell 2: meta.class.powershell entity.name.class.powershell - # Operators... + + - include: operators + + # Flags/Options/Parameters + - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? + scope: variable.parameter.option.powershell + captures: + 1: punctuation.definition.parameter.powershell + + operators: + # Word operators - match: \B(-)(?i:as){{kebab_break}} scope: keyword.operator.cast.powershell captures: @@ -171,19 +183,19 @@ contexts: scope: keyword.operator.string-format.powershell captures: 1: punctuation.definition.keyword.powershell - # Flags/Options/Parameters - - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? - scope: variable.parameter.option.powershell - captures: - 1: punctuation.definition.parameter.powershell - # Operators continue... + # Symbol operators - match: '[+/*%-]?=' scope: keyword.operator.assignment.powershell - - match: (?:\+\+|--)(?![ \t]*\d) + - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) scope: keyword.operator.assignment.powershell - match: '[+-](?=\.?\d)' # This is sort of heuristic scope: keyword.operator.unary.powershell - - match: '[+/*-]' + # Be careful about matching arithmetic with tightly following words + - match: '[/+](?![[:alpha:]])' + scope: keyword.operator.arithmetic.powershell + - match: -(?![[:alpha:]-]) + scope: keyword.operator.arithmetic.powershell + - match: \* scope: keyword.operator.arithmetic.powershell - match: '%(?!\s*\{)' scope: keyword.operator.arithmetic.powershell @@ -203,6 +215,7 @@ contexts: # This is very imprecise. Is there a syntax for 'must come after...'? scope: keyword.operator.range.powershell + redirection: # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection - match: ([2-6*])(>&)(1) @@ -270,15 +283,15 @@ contexts: - match: \) scope: punctuation.section.group.end.powershell pop: true - - include: variables - - include: variables-without-property - - include: hashtables - - include: script-blocks - - include: escape-sequences - - include: double-quoted-strings - - include: types - - include: numbers - - include: main + # - include: variables + # - include: variables-without-property + # - include: hashtables + # - include: script-blocks + # - include: escape-sequences + # - include: double-quoted-strings + # - include: types + # - include: numbers + - include: statements - match: |- (?xi: \b( @@ -396,7 +409,7 @@ contexts: 3: punctuation.definition.string.end.powershell 4: keyword.operator.assignment.powershell - include: script-blocks - - include: main + - include: statements groups: - match: \( @@ -406,7 +419,7 @@ contexts: - match: \) scope: punctuation.section.group.end.powershell pop: true - - include: main + - include: statements script-blocks: - match: (%)?(\{) @@ -418,7 +431,7 @@ contexts: - match: \} scope: punctuation.section.braces.end.powershell pop: true - - include: main + - include: statements types: # TODO: push a maybe-static-members context @@ -433,7 +446,7 @@ contexts: pop: true - match: (?!\d+|\.)[\p{L}\p{N}.]+ scope: storage.type.powershell - - include: main + - include: types variables: - match: (\$)(?i:True|False|Null)\b @@ -641,18 +654,46 @@ contexts: strings: - include: double-quoted-strings - include: single-quoted-strings - - match: \@"(?=$) + - include: double-quoted-heredoc-strings + - include: single-quoted-heredoc-strings + + single-quoted-strings: + - match: \' scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell - - match: ^"@ - scope: punctuation.definition.string.end.powershell - pop: true - - include: escape-sequences - - include: string-interpolations + push: inside-single-quoted-string + + inside-single-quoted-string: + - meta_scope: meta.string.powershell string.quoted.single.powershell + - match: "''" + scope: constant.character.escape.powershell + - match: \' + scope: punctuation.definition.string.end.powershell + pop: true + + double-quoted-strings: + - match: '"' + scope: punctuation.definition.string.begin.powershell + push: inside-double-quoted-string + + inside-double-quoted-string: + - meta_include_prototype: false + - meta_scope: meta.string.powershell string.quoted.double.powershell + - match: '""' + scope: constant.character.escape.powershell + - include: escape-sequences + - match: '"' + scope: punctuation.definition.string.end.powershell + pop: true + - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' + - include: string-interpolations + - match: '`\s*$' + scope: keyword.other.powershell + + single-quoted-heredoc-strings: - match: \@'(?=$) scope: punctuation.definition.string.begin.powershell push: + - meta_include_prototype: false - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell - match: ^'@ scope: punctuation.definition.string.end.powershell @@ -660,32 +701,17 @@ contexts: - match: "''" scope: constant.character.escape.powershell - single-quoted-strings: - - match: \' + double-quoted-heredoc-strings: + - match: \@"(?=$) scope: punctuation.definition.string.begin.powershell push: - - meta_scope: meta.string.powershell string.quoted.single.powershell - - match: "''" - scope: constant.character.escape.powershell - - match: \' + - meta_include_prototype: false + - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell + - match: ^"@ scope: punctuation.definition.string.end.powershell pop: true - - double-quoted-strings: - - match: '"' - scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: meta.string.powershell string.quoted.double.powershell - - match: '""' - scope: constant.character.escape.powershell - include: escape-sequences - - match: '"' - scope: punctuation.definition.string.end.powershell - pop: true - - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' - include: string-interpolations - - match: '`\s*$' - scope: keyword.other.powershell string-interpolations: - match: \$\( @@ -697,7 +723,7 @@ contexts: - match: \) scope: punctuation.section.interpolation.end.powershell pop: true - - include: main + - include: expressions - match: (?=\$) push: - clear_scopes: 1 @@ -766,6 +792,8 @@ contexts: ###[ COMMENTS ]################################################################ comments: + - include: regions + - include: requires-directives - include: comment-block - include: comment-line @@ -809,8 +837,6 @@ contexts: 3: markup.underline.link.powershell comment-line: - # TODO: Is requires-directive really a thing here? - - include: requires-directives - match: '#' scope: punctuation.definition.comment.powershell push: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index d9154142..85ba6d93 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -777,7 +777,6 @@ A 'single quoted' "heredoc" # <- punctuation.section.brackets.begin # ^^^^^^^^^^^ storage.type # ^^^^^^^^^^^^^^^^^ storage.type -# ^ keyword.operator # ^ punctuation.section.brackets.end [int]::MinValue # <- punctuation.section.brackets.begin From be846f37981c801008c66b814c5f90a50f494609 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 17:57:35 -0500 Subject: [PATCH 012/133] Move comment-like contexts --- PowerShell.sublime-syntax | 65 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 352a0d99..9d8ab4dc 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -215,7 +215,6 @@ contexts: # This is very imprecise. Is there a syntax for 'must come after...'? scope: keyword.operator.range.powershell - redirection: # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection - match: ([2-6*])(>&)(1) @@ -232,23 +231,6 @@ contexts: # - match: <+ # scope: invalid.illegal.powershell - requires-directives: - # TODO: add back `(?<=#)`-equivalent match - - match: (#)((?i:requires))\s - captures: - 1: punctuation.definition.keyword.powershell - 2: keyword.control.import.require.powershell - push: - - meta_scope: meta.requires.powershell - - include: pop-eol - - include: hashtables - - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) - scope: variable.parameter.option.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: ',' - scope: punctuation.separator.powershell - using-directives: - match: \b(?i:(using))\s+(?i:(namespace|module))\s+(?i:((?:\w+(?:\.)?)+)) captures: @@ -630,21 +612,6 @@ contexts: pop: true - include: comment-line - regions: - - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.begin.powershell - 4: meta.toc-list.powershell entity.name.section.powershell - 5: meta.fold.begin.powershell - - match: ^\s*((#)\s*(endregion\b).*(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.end.powershell - 4: meta.fold.end.powershell - ###[ LITERALS ]################################################################ literals: @@ -844,6 +811,38 @@ contexts: - include: pop-eol - include: comment-embedded-docs + regions: + - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.begin.powershell + 4: meta.toc-list.powershell entity.name.section.powershell + 5: meta.fold.begin.powershell + - match: ^\s*((#)\s*(endregion\b).*(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.end.powershell + 4: meta.fold.end.powershell + + requires-directives: + # TODO: add back `(?<=#)`-equivalent match + - match: (#)((?i:requires))\s + captures: + 1: punctuation.definition.keyword.powershell + 2: keyword.control.import.require.powershell + push: + - meta_scope: meta.requires.powershell + - include: pop-eol + - include: hashtables + - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) + scope: variable.parameter.option.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: ',' + scope: punctuation.separator.powershell + ###[ COMPONENTS ]############################################################## escape-sequences: From f9806e080926dc25b90bcc3d9109c909df50673b Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:00:21 -0500 Subject: [PATCH 013/133] Tighten attributes context --- PowerShell.sublime-syntax | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 9d8ab4dc..ffa68c5d 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -265,15 +265,6 @@ contexts: - match: \) scope: punctuation.section.group.end.powershell pop: true - # - include: variables - # - include: variables-without-property - # - include: hashtables - # - include: script-blocks - # - include: escape-sequences - # - include: double-quoted-strings - # - include: types - # - include: numbers - - include: statements - match: |- (?xi: \b( @@ -287,15 +278,7 @@ contexts: captures: 1: variable.parameter.attribute.powershell 2: keyword.operator.assignment.powershell - - match: \' - scope: punctuation.definition.string.begin.powershell - push: - - meta_scope: string.quoted.single.powershell - - match: \'\' - scope: constant.character.escape.powershell - - match: \' - scope: punctuation.definition.string.end.powershell - pop: true + - include: expressions commands: # "Verb-Noun pattern:" From 9bb056728c88bb4e297a8f8df2da24c7f7355701 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:18:36 -0500 Subject: [PATCH 014/133] Rearrange groups --- PowerShell.sublime-syntax | 102 ++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index ffa68c5d..83ea22a2 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -24,8 +24,8 @@ contexts: - include: statements statements: - - include: comments - include: expressions + - include: functions # Exceptions - match: \b(?i:throw){{kebab_break}} scope: keyword.control.exception.raise.powershell @@ -83,11 +83,13 @@ contexts: scope: keyword.declaration.parameter.powershell # This scope is not standard expressions: + # BUG: When we figure out what's wrong with `prototype`, remove this. + - include: comments + - include: redirection - include: commands + - include: constants - include: variables - - include: groups - - include: functions - include: attributes - include: using-directives - include: types @@ -97,27 +99,9 @@ contexts: - include: escape-sequences - include: numbers - include: class-methods - - match: (@)(\() - captures: - 1: keyword.other.array.begin.powershell - 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.array-expression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: true - - include: statements - - match: (\$)(\() - # TODO: move to repo; make recursive. - captures: - 1: keyword.other.variable.definition.powershell - 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.complex.subexpression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: true - - include: statements + - include: groups + - include: arrays + - include: subexpressions - match: \b[\w.-]+\.(?i:exe|com|cmd|bat)\b scope: variable.function.powershell # Consume a string with a trailing dot @@ -376,16 +360,6 @@ contexts: - include: script-blocks - include: statements - groups: - - match: \( - scope: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: true - - include: statements - script-blocks: - match: (%)?(\{) captures: @@ -414,10 +388,6 @@ contexts: - include: types variables: - - match: (\$)(?i:True|False|Null)\b - scope: constant.language.powershell - captures: - 1: punctuation.definition.variable.powershell - match: |- (?xi: (\$) @@ -502,10 +472,6 @@ contexts: push: members variables-without-property: - - match: (\$)(?i:True|False|Null)\b - scope: constant.language.powershell - captures: - 1: punctuation.definition.variable.powershell - match: |- (?xi: (\$) @@ -595,6 +561,58 @@ contexts: pop: true - include: comment-line +###[ GROUPS ]################################################################## + + groups: + - match: \( + scope: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: true + - include: expressions + + arrays: + - match: (@)(\() + captures: + 1: keyword.other.array.begin.powershell + 2: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.array-expression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: true + - include: expressions + + subexpressions: + - match: (\$)(\() + captures: + 1: keyword.other.variable.definition.powershell + 2: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.complex.subexpression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: true + - include: expressions + +###[ CONSTANTS ]############################################################### + + constants: + - match: (?i)(\$)True\b + scope: constant.language.boolean.true.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: (?i)(\$)False\b + scope: constant.language.boolean.false.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: (?i)(\$)Null\b + scope: constant.language.null.powershell + captures: + 1: punctuation.definition.variable.powershell + ###[ LITERALS ]################################################################ literals: From 600f7a06da1ff8bfb3d236a1d3d1b03d501e0ac1 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:23:30 -0500 Subject: [PATCH 015/133] Move classes to statements --- PowerShell.sublime-syntax | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 83ea22a2..0e9cb1aa 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -26,6 +26,10 @@ contexts: statements: - include: expressions - include: functions + - match: \b((?i:class))\s+([\w-]+)\b + captures: + 1: storage.type.class.powershell + 2: meta.class.powershell entity.name.class.powershell # Exceptions - match: \b(?i:throw){{kebab_break}} scope: keyword.control.exception.raise.powershell @@ -120,10 +124,6 @@ contexts: - match: \b(?i:hidden|static)\b # This should only be relevant inside a class but will require a rework of how classes are matched. This is a temp fix. scope: storage.modifier.powershell - - match: \b((?i:class))\s+([\w-]+)\b - captures: - 1: storage.type.class.powershell - 2: meta.class.powershell entity.name.class.powershell - include: operators From b3b62dfe641ec17933b0af8eeb8ad4920dbcd1fe Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:24:01 -0500 Subject: [PATCH 016/133] Comment out special handling of emails in strings --- PowerShell.sublime-syntax | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 0e9cb1aa..d13bfc76 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -652,7 +652,8 @@ contexts: - match: '"' scope: punctuation.definition.string.end.powershell pop: true - - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' + # # Silently eat email addresses + # - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' - include: string-interpolations - match: '`\s*$' scope: keyword.other.powershell From acd846321949561557ceb092a1cdf5cb940e58b5 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:34:25 -0500 Subject: [PATCH 017/133] Slot hashtables in among groups --- PowerShell.sublime-syntax | 40 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index d13bfc76..4c2087a4 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -81,7 +81,6 @@ contexts: scope: keyword.control.conditional.select.powershell # Declaration - match: \b(?i:var){{kebab_break}} - # scope: storage.type.variable.powershell scope: keyword.declaration.variable.powershell - match: \b(?i:(?:dynamic)?param){{kebab_break}} scope: keyword.declaration.parameter.powershell # This scope is not standard @@ -340,26 +339,6 @@ contexts: pop: true - include: comment-line - hashtables: - - match: (@)(\{) - captures: - 1: keyword.other.hashtable.begin.powershell - 2: punctuation.section.braces.begin.powershell - push: - - meta_scope: meta.hashtable.powershell - - match: \} - scope: punctuation.section.braces.end.powershell - pop: true - - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* - scope: meta.hashtable.assignment.powershell - captures: - 1: punctuation.definition.string.begin.powershell - 2: variable.other.readwrite.powershell - 3: punctuation.definition.string.end.powershell - 4: keyword.operator.assignment.powershell - - include: script-blocks - - include: statements - script-blocks: - match: (%)?(\{) captures: @@ -585,6 +564,25 @@ contexts: pop: true - include: expressions + hashtables: + - match: (@)(\{) + captures: + 1: keyword.other.hashtable.begin.powershell + 2: punctuation.section.braces.begin.powershell + push: + - meta_scope: meta.hashtable.powershell + - match: \} + scope: punctuation.section.braces.end.powershell + pop: true + - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* + scope: meta.hashtable.assignment.powershell + captures: + 1: punctuation.definition.string.begin.powershell + 2: variable.other.readwrite.powershell + 3: punctuation.definition.string.end.powershell + 4: keyword.operator.assignment.powershell + - include: expressions + subexpressions: - match: (\$)(\() captures: From 16cb8aa3382983824fc53d22d6457af1643188ac Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:41:14 -0500 Subject: [PATCH 018/133] Require class stuff to at least be in a block --- PowerShell.sublime-syntax | 53 +++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 4c2087a4..8ee4f560 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -24,12 +24,9 @@ contexts: - include: statements statements: + - include: classes - include: expressions - include: functions - - match: \b((?i:class))\s+([\w-]+)\b - captures: - 1: storage.type.class.powershell - 2: meta.class.powershell entity.name.class.powershell # Exceptions - match: \b(?i:throw){{kebab_break}} scope: keyword.control.exception.raise.powershell @@ -101,7 +98,6 @@ contexts: - include: script-blocks - include: escape-sequences - include: numbers - - include: class-methods - include: groups - include: arrays - include: subexpressions @@ -120,9 +116,6 @@ contexts: push: - meta_content_scope: string.unquoted.powershell - include: pop-before-eol - - match: \b(?i:hidden|static)\b - # This should only be relevant inside a class but will require a rework of how classes are matched. This is a temp fix. - scope: storage.modifier.powershell - include: operators @@ -349,6 +342,12 @@ contexts: - match: \} scope: punctuation.section.braces.end.powershell pop: true + + # TODO: Fix classes, so this doesn't nest here. + - include: class-methods + - match: \b(?i:hidden|static)\b + scope: storage.modifier.powershell + - include: statements types: @@ -366,6 +365,30 @@ contexts: scope: storage.type.powershell - include: types +###[ CLASSES ]################################################################# + + classes: + - match: \b((?i:class))\s+([\w-]+)\b + captures: + 1: storage.type.class.powershell + 2: meta.class.powershell entity.name.class.powershell + + class-methods: + - match: ^(?:\s*)(?i)(hidden|static)?\s*(\[)((?!\d+|\.)[\p{L}\p{N}.]+)(\])\s*((?:\p{L}|\d|_|-|\.)+)\s*(?=\() + scope: meta.function.powershell + captures: + 1: storage.modifier.powershell + 2: punctuation.section.brackets.begin.powershell + 3: storage.type.powershell + 4: punctuation.section.brackets.end.powershell + 5: entity.name.function.powershell + push: + - match: (?=\() + pop: true + - include: comment-line + +###[ VARIABLES ]############################################################### + variables: - match: |- (?xi: @@ -526,20 +549,6 @@ contexts: 4: variable.other.readwrite.powershell 5: punctuation.section.braces.end - class-methods: - - match: ^(?:\s*)(?i)(hidden|static)?\s*(\[)((?!\d+|\.)[\p{L}\p{N}.]+)(\])\s*((?:\p{L}|\d|_|-|\.)+)\s*(?=\() - scope: meta.function.powershell - captures: - 1: storage.modifier.powershell - 2: punctuation.section.brackets.begin.powershell - 3: storage.type.powershell - 4: punctuation.section.brackets.end.powershell - 5: entity.name.function.powershell - push: - - match: (?=\() - pop: true - - include: comment-line - ###[ GROUPS ]################################################################## groups: From 0f4d9da2f6c4b8c716573aaa671471b7058ed1b3 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 18:45:44 -0500 Subject: [PATCH 019/133] Make a heading for operators --- PowerShell.sublime-syntax | 166 +++++++++++++++++++------------------- 1 file changed, 84 insertions(+), 82 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 8ee4f560..bb886d89 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -125,88 +125,6 @@ contexts: captures: 1: punctuation.definition.parameter.powershell - operators: - # Word operators - - match: \B(-)(?i:as){{kebab_break}} - scope: keyword.operator.cast.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:[ic]?(?:eq|ne|[gl][te])){{kebab_break}} - scope: keyword.operator.comparison.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:[ic]?(?:not)?(?:like|match|contains|in)){{kebab_break}} - scope: keyword.operator.logical.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:join|split|replace){{kebab_break}} - scope: keyword.operator.string.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:is(?:not)?){{kebab_break}} - scope: keyword.operator.logical.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:and|or|not|xor){{kebab_break}}|! # <-- note `!` - scope: keyword.operator.logical.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:band|bor|bnot|bxor|sh[lr]){{kebab_break}} - scope: keyword.operator.bitwise.powershell - captures: - 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:f){{kebab_break}} - scope: keyword.operator.string-format.powershell - captures: - 1: punctuation.definition.keyword.powershell - # Symbol operators - - match: '[+/*%-]?=' - scope: keyword.operator.assignment.powershell - - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) - scope: keyword.operator.assignment.powershell - - match: '[+-](?=\.?\d)' # This is sort of heuristic - scope: keyword.operator.unary.powershell - # Be careful about matching arithmetic with tightly following words - - match: '[/+](?![[:alpha:]])' - scope: keyword.operator.arithmetic.powershell - - match: -(?![[:alpha:]-]) - scope: keyword.operator.arithmetic.powershell - - match: \* - scope: keyword.operator.arithmetic.powershell - - match: '%(?!\s*\{)' - scope: keyword.operator.arithmetic.powershell - - match: \|\||&& - scope: keyword.operator.logical.powershell - - match: \| - scope: keyword.operator.logical.pipe.powershell - - match: ; - scope: punctuation.terminator.statement.powershell - - match: \`(?=\n|$) - scope: punctuation.separator.continuation.line.powershell - - match: ',' - scope: punctuation.separator.sequence.powershell - - match: '&|\B\.(?= )' - scope: keyword.operator.other.powershell - - match: \.\.(?=\-?\d|\(|\$) - # This is very imprecise. Is there a syntax for 'must come after...'? - scope: keyword.operator.range.powershell - - redirection: - # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection - - match: ([2-6*])(>&)(1) - captures: - 1: constant.numeric.decimal.file-descriptor.powershell - 2: keyword.operator.redirection.powershell - 3: constant.numeric.decimal.file-descriptor.powershell - - match: ([1-6*])(>>?) - captures: - 1: constant.numeric.decimal.file-descriptor.powershell - 2: keyword.operator.redirection.powershell - - match: '>>?' - scope: keyword.operator.redirection.powershell - # - match: <+ - # scope: invalid.illegal.powershell - using-directives: - match: \b(?i:(using))\s+(?i:(namespace|module))\s+(?i:((?:\w+(?:\.)?)+)) captures: @@ -365,6 +283,90 @@ contexts: scope: storage.type.powershell - include: types +###[ OPERATORS ]############################################################### + + operators: + # Word operators + - match: \B(-)(?i:as){{kebab_break}} + scope: keyword.operator.cast.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:[ic]?(?:eq|ne|[gl][te])){{kebab_break}} + scope: keyword.operator.comparison.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:[ic]?(?:not)?(?:like|match|contains|in)){{kebab_break}} + scope: keyword.operator.logical.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:join|split|replace){{kebab_break}} + scope: keyword.operator.string.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:is(?:not)?){{kebab_break}} + scope: keyword.operator.logical.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:and|or|not|xor){{kebab_break}}|! # <-- note `!` + scope: keyword.operator.logical.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:band|bor|bnot|bxor|sh[lr]){{kebab_break}} + scope: keyword.operator.bitwise.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:f){{kebab_break}} + scope: keyword.operator.string-format.powershell + captures: + 1: punctuation.definition.keyword.powershell + # Symbol operators + - match: '[+/*%-]?=' + scope: keyword.operator.assignment.powershell + - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) + scope: keyword.operator.assignment.powershell + - match: '[+-](?=\.?\d)' # This is sort of heuristic + scope: keyword.operator.unary.powershell + # Be careful about matching arithmetic with tightly following words + - match: '[/+](?![[:alpha:]])' + scope: keyword.operator.arithmetic.powershell + - match: -(?![[:alpha:]-]) + scope: keyword.operator.arithmetic.powershell + - match: \* + scope: keyword.operator.arithmetic.powershell + - match: '%(?!\s*\{)' + scope: keyword.operator.arithmetic.powershell + - match: \|\||&& + scope: keyword.operator.logical.powershell + - match: \| + scope: keyword.operator.logical.pipe.powershell + - match: ; + scope: punctuation.terminator.statement.powershell + - match: \`(?=\n|$) + scope: punctuation.separator.continuation.line.powershell + - match: ',' + scope: punctuation.separator.sequence.powershell + - match: '&|\B\.(?= )' + scope: keyword.operator.other.powershell + - match: \.\.(?=\-?\d|\(|\$) + # This is very imprecise. Is there a syntax for 'must come after...'? + scope: keyword.operator.range.powershell + + redirection: + # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection + - match: ([2-6*])(>&)(1) + captures: + 1: constant.numeric.decimal.file-descriptor.powershell + 2: keyword.operator.redirection.powershell + 3: constant.numeric.decimal.file-descriptor.powershell + - match: ([1-6*])(>>?) + captures: + 1: constant.numeric.decimal.file-descriptor.powershell + 2: keyword.operator.redirection.powershell + - match: '>>?' + scope: keyword.operator.redirection.powershell + # - match: <+ + # scope: invalid.illegal.powershell + ###[ CLASSES ]################################################################# classes: From 468b920e154169cd70ccbdcacfaa6bd5b8aa8cea Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 19:18:46 -0500 Subject: [PATCH 020/133] Switch to pop: 1 --- PowerShell.sublime-syntax | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index bb886d89..315bbf9d 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -152,13 +152,13 @@ contexts: - meta_scope: meta.attribute.powershell - match: \] scope: punctuation.section.brackets.end.powershell - pop: true + pop: 1 - match: \( scope: punctuation.section.group.begin.powershell push: - match: \) scope: punctuation.section.group.end.powershell - pop: true + pop: 1 - match: |- (?xi: \b( @@ -212,7 +212,7 @@ contexts: members: # - meta_content_scope: debug.in.members - match: (?=\.\.) - pop: true + pop: 1 - match: \.(?=\w) scope: punctuation.accessor.dot.powershell - match: (\w+)(\() @@ -223,7 +223,7 @@ contexts: - meta_content_scope: meta.function-call.arguments.powershell - match: \) scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell - pop: true + pop: 1 - include: expressions - match: \w+ scope: variable.other.member.powershell @@ -233,10 +233,10 @@ contexts: - meta_scope: meta.brackets.indexer.powershell - match: \] scope: punctuation.section.brackets.end.powershell - pop: true + pop: 1 - include: expressions - match: '' - pop: true + pop: 1 functions: - match: ^(?:\s*)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) @@ -247,7 +247,7 @@ contexts: 3: entity.name.function.powershell push: - match: (?=\{|\() - pop: true + pop: 1 - include: comment-line script-blocks: @@ -259,7 +259,7 @@ contexts: - meta_scope: meta.block.powershell - match: \} scope: punctuation.section.braces.end.powershell - pop: true + pop: 1 # TODO: Fix classes, so this doesn't nest here. - include: class-methods @@ -278,7 +278,7 @@ contexts: set: static-members - match: \] scope: punctuation.section.brackets.end.powershell - pop: true + pop: 1 - match: (?!\d+|\.)[\p{L}\p{N}.]+ scope: storage.type.powershell - include: types @@ -386,7 +386,7 @@ contexts: 5: entity.name.function.powershell push: - match: (?=\() - pop: true + pop: 1 - include: comment-line ###[ VARIABLES ]############################################################### @@ -560,7 +560,7 @@ contexts: - meta_scope: meta.group.powershell - match: \) scope: punctuation.section.group.end.powershell - pop: true + pop: 1 - include: expressions arrays: @@ -572,7 +572,7 @@ contexts: - meta_scope: meta.group.array-expression.powershell - match: \) scope: punctuation.section.group.end.powershell - pop: true + pop: 1 - include: expressions hashtables: @@ -584,7 +584,7 @@ contexts: - meta_scope: meta.hashtable.powershell - match: \} scope: punctuation.section.braces.end.powershell - pop: true + pop: 1 - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* scope: meta.hashtable.assignment.powershell captures: @@ -603,7 +603,7 @@ contexts: - meta_scope: meta.group.complex.subexpression.powershell - match: \) scope: punctuation.section.group.end.powershell - pop: true + pop: 1 - include: expressions ###[ CONSTANTS ]############################################################### @@ -645,7 +645,7 @@ contexts: scope: constant.character.escape.powershell - match: \' scope: punctuation.definition.string.end.powershell - pop: true + pop: 1 double-quoted-strings: - match: '"' @@ -660,7 +660,7 @@ contexts: - include: escape-sequences - match: '"' scope: punctuation.definition.string.end.powershell - pop: true + pop: 1 # # Silently eat email addresses # - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' - include: string-interpolations @@ -675,7 +675,7 @@ contexts: - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell - match: ^'@ scope: punctuation.definition.string.end.powershell - pop: true + pop: 1 - match: "''" scope: constant.character.escape.powershell @@ -687,7 +687,7 @@ contexts: - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell - match: ^"@ scope: punctuation.definition.string.end.powershell - pop: true + pop: 1 - include: escape-sequences - include: string-interpolations @@ -700,7 +700,7 @@ contexts: - meta_content_scope: source.powershell.embedded - match: \) scope: punctuation.section.interpolation.end.powershell - pop: true + pop: 1 - include: expressions - match: (?=\$) push: @@ -782,7 +782,7 @@ contexts: - meta_scope: comment.block.powershell - match: '#>' scope: punctuation.definition.comment.block.end.powershell - pop: true + pop: 1 - include: comment-embedded-docs comment-embedded-docs: @@ -864,19 +864,19 @@ contexts: pop-eol: - match: $ - pop: true + pop: 1 pop-before-eol: - match: (?=$) - pop: true + pop: 1 immediately-pop: - match: '' - pop: true + pop: 1 else-pop: - match: (?=\S) - pop: true + pop: 1 ############################################################################### From 5c19b34e2bce169c6e0f92f3ff23b8f80f9e8694 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 19:21:17 -0500 Subject: [PATCH 021/133] Move redirection to statements --- PowerShell.sublime-syntax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 315bbf9d..6d0b389b 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -24,6 +24,7 @@ contexts: - include: statements statements: + - include: redirection - include: classes - include: expressions - include: functions @@ -86,7 +87,6 @@ contexts: # BUG: When we figure out what's wrong with `prototype`, remove this. - include: comments - - include: redirection - include: commands - include: constants - include: variables From d3cd164a0b8f971403dcb2de0582ac4215b4533f Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 19:31:44 -0500 Subject: [PATCH 022/133] Move the source function up to statements --- PowerShell.sublime-syntax | 4 +++- Tests/syntax_test_PowerShell.ps1 | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 6d0b389b..4d4ac400 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -28,6 +28,8 @@ contexts: - include: classes - include: expressions - include: functions + - match: \B\.(?= ) + scope: support.function.source.powershell # Exceptions - match: \b(?i:throw){{kebab_break}} scope: keyword.control.exception.raise.powershell @@ -345,7 +347,7 @@ contexts: scope: punctuation.separator.continuation.line.powershell - match: ',' scope: punctuation.separator.sequence.powershell - - match: '&|\B\.(?= )' + - match: '&' scope: keyword.operator.other.powershell - match: \.\.(?=\-?\d|\(|\$) # This is very imprecise. Is there a syntax for 'must come after...'? diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 85ba6d93..83ece94d 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -893,7 +893,7 @@ ls *.ps1 -recurse # Commands (executable files) . .\scripts\myscript.ps1 -parameter 'value' -# <- keyword.operator.other +# <- support.function.source.powershell # ^ punctuation.definition.parameter # ^^^^^^^^^^ variable.parameter.option # ^^^^^^^ string.quoted.single From 5729037328db93b263b11184ae91517a02127f58 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 22:03:20 -0500 Subject: [PATCH 023/133] Move begin/process/end/clean to script blocks --- PowerShell.sublime-syntax | 20 +++++++++++--------- Tests/syntax_test_Function.ps1 | 6 ++++++ Tests/syntax_test_PowerShell.ps1 | 4 ---- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 4d4ac400..c52d5035 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -39,15 +39,6 @@ contexts: scope: keyword.control.exception.catch.powershell - match: \b(?i:finally){{kebab_break}} scope: keyword.control.exception.finally.powershell - # Begin/End - - match: \b(?i:begin){{kebab_break}} - scope: keyword.context.block.begin.powershell - - match: \b(?i:process){{kebab_break}} - scope: keyword.context.block.process.powershell - - match: \b(?i:end){{kebab_break}} - scope: keyword.context.block.end.powershell - - match: \b(?i:clean){{kebab_break}} - scope: keyword.context.block.clean.powershell # Loops - match: \b(?i:for|foreach(?!-object)){{kebab_break}} scope: keyword.control.loop.for.powershell @@ -268,6 +259,17 @@ contexts: - match: \b(?i:hidden|static)\b scope: storage.modifier.powershell + # TODO: Fix functions, so this doesn't nest here. + # Begin/Process/End/Clean + - match: \b(?i:begin){{kebab_break}} + scope: keyword.context.block.begin.powershell + - match: \b(?i:process){{kebab_break}} + scope: keyword.context.block.process.powershell + - match: \b(?i:end){{kebab_break}} + scope: keyword.context.block.end.powershell + - match: \b(?i:clean){{kebab_break}} + scope: keyword.context.block.clean.powershell + - include: statements types: diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index f79bfdc7..220cd382 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -399,4 +399,10 @@ function Verb-Noun { #^^^ keyword.context.block.end } + clean { } +#^^^^^^^^^^^^ meta.block.powershell +# ^^^^^ keyword.context.block.clean.powershell +# ^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell } diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 83ece94d..39a349a2 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1338,10 +1338,6 @@ catch { } # <- keyword.control # ^ punctuation.section.braces.begin # ^ punctuation.section.braces.end -clean { } -# <- keyword.context.block.clean -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end # Reserved words Configuration Crazyness { From 36d1637d189f170f409edc1ff4a7108c8099c15b Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 22:12:57 -0500 Subject: [PATCH 024/133] Move attributes into groups and script blocks for Param and function metadata respectively --- PowerShell.sublime-syntax | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c52d5035..04d04146 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -83,7 +83,6 @@ contexts: - include: commands - include: constants - include: variables - - include: attributes - include: using-directives - include: types - include: hashtables @@ -259,7 +258,8 @@ contexts: - match: \b(?i:hidden|static)\b scope: storage.modifier.powershell - # TODO: Fix functions, so this doesn't nest here. + # TODO: Fix functions, so these don't nest here. + - include: attributes # Begin/Process/End/Clean - match: \b(?i:begin){{kebab_break}} scope: keyword.context.block.begin.powershell @@ -565,6 +565,7 @@ contexts: - match: \) scope: punctuation.section.group.end.powershell pop: 1 + - include: attributes - include: expressions arrays: From 62a7a8d9cc4de03631e0bf651d2588f443f49beb Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 22:16:14 -0500 Subject: [PATCH 025/133] Add some formatting --- PowerShell.sublime-syntax | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 04d04146..f82312eb 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -28,8 +28,11 @@ contexts: - include: classes - include: expressions - include: functions + + # TODO: Continue into a command statement - match: \B\.(?= ) scope: support.function.source.powershell + # Exceptions - match: \b(?i:throw){{kebab_break}} scope: keyword.control.exception.raise.powershell @@ -39,6 +42,7 @@ contexts: scope: keyword.control.exception.catch.powershell - match: \b(?i:finally){{kebab_break}} scope: keyword.control.exception.finally.powershell + # Loops - match: \b(?i:for|foreach(?!-object)){{kebab_break}} scope: keyword.control.loop.for.powershell @@ -48,6 +52,7 @@ contexts: scope: keyword.control.loop.while.powershell - match: \b(?i:until){{kebab_break}} scope: keyword.control.loop.repeat-until.powershell + # Flow - match: \b(?i:break){{kebab_break}} scope: keyword.control.flow.break.powershell @@ -57,6 +62,7 @@ contexts: scope: keyword.control.flow.exit.powershell - match: \b(?i:return){{kebab_break}} scope: keyword.control.flow.return.powershell + # Conditionals - match: \b(?i:if){{kebab_break}} scope: keyword.control.conditional.if.powershell @@ -70,7 +76,8 @@ contexts: scope: keyword.control.conditional.select.powershell - match: \b(?i:where(?!-object)){{kebab_break}} scope: keyword.control.conditional.select.powershell - # Declaration + + # Declarations - match: \b(?i:var){{kebab_break}} scope: keyword.declaration.variable.powershell - match: \b(?i:(?:dynamic)?param){{kebab_break}} @@ -95,14 +102,18 @@ contexts: - include: subexpressions - match: \b[\w.-]+\.(?i:exe|com|cmd|bat)\b scope: variable.function.powershell + # Consume a string with a trailing dot # to prevent members with particular names from being recognized as keywords. - match: \b[\w-]+(?=\.) scope: variable.other.object.powershell push: members + # Uncategorized keywords - match: \b(?i:data|default|define|from|in|inlinescript|parallel|sequence){{kebab_break}} scope: keyword.control.powershell + + # Make everything afterward a literal - match: \B--%\B scope: keyword.control.powershell push: @@ -196,13 +207,11 @@ contexts: scope: support.function.powershell static-members: - # - meta_content_scope: debug.in.static-members - match: '::' scope: punctuation.accessor.double-colon.powershell set: members members: - # - meta_content_scope: debug.in.members - match: (?=\.\.) pop: 1 - match: \.(?=\w) @@ -270,6 +279,7 @@ contexts: - match: \b(?i:clean){{kebab_break}} scope: keyword.context.block.clean.powershell + # Back to normal stuff - include: statements types: From 8f474e9990dabc438b27d119bb844341f527cdf3 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 22:34:47 -0500 Subject: [PATCH 026/133] Finish named contexts for string content --- PowerShell.sublime-syntax | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index f82312eb..d598da43 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -655,6 +655,7 @@ contexts: push: inside-single-quoted-string inside-single-quoted-string: + - meta_include_prototype: false - meta_scope: meta.string.powershell string.quoted.single.powershell - match: "''" scope: constant.character.escape.powershell @@ -685,26 +686,30 @@ contexts: single-quoted-heredoc-strings: - match: \@'(?=$) scope: punctuation.definition.string.begin.powershell - push: - - meta_include_prototype: false - - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell - - match: ^'@ - scope: punctuation.definition.string.end.powershell - pop: 1 - - match: "''" - scope: constant.character.escape.powershell + push: inside-single-quoted-heredoc-string + + inside-single-quoted-heredoc-string: + - meta_include_prototype: false + - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell + - match: ^'@ + scope: punctuation.definition.string.end.powershell + pop: 1 + - match: "''" + scope: constant.character.escape.powershell double-quoted-heredoc-strings: - match: \@"(?=$) scope: punctuation.definition.string.begin.powershell - push: - - meta_include_prototype: false - - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell - - match: ^"@ - scope: punctuation.definition.string.end.powershell - pop: 1 - - include: escape-sequences - - include: string-interpolations + push: inside-double-quoted-heredoc-string + + inside-double-quoted-heredoc-string: + - meta_include_prototype: false + - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell + - match: ^"@ + scope: punctuation.definition.string.end.powershell + pop: 1 + - include: escape-sequences + - include: string-interpolations string-interpolations: - match: \$\( From 6e109d5bf6b09d6bb353b97d935e9d3de319ad3d Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Thu, 4 Dec 2025 22:46:39 -0500 Subject: [PATCH 027/133] Activate the prototype context Thanks, @keith-hall --- PowerShell.sublime-syntax | 74 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index d598da43..6de5d525 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -84,8 +84,8 @@ contexts: scope: keyword.declaration.parameter.powershell # This scope is not standard expressions: - # BUG: When we figure out what's wrong with `prototype`, remove this. - - include: comments + - include: regions + - include: requires-directives - include: commands - include: constants @@ -117,6 +117,7 @@ contexts: - match: \B--%\B scope: keyword.control.powershell push: + - meta_include_prototype: false - meta_content_scope: string.unquoted.powershell - include: pop-before-eol @@ -135,6 +136,37 @@ contexts: 2: keyword.other.powershell 3: variable.parameter.powershell + requires-directives: + - match: (#)((?i:requires))\s + captures: + 1: punctuation.definition.keyword.powershell + 2: keyword.control.import.require.powershell + push: + - meta_scope: meta.requires.powershell + - include: pop-eol + - include: hashtables + - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) + scope: variable.parameter.option.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: ',' + scope: punctuation.separator.powershell + + regions: + - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.begin.powershell + 4: meta.toc-list.powershell entity.name.section.powershell + 5: meta.fold.begin.powershell + - match: ^\s*((#)\s*(endregion\b).*(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.end.powershell + 4: meta.fold.end.powershell + attributes: - match: |- (?xi: @@ -716,6 +748,7 @@ contexts: scope: punctuation.section.interpolation.begin.powershell push: - clear_scopes: 1 + - meta_include_prototype: false - meta_scope: meta.interpolation.powershell - meta_content_scope: source.powershell.embedded - match: \) @@ -725,6 +758,7 @@ contexts: - match: (?=\$) push: - clear_scopes: 1 + - meta_include_prototype: false - meta_scope: meta.interpolation.powershell - include: variables-without-property - include: variables @@ -790,8 +824,6 @@ contexts: ###[ COMMENTS ]################################################################ comments: - - include: regions - - include: requires-directives - include: comment-block - include: comment-line @@ -835,45 +867,13 @@ contexts: 3: markup.underline.link.powershell comment-line: - - match: '#' + - match: '#(?!(?i:requires|(?:end)?region)\b)' scope: punctuation.definition.comment.powershell push: - meta_scope: comment.line.powershell - include: pop-eol - include: comment-embedded-docs - regions: - - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.begin.powershell - 4: meta.toc-list.powershell entity.name.section.powershell - 5: meta.fold.begin.powershell - - match: ^\s*((#)\s*(endregion\b).*(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.end.powershell - 4: meta.fold.end.powershell - - requires-directives: - # TODO: add back `(?<=#)`-equivalent match - - match: (#)((?i:requires))\s - captures: - 1: punctuation.definition.keyword.powershell - 2: keyword.control.import.require.powershell - push: - - meta_scope: meta.requires.powershell - - include: pop-eol - - include: hashtables - - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) - scope: variable.parameter.option.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: ',' - scope: punctuation.separator.powershell - ###[ COMPONENTS ]############################################################## escape-sequences: From 2db88b347a989e9e61507b0d7bee34d2684ed0c8 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 10:21:16 -0500 Subject: [PATCH 028/133] Extract string tests to their own file --- Tests/syntax_test_PowerShell.ps1 | 209 +----------------------------- Tests/syntax_test_strings.ps1 | 212 +++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 208 deletions(-) create mode 100644 Tests/syntax_test_strings.ps1 diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 39a349a2..8ed1bb43 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -171,72 +171,6 @@ $variable.Name.Method( ) # ^^^^^^^^^^^^^^^ - variable.other.readwrite # ^ - meta.function-call -# In double-quoted strings, only the variable should be highlighted, not the property -"This is my $variable.Name!" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^ meta.interpolation variable.other.readwrite - string -# ^ punctuation.definition.variable -# ^^^^^^ string.quoted.double - meta.interpolation - variable - punctuation -# ^ punctuation.definition.string.end - -# When used in a subexpression, both should be highlighted -"This is my $($variable.Name)!" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^^^^^^^^^ meta.interpolation - string -# ^^ string.quoted.double - meta.interpolation -# ^^ punctuation.section.interpolation.begin -# ^^^^^^^^^ variable.other.readwrite -# ^ punctuation.definition.variable -# ^ punctuation.accessor.dot -# ^^^^ variable.other.member -# ^ punctuation.section.interpolation.end -# ^ punctuation.definition.string.end - -# $ENV:ComputerName should be highlighted -"This is the name of my computer: $ENV:ComputerName" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^^^^^^^^^ meta.interpolation - string -# ^ punctuation.definition.variable -# ^^^^ support.variable.drive -# ^^^^^^^^^^^^ variable.other.readwrite -# ^ punctuation.definition.string.end - -# Here as well -"This is the name of my computer: ${ENV:ComputerName}" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^^^^^^^^^^^ meta.interpolation - string -# ^ punctuation.definition.variable -# ^ punctuation.section.braces.begin -# ^^^^ support.variable.drive -# ^^^^^^^^^^^^ variable.other.readwrite -# ^ punctuation.definition.string.end - -# The @splat references only work in argument mode, should not highlight in strings -"This is a @double quoted string." -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double -# ^ - punctuation.definition.variable -# ^^^^^^^ - variable - -# double check scopes for automatic variables in strings -"$_ $$ $Pwd" -#^^ variable.language -# ^^ variable.language -# ^^^^ variable.language - -# Single quotes string -'This is a string' -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^ meta.string string.quoted.single -# ^ punctuation.definition.string.end - # Hashtable $properties = @{ # <- punctuation.definition.variable @@ -426,66 +360,6 @@ $a3[1..2] # ^ punctuation.section.brackets.end # ^^^^^^^^^^^^^^^ meta.brackets.indexer -# Single quoted strings - 'This is a single quoted string.' -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - '$This is a single ''quoted'' string.' -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single -# ^^ constant.character.escape -# ^^ constant.character.escape - 'This is a - single quoted string.' -# ^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - 'This #also' -# ^^^^^^^^^^^^ meta.string string.quoted.single - '$(Invoke-Something)' -# ^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - meta.interpolation - variable - support - 'This "string" is nice.' -# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - -# Double quoted strings - "This is a double quoted string." -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - "$This is a double ""quoted"" string." -# ^ meta.string string.quoted.double -# ^^^^^ meta.string meta.interpolation variable.language - string -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - meta.interpolation -# ^^ constant.character.escape -# ^^ constant.character.escape - "This is a - double quoted string." -# ^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - "This #also" -# ^^^^^^^^^^^^ meta.string string.quoted.double - "$(Invoke-Something)" -# ^ meta.string string.quoted.double -# ^^^^^^^^^^^^^^^^^^^ meta.string meta.interpolation - string -# ^^ punctuation.section.interpolation.begin -# ^^^^^^^^^^^^^^^^ support.function -# ^ punctuation.section.interpolation.end -# @@@@@@@@@@@@@@@@ reference - "This 'string' is nice." -# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - -# Double quoted here-string -@" -# <- string.quoted.double.heredoc - # <- string.quoted.double.heredoc -$This is a 'double quoted' -# <- punctuation.definition.variable -#^^^^ variable.language -Isn't it "nice"?? -There is no @platting here! -# ^^^^^^^^^ - variable - punctuation -"@ -# <- string.quoted.double.heredoc - # <- string.quoted.double.heredoc -@' -#<- meta.string string.quoted.single.heredoc punctuation.definition.string.begin -A 'single quoted' "heredoc" -'@ -#<- meta.string string.quoted.single.heredoc punctuation.definition.string.end - # Numeric constants -3 +3 3 3l 3lm 3lmb @@ -1487,75 +1361,6 @@ $b -cLike $c "HEY" -ile "hey" # ^^^^ keyword.operator.comparison -# format - "{0:N2}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format - "{0:D8}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format - "{0:C2}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format - "{0:P0}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format - "{0:X0}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format - (1.11).ToString("#.#") -# ^ punctuation.section.group.begin -# ^^^^ meta.number.float.decimal constant.numeric.value -# ^ punctuation.section.group.begin -# ^ string.quoted.double - "{1,10} {0,10} {2,10:x}" -f "First", "Second", 255 -# ^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format -# ^^^ meta.number.integer.decimal constant.numeric.value - ("{0,6}" -f 4.99), ("{0,6:##.00}" -f 15.9) -# ^^ keyword.operator.string-format -# ^^^^ meta.number.float.decimal constant.numeric.value -# ^^^^^^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format - "{0:R}" -f (1mb/2.0) -# ^ keyword.operator.string-format -# ^ meta.number.integer.decimal constant.numeric.value -# ^^ meta.number.integer.decimal constant.numeric.suffix - "{0:00.0}" -f 4.12341234 -# ^ keyword.operator.string-format - "{0:##.#}" -f 4.12341234 -# ^ string.quoted.double -# ^ keyword.operator.string-format -# ^^^^^^^^^^ meta.number.float.decimal constant.numeric.value - "{0:#,#.#}" -f 1234.121234 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{0:##,,.000}" -f 1048576 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{this is not a #comment}" -# ^ - comment - "{0:##.#E000}" -f 2.71828 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{0:#.00'##'}" -f 2.71828 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{0:POS;NEG;ZERO}" -f -14 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{0:$## Please}" -f 14 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{0,-8:P1}" -f 1.75 -# ^ string.quoted.double -# ^ keyword.operator.string-format - "{0,10:N3}{1,10:N3}{2,10:N3}{3,10:N3}" -f 0.2, 0.3, 0.45, 0.91 -# ^ keyword.operator.string-format - '{0:00000.000}' -f 7.125 -# ^ string.quoted.single -# ^ keyword.operator.string-format - function Test-Function {} # @@@@@@@@@@@@@ definition function New-Object {} @@ -1653,19 +1458,7 @@ function Out-WithYou {} # ^ constant.language # ^ punctuation.definition.comment # ^^^^^^^^^ comment.line -"Escaped chars: `", `n, `$, `b, `t, `e, `u{10ffff}, `"" -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^^^^^^^^^ constant.character.escape -# ^^ constant.character.escape -'But here they''re not escape chars: `", `n, `$, `b, `"' -# ^^ constant.character.escape -# ^^^^^^^^^^^^^^^^^^^ - constant + function get-number {} # @@@@@@@@@@ definition "When you call a method: $( get-number | %{ invoke-command $( [string]::format("Like (this{0})","what?") ) $var } )" diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 new file mode 100644 index 00000000..56f617fb --- /dev/null +++ b/Tests/syntax_test_strings.ps1 @@ -0,0 +1,212 @@ +# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" + +# In double-quoted strings, only the variable should be highlighted, not the property +"This is my $variable.Name!" +# <- punctuation.definition.string.begin +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string +#^^^^^^^^^^^ string.quoted.double +# ^^^^^^^^^ meta.interpolation variable.other.readwrite - string +# ^ punctuation.definition.variable +# ^^^^^^ string.quoted.double - meta.interpolation - variable - punctuation +# ^ punctuation.definition.string.end + +# When used in a subexpression, both should be highlighted +"This is my $($variable.Name)!" +# <- punctuation.definition.string.begin +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string +#^^^^^^^^^^^ string.quoted.double +# ^^^^^^^^^^^^^^^^^ meta.interpolation - string +# ^^ string.quoted.double - meta.interpolation +# ^^ punctuation.section.interpolation.begin +# ^^^^^^^^^ variable.other.readwrite +# ^ punctuation.definition.variable +# ^ punctuation.accessor.dot +# ^^^^ variable.other.member +# ^ punctuation.section.interpolation.end +# ^ punctuation.definition.string.end + +# $ENV:ComputerName should be highlighted +"This is the name of my computer: $ENV:ComputerName" +# <- punctuation.definition.string.begin +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +# ^^^^^^^^^^^^^^^^^ meta.interpolation - string +# ^ punctuation.definition.variable +# ^^^^ support.variable.drive +# ^^^^^^^^^^^^ variable.other.readwrite +# ^ punctuation.definition.string.end + +# Here as well +"This is the name of my computer: ${ENV:ComputerName}" +# <- punctuation.definition.string.begin +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +# ^^^^^^^^^^^^^^^^^^^ meta.interpolation - string +# ^ punctuation.definition.variable +# ^ punctuation.section.braces.begin +# ^^^^ support.variable.drive +# ^^^^^^^^^^^^ variable.other.readwrite +# ^ punctuation.definition.string.end + +# The @splat references only work in argument mode, should not highlight in strings +"This is a @double quoted string." +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double +# ^ - punctuation.definition.variable +# ^^^^^^^ - variable + +# double check scopes for automatic variables in strings +"$_ $$ $Pwd" +#^^ variable.language +# ^^ variable.language +# ^^^^ variable.language + +# Single quotes string +'This is a string' +# <- punctuation.definition.string.begin +#^^^^^^^^^^^^^^^^^ meta.string string.quoted.single +# ^ punctuation.definition.string.end + + +# Single quoted strings + 'This is a single quoted string.' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single + '$This is a single ''quoted'' string.' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single +# ^^ constant.character.escape +# ^^ constant.character.escape + 'This is a + single quoted string.' +# ^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single + 'This #also' +# ^^^^^^^^^^^^ meta.string string.quoted.single + '$(Invoke-Something)' +# ^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - meta.interpolation - variable - support + 'This "string" is nice.' +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single + +# Double quoted strings + "This is a double quoted string." +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double + "$This is a double ""quoted"" string." +# ^ meta.string string.quoted.double +# ^^^^^ meta.string meta.interpolation variable.language - string +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - meta.interpolation +# ^^ constant.character.escape +# ^^ constant.character.escape + "This is a + double quoted string." +# ^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double + "This #also" +# ^^^^^^^^^^^^ meta.string string.quoted.double + "$(Invoke-Something)" +# ^ meta.string string.quoted.double +# ^^^^^^^^^^^^^^^^^^^ meta.string meta.interpolation - string +# ^^ punctuation.section.interpolation.begin +# ^^^^^^^^^^^^^^^^ support.function +# ^ punctuation.section.interpolation.end +# @@@@@@@@@@@@@@@@ reference + "This 'string' is nice." +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double + +# Double quoted here-string +@" +# <- string.quoted.double.heredoc + # <- string.quoted.double.heredoc +$This is a 'double quoted' +# <- punctuation.definition.variable +#^^^^ variable.language +Isn't it "nice"?? +There is no @platting here! +# ^^^^^^^^^ - variable - punctuation +"@ +# <- string.quoted.double.heredoc + # <- string.quoted.double.heredoc +@' +#<- meta.string string.quoted.single.heredoc punctuation.definition.string.begin +A 'single quoted' "heredoc" +'@ +#<- meta.string string.quoted.single.heredoc punctuation.definition.string.end + + +# format + "{0:N2}" -f $a +# ^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format + "{0:D8}" -f $a +# ^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format + "{0:C2}" -f $a +# ^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format + "{0:P0}" -f $a +# ^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format + "{0:X0}" -f $a +# ^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format + (1.11).ToString("#.#") +# ^ punctuation.section.group.begin +# ^^^^ meta.number.float.decimal constant.numeric.value +# ^ punctuation.section.group.begin +# ^ string.quoted.double + "{1,10} {0,10} {2,10:x}" -f "First", "Second", 255 +# ^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format +# ^^^ meta.number.integer.decimal constant.numeric.value + ("{0,6}" -f 4.99), ("{0,6:##.00}" -f 15.9) +# ^^ keyword.operator.string-format +# ^^^^ meta.number.float.decimal constant.numeric.value +# ^^^^^^^^^^^^^ string.quoted.double +# ^^ keyword.operator.string-format + "{0:R}" -f (1mb/2.0) +# ^ keyword.operator.string-format +# ^ meta.number.integer.decimal constant.numeric.value +# ^^ meta.number.integer.decimal constant.numeric.suffix + "{0:00.0}" -f 4.12341234 +# ^ keyword.operator.string-format + "{0:##.#}" -f 4.12341234 +# ^ string.quoted.double +# ^ keyword.operator.string-format +# ^^^^^^^^^^ meta.number.float.decimal constant.numeric.value + "{0:#,#.#}" -f 1234.121234 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{0:##,,.000}" -f 1048576 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{this is not a #comment}" +# ^ - comment + "{0:##.#E000}" -f 2.71828 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{0:#.00'##'}" -f 2.71828 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{0:POS;NEG;ZERO}" -f -14 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{0:$## Please}" -f 14 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{0,-8:P1}" -f 1.75 +# ^ string.quoted.double +# ^ keyword.operator.string-format + "{0,10:N3}{1,10:N3}{2,10:N3}{3,10:N3}" -f 0.2, 0.3, 0.45, 0.91 +# ^ keyword.operator.string-format + '{0:00000.000}' -f 7.125 +# ^ string.quoted.single +# ^ keyword.operator.string-format + +"Escaped chars: `", `n, `$, `b, `t, `e, `u{10ffff}, `"" +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^ constant.character.escape +# ^^^^^^^^^^ constant.character.escape +# ^^ constant.character.escape +'But here they''re not escape chars: `", `n, `$, `b, `"' +# ^^ constant.character.escape +# ^^^^^^^^^^^^^^^^^^^ - constant From 31ba93e9d58cbba94cb7b7b15c0f3bf5d6eb1e54 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 10:51:00 -0500 Subject: [PATCH 029/133] Fully qualify the string test assertions --- PowerShell.sublime-syntax | 4 +- Tests/syntax_test_strings.ps1 | 544 +++++++++++++++++++++++----------- 2 files changed, 380 insertions(+), 168 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 6de5d525..067cf704 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -702,7 +702,7 @@ contexts: inside-double-quoted-string: - meta_include_prototype: false - - meta_scope: meta.string.powershell string.quoted.double.powershell + - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell - match: '""' scope: constant.character.escape.powershell - include: escape-sequences @@ -736,7 +736,7 @@ contexts: inside-double-quoted-heredoc-string: - meta_include_prototype: false - - meta_scope: meta.string.powershell string.quoted.double.heredoc.powershell + - meta_scope: meta.string.interpolated.powershell string.quoted.double.heredoc.powershell - match: ^"@ scope: punctuation.definition.string.end.powershell pop: 1 diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 56f617fb..f6f020d6 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -1,103 +1,156 @@ # SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" -# In double-quoted strings, only the variable should be highlighted, not the property -"This is my $variable.Name!" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^ meta.interpolation variable.other.readwrite - string -# ^ punctuation.definition.variable -# ^^^^^^ string.quoted.double - meta.interpolation - variable - punctuation -# ^ punctuation.definition.string.end - -# When used in a subexpression, both should be highlighted -"This is my $($variable.Name)!" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^^^^^^^^^ meta.interpolation - string -# ^^ string.quoted.double - meta.interpolation -# ^^ punctuation.section.interpolation.begin -# ^^^^^^^^^ variable.other.readwrite -# ^ punctuation.definition.variable -# ^ punctuation.accessor.dot -# ^^^^ variable.other.member -# ^ punctuation.section.interpolation.end -# ^ punctuation.definition.string.end - -# $ENV:ComputerName should be highlighted -"This is the name of my computer: $ENV:ComputerName" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^^^^^^^^^ meta.interpolation - string -# ^ punctuation.definition.variable -# ^^^^ support.variable.drive -# ^^^^^^^^^^^^ variable.other.readwrite -# ^ punctuation.definition.string.end - -# Here as well -"This is the name of my computer: ${ENV:ComputerName}" -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^^^^^^^^^^^^^^^^^^ meta.interpolation - string -# ^ punctuation.definition.variable -# ^ punctuation.section.braces.begin -# ^^^^ support.variable.drive -# ^^^^^^^^^^^^ variable.other.readwrite -# ^ punctuation.definition.string.end - -# The @splat references only work in argument mode, should not highlight in strings -"This is a @double quoted string." -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double -# ^ - punctuation.definition.variable -# ^^^^^^^ - variable - -# double check scopes for automatic variables in strings -"$_ $$ $Pwd" -#^^ variable.language -# ^^ variable.language -# ^^^^ variable.language - -# Single quotes string -'This is a string' -# <- punctuation.definition.string.begin -#^^^^^^^^^^^^^^^^^ meta.string string.quoted.single -# ^ punctuation.definition.string.end - - -# Single quoted strings +###[ Single Quoted Strings ]################################################### + 'This is a single quoted string.' -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - '$This is a single ''quoted'' string.' -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single -# ^^ constant.character.escape -# ^^ constant.character.escape +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - meta.string.interpolated +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + 'This is a +# ^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - meta.string.interpolated +# ^ punctuation.definition.string.begin.powershell single quoted string.' -# ^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - meta.string.interpolated +# ^ punctuation.definition.string.end.powershell + 'This #also' -# ^^^^^^^^^^^^ meta.string string.quoted.single - '$(Invoke-Something)' -# ^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single - meta.interpolation - variable - support +# ^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - comment +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + 'This "string" is nice.' -# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.single +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - constant +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + '$This is a single ''quoted'' string.' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - meta.string.interpolated +# ^ punctuation.definition.string.begin.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.string.end.powershell + + '$(Invoke-Something)' +# ^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - meta.interpolation - variable - support +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + 'Not escape chars: `", `n, `$, `b, `"' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell - constant +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + @' +# ^^ meta.string.powershell string.quoted.single.heredoc.powershell punctuation.definition.string.begin.powershell - meta.string.interpolated + A 'single quoted' "heredoc" +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.heredoc.powershell - punctuation + '@ +#^^^^^ meta.string.powershell string.quoted.single.heredoc.powershell - punctuation +'@ +#^ meta.string.powershell string.quoted.single.heredoc.powershell punctuation.definition.string.end.powershell + + +###[ Double Quoted Strings ]################################################### -# Double quoted strings "This is a double quoted string." -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + "This is a +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell + double quoted string." +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.end.powershell + + "This #also" +# ^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + "This 'string' is nice." +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - constant +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "$This is a double ""quoted"" string." # ^ meta.string string.quoted.double # ^^^^^ meta.string meta.interpolation variable.language - string # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - meta.interpolation # ^^ constant.character.escape # ^^ constant.character.escape - "This is a - double quoted string." -# ^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - "This #also" -# ^^^^^^^^^^^^ meta.string string.quoted.double + + # In double-quoted strings, only the variable should be highlighted, not the property + "This is my $variable.Name!" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^ string.quoted.double.powershell - meta.interpolation - variable - punctuation.accessor +# ^ punctuation.definition.string.end.powershell + + # When used in a subexpression, both should be highlighted + "This is my $($variable.Name)!" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^ meta.interpolation.powershell - string +# ^^ punctuation.section.interpolation.begin.powershell +# ^^^^^^^^^^^^^^ source.powershell.embedded +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^ variable.other.member.powershell +# ^ punctuation.section.interpolation.end.powershell +# ^^ string.quoted.double.powershell - meta.interpolation +# ^ punctuation.definition.string.end.powershell + + # $ENV:ComputerName should be highlighted + "This is the name of my computer: $ENV:ComputerName" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell - string +# ^ punctuation.definition.variable.powershell +# ^^^^ support.variable.drive.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.end.powershell + + # Here as well + "This is the name of my computer: ${ENV:ComputerName}" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell - string +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.begin +# ^^^^ support.variable.drive.powershell +# ^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.section.braces.end +# ^ string.quoted.double.powershell punctuation.definition.string.end.powershell + + # The @splat references only work in argument mode, should not highlight in strings + "This is a @double quoted string." +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - variable - punctuation.definition.variable +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + # Double check scopes for automatic variables in strings + "$_ $$ $Pwd" +# ^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.begin.powershell +# ^^ meta.interpolation.powershell variable.language.powershell - string +# ^ punctuation.definition.variable.powershell +# ^ string.quoted.double.powershell +# ^^ meta.interpolation.powershell variable.language.powershell - string +# ^ punctuation.definition.variable.powershell +# ^ string.quoted.double.powershell +# ^^^^ meta.interpolation.powershell variable.language.powershell - string +# ^ punctuation.definition.variable.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.end.powershell + "$(Invoke-Something)" # ^ meta.string string.quoted.double # ^^^^^^^^^^^^^^^^^^^ meta.string meta.interpolation - string @@ -105,108 +158,267 @@ # ^^^^^^^^^^^^^^^^ support.function # ^ punctuation.section.interpolation.end # @@@@@@@@@@@@@@@@ reference - "This 'string' is nice." -# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double - -# Double quoted here-string -@" -# <- string.quoted.double.heredoc - # <- string.quoted.double.heredoc -$This is a 'double quoted' -# <- punctuation.definition.variable -#^^^^ variable.language -Isn't it "nice"?? -There is no @platting here! -# ^^^^^^^^^ - variable - punctuation + + # Double quoted here-string + @" +# ^^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell punctuation.definition.string.begin.powershell + $This is a 'double quoted' +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +#^^^ string.quoted.double.heredoc.powershell +# ^^^^^ meta.interpolation.powershell variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.heredoc.powershell + Isn't it "nice"?? +#^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell - punctuation + There is no @splatting here! +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell + "@ +#^^^^^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell - punctuation "@ -# <- string.quoted.double.heredoc - # <- string.quoted.double.heredoc -@' -#<- meta.string string.quoted.single.heredoc punctuation.definition.string.begin -A 'single quoted' "heredoc" -'@ -#<- meta.string string.quoted.single.heredoc punctuation.definition.string.end +#^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell punctuation.definition.string.end.powershell + + "Escaped chars: `", `n, `$, `b, `t, `e, `u{10ffff}, `"" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^^^^^^^^^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.string.end.powershell + + +###[ String Formatting ]####################################################### -# format "{0:N2}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + "{0:D8}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + "{0:C2}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + "{0:P0}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + "{0:X0}" -f $a -# ^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + + # TODO: Mark ToString as a function (1.11).ToString("#.#") -# ^ punctuation.section.group.begin -# ^^^^ meta.number.float.decimal constant.numeric.value -# ^ punctuation.section.group.begin -# ^ string.quoted.double +# ^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.section.group.end.powershell +# ^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell + "{1,10} {0,10} {2,10:x}" -f "First", "Second", 255 -# ^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format -# ^^^ meta.number.integer.decimal constant.numeric.value +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + ("{0,6}" -f 4.99), ("{0,6:##.00}" -f 15.9) -# ^^ keyword.operator.string-format -# ^^^^ meta.number.float.decimal constant.numeric.value -# ^^^^^^^^^^^^^ string.quoted.double -# ^^ keyword.operator.string-format +# ^^^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.section.group.end.powershell + "{0:R}" -f (1mb/2.0) -# ^ keyword.operator.string-format -# ^ meta.number.integer.decimal constant.numeric.value -# ^^ meta.number.integer.decimal constant.numeric.suffix +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^ meta.number.integer.decimal.powershell +# ^ constant.numeric.value.powershell +# ^^ constant.numeric.suffix.powershell +# ^ keyword.operator.arithmetic.powershell +# ^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.section.group.end.powershell + "{0:00.0}" -f 4.12341234 -# ^ keyword.operator.string-format +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:##.#}" -f 4.12341234 -# ^ string.quoted.double -# ^ keyword.operator.string-format -# ^^^^^^^^^^ meta.number.float.decimal constant.numeric.value +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:#,#.#}" -f 1234.121234 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:##,,.000}" -f 1048576 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + "{this is not a #comment}" -# ^ - comment +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "{0:##.#E000}" -f 2.71828 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:#.00'##'}" -f 2.71828 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:POS;NEG;ZERO}" -f -14 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^ keyword.operator.unary.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + "{0:$## Please}" -f 14 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ meta.interpolation.powershell +# ^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + "{0,-8:P1}" -f 1.75 -# ^ string.quoted.double -# ^ keyword.operator.string-format +# ^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0,10:N3}{1,10:N3}{2,10:N3}{3,10:N3}" -f 0.2, 0.3, 0.45, 0.91 -# ^ keyword.operator.string-format +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + + # Single-quoted format string '{0:00000.000}' -f 7.125 -# ^ string.quoted.single -# ^ keyword.operator.string-format - -"Escaped chars: `", `n, `$, `b, `t, `e, `u{10ffff}, `"" -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^ constant.character.escape -# ^^^^^^^^^^ constant.character.escape -# ^^ constant.character.escape -'But here they''re not escape chars: `", `n, `$, `b, `"' -# ^^ constant.character.escape -# ^^^^^^^^^^^^^^^^^^^ - constant +# ^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell From 81f911d83b8eda6e64821afe8fdee294418c2ede Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 10:57:53 -0500 Subject: [PATCH 030/133] Test constants --- Tests/syntax_test_PowerShell.ps1 | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 8ed1bb43..6ae44605 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -103,6 +103,37 @@ throw "Do not run this file!" # ^ variable.parameter.option punctuation.definition.parameter # ^^^^^^^^^^^ variable.parameter.option + # Constants + $true +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + $True +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + $TRUE +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + + $false +# ^^^^^^ constant.language.boolean.false.powershell +# ^ punctuation.definition.variable.powershell + $False +# ^^^^^^ constant.language.boolean.false.powershell +# ^ punctuation.definition.variable.powershell + $FALSE +# ^^^^^^ constant.language.boolean.false.powershell +# ^ punctuation.definition.variable.powershell + + $null +# ^^^^^ constant.language.null.powershell +# ^ punctuation.definition.variable.powershell + $Null +# ^^^^^ constant.language.null.powershell +# ^ punctuation.definition.variable.powershell + $NULL +# ^^^^^ constant.language.null.powershell +# ^ punctuation.definition.variable.powershell + # Automatic variables $_, $$, $^, $? # <- punctuation.definition.variable From 1a2da7c562237cffd803101f666ad85608f903b4 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 11:03:11 -0500 Subject: [PATCH 031/133] Call & a "background" operator --- PowerShell.sublime-syntax | 2 +- Tests/syntax_test_PowerShell.ps1 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 067cf704..90b18955 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -392,7 +392,7 @@ contexts: - match: ',' scope: punctuation.separator.sequence.powershell - match: '&' - scope: keyword.operator.other.powershell + scope: keyword.operator.background.powershell - match: \.\.(?=\-?\d|\(|\$) # This is very imprecise. Is there a syntax for 'must come after...'? scope: keyword.operator.range.powershell diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 6ae44605..f6ad3a50 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -83,7 +83,7 @@ throw "Do not run this file!" # Stop parsing & tool.exe /arg1 'value' /arg2 $value --% /arg3 $value /arg4 "value" # Comment -# <- keyword.operator.other +# <- keyword.operator.background # ^^^^^^^^ variable.function # ^ punctuation.definition.parameter # ^^^^^ variable.parameter.option @@ -93,7 +93,7 @@ throw "Do not run this file!" # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted - constant - variable - comment & gnutool.exe -s 'short option' --long-option --very_long_option value +plus-option -#<- keyword.operator.other +#<- keyword.operator.background # ^^^^^^^^^^^ variable.function # ^ variable.parameter.option punctuation.definition.parameter # ^ variable.parameter.option @@ -803,7 +803,7 @@ ls *.ps1 -recurse # ^^^^^^^^^^ variable.parameter.option # ^^^^^^^ string.quoted.single & tool.exe -# <- keyword.operator.other +# <- keyword.operator.background # ^^^^^^^^ variable.function something.cmd #^^^^^^^^^^^^ variable.function From d5552bb7012e8b66db8a0f1c7e5dd5899ecee4ae Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 11:03:24 -0500 Subject: [PATCH 032/133] Move ! to symbol operators --- PowerShell.sublime-syntax | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 90b18955..875002b5 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -353,7 +353,7 @@ contexts: scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:and|or|not|xor){{kebab_break}}|! # <-- note `!` + - match: \B(-)(?i:and|or|not|xor){{kebab_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell @@ -365,7 +365,10 @@ contexts: scope: keyword.operator.string-format.powershell captures: 1: punctuation.definition.keyword.powershell + # Symbol operators + - match: \! + scope: keyword.operator.logical.powershell - match: '[+/*%-]?=' scope: keyword.operator.assignment.powershell - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) From a59cdf1115d856b90d3f1ca5526cf4cd3dc8160e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 11:31:56 -0500 Subject: [PATCH 033/133] Improve type scopes --- PowerShell.sublime-syntax | 35 ++++++--- Tests/syntax_test_PowerShell.ps1 | 125 ++++++++++++++++++++----------- 2 files changed, 105 insertions(+), 55 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 875002b5..c8352e79 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -314,20 +314,35 @@ contexts: # Back to normal stuff - include: statements +###[ TYPES ]################################################################### + types: # TODO: push a maybe-static-members context - match: \[ scope: punctuation.section.brackets.begin.powershell - push: - - match: \](?=::) - scope: punctuation.section.brackets.end.powershell - set: static-members - - match: \] - scope: punctuation.section.brackets.end.powershell - pop: 1 - - match: (?!\d+|\.)[\p{L}\p{N}.]+ - scope: storage.type.powershell - - include: types + push: inside-type + + inside-type: + - meta_include_prototype: false + - match: \](?=::) + scope: punctuation.section.brackets.end.powershell + set: static-members + - match: \] + scope: punctuation.section.brackets.end.powershell + pop: 1 + - match: \p{L}[\p{L}\p{N}]+(\.) + scope: meta.generic-name.powershell + captures: + 1: punctuation.accessor.dot.powershell + - match: \b(?:void|null|object|bool|char|string|int(?:32|64)?|long|byte|float|double|decimal)\b + scope: storage.type.powershell + - match: (?!\d+|\.)[\p{L}\p{N}.]+ + scope: support.type.powershell + - include: types + - match: \, + scope: punctuation.separator.sequence.powershell + - match: \+ + scope: punctuation.accessor.plus.powershell ###[ OPERATORS ]############################################################### diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index f6ad3a50..989a584e 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -654,51 +654,86 @@ $a3[1..2] # ^^ constant.numeric.value # ^^ constant.numeric.suffix -# Types -[string] -# <- punctuation.section.brackets.begin -# ^ storage.type -# ^ punctuation.section.brackets.end -[string[]] -# <- punctuation.section.brackets.begin -# ^ storage.type -# ^ punctuation.section.brackets.begin -# ^^ punctuation.section.brackets.end -[int32] -# <- punctuation.section.brackets.begin -# ^^^^ storage.type -# ^ punctuation.section.brackets.end -[System.Collections.Generic.Dictionary[[System.String, mscorlib],[System.Management.Automation.ParameterMetadata,System.Management.Automation]]] -# <- punctuation.section.brackets.begin -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ storage.type -# ^^ punctuation.section.brackets.begin -# ^^^^^^^^^^^^^ storage.type -# ^^^^^^^^ storage.type -# ^ punctuation.section.brackets.end -# ^ punctuation.section.brackets.begin -# ^^^^^^^^^^^^^^^^ storage.type -# ^^^ punctuation.section.brackets.end -[System.Array+SZArrayEnumerator] -# <- punctuation.section.brackets.begin -# ^^^^^^^^^^^ storage.type -# ^^^^^^^^^^^^^^^^^ storage.type -# ^ punctuation.section.brackets.end -[int]::MinValue -# <- punctuation.section.brackets.begin -# ^ storage.type -# ^ punctuation.section.brackets.end -# ^^ punctuation.accessor.double-colon -# ^^^^^^^^ variable.other.member -[System.DateTime]::Parse('2016/09/21') -# <- punctuation.section.brackets.begin -# ^^^^^^^^^^^^^^ storage.type -# ^ punctuation.section.brackets.end -# ^^ punctuation.accessor.double-colon -# ^^^^^ meta.function-call variable.function -# @@@@@ reference -# ^^^^^^^^^^^^^^ meta.function-call.arguments -# ^ punctuation.section.arguments.begin -# ^ punctuation.section.arguments.end + +###[ Types ]################################################################### + + [string] +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell + + [string[]] +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^ punctuation.section.brackets.end.powershell + + [int32] +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell + + [System.Collections.Generic.Dictionary[[System.String, mscorlib],[System.Management.Automation.ParameterMetadata,System.Management.Automation]]] +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^ support.type.powershell +# ^^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^ support.type.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^^^^^^^^ support.type.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^^^^^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^ support.type.powershell +# ^^^ punctuation.section.brackets.end.powershell + + [System.Array+SZArrayEnumerator] +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ support.type.powershell +# ^ punctuation.accessor.plus.powershell +# ^^^^^^^^^^^^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell + + [int]::MinValue +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^^^^ variable.other.member.powershell + + [System.DateTime]::Parse('2016/09/21') +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^ meta.function-call.powershell variable.function.powershell +# ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.arguments.end.powershell + + +###[ Commands ]################################################################ # Commands (functions) Invoke-Something -foobar From c372ed6788b0bef82c8b754457d0bbb5aa3caa42 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 11:52:42 -0500 Subject: [PATCH 034/133] Refactor types --- PowerShell.sublime-syntax | 33 ++++++++++++------ Tests/syntax_test_Class.ps1 | 52 ++++++++++++++-------------- Tests/syntax_test_Function.ps1 | 39 ++++++++++++--------- Tests/syntax_test_PowerShell.ps1 | 59 +++++++++++++++++++++++++------- 4 files changed, 116 insertions(+), 67 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c8352e79..b593a43c 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -238,11 +238,6 @@ contexts: - match: \b(?i:(?:foreach|where|sort|tee)-object)\b scope: support.function.powershell - static-members: - - match: '::' - scope: punctuation.accessor.double-colon.powershell - set: members - members: - match: (?=\.\.) pop: 1 @@ -317,16 +312,17 @@ contexts: ###[ TYPES ]################################################################### types: - # TODO: push a maybe-static-members context + - match: \[ + scope: punctuation.section.brackets.begin.powershell + push: [maybe-static-member, inside-type] + + types-without-members: - match: \[ scope: punctuation.section.brackets.begin.powershell push: inside-type inside-type: - meta_include_prototype: false - - match: \](?=::) - scope: punctuation.section.brackets.end.powershell - set: static-members - match: \] scope: punctuation.section.brackets.end.powershell pop: 1 @@ -334,16 +330,25 @@ contexts: scope: meta.generic-name.powershell captures: 1: punctuation.accessor.dot.powershell - - match: \b(?:void|null|object|bool|char|string|int(?:32|64)?|long|byte|float|double|decimal)\b + - match: '{{builtin_types}}' scope: storage.type.powershell - match: (?!\d+|\.)[\p{L}\p{N}.]+ scope: support.type.powershell - - include: types + - include: types-without-members - match: \, scope: punctuation.separator.sequence.powershell - match: \+ scope: punctuation.accessor.plus.powershell + static-members: + - match: '::' + scope: punctuation.accessor.double-colon.powershell + set: members + + maybe-static-member: + - include: static-members + - include: immediately-pop + ###[ OPERATORS ]############################################################### operators: @@ -925,3 +930,9 @@ variables: int_suffix: (?i:u[lsy]?|[lnsy]) unit_suffix: (?i:[kmgtp]b\b) kebab_break: (?![\w-]) + builtin_types: |- + \b(?x: + void | null | object | bool | char | string + | int (?:32|64)? | long | byte | float | double | decimal + | array | hashtable + )\b diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index fe41a23c..22904748 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -90,39 +90,37 @@ class TypeName # ^ variable.other.readwrite # ^ punctuation.section.group.end [TypeName]::P2 = $h - # <- punctuation.section.brackets.begin - # ^ storage.type - # ^ punctuation.section.brackets.end - # ^^ punctuation.accessor.double-colon - # ^^ variable.other.member - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^ variable.other.readwrite +#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell meta.block.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^ variable.other.member.powershell +# ^ keyword.operator.assignment.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell } # Instance method # <- punctuation.definition.comment # ^^^^^^^^^^^^^^^ comment.line [int] MemberMethod2([int] $i) { - # <- punctuation.section.brackets.begin - # ^ storage.type - # ^ punctuation.section.brackets.end - # ^^^^^^^^^^^^^ entity.name.function - # @@@@@@@@@@@@@ definition - # ^ punctuation.section.group.begin - # ^ punctuation.section.brackets.begin - # ^^^ storage.type - # ^ punctuation.section.brackets.end - # ^ punctuation.definition.variable - # ^ variable.other.readwrite - # ^ punctuation.section.group.end - $this.P3 = $i - # <- punctuation.definition.variable - # ^^^ variable.language - # ^^ variable.other.member - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^ variable.other.readwrite +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +#^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@ definition +# ^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.group.end.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell return $this.P3 # <- keyword.control # ^ punctuation.definition.variable diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index 220cd382..d8991122 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -93,14 +93,16 @@ function Verb-Noun { # ^ meta.attribute punctuation.section.group.end # ^ meta.attribute punctuation.section.brackets.end [OutputType([String])] - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^ meta.attribute punctuation.section.brackets.begin - # ^^^^^^ meta.attribute storage.type - # ^ meta.attribute punctuation.section.brackets.end - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell Param #^^^^^ keyword.declaration.parameter ( @@ -302,9 +304,10 @@ function Verb-Noun { # ^ meta.attribute punctuation.section.group.end # ^ meta.attribute punctuation.section.brackets.end [String] - # <- punctuation.section.brackets.begin - #^^^^^^ storage.type - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^^ meta.block.powershell meta.group.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell $Param3, # <- punctuation.definition.variable #^^^^^^ variable.other.readwrite @@ -335,9 +338,10 @@ function Verb-Noun { # ^ meta.attribute punctuation.section.group.end # ^ meta.attribute punctuation.section.brackets.end [string] - # <- punctuation.section.brackets.begin - # ^ storage.type - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^^ meta.block.powershell meta.group.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell $Param4, # <- punctuation.definition.variable # ^ variable.other.readwrite @@ -365,9 +369,10 @@ function Verb-Noun { # ^ comment.line punctuation.definition.comment # ^ comment.line [string] - # <- punctuation.section.brackets.begin - # ^ storage.type - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^^ meta.block.powershell meta.group.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell $Param5 # <- punctuation.definition.variable # ^ variable.other.readwrite diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 989a584e..ec7948a5 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -725,6 +725,7 @@ $a3[1..2] # ^ punctuation.section.brackets.end.powershell # ^^ punctuation.accessor.double-colon.powershell # ^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@ reference # ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^ punctuation.section.arguments.begin.powershell # ^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell @@ -1359,14 +1360,26 @@ $a -ceq 4 -and $a -ine $d -or # ^^^^ keyword.operator.comparison # ^^^ keyword.operator.logical $c -is [Type] -# ^^^ keyword.operator.logical -# ^ storage.type +#^ variable.other.readwrite.powershell +# ^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell $c -isnot [Type] -# ^^^^^^ keyword.operator.logical -# ^ storage.type +#^ variable.other.readwrite.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell $c -as [Type] -# ^^^ keyword.operator.cast -# ^ storage.type +#^ variable.other.readwrite.powershell +# ^^^ keyword.operator.cast.powershell +# ^ punctuation.definition.keyword.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell $k = $y -bor $k # ^ keyword.operator.assignment # ^ keyword.operator.bitwise @@ -1474,17 +1487,39 @@ echo `"test`" # ^ meta.group.array-expression # ^ keyword.control # ^ meta.block + function join-path {} # @@@@@@@@@ definition + $file = join-path $env:SystemDrive "$([System.io.path]::GetRandomFileName()).ps1" -# <- punctuation.definition.variable +#^^^^ variable.other.readwrite.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@ reference -# ^ support.function -# ^ support.variable.drive -# ^ variable.other.readwrite -# ^^ meta.string meta.interpolation punctuation.section.interpolation.begin -# ^ storage.type +# ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^ support.variable.drive.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell +# ^^ punctuation.section.interpolation.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.powershell.embedded +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell +# ^ punctuation.section.interpolation.end.powershell +# ^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.end.powershell + function out-file {} # @@@@@@@@ definition $ScriptBlock | Out-File $file -Force From f8cef2f735a6b55bda8c8847d84b533fa31ec39e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 12:18:38 -0500 Subject: [PATCH 035/133] Extract variable name lists --- PowerShell.sublime-syntax | 146 +++++++++++++------------------------- 1 file changed, 48 insertions(+), 98 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index b593a43c..be80c46e 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -461,66 +461,23 @@ contexts: ###[ VARIABLES ]############################################################### variables: - - match: |- - (?xi: - (\$) - (?: - ExecutionContext | Host | Home | IsCoreCLR | IsLinux | IsWindows - | IsMacOS | PID | Profile | PsCommandPath | PsHome | PsScriptRoot - | PsUiCulture | PsVersionTable | ShellID - ) - ) + - match: (\$){{var_constants}} scope: support.constant.variable.powershell captures: 1: punctuation.definition.variable.powershell push: members - - match: |- - (?xi: - (\$) - (?: - [$^?_] - | (?: - Args | ConsoleFileName | Error | Event | EventArgs - | EventSubscriber | ForEach | Input | LastExitCode | Matches - | MyInvocation | NestedPromptLevel | PsBoundParameters | PsCmdlet - | PsCulture | PsDebugContext | PsItem | Pwd | Sender | SourceArgs - | SourceEventArgs | StackTrace | Switch | This - )\b - ) - ) + - match: (\$){{var_language}} scope: variable.language.powershell captures: 1: punctuation.definition.variable.powershell push: members - - match: |- - (?xi: - (\$) - (?: - (?: - Confirm | Debug | ErrorAction | Information | Progress | Verbose # *Preference - | Warning | WhatIf - ) - Preference - | Maximum(?:Alias|Drive|Error|Function|History|Variable)Count # Maximum*Count - | Log(?:Command|Engine|Provider)(?:Health|Lifecycle)Event # Log*Event - | PsDebugContext | PsDefaultParameterValues | PsEmailServer - | PsModuleAutoloadingPreference | PsSenderInfo - | PsSessionApplicationName | PsSessionConfigurationName - | PsSessionOption | ErrorView | FormatEnumerationLimit | OFS - | OutputEncoding - ) - ) - scope: variable.language.powershell - captures: - 1: punctuation.definition.variable.powershell - push: members - - match: ((\$|@)(?i:(global|local|private|script|using|workflow):\w+)) + - match: ((\$|@)(?i:({{var_scope_mod}}):\w+)) captures: 1: variable.other.readwrite.powershell 2: punctuation.definition.variable.powershell 3: storage.modifier.scope.powershell push: members - - match: ((\$)(\{)((?i:global|local|private|script|using|workflow)):([^}]*[^}`])(\})) + - match: ((\$)(\{)({{var_scope_mod}}):([^}]*[^}`])(\})) captures: 1: variable.other.readwrite.powershell 2: punctuation.definition.variable.powershell @@ -545,62 +502,20 @@ contexts: push: members variables-without-property: - - match: |- - (?xi: - (\$) - (?: - ExecutionContext | Host | Home | IsCoreCLR | IsLinux | IsWindows - | IsMacOS | PID | Profile | PsCommandPath | PsHome | PsScriptRoot - | PsUiCulture | PsVersionTable | ShellID - ) - ) + - match: (\$){{var_constants}} scope: support.constant.variable.powershell captures: 1: punctuation.definition.variable.powershell - - match: |- - (?xi: - (\$) - (?: - [$^?_] - | (?: - Args | ConsoleFileName | Error | Event | EventArgs - | EventSubscriber | ForEach | Input | LastExitCode | Matches - | MyInvocation | NestedPromptLevel | PsBoundParameters | PsCmdlet - | PsCulture | PsDebugContext | PsItem | Pwd | Sender | SourceArgs - | SourceEventArgs | StackTrace | Switch | This - )\b - ) - ) - scope: variable.language.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: |- - (?xi: - (\$) - (?: - (?: - Confirm | Debug | ErrorAction | Information | Progress | Verbose # *Preference - | Warning | WhatIf - ) - Preference - | Maximum(?:Alias|Drive|Error|Function|History|Variable)Count # Maximum*Count - | Log(?:Command|Engine|Provider)(?:Health|Lifecycle)Event # Log*Event - | PsDebugContext | PsDefaultParameterValues | PsEmailServer - | PsModuleAutoloadingPreference | PsSenderInfo - | PsSessionApplicationName | PsSessionConfigurationName - | PsSessionOption | ErrorView | FormatEnumerationLimit | OFS - | OutputEncoding - ) - ) + - match: (\$){{var_language}} scope: variable.language.powershell captures: 1: punctuation.definition.variable.powershell - - match: (?i:(\$|@)(global|local|private|script|using|workflow):(\w+)) + - match: (?i:(\$|@)({{var_scope_mod}}):(\w+)) captures: 1: punctuation.definition.variable.powershell 2: storage.modifier.scope.powershell 3: variable.other.readwrite.powershell - - match: (?i:(\$)(\{)(global|local|private|script|using|workflow):([^}]*[^}`])(\})) + - match: (?i:(\$)(\{)({{var_scope_mod}}):([^}]*[^}`])(\})) captures: 1: punctuation.definition.variable.powershell 2: punctuation.section.braces.begin @@ -924,11 +839,6 @@ contexts: ############################################################################### variables: - dec_exponent: (?:[eE][-+]?\d*) - dec_suffix: '[dD]' - float_suffix: '[dDlL]' - int_suffix: (?i:u[lsy]?|[lnsy]) - unit_suffix: (?i:[kmgtp]b\b) kebab_break: (?![\w-]) builtin_types: |- \b(?x: @@ -936,3 +846,43 @@ variables: | int (?:32|64)? | long | byte | float | double | decimal | array | hashtable )\b + + # Numbers + dec_exponent: (?:[eE][-+]?\d*) + dec_suffix: '[dD]' + float_suffix: '[dDlL]' + int_suffix: (?i:u[lsy]?|[lnsy]) + unit_suffix: (?i:[kmgtp]b\b) + + # Variables + var_constants: |- + \b(?xi: + (?: + ExecutionContext | Host | Home | IsCoreCLR | IsLinux | IsWindows + | IsMacOS | PID | Profile | PsCommandPath | PsHome | PsScriptRoot + | PsUiCulture | PsVersionTable | ShellID + ) + )\b + var_language: |- + (?xi: + [$^?_] + | \b(?: + Args | ConsoleFileName | Error | Event | EventArgs + | EventSubscriber | ForEach | Input | LastExitCode | Matches + | MyInvocation | NestedPromptLevel | PsBoundParameters | PsCmdlet + | PsCulture | PsDebugContext | PsItem | Pwd | Sender | SourceArgs + | SourceEventArgs | StackTrace | Switch | This + | (?: + Confirm | Debug | ErrorAction | Information | Progress # *Preference + | Verbose | Warning | WhatIf + ) Preference + | Maximum (?: Alias | Drive | Error | Function | History | Variable ) Count # Maximum*Count + | Log (?: Command | Engine | Provider ) (?: Health | Lifecycle ) Event # Log*Event + | PsDebugContext | PsDefaultParameterValues | PsEmailServer + | PsModuleAutoloadingPreference | PsSenderInfo + | PsSessionApplicationName | PsSessionConfigurationName + | PsSessionOption | ErrorView | FormatEnumerationLimit | OFS + | OutputEncoding + )\b + ) + var_scope_mod: (?i:global|local|private|script|using|workflow) From 1bb4cfced3ee4d4fd5acafa9cc28205d81adf3d3 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 12:21:09 -0500 Subject: [PATCH 036/133] Move the members context --- PowerShell.sublime-syntax | 55 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index be80c46e..5f2fb692 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -238,34 +238,6 @@ contexts: - match: \b(?i:(?:foreach|where|sort|tee)-object)\b scope: support.function.powershell - members: - - match: (?=\.\.) - pop: 1 - - match: \.(?=\w) - scope: punctuation.accessor.dot.powershell - - match: (\w+)(\() - captures: - 1: meta.function-call.powershell variable.function.powershell - 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell - push: - - meta_content_scope: meta.function-call.arguments.powershell - - match: \) - scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell - pop: 1 - - include: expressions - - match: \w+ - scope: variable.other.member.powershell - - match: \[ - scope: punctuation.section.brackets.begin.powershell - push: - - meta_scope: meta.brackets.indexer.powershell - - match: \] - scope: punctuation.section.brackets.end.powershell - pop: 1 - - include: expressions - - match: '' - pop: 1 - functions: - match: ^(?:\s*)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) scope: meta.function.powershell @@ -535,6 +507,33 @@ contexts: 4: variable.other.readwrite.powershell 5: punctuation.section.braces.end + members: + - match: (?=\.\.) + pop: 1 + - match: \.(?=\w) + scope: punctuation.accessor.dot.powershell + - match: (\w+)(\() + captures: + 1: meta.function-call.powershell variable.function.powershell + 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell + push: + - meta_content_scope: meta.function-call.arguments.powershell + - match: \) + scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell + pop: 1 + - include: expressions + - match: \w+ + scope: variable.other.member.powershell + - match: \[ + scope: punctuation.section.brackets.begin.powershell + push: + - meta_scope: meta.brackets.indexer.powershell + - match: \] + scope: punctuation.section.brackets.end.powershell + pop: 1 + - include: expressions + - include: immediately-pop + ###[ GROUPS ]################################################################## groups: From e01a883ae87818c6c3f881de0b03d2d0c4142521 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 12:44:24 -0500 Subject: [PATCH 037/133] Extract approved verbs to a variable --- PowerShell.sublime-syntax | 47 +++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 5f2fb692..4f162439 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -210,26 +210,11 @@ contexts: - include: expressions commands: - # "Verb-Noun pattern:" + # The "Verb-Noun" pattern - match: |- (?x: (?:[\w\\:-]*\\)? # Path stuff - \b(?i: - Add | Approve | Assert | Backup | Block | Build | Checkpoint # "Official" Verbs - | 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 - ) + {{command_verbs}} # Approved verbs \-\w+? # Any "noun" (?:\.(?i:exe|cmd|bat|ps1))?\b # More path stuff ) @@ -885,3 +870,31 @@ variables: )\b ) var_scope_mod: (?i:global|local|private|script|using|workflow) + + # The "Approved Verbs" list + # https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands + command_verbs: |- + \b(?xi: + # Common verbs + Add | Clear | Close | Copy | Enter | Exit | Find | Format | Get | Hide + | Join | Lock | Move | New | Open | Optimize | Pop | Push | Redo | Remove + | Rename | Reset | Resize | Search | Select | Set | Show | Skip | Split + | Step | Switch | Undo | Unlock | Watch + # Communications verbs + | Connect | Disconnect | Read | Receive | Send | Write + # Data verbs + | Backup | Checkpoint | Compare | Compress | Convert | ConvertFrom + | ConvertTo | Dismount | Edit | Expand | Export | Group | Import + | Initialize | Limit | Merge | Mount | Out | Publish | Restore | Save + | Sync | Unpublish | Update + # Diagnostic verbs + | Debug | Measure | Ping | Repair | Resolve | Test | Trace + # Lifecycle verbs + | Approve | Assert | Build | Complete | Confirm | Deny | Deploy | Disable + | Enable | Install | Invoke | Register | Request | Restart | Resume | Start + | Stop | Submit | Suspend | Uninstall | Unregister | Wait + # Security verbs + | Block | Grant | Protect | Revoke | Unblock | Unprotect + # Other verbs + | Use + )\b From ab07e6477a12880e3c7eaa03a81c54a73befe564 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 13:03:10 -0500 Subject: [PATCH 038/133] Sort function contexts --- PowerShell.sublime-syntax | 135 ++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 4f162439..c836405e 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -80,8 +80,6 @@ contexts: # Declarations - match: \b(?i:var){{kebab_break}} scope: keyword.declaration.variable.powershell - - match: \b(?i:(?:dynamic)?param){{kebab_break}} - scope: keyword.declaration.parameter.powershell # This scope is not standard expressions: - include: regions @@ -167,48 +165,6 @@ contexts: 3: keyword.other.region.end.powershell 4: meta.fold.end.powershell - attributes: - - match: |- - (?xi: - (\[)\s* - ( - CmdletBinding | Alias | OutputType | Parameter - | Validate - (?: - Count | NotNull(?:OrEmpty)? | Range | Pattern | Length | Set - | Script) - | Allow(?: Null | Empty(?: Collection | String )) - )\b - ) - captures: - 1: punctuation.section.brackets.begin.powershell - 2: support.function.attribute.powershell - push: - - meta_scope: meta.attribute.powershell - - match: \] - scope: punctuation.section.brackets.end.powershell - pop: 1 - - match: \( - scope: punctuation.section.group.begin.powershell - push: - - match: \) - scope: punctuation.section.group.end.powershell - pop: 1 - - match: |- - (?xi: - \b( - Mandatory | ValueFromPipeline(?:ByPropertyName)? - | ValueFromRemainingArguments | Position(?:alBinding)? - | (?:Default)?ParameterSetName | SupportsShouldProcess | SupportsPaging - | HelpUri | ConfirmImpact | HelpMessage - )\b - \s*(=)? - ) - captures: - 1: variable.parameter.attribute.powershell - 2: keyword.operator.assignment.powershell - - include: expressions - commands: # The "Verb-Noun" pattern - match: |- @@ -223,18 +179,6 @@ contexts: - match: \b(?i:(?:foreach|where|sort|tee)-object)\b scope: support.function.powershell - functions: - - match: ^(?:\s*)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) - scope: meta.function.powershell - captures: - 1: storage.type.powershell - 2: storage.modifier.scope.powershell - 3: entity.name.function.powershell - push: - - match: (?=\{|\() - pop: 1 - - include: comment-line - script-blocks: - match: (%)?(\{) captures: @@ -252,20 +196,65 @@ contexts: scope: storage.modifier.powershell # TODO: Fix functions, so these don't nest here. + - include: function-sections - include: attributes - # Begin/Process/End/Clean - - match: \b(?i:begin){{kebab_break}} - scope: keyword.context.block.begin.powershell - - match: \b(?i:process){{kebab_break}} - scope: keyword.context.block.process.powershell - - match: \b(?i:end){{kebab_break}} - scope: keyword.context.block.end.powershell - - match: \b(?i:clean){{kebab_break}} - scope: keyword.context.block.clean.powershell # Back to normal stuff - include: statements +###[ FUNCTIONS ]############################################################### + + functions: + - match: ^(?:\s*)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) + scope: meta.function.powershell + captures: + 1: storage.type.powershell + 2: storage.modifier.scope.powershell + 3: entity.name.function.powershell + push: + - match: (?=\{|\() + pop: 1 + - include: comment-line + + function-sections: + - match: \b(?i:(?:dynamic)?param){{kebab_break}} + scope: keyword.declaration.parameter.powershell # This scope is not standard + # Begin/Process/End/Clean + - match: \b(?i:begin){{kebab_break}} + scope: keyword.context.block.begin.powershell + - match: \b(?i:process){{kebab_break}} + scope: keyword.context.block.process.powershell + - match: \b(?i:end){{kebab_break}} + scope: keyword.context.block.end.powershell + - match: \b(?i:clean){{kebab_break}} + scope: keyword.context.block.clean.powershell + + attributes: + - match: (\[)\s*({{attributes}}) + captures: + 1: punctuation.section.brackets.begin.powershell + 2: support.function.attribute.powershell + push: inside-attribute + + inside-attribute: + - meta_scope: meta.attribute.powershell + - match: \] + scope: punctuation.section.brackets.end.powershell + pop: 1 + - match: \( + scope: punctuation.section.group.begin.powershell + push: inside-attribute-parameters + + inside-attribute-parameters: + - match: \) + scope: punctuation.section.group.end.powershell + pop: 1 + - match: ({{attribute_parameters}})\s*(=)? + captures: + 1: variable.parameter.attribute.powershell + 2: keyword.operator.assignment.powershell + - include: expressions + ###[ TYPES ]################################################################### types: @@ -831,6 +820,22 @@ variables: | array | hashtable )\b + # Attributes + attributes: |- + \b(?xi: + CmdletBinding | Alias | OutputType | Parameter + | Validate + (?: Count | NotNull (?:OrEmpty)? | Range | Pattern | Length | Set | Script) + | Allow (?: Null | Empty (?: Collection | String )) + )\b + attribute_parameters: |- + \b(?xi: + Mandatory | ValueFromPipeline (?:ByPropertyName)? + | ValueFromRemainingArguments | Position(?:alBinding)? + | (?:Default)? ParameterSetName | SupportsShouldProcess | SupportsPaging + | HelpUri | ConfirmImpact | HelpMessage + )\b + # Numbers dec_exponent: (?:[eE][-+]?\d*) dec_suffix: '[dD]' From 10c1df63d79b5afe5c1c8c4090dd0ba7a0776584 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 13:48:30 -0500 Subject: [PATCH 039/133] Add a dedicated using context and don't return to it when you leave. Also, make a context for shebang. Fixes #198 --- PowerShell.sublime-syntax | 70 +++++++++++++++++++++++++++----- Tests/syntax_test_Class.ps1 | 8 ++-- Tests/syntax_test_Function.ps1 | 8 ++-- Tests/syntax_test_PowerShell.ps1 | 9 ++-- 4 files changed, 75 insertions(+), 20 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c836405e..c33581d5 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -12,7 +12,7 @@ file_extensions: first_line_match: |- (?x: - ^\#!.*\b(?:pwsh|powershell)\b + ^\#!.*{{shebang_language}} | ^\# \s* -\*- [^*]* mode: \s* powershell [^*]* -\*- ) @@ -21,7 +21,28 @@ contexts: - include: comments main: - - include: statements + - meta_include_prototype: false + - match: '' + push: [statements, imports, shebang] + + shebang: + - meta_include_prototype: false + - match: ^\s*(\#!) + captures: + 1: punctuation.definition.comment.powershell + set: shebang-body + - include: else-pop + + shebang-body: + - meta_include_prototype: false + - meta_scope: comment.line.shebang.powershell + - match: '{{shebang_language}}' + scope: constant.language.shebang.powershell + - include: pop-eol + + imports: + - include: using-directives + - include: else-pop statements: - include: redirection @@ -88,7 +109,6 @@ contexts: - include: commands - include: constants - include: variables - - include: using-directives - include: types - include: hashtables - include: strings @@ -127,13 +147,6 @@ contexts: captures: 1: punctuation.definition.parameter.powershell - using-directives: - - match: \b(?i:(using))\s+(?i:(namespace|module))\s+(?i:((?:\w+(?:\.)?)+)) - captures: - 1: keyword.control.using.powershell - 2: keyword.other.powershell - 3: variable.parameter.powershell - requires-directives: - match: (#)((?i:requires))\s captures: @@ -202,6 +215,40 @@ contexts: # Back to normal stuff - include: statements +###[ USINGS ]################################################################## + + using-directives: + - match: \b(?i)using(?=\s) + scope: keyword.control.import.powershell + push: inside-using + + inside-using: + - match: \bnamespace(?=\s) + scope: keyword.control.import.powershell + set: inside-using-namespace + - match: \bmodule(?=\s) + scope: keyword.control.import.powershell + set: inside-using-module + - include: else-pop + + inside-using-namespace: + - include: pop-eol + - match: \p{L}[\p{L}\p{N}]+(\.) + scope: meta.path.powershell + captures: + 1: punctuation.accessor.dot.powershell + - match: \p{L}[\p{L}\p{N}]+ + scope: meta.path.powershell + + inside-using-module: + - include: pop-eol + - match: \p{L}[\p{L}\p{N}]+(\.) + scope: meta.path.powershell + captures: + 1: punctuation.accessor.dot.powershell + - match: \p{L}[\p{L}\p{N}]+ + scope: meta.path.powershell support.type.powershell + ###[ FUNCTIONS ]############################################################### functions: @@ -278,7 +325,7 @@ contexts: 1: punctuation.accessor.dot.powershell - match: '{{builtin_types}}' scope: storage.type.powershell - - match: (?!\d+|\.)[\p{L}\p{N}.]+ + - match: \p{L}[\p{L}\p{N}]+ scope: support.type.powershell - include: types-without-members - match: \, @@ -819,6 +866,7 @@ variables: | int (?:32|64)? | long | byte | float | double | decimal | array | hashtable )\b + shebang_language: \b(?:pwsh|powershell)\b # Attributes attributes: |- diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index 22904748..8e94d1d9 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -1,8 +1,10 @@ # SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" using namespace system.management.automation -# <- keyword.control.using -# ^^^^^^^^^ keyword.other -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter +#^^^^ keyword.control.import.powershell +# ^^^^^^^^^ keyword.control.import.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.path.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell # Define a class class TypeName diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index d8991122..747e13a8 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -1,9 +1,11 @@ # SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" using module Microsoft.Management -# <- keyword.control.using -# ^ keyword.other -# ^ variable.parameter +#^^^^ keyword.control.import.powershell +# ^^^^^^ keyword.control.import.powershell +# ^^^^^^^^^^^^^^^^^^^^ meta.path.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^ support.type.powershell function Test-Path {} # @@@@@@@@@ definition diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index ec7948a5..78b31d89 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1,8 +1,11 @@ # SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" using namespace System.Management.Automation -# <- keyword.control.using -# ^ keyword.other -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter +#^^^^ keyword.control.import.powershell +# ^^^^^^^^^ keyword.control.import.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.path.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell + #Requires -PSSnapin DiskSnapin -Version 1.2 # <- punctuation.definition.keyword #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.requires From fbd075289953f3ac01156776ca14c9e125dd1d37 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 13:57:37 -0500 Subject: [PATCH 040/133] Delete TODO for Atom --- Tests/syntax_test_PowerShell.ps1 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 78b31d89..77223232 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -217,8 +217,12 @@ $properties = @{ # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment # ^ meta.hashtable string.quoted.single Something = $else - # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite - # Atom-grammar-test is not tokenizing this correctly... Need to test in Atom - TODO +#^^^^^^^^^^^^^^^^^^^^ meta.hashtable.powershell +# ^^^^^^^^^^^^ meta.hashtable.assignment.powershell +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell Number = 16 # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment From dcb7203dec5b70730033c168cfb1bcb42a1c8347 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 14:09:37 -0500 Subject: [PATCH 041/133] Group commands contexts --- PowerShell.sublime-syntax | 44 ++++++++++++++++++++------------ Tests/syntax_test_PowerShell.ps1 | 13 ++++++---- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c33581d5..f3d78c59 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -50,7 +50,6 @@ contexts: - include: expressions - include: functions - # TODO: Continue into a command statement - match: \B\.(?= ) scope: support.function.source.powershell @@ -118,8 +117,6 @@ contexts: - include: groups - include: arrays - include: subexpressions - - match: \b[\w.-]+\.(?i:exe|com|cmd|bat)\b - scope: variable.function.powershell # Consume a string with a trailing dot # to prevent members with particular names from being recognized as keywords. @@ -178,20 +175,6 @@ contexts: 3: keyword.other.region.end.powershell 4: meta.fold.end.powershell - commands: - # The "Verb-Noun" pattern - - match: |- - (?x: - (?:[\w\\:-]*\\)? # Path stuff - {{command_verbs}} # Approved verbs - \-\w+? # Any "noun" - (?:\.(?i:exe|cmd|bat|ps1))?\b # More path stuff - ) - scope: meta.function-call.powershell support.function.powershell - # Builtin cmdlets with reserved verbs - - match: \b(?i:(?:foreach|where|sort|tee)-object)\b - scope: support.function.powershell - script-blocks: - match: (%)?(\{) captures: @@ -215,6 +198,33 @@ contexts: # Back to normal stuff - include: statements +###[ COMMANDS ]################################################################ + + commands: + - include: commands-verb-noun + - include: commands-reserved + - include: script-invocation + + commands-verb-noun: + # The "Verb-Noun" pattern + - match: |- + (?x: + (?:[.\w\\/:-]*[\\/])? # Path stuff + {{command_verbs}} # Approved verbs + \-\w+? # Any "noun" + (?:\.(?i:exe|cmd|bat|ps1))?\b # More path stuff + ) + scope: meta.function-call.powershell support.function.powershell + + commands-reserved: + # Builtin cmdlets with reserved verbs + - match: \b(?i:(?:foreach|where|sort|tee)-object)\b + scope: support.function.powershell + + script-invocation: + - match: \b[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b + scope: variable.function.powershell + ###[ USINGS ]################################################################## using-directives: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 77223232..4403147a 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -840,11 +840,14 @@ ls *.ps1 -recurse # ^^^^^^^^ variable.parameter.option # Commands (executable files) -. .\scripts\myscript.ps1 -parameter 'value' -# <- support.function.source.powershell -# ^ punctuation.definition.parameter -# ^^^^^^^^^^ variable.parameter.option -# ^^^^^^^ string.quoted.single +. .\scripts\Test-Foo.ps1 -parameter 'value' +# ^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell & tool.exe # <- keyword.operator.background # ^^^^^^^^ variable.function From 15fd7a5fd568edb989e67497a6650201aa2d216b Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 14:31:19 -0500 Subject: [PATCH 042/133] Add supplemental scopes to some documentation --- PowerShell.sublime-syntax | 40 +++++++++++++++++++++------------- Tests/syntax_test_Function.ps1 | 17 +++++++++++++++ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index f3d78c59..2c767847 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -806,33 +806,30 @@ contexts: - include: comment-embedded-docs comment-embedded-docs: - # TODO # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help - - match: |- - (?xi: - ^\s*(\.) - ( - Component | Description | Example | ExternalHelp | ForwardHelpCategory | ForwardHelpTargetName - | Functionality | Inputs | Link | Notes | Outputs | Parameter | RemoteHelpRunSpace - | Role | Synopsis - ) - ) - scope: comment.documentation.embedded.powershell - captures: - 1: punctuation.definition.keyword.documentation.powershell - 2: keyword.other.documentation.powershell - match: ^\s*(\.)(?i:(Parameter)\s+([a-z0-9-_]+)) scope: comment.documentation.embedded.powershell captures: 1: punctuation.definition.keyword.documentation.powershell 2: keyword.other.documentation.param.powershell 3: variable.parameter.powershell - - match: ^\s*(\.)(?i:(ForwardHelpTargetName|ForwardHelpCategory|ExternalHelp|Link)\s+([a-z0-9-_]+)) + - match: ^\s*(\.)(?i:(ForwardHelpTargetName|ExternalHelp|Link)\s+([a-z0-9-_:/.&]+)) scope: comment.documentation.embedded.powershell captures: 1: punctuation.definition.keyword.documentation.powershell 2: keyword.other.documentation.powershell 3: markup.underline.link.powershell + - match: ^\s*(\.)(?i:(ForwardHelpCategory)\s+({{doc_fwdhelp_cat}})) + scope: comment.documentation.embedded.powershell + captures: + 1: punctuation.definition.keyword.documentation.powershell + 2: keyword.other.documentation.powershell + 3: support.type.powershell + - match: ^\s*(\.)({{doc}}) + scope: comment.documentation.embedded.powershell + captures: + 1: punctuation.definition.keyword.documentation.powershell + 2: keyword.other.documentation.powershell comment-line: - match: '#(?!(?i:requires|(?:end)?region)\b)' @@ -961,3 +958,16 @@ variables: # Other verbs | Use )\b + + # Documentation + doc: |- + (?xi: + Component | Description | Example | ExternalHelp | ForwardHelpCategory + | ForwardHelpTargetName | Functionality | Inputs | Link | Notes | Outputs + | Parameter | RemoteHelpRunSpace | Role | Synopsis + ) + doc_fwdhelp_cat: |- + (?x: + Alias | Cmdlet | HelpFile | Function | Provider | General | FAQ + | Glossary | ScriptCommand | ExternalScript | Filter | All + ) diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index 747e13a8..ba922156 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -51,6 +51,23 @@ function Test-Path {} # <- punctuation.definition.keyword # ^ keyword.other.documentation The functionality that best describes this cmdlet + .ForwardHelpCategory Alias +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.powershell comment.documentation.embedded.powershell +# ^ punctuation.definition.keyword.documentation.powershell +# ^^^^^^^^^^^^^^^^^^^ keyword.other.documentation.powershell +# ^^^^^ support.type.powershell + + .parameter foo +#^^^^^^^^^^^^^^^^^ comment.block.powershell comment.documentation.embedded.powershell +# ^ punctuation.definition.keyword.documentation.powershell +# ^^^^^^^^^ keyword.other.documentation.param.powershell +# ^^^ variable.parameter.powershell + + .LINK https://example.com +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.powershell comment.documentation.embedded.powershell +# ^ punctuation.definition.keyword.documentation.powershell +# ^^^^ keyword.other.documentation.powershell +# ^^^^^^^^^^^^^^^^^^^ markup.underline.link.powershell This should not be considered documentaton -> .role # ^ - keyword.operator.documentation From 4f67256f1a0733db665977d645fb2c4f08954d9e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 15:00:00 -0500 Subject: [PATCH 043/133] Embed C# in Add-Type strings Fixes #201 --- PowerShell.sublime-syntax | 31 ++++++++++++++++++++++++++++++- Tests/syntax_test_Add-Type.ps1 | 24 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 Tests/syntax_test_Add-Type.ps1 diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 2c767847..28e01506 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -137,7 +137,9 @@ contexts: - include: pop-before-eol - include: operators + - include: parameters + parameters: # Flags/Options/Parameters - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? scope: variable.parameter.option.powershell @@ -201,6 +203,7 @@ contexts: ###[ COMMANDS ]################################################################ commands: + - include: commands-add-type - include: commands-verb-noun - include: commands-reserved - include: script-invocation @@ -218,13 +221,39 @@ contexts: commands-reserved: # Builtin cmdlets with reserved verbs - - match: \b(?i:(?:foreach|where|sort|tee)-object)\b + - match: \b(?i:(?:ForEach|Where|Sort|Tee)-Object)\b scope: support.function.powershell script-invocation: - match: \b[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b scope: variable.function.powershell + commands-add-type: + - match: \b(?i:Add-Type)\b + scope: support.function.powershell + push: inside-add-type + + inside-add-type: + - include: pop-eol + + - match: '@"' + scope: meta.string.interpolated.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell + embed: scope:source.cs + embed_scope: meta.string.interpolated.powershell string.quoted.double.powershell source.cs.embedded + escape: ("@) + escape_captures: + 1: meta.string.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell + + - match: "@'" + scope: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell + embed: scope:source.cs + embed_scope: meta.string.powershell string.quoted.single.powershell source.cs.embedded + escape: ('@) + escape_captures: + 1: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell + + - include: expressions + ###[ USINGS ]################################################################## using-directives: diff --git a/Tests/syntax_test_Add-Type.ps1 b/Tests/syntax_test_Add-Type.ps1 new file mode 100644 index 00000000..0107efb2 --- /dev/null +++ b/Tests/syntax_test_Add-Type.ps1 @@ -0,0 +1,24 @@ +# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" + + + Add-Type -Language CSharp @" +# ^^^^^^^^ support.function.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ meta.string.interpolated.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell + using System; +#^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell source.cs.embedded +# ^^^^^ keyword.control.import.cs +# ^^^^^^ meta.path.cs + using System.Runtime.InteropServices; + public class ClassGetForegroundWindow { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell source.cs.embedded +# ^^^^^^ storage.modifier.access.cs +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.cs +# ^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.class.cs +# ^ meta.class.body.cs meta.block.cs punctuation.section.block.begin.cs + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + } +"@ +#^ meta.string.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell - source.cs From 360df292dddc783a0db2db6728ca3f32bca7a024 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 5 Dec 2025 17:30:22 -0500 Subject: [PATCH 044/133] Add context-sensitive functions --- PowerShell.sublime-syntax | 107 ++++++++++++---- Tests/syntax_test_Function.ps1 | 93 ++++++++------ Tests/syntax_test_PowerShell.ps1 | 211 +++++++++++++++++-------------- 3 files changed, 255 insertions(+), 156 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 28e01506..f331ed40 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -192,9 +192,6 @@ contexts: - include: class-methods - match: \b(?i:hidden|static)\b scope: storage.modifier.powershell - - # TODO: Fix functions, so these don't nest here. - - include: function-sections - include: attributes # Back to normal stuff @@ -291,29 +288,86 @@ contexts: ###[ FUNCTIONS ]############################################################### functions: - - match: ^(?:\s*)(?i)(function|filter|configuration|workflow)\s+(?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) - scope: meta.function.powershell + - match: ^\s*(?i)(function|filter|configuration|workflow)(?=\s) captures: - 1: storage.type.powershell - 2: storage.modifier.scope.powershell - 3: entity.name.function.powershell - push: - - match: (?=\{|\() - pop: 1 - - include: comment-line + 1: keyword.declaration.function.powershell + push: [function-body, function-inline-params, function-name] + + function-name: + - match: (?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) + captures: + 1: storage.modifier.scope.powershell + 2: entity.name.function.powershell + - match: (?=[{(]) + pop: 1 + + function-inline-params: + - match: \( + scope: punctuation.section.parameters.begin.powershell + push: inside-function-inline-params + - include: else-pop + + inside-function-inline-params: + - match: \) + scope: punctuation.section.parameters.end.powershell + pop: 1 + - include: comma-separators + - include: types + - match: (\$)\p{L}[\p{L}\p{N}]* + scope: variable.parameter.powershell + captures: + 1: punctuation.definition.variable.begin.powershell + + function-body: + - meta_scope: meta.function.powershell + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-function-body + - include: else-pop + + inside-function-body: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 1 + + - include: attributes - function-sections: - - match: \b(?i:(?:dynamic)?param){{kebab_break}} + - match: \b(?i:(?:Dynamic)?Param){{kebab_break}} scope: keyword.declaration.parameter.powershell # This scope is not standard - # Begin/Process/End/Clean - - match: \b(?i:begin){{kebab_break}} - scope: keyword.context.block.begin.powershell - - match: \b(?i:process){{kebab_break}} - scope: keyword.context.block.process.powershell - - match: \b(?i:end){{kebab_break}} - scope: keyword.context.block.end.powershell - - match: \b(?i:clean){{kebab_break}} - scope: keyword.context.block.clean.powershell + push: expect-param-context + + - match: \b(?i:Begin|Process|End|Clean){{kebab_break}} + scope: keyword.context.block.powershell + push: expect-function-context + + - include: statements + + expect-function-context: + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-function-context + - include: else-pop + + inside-function-context: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 1 + - include: statements + + expect-param-context: + - match: \( + scope: punctuation.section.block.begin.powershell + push: inside-param-context + - include: else-pop + + inside-param-context: + - match: \) + scope: punctuation.section.block.end.powershell + pop: 1 + - include: comma-separators + - include: attributes + - include: types + - include: variables-without-property attributes: - match: (\[)\s*({{attributes}}) @@ -444,8 +498,7 @@ contexts: scope: punctuation.terminator.statement.powershell - match: \`(?=\n|$) scope: punctuation.separator.continuation.line.powershell - - match: ',' - scope: punctuation.separator.sequence.powershell + - include: comma-separators - match: '&' scope: keyword.operator.background.powershell - match: \.\.(?=\-?\d|\(|\$) @@ -870,6 +923,10 @@ contexts: ###[ COMPONENTS ]############################################################## + comma-separators: + - match: ',' + scope: punctuation.separator.sequence.powershell + escape-sequences: - match: '`[0abenfrvt"''$`]' scope: constant.character.escape.powershell diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index ba922156..a76d4cec 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -74,10 +74,11 @@ function Test-Path {} #> # <- punctuation.definition.comment.block.end function Verb-Noun { -#^^^^^^^^^^^^^^^^^ meta.function -#^^^^^^^ storage.type -# ^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1', # <- meta.attribute punctuation.section.brackets.begin # ^ meta.attribute support.function.attribute @@ -112,7 +113,7 @@ function Verb-Noun { # ^ meta.attribute punctuation.section.group.end # ^ meta.attribute punctuation.section.brackets.end [OutputType([String])] -#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell # ^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^^^^^ support.function.attribute.powershell @@ -123,9 +124,11 @@ function Verb-Noun { # ^ punctuation.section.group.end.powershell # ^ punctuation.section.brackets.end.powershell Param - #^^^^^ keyword.declaration.parameter +#^^^^^^^^ meta.function.powershell +# ^^^^^ keyword.declaration.parameter.powershell ( - # <- punctuation.section.group.begin +#^^^^ meta.function.powershell +# ^ punctuation.section.block.begin.powershell # Param1 help description # <- comment.line punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line @@ -285,13 +288,15 @@ function Verb-Noun { # ^ punctuation.section.group.end # ^ punctuation.section.brackets.end [int32] - # <- punctuation.section.brackets.begin - #^^^^^ storage.type - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^ meta.function.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell $Param2, - # <- punctuation.definition.variable - # ^ variable.other.readwrite - # ^ punctuation.separator +#^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell # Param3 help description # <- comment.line punctuation.definition.comment @@ -323,7 +328,7 @@ function Verb-Noun { # ^ meta.attribute punctuation.section.group.end # ^ meta.attribute punctuation.section.brackets.end [String] -#^^^^^^^^^^^^^^^ meta.block.powershell meta.group.powershell +#^^^^^^^^^^^^^^^ meta.function.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^ support.type.powershell # ^ punctuation.section.brackets.end.powershell @@ -357,7 +362,7 @@ function Verb-Noun { # ^ meta.attribute punctuation.section.group.end # ^ meta.attribute punctuation.section.brackets.end [string] -#^^^^^^^^^^^^^^^ meta.block.powershell meta.group.powershell +#^^^^^^^^^^^^^^^ meta.function.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell @@ -388,7 +393,7 @@ function Verb-Noun { # ^ comment.line punctuation.definition.comment # ^ comment.line [string] -#^^^^^^^^^^^^^^^ meta.block.powershell meta.group.powershell +#^^^^^^^^^^^^^^^ meta.function.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell @@ -396,37 +401,53 @@ function Verb-Noun { # <- punctuation.definition.variable # ^ variable.other.readwrite ) - # <- punctuation.section.group.end +#^^^^^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell Begin - #^^^^^ keyword.context.block.begin +#^^^^^^^^ meta.function.powershell +# ^^^^^ keyword.context.block.powershell { +#^^^^ meta.function.powershell +# ^ punctuation.section.block.begin.powershell } Process { - # <- keyword.context.block.process +#^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ keyword.context.block.powershell +# ^ punctuation.section.block.begin.powershell if ($pscmdlet.ShouldProcess("Target", "Operation")) { - # <- keyword.control - # ^ punctuation.section.group.begin - # ^ punctuation.definition.variable - # ^^^^^^^^ variable.language - # ^^^^^^^^^^^^^ variable.function - # @@@@@@@@@@@@@ reference - # ^ punctuation.section.arguments.begin - # ^^^^^^^^ string.quoted.double - # ^ punctuation.separator - # ^^^^^^^^^^^ string.quoted.double - # ^ punctuation.section.arguments.end - # ^ punctuation.section.group.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^ keyword.control.conditional.if.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.arguments.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell } } End { - #^^^ keyword.context.block.end +#^^^^^^^^ meta.function.powershell +# ^^^ keyword.context.block.powershell +# ^ punctuation.section.block.begin.powershell } clean { } -#^^^^^^^^^^^^ meta.block.powershell -# ^^^^^ keyword.context.block.clean.powershell -# ^^^ meta.block.powershell -# ^ punctuation.section.braces.begin.powershell -# ^ punctuation.section.braces.end.powershell +#^^^^^^^^^^^^ meta.function.powershell +# ^^^^^ keyword.context.block.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell } diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 4403147a..2af1c3ce 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -976,121 +976,134 @@ switch ('this') { # Functions and filters functioN MyFunction{} -# <- storage.type -# ^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell function My-Function {} -# <- storage.type -# ^^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell Function My.Function{} -# <- storage.type -# ^^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell function My-Function.Other{} -# <- storage.type -# ^^^^^^^^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell function Some.other.function{} -# <- storage.type -# ^^^^^^^^^^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@@@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell FUNCTION MyFunction2 {} -# <- storage.type -# ^^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell function New-File { } -# <- storage.type -# ^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell # @@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell function New-File ($Name) { } -# <- storage.type -# ^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell # @@@@@@@@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end New-File -#^^^^^^^^ meta.function-call support.function +#^^^^^^^^ meta.function-call.powershell support.function.powershell #@@@@@@@@ reference function NewFile($Name) { } -# <- storage.type -# ^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^ entity.name.function.powershell # @@@@@@@ definition -# ^ punctuation.section.group.begin -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.parameters.begin.powershell +# ^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell filter myfilter($param) {} -# <- storage.type -# ^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell # @@@@@@@@ definition -# ^ punctuation.section.group.begin -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.parameters.begin.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell Filter my-Filter ($param){} -# <- storage.type -# ^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@ definition -# ^ punctuation.section.group.begin -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.parameters.begin.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell # Note that the # in the path should highlight as a comment! function Test-Drive([string]$roman) { -# <- storage.type -# ^^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@ definition -# ^ punctuation.section.group.begin -# ^ punctuation.section.brackets.begin -# ^^^^^^ storage.type -# ^ punctuation.section.brackets.end -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell $roman | c:\users\Me\Documents\Programming\F#\test.exe $roman # ^ punctuation.definition.variable # ^ variable.other.readwrite # ^ keyword.operator.logical.pipe # ^ punctuation.definition.comment # ^^^^ comment.line -} -# <- punctuation.section.braces.end + } +#^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell function Verb-Noun -#^^^^^^^^^^^^^^^^^ meta.function -#^^^^^^^ storage.type -# ^^^^^^^^^ meta.function entity.name.function +#^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@ definition -{ -# <- punctuation.section.braces.begin + { +#^^^^ meta.function.powershell +# ^ punctuation.section.block.begin.powershell Param #^^^^^ keyword.declaration.parameter ( - # <- punctuation.section.group.begin +#^^^^ meta.function.powershell +# ^ punctuation.section.block.begin.powershell # Param1 help description # <- comment.line punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line @@ -1198,12 +1211,14 @@ function Verb-Noun # <- punctuation.definition.variable # ^ variable.other.readwrite ) - # <- punctuation.section.group.end +#^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell # Do Something.... -} -# <- punctuation.section.braces.end + } +#^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell # Class class Vehicle { @@ -1292,16 +1307,19 @@ catch { } # Reserved words Configuration Crazyness { -# <- storage.type -# ^^^^^^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@ definition -# ^ punctuation.section.braces.begin +# ^ punctuation.section.block.begin.powershell Node Whatever { # ^ punctuation.section.braces.begin } - # <- punctuation.section.braces.end -} -# <- punctuation.section.braces.end +#^^^^ meta.function.powershell meta.block.powershell +# ^ punctuation.section.braces.end.powershell + } +#^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell # Redirection notepad.exe > log.txt @@ -1540,20 +1558,23 @@ $ScriptBlock | Out-File $file -Force # ^ punctuation.definition.parameter # ^^^^^^ variable.parameter.option workflow w1 {} -# <- storage.type -# ^^ entity.name.function +#^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^ entity.name.function.powershell # @@ definition -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell Workflow work { sequence {} } -# <- storage.type -# ^^^^ entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^ keyword.declaration.function.powershell +# ^^^^ entity.name.function.powershell # @@@@ definition -# ^ punctuation.section.braces.begin -# ^^^^^^^^ keyword.control -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end -# ^ punctuation.section.braces.end +# ^ punctuation.section.block.begin.powershell +# ^^^^^^^^ keyword.control.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.section.block.end.powershell function get-something {} # @@@@@@@@@@@@@ definition function Out-WithYou {} From 87eb5b3e1b2ef0ef239fe8083794d722a5623e3c Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 13:12:33 -0500 Subject: [PATCH 045/133] Add the PowerShell documentation Class samples --- PowerShell.sublime-syntax | 2 +- Tests/syntax_test_Class.ps1 | 281 ++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index f331ed40..dd71c00d 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -219,7 +219,7 @@ contexts: commands-reserved: # Builtin cmdlets with reserved verbs - match: \b(?i:(?:ForEach|Where|Sort|Tee)-Object)\b - scope: support.function.powershell + scope: meta.function-call.powershell support.function.powershell script-invocation: - match: \b[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index 8e94d1d9..b50af7d9 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -136,3 +136,284 @@ class TypeName $object.MemberMethod2() # @@@@@@@@@@@@@ reference + + +# PowerShell documentation examples +# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes + +# Example 1 - Minimal definition +class Device { +# @@@@@@ definition + [string]$Brand +} + +$dev = [Device]::new() +# @@@ reference +$dev.Brand = "Fabrikam, Inc." +$dev + + +# Example 2 - Class with instance members +class Book { +# @@@@ definition + # Class properties + [string] $Title + [string] $Author + [string] $Synopsis + [string] $Publisher + [datetime] $PublishDate + [int] $PageCount + [string[]] $Tags + # Default constructor + Book() { $this.Init(@{}) } +# @@@@ reference + # Convenience constructor from hashtable + Book([hashtable]$Properties) { $this.Init($Properties) } +# @@@@ reference + # Common constructor for title and author + Book([string]$Title, [string]$Author) { + $this.Init(@{Title = $Title; Author = $Author }) +# @@@@ reference + } + # Shared initializer method + [void] Init([hashtable]$Properties) { +# @@@@ definition + foreach ($Property in $Properties.Keys) { + $this.$Property = $Properties.$Property + } + } + # Method to calculate reading time as 2 minutes per page + [timespan] GetReadingTime() { +# @@@@@@@@@@@@@@ definition + if ($this.PageCount -le 0) { + throw 'Unable to determine reading time from page count.' + } + $Minutes = $this.PageCount * 2 + return [timespan]::new(0, $Minutes, 0) +# @@@ reference + } + # Method to calculate how long ago a book was published + [timespan] GetPublishedAge() { +# @@@@@@@@@@@@@@@ definition + if ( + $null -eq $this.PublishDate -or + $this.PublishDate -eq [datetime]::MinValue + ) { throw 'PublishDate not defined' } + + return (Get-Date) - $this.PublishDate +# @@@@@@@@ reference + } + # Method to return a string representation of the book + [string] ToString() { +# @@@@@@@@ definition + return "$($this.Title) by $($this.Author) ($($this.PublishDate.Year))" + } +} + +[BookList]::Add([Book]::new(@{ +# @@@ reference +# @@@ reference + Title = 'The Fellowship of the Ring' + Author = 'J.R.R. Tolkien' + Publisher = 'George Allen & Unwin' + PublishDate = '1954-07-29' + PageCount = 423 + Tags = @('Fantasy', 'Adventure') +})) + +[BookList]::Find({ +# @@@@ reference + param ($b) + + $b.PublishDate -gt '1950-01-01' +}).Title + +[BookList]::FindAll({ +# @@@@@@@ reference + param($b) + + $b.Author -match 'Tolkien' +}).Title + +[BookList]::Remove($Book) +# @@@@@@ reference +[BookList]::Books.Title + +[BookList]::RemoveBy('Author', 'J.R.R. Tolkien') +# @@@@@@@@ reference +"Titles: $([BookList]::Books.Title)" + +[BookList]::Add($Book) +# @@@ reference +[BookList]::Add($Book) +# @@@ reference + + +# Example 3 - Class with static members +class BookList { +# @@@@@@@@ definition + # Static property to hold the list of books + static [System.Collections.Generic.List[Book]] $Books + # Static method to initialize the list of books. Called in the other + # static methods to avoid needing to explicit initialize the value. + static [void] Initialize() { [BookList]::Initialize($false) } +# @@@@@@@@@@ definition +# @@@@@@@@@@ reference + static [bool] Initialize([bool]$Force) { +# @@@@@@@@@@ definition + if ([BookList]::Books.Count -gt 0 -and -not $Force) { + return $false + } + + [BookList]::Books = [System.Collections.Generic.List[Book]]::new() +# @@@ reference + + return $true + } + # Ensure a book is valid for the list. + static [void] Validate([book]$Book) { +# @@@@@@@@ definition + $Prefix = @( + 'Book validation failed: Book must be defined with the Title,' + 'Author, and PublishDate properties, but' + ) -join ' ' + if ($null -eq $Book) { throw "$Prefix was null" } + if ([string]::IsNullOrEmpty($Book.Title)) { +# @@@@@@@@@@@@@ reference + throw "$Prefix Title wasn't defined" + } + if ([string]::IsNullOrEmpty($Book.Author)) { +# @@@@@@@@@@@@@ reference + throw "$Prefix Author wasn't defined" + } + if ([datetime]::MinValue -eq $Book.PublishDate) { + throw "$Prefix PublishDate wasn't defined" + } + } + # Static methods to manage the list of books. + # Add a book if it's not already in the list. + static [void] Add([Book]$Book) { +# @@@ definition + [BookList]::Initialize() +# @@@@@@@@@@ reference + [BookList]::Validate($Book) +# @@@@@@@@ reference + if ([BookList]::Books.Contains($Book)) { +# @@@@@@@@ reference + throw "Book '$Book' already in list" + } + + $FindPredicate = { + param([Book]$b) + + $b.Title -eq $Book.Title -and + $b.Author -eq $Book.Author -and + $b.PublishDate -eq $Book.PublishDate + }.GetNewClosure() + if ([BookList]::Books.Find($FindPredicate)) { +# @@@@ reference + throw "Book '$Book' already in list" + } + + [BookList]::Books.Add($Book) +# @@@ reference + } + # Clear the list of books. + static [void] Clear() { +# @@@@@ definition + [BookList]::Initialize() +# @@@@@@@@@@ reference + [BookList]::Books.Clear() +# @@@@@ reference + } + # Find a specific book using a filtering scriptblock. + static [Book] Find([scriptblock]$Predicate) { +# @@@@ definition + [BookList]::Initialize() +# @@@@@@@@@@ reference + return [BookList]::Books.Find($Predicate) +# @@@@ reference + } + # Find every book matching the filtering scriptblock. + static [Book[]] FindAll([scriptblock]$Predicate) { + [BookList]::Initialize() +# @@@@@@@@@@ reference + return [BookList]::Books.FindAll($Predicate) +# @@@@@@@ reference + } + # Remove a specific book. + static [void] Remove([Book]$Book) { +# @@@@@@ definition + [BookList]::Initialize() +# @@@@@@@@@@ reference + [BookList]::Books.Remove($Book) +# @@@@@@ reference + } + # Remove a book by property value. + static [void] RemoveBy([string]$Property, [string]$Value) { +# @@@@@@@@ definition + [BookList]::Initialize() +# @@@@@@@@@@ reference + $Index = [BookList]::Books.FindIndex({ +# @@@@@@@@@ reference + param($b) + $b.$Property -eq $Value + }.GetNewClosure()) + if ($Index -ge 0) { + [BookList]::Books.RemoveAt($Index) +# @@@@@@@@ reference + } + } +} + + +# Example 4 - Class definition with and without Runspace affinity + +# Class definition with Runspace affinity (default behavior) +class UnsafeClass { +# @@@@@@@@@@@ definition + static [Object] ShowRunspaceId($Val) { +# @@@@@@@@@@@@@@ definition + return [pscustomobject]@{ + ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId + RunspaceId = [runspace]::DefaultRunspace.Id + } + } +} + +$unsafe = [UnsafeClass]::new() +# @@@ reference + +while ($true) { + 1..10 | ForEach-Object -Parallel { +# @@@@@@@@@@@@@@ reference + Start-Sleep -ms 100 +# @@@@@@@@@@@ reference + ($Using:unsafe)::ShowRunspaceId($_) + } +} + +# Class definition with NoRunspaceAffinity attribute +[NoRunspaceAffinity()] +class SafeClass { +# @@@@@@@@@ definition + static [Object] ShowRunspaceId($Val) { +# @@@@@@@@@@@@@@ definition + return [pscustomobject]@{ + ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId + RunspaceId = [runspace]::DefaultRunspace.Id + } + } +} + +$safe = [SafeClass]::new() +# @@@ reference + +while ($true) { + 1..10 | ForEach-Object -Parallel { +# @@@@@@@@@@@@@@ reference + Start-Sleep -ms 100 +# @@@@@@@@@@@ reference + ($Using:safe)::ShowRunspaceId($_) + } +} From 40e406c47b2c1658b0c61fb32769e8422fa5e444 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 17:46:29 -0500 Subject: [PATCH 046/133] Improve variable matches --- PowerShell.sublime-syntax | 83 +++++++++++-------- Tests/syntax_test_PowerShell.ps1 | 138 ++++++++++++++++--------------- Tests/syntax_test_strings.ps1 | 15 ++-- 3 files changed, 128 insertions(+), 108 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index dd71c00d..b2b5c8a0 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -546,79 +546,86 @@ contexts: ###[ VARIABLES ]############################################################### variables: - - match: (\$){{var_constants}} + - match: (\$|@){{var_constants}} scope: support.constant.variable.powershell captures: 1: punctuation.definition.variable.powershell push: members - - match: (\$){{var_language}} + - match: (\$|@){{var_language}} scope: variable.language.powershell captures: 1: punctuation.definition.variable.powershell push: members - - match: ((\$|@)(?i:({{var_scope_mod}}):\w+)) + - match: (\$|@)({{var_scope_mod}})(:){{identifier_simple}} + scope: variable.other.readwrite.powershell captures: - 1: variable.other.readwrite.powershell - 2: punctuation.definition.variable.powershell - 3: storage.modifier.scope.powershell + 1: punctuation.definition.variable.powershell + 2: storage.modifier.scope.powershell + 3: punctuation.separator.sequence.powershell push: members - - match: ((\$)(\{)({{var_scope_mod}}):([^}]*[^}`])(\})) + - match: (\$|@)(\{)({{var_scope_mod}})(:){{identifier_special}}(\}) + scope: variable.other.readwrite.powershell captures: - 1: variable.other.readwrite.powershell - 2: punctuation.definition.variable.powershell - 3: punctuation.section.braces.begin.powershell - 4: storage.modifier.scope.powershell - 6: punctuation.section.braces.end.powershell + 1: punctuation.definition.variable.powershell + 2: punctuation.section.interpolation.begin.powershell + 3: storage.modifier.scope.powershell + 4: punctuation.separator.sequence.powershell + 5: punctuation.section.interpolation.end.powershell push: members - - match: ((?i:(\$|@)(\w+:)?\w+)) + - match: (\$|@)(?:({{identifier_simple}})(:))?{{identifier_simple}} + scope: variable.other.readwrite.powershell captures: - 1: variable.other.readwrite.powershell - 2: punctuation.definition.variable.powershell - 3: support.variable.drive.powershell - 4: variable.other.member.powershell + 1: punctuation.definition.variable.powershell + 2: support.variable.drive.powershell + 3: punctuation.separator.sequence.powershell push: members - - match: ((?i:(\$)(\{)(\w+:)?([^}]*[^}`])(\}))) + - match: (\$|@)(\{)(?:({{identifier_special}})(:))?{{identifier_special}}(\}) + scope: variable.other.readwrite.powershell captures: - 1: variable.other.readwrite.powershell - 2: punctuation.definition.variable.powershell - 3: punctuation.section.braces.begin.powershell - 4: support.variable.drive.powershell - 6: punctuation.section.braces.end.powershell + 1: punctuation.definition.variable.powershell + 2: punctuation.section.interpolation.begin.powershell + 3: support.variable.drive.powershell + 4: punctuation.separator.sequence.powershell + 5: punctuation.section.interpolation.end.powershell push: members variables-without-property: - - match: (\$){{var_constants}} + - match: (\$|@){{var_constants}} scope: support.constant.variable.powershell captures: 1: punctuation.definition.variable.powershell - - match: (\$){{var_language}} + - match: (\$|@){{var_language}} scope: variable.language.powershell captures: 1: punctuation.definition.variable.powershell - - match: (?i:(\$|@)({{var_scope_mod}}):(\w+)) + - match: (\$|@)({{var_scope_mod}})(:){{identifier_simple}} + scope: variable.other.readwrite.powershell captures: 1: punctuation.definition.variable.powershell 2: storage.modifier.scope.powershell - 3: variable.other.readwrite.powershell - - match: (?i:(\$)(\{)({{var_scope_mod}}):([^}]*[^}`])(\})) + 3: punctuation.separator.sequence.powershell + - match: (\$|@)(\{)({{var_scope_mod}})(:){{identifier_special}}(\}) + scope: variable.other.readwrite.powershell captures: 1: punctuation.definition.variable.powershell - 2: punctuation.section.braces.begin + 2: punctuation.section.interpolation.begin.powershell 3: storage.modifier.scope.powershell - 4: variable.other.readwrite.powershell - 5: punctuation.section.braces.end - - match: (?i:(\$)(\w+:)?\w+) + 4: punctuation.separator.sequence.powershell + 5: punctuation.section.interpolation.end.powershell + - match: (\$|@)(?:({{identifier_simple}})(:))?{{identifier_simple}} scope: variable.other.readwrite.powershell captures: 1: punctuation.definition.variable.powershell 2: support.variable.drive.powershell - - match: (?i:(\$)(\{)(\w+:)?([^}]*[^}`])(\})) + 3: punctuation.separator.sequence.powershell + - match: (\$|@)(\{)(?:({{identifier_special}})(:))?{{identifier_special}}(\}) + scope: variable.other.readwrite.powershell captures: 1: punctuation.definition.variable.powershell - 2: punctuation.section.braces.begin + 2: punctuation.section.interpolation.begin.powershell 3: support.variable.drive.powershell - 4: variable.other.readwrite.powershell - 5: punctuation.section.braces.end + 4: punctuation.separator.sequence.powershell + 5: punctuation.section.interpolation.end.powershell members: - match: (?=\.\.) @@ -985,6 +992,10 @@ variables: unit_suffix: (?i:[kmgtp]b\b) # Variables + # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables + identifier_simple: '[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nd}_?]+' + identifier_special: '[^}]*[^}`]' + # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables var_constants: |- \b(?xi: (?: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 2af1c3ce..bfb0d5b5 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -137,73 +137,80 @@ throw "Do not run this file!" # ^^^^^ constant.language.null.powershell # ^ punctuation.definition.variable.powershell -# Automatic variables -$_, $$, $^, $? -# <- punctuation.definition.variable -#^ variable.language -# ^ punctuation.definition.variable -# ^^ variable.language -# ^ punctuation.definition.variable -# ^^ variable.language -# ^ punctuation.definition.variable -# ^^ variable.language -$args -# <- punctuation.definition.variable -#^^^^ variable.language -$error -# <- punctuation.definition.variable -# ^^^^ variable.language -$home -# <- punctuation.definition.variable -# ^^^ support.constant.variable -$foreach -# <- punctuation.definition.variable -#^^^^^^^ variable.language + # Automatic variables + $_, $$, $^, $? +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell + $args +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell + $error +# ^^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell + $home +# ^^^^^ support.constant.variable.powershell +# ^ punctuation.definition.variable.powershell + $foreach +# ^^^^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell -# Normal variables -$variable -# <- punctuation.definition.variable -# ^ variable.other.readwrite -$script:variable -# <- variable.other.readwrite punctuation.definition.variable -# ^ storage.modifier.scope -# ^ variable.other.readwrite -$ENV:ComputerName -# <- variable.other.readwrite punctuation.definition.variable -# ^ support.variable.drive -# ^ variable.other.readwrite -${variable} -# <- variable.other.readwrite punctuation.definition.variable - # <- punctuation.section.braces.begin -# ^^^^^^^^ variable.other.readwrite -# ^ punctuation.section.braces.end -${script:variable} -# <- variable.other.readwrite punctuation.definition.variable - # <- punctuation.section.braces.begin -# ^ storage.modifier.scope -# ^ variable.other.readwrite -# ^ punctuation.section.braces.end -# Variable properties should be highlighted -$variable.Name -# <- variable.other.readwrite punctuation.definition.variable -#^^^^^^^^ variable.other.readwrite -# ^ punctuation.accessor.dot -# ^^^^^ - variable.other.readwrite -# ^^^^ variable.other.member + # Normal variables + $variable +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $script:variable +# ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ storage.modifier.scope.powershell +# ^ punctuation.separator.sequence.powershell + $ENV:ComputerName +# ^^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ support.variable.drive.powershell +# ^ punctuation.separator.sequence.powershell + ${variable} +# ^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.interpolation.begin.powershell +# ^ punctuation.section.interpolation.end.powershell + ${script:variable} +# ^^^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.interpolation.begin.powershell +# ^^^^^^ storage.modifier.scope.powershell +# ^ punctuation.separator.sequence.powershell +# ^ punctuation.section.interpolation.end.powershell -# Variable properties should be highlighted -$variable.Name.Method( ) -# <- variable.other.readwrite punctuation.definition.variable -#^^^^^^^^ variable.other.readwrite -# ^ punctuation.accessor.dot -# ^^^^ variable.other.member -# ^ punctuation.accessor.dot -# ^^^^^^ meta.function-call variable.function -# @@@@@@ reference -# ^^^ meta.function-call.arguments -# ^^^^^^^^^^^^^^^ - variable.other.readwrite -# ^ - meta.function-call + + # Variable properties should be highlighted + $variable.Name +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^ variable.other.member.powershell + + # Variable properties should be highlighted + $variable.Name.Method( ) +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^ variable.other.member.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@ reference +# ^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell # Hashtable $properties = @{ @@ -1526,7 +1533,8 @@ $file = join-path $env:SystemDrive "$([System.io.path]::GetRandomFileName()).ps1 # @@@@@@@@@ reference # ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^^^^ support.variable.drive.powershell +# ^^^ support.variable.drive.powershell +# ^ punctuation.separator.sequence.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell # ^ string.quoted.double.powershell punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index f6f020d6..4bdb7940 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -113,9 +113,10 @@ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell -# ^^^^^^^^^^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell - string +# ^^^^^^^^^^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^^^^ support.variable.drive.powershell +# ^^^ support.variable.drive.powershell +# ^ punctuation.separator.sequence.powershell # ^ string.quoted.double.powershell punctuation.definition.string.end.powershell # Here as well @@ -123,12 +124,12 @@ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell -# ^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell - string +# ^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^ punctuation.section.braces.begin -# ^^^^ support.variable.drive.powershell -# ^^^^^^^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.section.braces.end +# ^ punctuation.section.interpolation.begin.powershell +# ^^^ support.variable.drive.powershell +# ^ punctuation.separator.sequence.powershell +# ^ punctuation.section.interpolation.end.powershell # ^ string.quoted.double.powershell punctuation.definition.string.end.powershell # The @splat references only work in argument mode, should not highlight in strings From 5dcac7544d5e0f77de7c5bcdb9b05f064af7d7b3 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 18:01:25 -0500 Subject: [PATCH 047/133] Allow member access of groups --- PowerShell.sublime-syntax | 15 ++++---------- Tests/syntax_test_Class.ps1 | 2 ++ Tests/syntax_test_PowerShell.ps1 | 34 ++++++++++++++++++++++++++++++++ Tests/syntax_test_strings.ps1 | 12 ++++++----- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index b2b5c8a0..54fefe4e 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -400,7 +400,7 @@ contexts: types: - match: \[ scope: punctuation.section.brackets.begin.powershell - push: [maybe-static-member, inside-type] + push: [members, inside-type] types-without-members: - match: \[ @@ -426,15 +426,6 @@ contexts: - match: \+ scope: punctuation.accessor.plus.powershell - static-members: - - match: '::' - scope: punctuation.accessor.double-colon.powershell - set: members - - maybe-static-member: - - include: static-members - - include: immediately-pop - ###[ OPERATORS ]############################################################### operators: @@ -632,6 +623,8 @@ contexts: pop: 1 - match: \.(?=\w) scope: punctuation.accessor.dot.powershell + - match: ::(?=\w) + scope: punctuation.accessor.double-colon.powershell - match: (\w+)(\() captures: 1: meta.function-call.powershell variable.function.powershell @@ -663,7 +656,7 @@ contexts: - meta_scope: meta.group.powershell - match: \) scope: punctuation.section.group.end.powershell - pop: 1 + set: members - include: attributes - include: expressions diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index b50af7d9..f202d4d6 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -390,6 +390,7 @@ while ($true) { Start-Sleep -ms 100 # @@@@@@@@@@@ reference ($Using:unsafe)::ShowRunspaceId($_) +# @@@@@@@@@@@@@@ reference } } @@ -415,5 +416,6 @@ while ($true) { Start-Sleep -ms 100 # @@@@@@@@@@@ reference ($Using:safe)::ShowRunspaceId($_) +# @@@@@@@@@@@@@@ reference } } diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index bfb0d5b5..8a70b5f4 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1617,6 +1617,40 @@ function get-number {} # ^ meta.group.complex.subexpression punctuation.section.group.end # ^ punctuation.definition.variable # ^ punctuation.section.interpolation.end - source.powershell.embedded + + ([MyType])::Name[2] +# ^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^ punctuation.section.group.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^ variable.other.member.powershell +# ^^^ meta.brackets.indexer.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.brackets.end.powershell + ([MyType])::Name.ToString()[2] +# ^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^ punctuation.section.group.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^ variable.other.member.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell +# ^^^ meta.brackets.indexer.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.brackets.end.powershell + "This is the DebugPreference variable: $DebugPreference" #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string string.quoted.double # ^^^^^^^^^^^^^^^^ meta.string meta.interpolation variable.language - string diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 4bdb7940..2b06b7ca 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -240,19 +240,21 @@ # ^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell - # TODO: Mark ToString as a function (1.11).ToString("#.#") # ^^^^^^ meta.group.powershell # ^ punctuation.section.group.begin.powershell # ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell # ^ punctuation.section.group.end.powershell -# ^^^^^^^ meta.group.powershell -# ^ punctuation.section.group.begin.powershell -# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@ reference +# ^^^^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell # ^ punctuation.definition.string.end.powershell -# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.arguments.end.powershell "{1,10} {0,10} {2,10:x}" -f "First", "Second", 255 # ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell From 717260f257358d7c5585d44a94259d61c1581f0a Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 18:33:23 -0500 Subject: [PATCH 048/133] Refactor variables so we can stop synchronizing the with/without members matches We also get to mark escaped chars in the full-unicode var names --- PowerShell.sublime-syntax | 102 ++++++++++++------------------- Tests/syntax_test_PowerShell.ps1 | 17 ++++++ 2 files changed, 57 insertions(+), 62 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 54fefe4e..72cb907a 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -107,9 +107,9 @@ contexts: - include: commands - include: constants - - include: variables - include: types - include: hashtables + - include: variables - include: strings - include: script-blocks - include: escape-sequences @@ -537,86 +537,64 @@ contexts: ###[ VARIABLES ]############################################################### variables: + - match: (?=[$@](?:[{$^]|{{identifier_simple}})) + push: [members, expect-variable] + + variables-without-property: + - match: (?=[$@](?:[{$^]|{{identifier_simple}})) + push: [expect-variable] + + expect-variable: - match: (\$|@){{var_constants}} scope: support.constant.variable.powershell captures: 1: punctuation.definition.variable.powershell - push: members - match: (\$|@){{var_language}} scope: variable.language.powershell captures: 1: punctuation.definition.variable.powershell - push: members - - match: (\$|@)({{var_scope_mod}})(:){{identifier_simple}} - scope: variable.other.readwrite.powershell - captures: - 1: punctuation.definition.variable.powershell - 2: storage.modifier.scope.powershell - 3: punctuation.separator.sequence.powershell - push: members - - match: (\$|@)(\{)({{var_scope_mod}})(:){{identifier_special}}(\}) - scope: variable.other.readwrite.powershell + - match: (\$)(\{) captures: 1: punctuation.definition.variable.powershell 2: punctuation.section.interpolation.begin.powershell - 3: storage.modifier.scope.powershell - 4: punctuation.separator.sequence.powershell - 5: punctuation.section.interpolation.end.powershell - push: members - - match: (\$|@)(?:({{identifier_simple}})(:))?{{identifier_simple}} - scope: variable.other.readwrite.powershell - captures: - 1: punctuation.definition.variable.powershell - 2: support.variable.drive.powershell - 3: punctuation.separator.sequence.powershell - push: members - - match: (\$|@)(\{)(?:({{identifier_special}})(:))?{{identifier_special}}(\}) - scope: variable.other.readwrite.powershell + push: inside-variable-special-char + - match: (\$|@)(?!\{) captures: 1: punctuation.definition.variable.powershell 2: punctuation.section.interpolation.begin.powershell - 3: support.variable.drive.powershell - 4: punctuation.separator.sequence.powershell - 5: punctuation.section.interpolation.end.powershell - push: members + push: inside-variable-simple + - include: immediately-pop - variables-without-property: - - match: (\$|@){{var_constants}} - scope: support.constant.variable.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: (\$|@){{var_language}} - scope: variable.language.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: (\$|@)({{var_scope_mod}})(:){{identifier_simple}} - scope: variable.other.readwrite.powershell + inside-variable-simple: + - meta_include_prototype: false + - meta_scope: variable.other.readwrite.powershell + - match: ({{var_scope_mod}})(:) captures: - 1: punctuation.definition.variable.powershell - 2: storage.modifier.scope.powershell - 3: punctuation.separator.sequence.powershell - - match: (\$|@)(\{)({{var_scope_mod}})(:){{identifier_special}}(\}) - scope: variable.other.readwrite.powershell + 1: storage.modifier.scope.powershell + 2: punctuation.separator.sequence.powershell + - match: ({{identifier_simple}})(:) captures: - 1: punctuation.definition.variable.powershell - 2: punctuation.section.interpolation.begin.powershell - 3: storage.modifier.scope.powershell - 4: punctuation.separator.sequence.powershell - 5: punctuation.section.interpolation.end.powershell - - match: (\$|@)(?:({{identifier_simple}})(:))?{{identifier_simple}} - scope: variable.other.readwrite.powershell + 1: support.variable.drive.powershell + 2: punctuation.separator.sequence.powershell + - match: '{{identifier_simple}}' + - include: immediately-pop + + inside-variable-special-char: + - meta_include_prototype: false + - meta_scope: variable.other.readwrite.powershell + - match: '`.' + scope: constant.character.escape.powershell + - match: \} + scope: punctuation.section.interpolation.end.powershell + pop: 1 + - match: ({{var_scope_mod}})(:) captures: - 1: punctuation.definition.variable.powershell - 2: support.variable.drive.powershell - 3: punctuation.separator.sequence.powershell - - match: (\$|@)(\{)(?:({{identifier_special}})(:))?{{identifier_special}}(\}) - scope: variable.other.readwrite.powershell + 1: storage.modifier.scope.powershell + 2: punctuation.separator.sequence.powershell + - match: ({{identifier_simple}})(:) captures: - 1: punctuation.definition.variable.powershell - 2: punctuation.section.interpolation.begin.powershell - 3: support.variable.drive.powershell - 4: punctuation.separator.sequence.powershell - 5: punctuation.section.interpolation.end.powershell + 1: support.variable.drive.powershell + 2: punctuation.separator.sequence.powershell members: - match: (?=\.\.) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 8a70b5f4..58d6f1d3 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -183,6 +183,23 @@ throw "Do not run this file!" # ^ punctuation.definition.variable.powershell # ^ punctuation.section.interpolation.begin.powershell # ^ punctuation.section.interpolation.end.powershell + ${vari-able} +# ^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.interpolation.begin.powershell +# ^ punctuation.section.interpolation.end.powershell + ${var`iable} +# ^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.interpolation.begin.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.section.interpolation.end.powershell + ${variable`}} +# ^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.interpolation.begin.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.section.interpolation.end.powershell ${script:variable} # ^^^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell From 2f2c4e4a93ea04c6101aaf7df22969157302e4e2 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 18:42:18 -0500 Subject: [PATCH 049/133] Rename variables-without-members --- PowerShell.sublime-syntax | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 72cb907a..24fc24ea 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -367,7 +367,7 @@ contexts: - include: comma-separators - include: attributes - include: types - - include: variables-without-property + - include: variables-without-members attributes: - match: (\[)\s*({{attributes}}) @@ -540,7 +540,7 @@ contexts: - match: (?=[$@](?:[{$^]|{{identifier_simple}})) push: [members, expect-variable] - variables-without-property: + variables-without-members: - match: (?=[$@](?:[{$^]|{{identifier_simple}})) push: [expect-variable] @@ -788,8 +788,7 @@ contexts: - clear_scopes: 1 - meta_include_prototype: false - meta_scope: meta.interpolation.powershell - - include: variables-without-property - - include: variables + - include: variables-without-members - include: immediately-pop numbers: From 2454ef640e7dfc5e20f619b3a3fe10d119b36ebf Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 18:53:42 -0500 Subject: [PATCH 050/133] fixup --- Tests/syntax_test_Function.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index a76d4cec..a01002db 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -400,9 +400,9 @@ function Verb-Noun { $Param5 # <- punctuation.definition.variable # ^ variable.other.readwrite - ) -#^^^^^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell + ) +#^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell Begin #^^^^^^^^ meta.function.powershell From f7506fff637b5938ce20daf0e6972456e6f8625b Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 19:54:07 -0500 Subject: [PATCH 051/133] Add context-sensitive classes --- PowerShell.sublime-syntax | 84 +++++++++------ Tests/syntax_test_Class.ps1 | 174 +++++++++++++++++++------------ Tests/syntax_test_PowerShell.ps1 | 87 +++++++++++----- 3 files changed, 223 insertions(+), 122 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 24fc24ea..dca9a1e6 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -187,14 +187,6 @@ contexts: - match: \} scope: punctuation.section.braces.end.powershell pop: 1 - - # TODO: Fix classes, so this doesn't nest here. - - include: class-methods - - match: \b(?i:hidden|static)\b - scope: storage.modifier.powershell - - include: attributes - - # Back to normal stuff - include: statements ###[ COMMANDS ]################################################################ @@ -294,7 +286,7 @@ contexts: push: [function-body, function-inline-params, function-name] function-name: - - match: (?:(global|local|script|private):)?((?:\p{L}|\d|_|-|\.)+) + - match: (?:(global|local|script|private):)?({{identifier_function}}+) captures: 1: storage.modifier.scope.powershell 2: entity.name.function.powershell @@ -313,7 +305,7 @@ contexts: pop: 1 - include: comma-separators - include: types - - match: (\$)\p{L}[\p{L}\p{N}]* + - match: (\$){{identifier_simple}} scope: variable.parameter.powershell captures: 1: punctuation.definition.variable.begin.powershell @@ -330,8 +322,6 @@ contexts: scope: punctuation.section.block.end.powershell pop: 1 - - include: attributes - - match: \b(?i:(?:Dynamic)?Param){{kebab_break}} scope: keyword.declaration.parameter.powershell # This scope is not standard push: expect-param-context @@ -340,6 +330,7 @@ contexts: scope: keyword.context.block.powershell push: expect-function-context + - include: attributes - include: statements expect-function-context: @@ -515,24 +506,46 @@ contexts: ###[ CLASSES ]################################################################# classes: - - match: \b((?i:class))\s+([\w-]+)\b - captures: - 1: storage.type.class.powershell - 2: meta.class.powershell entity.name.class.powershell + - match: \b(?i)class(?=\s) + scope: keyword.declaration.class.powershell + push: [class-body, class-parents, class-name] - class-methods: - - match: ^(?:\s*)(?i)(hidden|static)?\s*(\[)((?!\d+|\.)[\p{L}\p{N}.]+)(\])\s*((?:\p{L}|\d|_|-|\.)+)\s*(?=\() - scope: meta.function.powershell - captures: - 1: storage.modifier.powershell - 2: punctuation.section.brackets.begin.powershell - 3: storage.type.powershell - 4: punctuation.section.brackets.end.powershell - 5: entity.name.function.powershell - push: - - match: (?=\() - pop: 1 - - include: comment-line + class-name: + - match: '{{identifier_simple}}' + scope: entity.name.class.powershell + pop: 1 + - include: else-pop + + class-parents: + - match: ':' + scope: punctuation.separator.type.powershell + push: inside-class-parents + - include: else-pop + + inside-class-parents: + - include: comma-separators + - match: '{{identifier_simple}}' + scope: entity.other.inherited-class.powershell + - include: else-pop + + class-body: + - meta_scope: meta.class.powershell + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-class-body + - include: else-pop + + inside-class-body: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 1 + - match: \b(?i:hidden|static)\b + scope: storage.modifier.powershell + - include: attributes + - include: types-without-members + - include: variables-without-members + - match: (?={{identifier_simple}}) + push: [function-body, function-inline-params, function-name] ###[ VARIABLES ]############################################################### @@ -603,6 +616,16 @@ contexts: scope: punctuation.accessor.dot.powershell - match: ::(?=\w) scope: punctuation.accessor.double-colon.powershell + - match: (new)(\() + captures: + 1: meta.function-call.powershell support.function.constructor.powershell + 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell + push: + - meta_content_scope: meta.function-call.arguments.powershell + - match: \) + scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell + pop: 1 + - include: expressions - match: (\w+)(\() captures: 1: meta.function-call.powershell variable.function.powershell @@ -963,8 +986,9 @@ variables: # Variables # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables - identifier_simple: '[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nd}_?]+' + identifier_simple: '[\p{L}\p{Nd}_?]+' identifier_special: '[^}]*[^}`]' + identifier_function: '[\p{L}\p{Nd}_.-]+' # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables var_constants: |- \b(?xi: diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index f202d4d6..33e28ea8 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -6,93 +6,127 @@ using namespace system.management.automation # ^ punctuation.accessor.dot.powershell # ^ punctuation.accessor.dot.powershell +class Foo : Bar, Baz { } +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +#^^^^ keyword.declaration.class.powershell +# ^^^ entity.name.class.powershell +# @@@ definition +# ^ punctuation.separator.type.powershell +# ^^^ entity.other.inherited-class.powershell +# @@@ reference +# ^ punctuation.separator.sequence.powershell +# ^^^ entity.other.inherited-class.powershell +# @@@ reference +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + # Define a class class TypeName -# <- storage.type -# ^^^^^^^^ entity.name.class +#^^^^^^^^^^^^^ meta.class.powershell +#^^^^ keyword.declaration.class.powershell +# ^^^^^^^^ entity.name.class.powershell # @@@@@@@@ definition { # Property with validate set # <- punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line [ValidateSet("val1", "Val2")] - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^^^^^^ string.quoted.double - # ^ punctuation.separator - # ^^^^^^ string.quoted.double - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [string] $P1 - # <- punctuation.section.brackets.begin - # ^^^^^ storage.type - # ^ punctuation.section.brackets.end - # ^ punctuation.definition.variable - # ^^ variable.other.readwrite +#^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell # Static property # <- punctuation.definition.comment # ^^^^^^^^^^^^^^^ comment.line static [hashtable] $P2 - #^^^^^ storage.modifier - # ^ punctuation.section.brackets.begin - # ^^^^^^^^^ storage.type - # ^ punctuation.section.brackets.end - # ^ punctuation.definition.variable - # ^^ variable.other.readwrite +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^ storage.modifier.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell # Hidden property does not show as result of Get-Member # <- punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line hidden [int] $P3 - #^^^^^ storage.modifier - # ^ punctuation.section.brackets.begin - # ^ storage.type - # ^ punctuation.section.brackets.end - # ^ punctuation.definition.variable - # ^^ variable.other.readwrite +#^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^ storage.modifier.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell # Constructor # <- punctuation.definition.comment # ^^^^^^^^^^^ comment.line TypeName ([string] $s) { - # ^ punctuation.section.group.begin - # ^ punctuation.section.brackets.begin - # ^^^^^^ storage.type - # ^ punctuation.section.brackets.end - # ^ punctuation.definition.variable - # ^ variable.other.readwrite - # ^ punctuation.section.group.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ entity.name.function.powershell +# @@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell $this.P1 = $s - # <- punctuation.definition.variable - # ^ variable.language - # ^^ variable.other.member - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^ variable.other.readwrite +#^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^ variable.other.member.powershell +# ^ keyword.operator.assignment.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell } # Static method # <- punctuation.definition.comment # ^^^^^^^^^^^^^ comment.line static [void] MemberMethod1([hashtable] $h) { - # <- storage.modifier - # ^ punctuation.section.brackets.begin - # ^^^^ storage.type - # ^ punctuation.section.brackets.end - # ^^^^^^^^^^^^^ entity.name.function - # @@@@@@@@@@@@@ definition - # ^ punctuation.section.group.begin - # ^ punctuation.section.brackets.begin - # ^^^^^^^^^ storage.type - # ^ punctuation.section.brackets.end - # ^ punctuation.definition.variable - # ^ variable.other.readwrite - # ^ punctuation.section.group.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +#^^^ meta.function.powershell +# ^^^^^^ storage.modifier.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell [TypeName]::P2 = $h -#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell meta.block.powershell +#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^^^ support.type.powershell # ^ punctuation.section.brackets.end.powershell @@ -107,27 +141,29 @@ class TypeName # <- punctuation.definition.comment # ^^^^^^^^^^^^^^^ comment.line [int] MemberMethod2([int] $i) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell -#^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +#^^^ meta.function.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell # ^^^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@@@ definition -# ^^^^^^^^^^ meta.group.powershell -# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.parameters.begin.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell -# ^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.section.group.end.powershell -# ^ meta.block.powershell punctuation.section.braces.begin.powershell +# ^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell return $this.P3 - # <- keyword.control - # ^ punctuation.definition.variable - # ^^^^ variable.language - # ^^ variable.other.member +#^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^^ keyword.control.flow.return.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^ variable.other.member.powershell } } @@ -166,12 +202,15 @@ class Book { [string[]] $Tags # Default constructor Book() { $this.Init(@{}) } +# @@@@ definition # @@@@ reference # Convenience constructor from hashtable Book([hashtable]$Properties) { $this.Init($Properties) } +# @@@@ definition # @@@@ reference # Common constructor for title and author Book([string]$Title, [string]$Author) { +# @@@@ definition $this.Init(@{Title = $Title; Author = $Author }) # @@@@ reference } @@ -336,6 +375,7 @@ class BookList { } # Find every book matching the filtering scriptblock. static [Book[]] FindAll([scriptblock]$Predicate) { +# @@@@@@@ definition [BookList]::Initialize() # @@@@@@@@@@ reference return [BookList]::Books.FindAll($Predicate) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 58d6f1d3..94da686d 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1246,20 +1246,32 @@ function Verb-Noun # Class class Vehicle { -# <- storage.type.class -# ^^^^^^^ entity.name.class +#^^^^^^^^^^^^^^ meta.class.powershell +#^^^^ keyword.declaration.class.powershell +# ^^^^^^^ entity.name.class.powershell # @@@@@@@ definition -# ^ punctuation.section.braces.begin +# ^ punctuation.section.block.begin.powershell Vehicle() {} -# ^ punctuation.section.group.begin -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +#^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell Vehicle([string]$Owner) { -# ^ storage.type -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ punctuation.section.braces.begin +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell $this.Owner = $Owner } @@ -1277,29 +1289,54 @@ class Vehicle { # ^ variable.other.readwrite [void]Drive([int]$NumberOfMiles) { -# ^^^^ storage.type -# ^^^^^ meta.function entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^ entity.name.function.powershell # @@@@@ definition -# ^^^ storage.type -# ^ punctuation.definition.variable -# ^ variable.other.readwrite +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell $this.Mileage += $NumberOfMiles -# ^^^^^ variable.language -# ^ punctuation.definition.variable -# ^^^^^^^ variable.other.member -# ^^ keyword.operator.assignment +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^ variable.other.member.powershell +# ^^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell } - # <- punctuation.section.braces.end +#^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell + static [System.Array] GetAvailableColors() { -# ^^^^^^^^^^^^^^^^^^ meta.function entity.name.function +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +#^^^ meta.function.powershell +# ^^^^^^ storage.modifier.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@@@@@@@@@@ definition -# ^^^^^^ meta.function storage.modifier -# ^^^^^^^^^^^ meta.function storage.type +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell return 'yellow', 'red' } } -# <- punctuation.section.braces.end +# <- punctuation.section.block.end $fiat.Drive(42) # ^^^^^ meta.function-call From 5642d9dc20674a942e708c3b78e3610d6529ee95 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 19:58:26 -0500 Subject: [PATCH 052/133] Name the anonymous member contexts --- PowerShell.sublime-syntax | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index dca9a1e6..d3e09c25 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -620,34 +620,33 @@ contexts: captures: 1: meta.function-call.powershell support.function.constructor.powershell 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell - push: - - meta_content_scope: meta.function-call.arguments.powershell - - match: \) - scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell - pop: 1 - - include: expressions + push: inside-function-call-arguments - match: (\w+)(\() captures: 1: meta.function-call.powershell variable.function.powershell 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell - push: - - meta_content_scope: meta.function-call.arguments.powershell - - match: \) - scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell - pop: 1 - - include: expressions + push: inside-function-call-arguments - match: \w+ scope: variable.other.member.powershell - match: \[ scope: punctuation.section.brackets.begin.powershell - push: - - meta_scope: meta.brackets.indexer.powershell - - match: \] - scope: punctuation.section.brackets.end.powershell - pop: 1 - - include: expressions + push: inside-indexer - include: immediately-pop + inside-function-call-arguments: + - meta_content_scope: meta.function-call.arguments.powershell + - match: \) + scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell + pop: 1 + - include: expressions + + inside-indexer: + - meta_scope: meta.brackets.indexer.powershell + - match: \] + scope: punctuation.section.brackets.end.powershell + pop: 1 + - include: expressions + ###[ GROUPS ]################################################################## groups: From a3e3627c95dafadc036cae3688cb7d457608ae52 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 20:10:12 -0500 Subject: [PATCH 053/133] Organize major syntax sections --- PowerShell.sublime-syntax | 463 +++++++++++++++++++------------------- 1 file changed, 232 insertions(+), 231 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index d3e09c25..b7a62360 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1,6 +1,7 @@ %YAML 1.2 --- # http://www.sublimetext.com/docs/syntax.html +# https://learn.microsoft.com/en-us/powershell/ name: PowerShell scope: source.powershell version: 2 @@ -139,43 +140,61 @@ contexts: - include: operators - include: parameters - parameters: - # Flags/Options/Parameters - - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? - scope: variable.parameter.option.powershell +###[ GROUPS ]################################################################## + + groups: + - match: \( + scope: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.powershell + - match: \) + scope: punctuation.section.group.end.powershell + set: members + - include: attributes + - include: expressions + + arrays: + - match: (@)(\() captures: - 1: punctuation.definition.parameter.powershell + 1: keyword.other.array.begin.powershell + 2: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.array-expression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: 1 + - include: expressions - requires-directives: - - match: (#)((?i:requires))\s + hashtables: + - match: (@)(\{) captures: - 1: punctuation.definition.keyword.powershell - 2: keyword.control.import.require.powershell + 1: keyword.other.hashtable.begin.powershell + 2: punctuation.section.braces.begin.powershell push: - - meta_scope: meta.requires.powershell - - include: pop-eol - - include: hashtables - - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) - scope: variable.parameter.option.powershell + - meta_scope: meta.hashtable.powershell + - match: \} + scope: punctuation.section.braces.end.powershell + pop: 1 + - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* + scope: meta.hashtable.assignment.powershell captures: - 1: punctuation.definition.variable.powershell - - match: ',' - scope: punctuation.separator.powershell + 1: punctuation.definition.string.begin.powershell + 2: variable.other.readwrite.powershell + 3: punctuation.definition.string.end.powershell + 4: keyword.operator.assignment.powershell + - include: expressions - regions: - - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.begin.powershell - 4: meta.toc-list.powershell entity.name.section.powershell - 5: meta.fold.begin.powershell - - match: ^\s*((#)\s*(endregion\b).*(\n?)) + subexpressions: + - match: (\$)(\() captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.end.powershell - 4: meta.fold.end.powershell + 1: keyword.other.variable.definition.powershell + 2: punctuation.section.group.begin.powershell + push: + - meta_scope: meta.group.complex.subexpression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: 1 + - include: expressions script-blocks: - match: (%)?(\{) @@ -243,7 +262,30 @@ contexts: - include: expressions -###[ USINGS ]################################################################## + parameters: + # Flags/Options/Parameters + - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? + scope: variable.parameter.option.powershell + captures: + 1: punctuation.definition.parameter.powershell + +###[ DIRECTIVES ]############################################################## + + requires-directives: + - match: (#)((?i:requires))\s + captures: + 1: punctuation.definition.keyword.powershell + 2: keyword.control.import.require.powershell + push: + - meta_scope: meta.requires.powershell + - include: pop-eol + - include: hashtables + - match: (-)(?i:Modules|PSSnapin|RunAsAdministrator|ShellId|Version) + scope: variable.parameter.option.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: ',' + scope: punctuation.separator.powershell using-directives: - match: \b(?i)using(?=\s) @@ -277,6 +319,50 @@ contexts: - match: \p{L}[\p{L}\p{N}]+ scope: meta.path.powershell support.type.powershell +###[ CLASSES ]################################################################# + + classes: + - match: \b(?i)class(?=\s) + scope: keyword.declaration.class.powershell + push: [class-body, class-parents, class-name] + + class-name: + - match: '{{identifier_simple}}' + scope: entity.name.class.powershell + pop: 1 + - include: else-pop + + class-parents: + - match: ':' + scope: punctuation.separator.type.powershell + push: inside-class-parents + - include: else-pop + + inside-class-parents: + - include: comma-separators + - match: '{{identifier_simple}}' + scope: entity.other.inherited-class.powershell + - include: else-pop + + class-body: + - meta_scope: meta.class.powershell + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-class-body + - include: else-pop + + inside-class-body: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 1 + - match: \b(?i:hidden|static)\b + scope: storage.modifier.powershell + - include: attributes + - include: types-without-members + - include: variables-without-members + - match: (?={{identifier_simple}}) + push: [function-body, function-inline-params, function-name] + ###[ FUNCTIONS ]############################################################### functions: @@ -386,6 +472,106 @@ contexts: 2: keyword.operator.assignment.powershell - include: expressions +###[ VARIABLES ]############################################################### + + variables: + - match: (?=[$@](?:[{$^]|{{identifier_simple}})) + push: [members, expect-variable] + + variables-without-members: + - match: (?=[$@](?:[{$^]|{{identifier_simple}})) + push: [expect-variable] + + expect-variable: + - match: (\$|@){{var_constants}} + scope: support.constant.variable.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: (\$|@){{var_language}} + scope: variable.language.powershell + captures: + 1: punctuation.definition.variable.powershell + - match: (\$)(\{) + captures: + 1: punctuation.definition.variable.powershell + 2: punctuation.section.interpolation.begin.powershell + push: inside-variable-special-char + - match: (\$|@)(?!\{) + captures: + 1: punctuation.definition.variable.powershell + 2: punctuation.section.interpolation.begin.powershell + push: inside-variable-simple + - include: immediately-pop + + inside-variable-simple: + - meta_include_prototype: false + - meta_scope: variable.other.readwrite.powershell + - match: ({{var_scope_mod}})(:) + captures: + 1: storage.modifier.scope.powershell + 2: punctuation.separator.sequence.powershell + - match: ({{identifier_simple}})(:) + captures: + 1: support.variable.drive.powershell + 2: punctuation.separator.sequence.powershell + - match: '{{identifier_simple}}' + - include: immediately-pop + + inside-variable-special-char: + - meta_include_prototype: false + - meta_scope: variable.other.readwrite.powershell + - match: '`.' + scope: constant.character.escape.powershell + - match: \} + scope: punctuation.section.interpolation.end.powershell + pop: 1 + - match: ({{var_scope_mod}})(:) + captures: + 1: storage.modifier.scope.powershell + 2: punctuation.separator.sequence.powershell + - match: ({{identifier_simple}})(:) + captures: + 1: support.variable.drive.powershell + 2: punctuation.separator.sequence.powershell + + members: + - match: (?=\.\.) + pop: 1 + - match: \.(?=\w) + scope: punctuation.accessor.dot.powershell + - match: ::(?=\w) + scope: punctuation.accessor.double-colon.powershell + - match: (new)(\() + captures: + 1: meta.function-call.powershell support.function.constructor.powershell + 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell + push: inside-function-call-arguments + - match: (\w+)(\() + captures: + 1: meta.function-call.powershell variable.function.powershell + 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell + push: inside-function-call-arguments + - match: \w+ + scope: variable.other.member.powershell + - match: \[ + scope: punctuation.section.brackets.begin.powershell + push: inside-indexer + - include: immediately-pop + + inside-function-call-arguments: + - meta_content_scope: meta.function-call.arguments.powershell + - match: \) + scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell + pop: 1 + - include: expressions + + inside-indexer: + - meta_scope: meta.brackets.indexer.powershell + - match: \] + scope: punctuation.section.brackets.end.powershell + pop: 1 + - include: expressions + ###[ TYPES ]################################################################### types: @@ -503,206 +689,6 @@ contexts: # - match: <+ # scope: invalid.illegal.powershell -###[ CLASSES ]################################################################# - - classes: - - match: \b(?i)class(?=\s) - scope: keyword.declaration.class.powershell - push: [class-body, class-parents, class-name] - - class-name: - - match: '{{identifier_simple}}' - scope: entity.name.class.powershell - pop: 1 - - include: else-pop - - class-parents: - - match: ':' - scope: punctuation.separator.type.powershell - push: inside-class-parents - - include: else-pop - - inside-class-parents: - - include: comma-separators - - match: '{{identifier_simple}}' - scope: entity.other.inherited-class.powershell - - include: else-pop - - class-body: - - meta_scope: meta.class.powershell - - match: \{ - scope: punctuation.section.block.begin.powershell - push: inside-class-body - - include: else-pop - - inside-class-body: - - match: \} - scope: punctuation.section.block.end.powershell - pop: 1 - - match: \b(?i:hidden|static)\b - scope: storage.modifier.powershell - - include: attributes - - include: types-without-members - - include: variables-without-members - - match: (?={{identifier_simple}}) - push: [function-body, function-inline-params, function-name] - -###[ VARIABLES ]############################################################### - - variables: - - match: (?=[$@](?:[{$^]|{{identifier_simple}})) - push: [members, expect-variable] - - variables-without-members: - - match: (?=[$@](?:[{$^]|{{identifier_simple}})) - push: [expect-variable] - - expect-variable: - - match: (\$|@){{var_constants}} - scope: support.constant.variable.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: (\$|@){{var_language}} - scope: variable.language.powershell - captures: - 1: punctuation.definition.variable.powershell - - match: (\$)(\{) - captures: - 1: punctuation.definition.variable.powershell - 2: punctuation.section.interpolation.begin.powershell - push: inside-variable-special-char - - match: (\$|@)(?!\{) - captures: - 1: punctuation.definition.variable.powershell - 2: punctuation.section.interpolation.begin.powershell - push: inside-variable-simple - - include: immediately-pop - - inside-variable-simple: - - meta_include_prototype: false - - meta_scope: variable.other.readwrite.powershell - - match: ({{var_scope_mod}})(:) - captures: - 1: storage.modifier.scope.powershell - 2: punctuation.separator.sequence.powershell - - match: ({{identifier_simple}})(:) - captures: - 1: support.variable.drive.powershell - 2: punctuation.separator.sequence.powershell - - match: '{{identifier_simple}}' - - include: immediately-pop - - inside-variable-special-char: - - meta_include_prototype: false - - meta_scope: variable.other.readwrite.powershell - - match: '`.' - scope: constant.character.escape.powershell - - match: \} - scope: punctuation.section.interpolation.end.powershell - pop: 1 - - match: ({{var_scope_mod}})(:) - captures: - 1: storage.modifier.scope.powershell - 2: punctuation.separator.sequence.powershell - - match: ({{identifier_simple}})(:) - captures: - 1: support.variable.drive.powershell - 2: punctuation.separator.sequence.powershell - - members: - - match: (?=\.\.) - pop: 1 - - match: \.(?=\w) - scope: punctuation.accessor.dot.powershell - - match: ::(?=\w) - scope: punctuation.accessor.double-colon.powershell - - match: (new)(\() - captures: - 1: meta.function-call.powershell support.function.constructor.powershell - 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell - push: inside-function-call-arguments - - match: (\w+)(\() - captures: - 1: meta.function-call.powershell variable.function.powershell - 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell - push: inside-function-call-arguments - - match: \w+ - scope: variable.other.member.powershell - - match: \[ - scope: punctuation.section.brackets.begin.powershell - push: inside-indexer - - include: immediately-pop - - inside-function-call-arguments: - - meta_content_scope: meta.function-call.arguments.powershell - - match: \) - scope: meta.function-call.arguments.powershell punctuation.section.arguments.end.powershell - pop: 1 - - include: expressions - - inside-indexer: - - meta_scope: meta.brackets.indexer.powershell - - match: \] - scope: punctuation.section.brackets.end.powershell - pop: 1 - - include: expressions - -###[ GROUPS ]################################################################## - - groups: - - match: \( - scope: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.powershell - - match: \) - scope: punctuation.section.group.end.powershell - set: members - - include: attributes - - include: expressions - - arrays: - - match: (@)(\() - captures: - 1: keyword.other.array.begin.powershell - 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.array-expression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: 1 - - include: expressions - - hashtables: - - match: (@)(\{) - captures: - 1: keyword.other.hashtable.begin.powershell - 2: punctuation.section.braces.begin.powershell - push: - - meta_scope: meta.hashtable.powershell - - match: \} - scope: punctuation.section.braces.end.powershell - pop: 1 - - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* - scope: meta.hashtable.assignment.powershell - captures: - 1: punctuation.definition.string.begin.powershell - 2: variable.other.readwrite.powershell - 3: punctuation.definition.string.end.powershell - 4: keyword.operator.assignment.powershell - - include: expressions - - subexpressions: - - match: (\$)(\() - captures: - 1: keyword.other.variable.definition.powershell - 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.complex.subexpression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: 1 - - include: expressions - ###[ CONSTANTS ]############################################################### constants: @@ -920,6 +906,21 @@ contexts: - include: pop-eol - include: comment-embedded-docs + regions: + - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.begin.powershell + 4: meta.toc-list.powershell entity.name.section.powershell + 5: meta.fold.begin.powershell + - match: ^\s*((#)\s*(endregion\b).*(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.end.powershell + 4: meta.fold.end.powershell + ###[ COMPONENTS ]############################################################## comma-separators: From cd1614078f0f4c655bf43b763a10ed34508aa224 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 20:33:40 -0500 Subject: [PATCH 054/133] Change C# context to use indicators Rather than triggering on Add-Type --- PowerShell.sublime-syntax | 64 +++++++++++++++++++--------------- Tests/syntax_test_Add-Type.ps1 | 24 ------------- Tests/syntax_test_strings.ps1 | 15 ++++++++ 3 files changed, 50 insertions(+), 53 deletions(-) delete mode 100644 Tests/syntax_test_Add-Type.ps1 diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index b7a62360..42661368 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -211,7 +211,6 @@ contexts: ###[ COMMANDS ]################################################################ commands: - - include: commands-add-type - include: commands-verb-noun - include: commands-reserved - include: script-invocation @@ -236,32 +235,6 @@ contexts: - match: \b[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b scope: variable.function.powershell - commands-add-type: - - match: \b(?i:Add-Type)\b - scope: support.function.powershell - push: inside-add-type - - inside-add-type: - - include: pop-eol - - - match: '@"' - scope: meta.string.interpolated.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell - embed: scope:source.cs - embed_scope: meta.string.interpolated.powershell string.quoted.double.powershell source.cs.embedded - escape: ("@) - escape_captures: - 1: meta.string.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell - - - match: "@'" - scope: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell - embed: scope:source.cs - embed_scope: meta.string.powershell string.quoted.single.powershell source.cs.embedded - escape: ('@) - escape_captures: - 1: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell - - - include: expressions - parameters: # Flags/Options/Parameters - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? @@ -754,7 +727,20 @@ contexts: single-quoted-heredoc-strings: - match: \@'(?=$) scope: punctuation.definition.string.begin.powershell - push: inside-single-quoted-heredoc-string + push: + - inside-single-quoted-heredoc-string + - inside-single-quoted-heredoc-string.syntax + + inside-single-quoted-heredoc-string.syntax: + - meta_include_prototype: false + - match: (?={{csharp_indicator}}) + set: scope:source.cs + with_prototype: + - match: (?=^'@) + pop: 1 + - match: "''" + scope: constant.character.escape.powershell + - include: else-pop inside-single-quoted-heredoc-string: - meta_include_prototype: false @@ -768,7 +754,9 @@ contexts: double-quoted-heredoc-strings: - match: \@"(?=$) scope: punctuation.definition.string.begin.powershell - push: inside-double-quoted-heredoc-string + push: + - inside-double-quoted-heredoc-string + - inside-double-quoted-heredoc-string.syntax inside-double-quoted-heredoc-string: - meta_include_prototype: false @@ -779,6 +767,16 @@ contexts: - include: escape-sequences - include: string-interpolations + inside-double-quoted-heredoc-string.syntax: + - meta_include_prototype: false + - match: (?={{csharp_indicator}}) + set: scope:source.cs + with_prototype: + - match: (?=^"@) + pop: 1 + - include: escape-sequences + - include: else-pop + string-interpolations: - match: \$\( scope: punctuation.section.interpolation.begin.powershell @@ -1062,3 +1060,11 @@ variables: Alias | Cmdlet | HelpFile | Function | Provider | General | FAQ | Glossary | ScriptCommand | ExternalScript | Filter | All ) + + # Strings + csharp_indicator: |- + (?x: \s* (?: + using\s+System[.;] + | public\s+class\s+ + | \[DllImport\b + )) diff --git a/Tests/syntax_test_Add-Type.ps1 b/Tests/syntax_test_Add-Type.ps1 deleted file mode 100644 index 0107efb2..00000000 --- a/Tests/syntax_test_Add-Type.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" - - - Add-Type -Language CSharp @" -# ^^^^^^^^ support.function.powershell -# ^^^^^^^^^ variable.parameter.option.powershell -# ^ punctuation.definition.parameter.powershell -# ^^ meta.string.interpolated.powershell string.quoted.double.powershell punctuation.definition.string.begin.powershell - using System; -#^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell source.cs.embedded -# ^^^^^ keyword.control.import.cs -# ^^^^^^ meta.path.cs - using System.Runtime.InteropServices; - public class ClassGetForegroundWindow { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell source.cs.embedded -# ^^^^^^ storage.modifier.access.cs -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.cs -# ^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.class.cs -# ^ meta.class.body.cs meta.block.cs punctuation.section.block.begin.cs - [DllImport("user32.dll")] - public static extern IntPtr GetForegroundWindow(); - } -"@ -#^ meta.string.powershell string.quoted.double.powershell punctuation.definition.string.end.powershell - source.cs diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 2b06b7ca..05690d37 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -50,6 +50,13 @@ '@ #^ meta.string.powershell string.quoted.single.heredoc.powershell punctuation.definition.string.end.powershell + @' + using System; +#^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.heredoc.powershell source.cs +# ^^^^^ keyword.control.import.cs +# ^^^^^^ meta.path.cs +# ^ punctuation.terminator +'@ ###[ Double Quoted Strings ]################################################### @@ -192,6 +199,14 @@ # ^^ constant.character.escape.powershell # ^ punctuation.definition.string.end.powershell + @" + using System; +#^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell source.cs +# ^^^^^ keyword.control.import.cs +# ^^^^^^ meta.path.cs +# ^ punctuation.terminator +"@ + ###[ String Formatting ]####################################################### From fa442864ae3bbb6eb48eaa1b9aa13bebb57cfc9e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sat, 6 Dec 2025 20:51:15 -0500 Subject: [PATCH 055/133] Add labels --- PowerShell.sublime-syntax | 41 ++++++++++++++++++++------------ Tests/syntax_test_PowerShell.ps1 | 4 ++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 42661368..7148de50 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -103,9 +103,12 @@ contexts: scope: keyword.declaration.variable.powershell expressions: + # Meta + - include: labels - include: regions - include: requires-directives + # Normal code - include: commands - include: constants - include: types @@ -854,6 +857,29 @@ contexts: 2: constant.numeric.suffix.powershell push: members +###[ LABELS ]################################################################## + + labels: + - match: ^\s*((:){{identifier_simple}}) + captures: + 1: entity.name.label.powershell + 2: punctuation.definition.label.powershell + + regions: + - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.begin.powershell + 4: meta.toc-list.powershell entity.name.section.powershell + 5: meta.fold.begin.powershell + - match: ^\s*((#)\s*(endregion\b).*(\n?)) + captures: + 1: comment.line.powershell + 2: punctuation.definition.comment.powershell + 3: keyword.other.region.end.powershell + 4: meta.fold.end.powershell + ###[ COMMENTS ]################################################################ comments: @@ -904,21 +930,6 @@ contexts: - include: pop-eol - include: comment-embedded-docs - regions: - - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.begin.powershell - 4: meta.toc-list.powershell entity.name.section.powershell - 5: meta.fold.begin.powershell - - match: ^\s*((#)\s*(endregion\b).*(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.end.powershell - 4: meta.fold.end.powershell - ###[ COMPONENTS ]############################################################## comma-separators: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 94da686d..52001f50 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -80,6 +80,10 @@ using namespace System.Management.Automation # ^ meta.requires meta.hashtable # ^^^^^^^^^ meta.requires meta.hashtable string.quoted.double + :label1 +# ^^^^^^^ entity.name.label.powershell +# ^ punctuation.definition.label.powershell + throw "Do not run this file!" # <- keyword.control # ^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double From de1ea19d806eee2b3978901912036c823665bf41 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 12:41:57 -0500 Subject: [PATCH 056/133] Move some reserved words to a not-in-use section --- PowerShell.sublime-syntax | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 7148de50..e951b07b 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -98,10 +98,6 @@ contexts: - match: \b(?i:where(?!-object)){{kebab_break}} scope: keyword.control.conditional.select.powershell - # Declarations - - match: \b(?i:var){{kebab_break}} - scope: keyword.declaration.variable.powershell - expressions: # Meta - include: labels @@ -128,6 +124,13 @@ contexts: scope: variable.other.object.powershell push: members + # "Reserved for future use" + # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words + - match: \b(?i:define|from){{kebab_break}} + scope: keyword.control.powershell + - match: \b(?i:var){{kebab_break}} + scope: keyword.declaration.variable.powershell + # Uncategorized keywords - match: \b(?i:data|default|define|from|in|inlinescript|parallel|sequence){{kebab_break}} scope: keyword.control.powershell From e31439545c5bb7f52ba94f96dfbc331336af4b89 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 12:43:00 -0500 Subject: [PATCH 057/133] Add data sections --- PowerShell.sublime-syntax | 34 ++++++++++++++++++++++++++++++-- Tests/syntax_test_PowerShell.ps1 | 25 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index e951b07b..154c6ffe 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -105,15 +105,18 @@ contexts: - include: requires-directives # Normal code + - include: escape-sequences + - include: commands - include: constants - include: types - include: hashtables - include: variables - include: strings - - include: script-blocks - - include: escape-sequences - include: numbers + - include: data-blocks + + - include: script-blocks - include: groups - include: arrays - include: subexpressions @@ -668,6 +671,33 @@ contexts: # - match: <+ # scope: invalid.illegal.powershell +###[ DATA BLOCK ]############################################################## + + data-blocks: + - match: \b(?i:data){{kebab_break}} + scope: keyword.control.context.powershell + push: [data-block-body, data-block-name] + + data-block-name: + - match: '{{identifier_simple}}' + scope: entity.name.section.powershell + pop: 1 + - include: else-pop + + data-block-body: + - meta_scope: meta.block.data.powershell + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-data-block + - include: else-pop + + inside-data-block: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 1 + # Data sections use a subset of Pwsh, but we don't distinguish yet. + - include: statements + ###[ CONSTANTS ]############################################################### constants: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 52001f50..85863edf 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1002,6 +1002,31 @@ switch ('this') { } # <- meta.block punctuation.section.braces.end + data { + "Thank you for using my PowerShell Organize.pst script." +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.data.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "It is provided free of charge to the community." + "I appreciate your comments and feedback." + } + + data TextMsgs { +#^^^^^^^^^^^^^^^^^^ meta.block.data.powershell +# ^^^^ keyword.control.context.powershell +# ^^^^^^^^ entity.name.section.powershell +# ^ punctuation.section.block.begin.powershell + ConvertFrom-StringData -StringData @' +# @@@@@@@@@@@@@@@@@@@@@@ reference + Text001 = Windows 7 + Text002 = Windows Server 2008 R2 +'@ + } + +$TextMsgs + + # Functions and filters functioN MyFunction{} #^^^^^^^^^^^^^^^^^^^^ meta.function.powershell From 77e168cc5108dfb17c49f5a02bc057e18018bad2 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 12:44:00 -0500 Subject: [PATCH 058/133] Restrict workflow execution contexts to functions --- PowerShell.sublime-syntax | 10 +++++++++- Tests/syntax_test_PowerShell.ps1 | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 154c6ffe..dc49814d 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -135,7 +135,7 @@ contexts: scope: keyword.declaration.variable.powershell # Uncategorized keywords - - match: \b(?i:data|default|define|from|in|inlinescript|parallel|sequence){{kebab_break}} + - match: \b(?i:default|in){{kebab_break}} scope: keyword.control.powershell # Make everything afterward a literal @@ -399,6 +399,7 @@ contexts: push: expect-function-context - include: attributes + - include: workflow-execution-contexts - include: statements expect-function-context: @@ -411,6 +412,7 @@ contexts: - match: \} scope: punctuation.section.block.end.powershell pop: 1 + - include: workflow-execution-contexts - include: statements expect-param-context: @@ -428,6 +430,12 @@ contexts: - include: types - include: variables-without-members + workflow-execution-contexts: + - match: \b(?i:inlinescript){{kebab_break}} + scope: keyword.control.context.powershell + - match: \b(?i:parallel|sequence){{kebab_break}} + scope: keyword.control.flow.powershell + attributes: - match: (\[)\s*({{attributes}}) captures: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 85863edf..bbc1f236 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1661,7 +1661,7 @@ Workflow work { sequence {} } # ^^^^ entity.name.function.powershell # @@@@ definition # ^ punctuation.section.block.begin.powershell -# ^^^^^^^^ keyword.control.powershell +# ^^^^^^^^ keyword.control.flow.powershell # ^^ meta.block.powershell # ^ punctuation.section.braces.begin.powershell # ^ punctuation.section.braces.end.powershell From 3ec857f577e5fa0e11761193b6cc416d06a8d9bc Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:00:20 -0500 Subject: [PATCH 059/133] Add null-aware operators and accessors --- PowerShell.sublime-syntax | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index dc49814d..d2f2a2cc 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -527,22 +527,29 @@ contexts: members: - match: (?=\.\.) pop: 1 - - match: \.(?=\w) + - match: \?\.(?={{identifier_simple}}) + scope: punctuation.accessor.null-coalescing.powershell + - match: \??\.(?={{identifier_simple}}) scope: punctuation.accessor.dot.powershell - - match: ::(?=\w) + - match: ::(?={{identifier_simple}}) scope: punctuation.accessor.double-colon.powershell - match: (new)(\() captures: 1: meta.function-call.powershell support.function.constructor.powershell 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell push: inside-function-call-arguments - - match: (\w+)(\() + - match: ({{identifier_simple}})(\() captures: 1: meta.function-call.powershell variable.function.powershell 2: meta.function-call.arguments.powershell punctuation.section.arguments.begin.powershell push: inside-function-call-arguments - - match: \w+ + - match: '{{identifier_simple}}' scope: variable.other.member.powershell + - match: (\?)(\[) + captures: + 1: punctuation.accessor.null-coalescing.powershell + 2: punctuation.section.brackets.begin.powershell + push: inside-indexer - match: \[ scope: punctuation.section.brackets.begin.powershell push: inside-indexer @@ -652,11 +659,14 @@ contexts: scope: keyword.operator.logical.powershell - match: \| scope: keyword.operator.logical.pipe.powershell + - match: \?\? + scope: keyword.operator.null-coalescing.powershell - match: ; scope: punctuation.terminator.statement.powershell - match: \`(?=\n|$) scope: punctuation.separator.continuation.line.powershell - include: comma-separators + # TODO: Distinguish call operator from background operator - match: '&' scope: keyword.operator.background.powershell - match: \.\.(?=\-?\d|\(|\$) From 29094fd8a680d918e45b5614d40e924313e91dea Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:02:19 -0500 Subject: [PATCH 060/133] Let script invocation start with a drive letter --- PowerShell.sublime-syntax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index d2f2a2cc..1dd971c6 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -241,7 +241,7 @@ contexts: scope: meta.function-call.powershell support.function.powershell script-invocation: - - match: \b[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b + - match: \b(?i:[a-z]:)?[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b scope: variable.function.powershell parameters: From d0e1c7bdb886cc084b9f5076fe1d4552e19f9a17 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:24:04 -0500 Subject: [PATCH 061/133] Extract flow-like matches to named contexts --- PowerShell.sublime-syntax | 98 ++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 1dd971c6..5ba9db2c 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -54,49 +54,10 @@ contexts: - match: \B\.(?= ) scope: support.function.source.powershell - # Exceptions - - match: \b(?i:throw){{kebab_break}} - scope: keyword.control.exception.raise.powershell - - match: \b(?i:try){{kebab_break}} - scope: keyword.control.exception.try.powershell - - match: \b(?i:catch|trap){{kebab_break}} - scope: keyword.control.exception.catch.powershell - - match: \b(?i:finally){{kebab_break}} - scope: keyword.control.exception.finally.powershell - - # Loops - - match: \b(?i:for|foreach(?!-object)){{kebab_break}} - scope: keyword.control.loop.for.powershell - - match: \b(?i:do){{kebab_break}} - scope: keyword.control.loop.do-while.powershell - - match: \b(?i:while){{kebab_break}} - scope: keyword.control.loop.while.powershell - - match: \b(?i:until){{kebab_break}} - scope: keyword.control.loop.repeat-until.powershell - - # Flow - - match: \b(?i:break){{kebab_break}} - scope: keyword.control.flow.break.powershell - - match: \b(?i:continue){{kebab_break}} - scope: keyword.control.flow.continue.powershell - - match: \b(?i:exit){{kebab_break}} - scope: keyword.control.flow.exit.powershell - - match: \b(?i:return){{kebab_break}} - scope: keyword.control.flow.return.powershell - - # Conditionals - - match: \b(?i:if){{kebab_break}} - scope: keyword.control.conditional.if.powershell - - match: \b(?i:elseif){{kebab_break}} - scope: keyword.control.conditional.elseif.powershell - - match: \b(?i:else){{kebab_break}} - scope: keyword.control.conditional.else.powershell - - match: \b(?i:switch){{kebab_break}} - scope: keyword.control.conditional.switch.powershell - - match: \? - scope: keyword.control.conditional.select.powershell - - match: \b(?i:where(?!-object)){{kebab_break}} - scope: keyword.control.conditional.select.powershell + - include: exceptions + - include: loops + - include: flow + - include: conditionals expressions: # Meta @@ -148,6 +109,57 @@ contexts: - include: operators - include: parameters +###[ EXCEPTIONS ]############################################################## + + exceptions: + - match: \b(?i:throw){{kebab_break}} + scope: keyword.control.exception.raise.powershell + - match: \b(?i:try){{kebab_break}} + scope: keyword.control.exception.try.powershell + - match: \b(?i:catch|trap){{kebab_break}} + scope: keyword.control.exception.catch.powershell + - match: \b(?i:finally){{kebab_break}} + scope: keyword.control.exception.finally.powershell + +###[ LOOPS ]################################################################### + + loops: + - match: \b(?i:for|foreach(?!-object)){{kebab_break}} + scope: keyword.control.loop.for.powershell + - match: \b(?i:do){{kebab_break}} + scope: keyword.control.loop.do-while.powershell + - match: \b(?i:while){{kebab_break}} + scope: keyword.control.loop.while.powershell + - match: \b(?i:until){{kebab_break}} + scope: keyword.control.loop.repeat-until.powershell + +###[ FLOW ]#################################################################### + + flow: + - match: \b(?i:break){{kebab_break}} + scope: keyword.control.flow.break.powershell + - match: \b(?i:continue){{kebab_break}} + scope: keyword.control.flow.continue.powershell + - match: \b(?i:exit){{kebab_break}} + scope: keyword.control.flow.exit.powershell + - match: \b(?i:return){{kebab_break}} + scope: keyword.control.flow.return.powershell + +###[ CONDITIONALS ]############################################################ + + conditionals: + - match: \b(?i:if){{kebab_break}} + scope: keyword.control.conditional.if.powershell + - match: \b(?i:elseif){{kebab_break}} + scope: keyword.control.conditional.elseif.powershell + - match: \b(?i:else){{kebab_break}} + scope: keyword.control.conditional.else.powershell + - match: \b(?i:switch){{kebab_break}} + scope: keyword.control.conditional.switch.powershell + - match: \? + scope: keyword.control.conditional.select.powershell + - match: \b(?i:where(?!-object)){{kebab_break}} + scope: keyword.control.conditional.select.powershell ###[ GROUPS ]################################################################## From 965b8d3c1559c29421449084ad35cd934ac8bc2f Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:24:52 -0500 Subject: [PATCH 062/133] Sort the last two reserved words --- PowerShell.sublime-syntax | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 5ba9db2c..304b6464 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -95,9 +95,6 @@ contexts: - match: \b(?i:var){{kebab_break}} scope: keyword.declaration.variable.powershell - # Uncategorized keywords - - match: \b(?i:default|in){{kebab_break}} - scope: keyword.control.powershell # Make everything afterward a literal - match: \B--%\B @@ -156,6 +153,8 @@ contexts: scope: keyword.control.conditional.else.powershell - match: \b(?i:switch){{kebab_break}} scope: keyword.control.conditional.switch.powershell + - match: \b(?i:default){{kebab_break}} + scope: keyword.control.conditional.default.powershell - match: \? scope: keyword.control.conditional.select.powershell - match: \b(?i:where(?!-object)){{kebab_break}} @@ -171,6 +170,9 @@ contexts: - match: \) scope: punctuation.section.group.end.powershell set: members + # TODO: Move this to a foreach (X in Y) construct + - match: \b(?i:in){{kebab_break}} + scope: keyword.control.loop.in.powershell - include: attributes - include: expressions From 6c145b069483c6f3f0630c293bfdb85250e1b5fe Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:25:21 -0500 Subject: [PATCH 063/133] Extract --% to a named context --- PowerShell.sublime-syntax | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 304b6464..da5ea9ba 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -67,6 +67,7 @@ contexts: # Normal code - include: escape-sequences + - include: literal-after - include: commands - include: constants @@ -82,8 +83,8 @@ contexts: - include: arrays - include: subexpressions - # Consume a string with a trailing dot - # to prevent members with particular names from being recognized as keywords. + # Consume a string with a trailing dot to prevent members with + # particular names from being recognized as keywords. - match: \b[\w-]+(?=\.) scope: variable.other.object.powershell push: members @@ -95,8 +96,10 @@ contexts: - match: \b(?i:var){{kebab_break}} scope: keyword.declaration.variable.powershell + - include: operators + - include: parameters - # Make everything afterward a literal + literal-after: - match: \B--%\B scope: keyword.control.powershell push: @@ -104,8 +107,6 @@ contexts: - meta_content_scope: string.unquoted.powershell - include: pop-before-eol - - include: operators - - include: parameters ###[ EXCEPTIONS ]############################################################## exceptions: From 35df225fbd22e6b791b5b8eca513c1ab56e9f7d0 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:33:49 -0500 Subject: [PATCH 064/133] Consolidate variable lookahead And make sure it doesn't make hashtables --- PowerShell.sublime-syntax | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index da5ea9ba..cd687158 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -480,11 +480,11 @@ contexts: ###[ VARIABLES ]############################################################### variables: - - match: (?=[$@](?:[{$^]|{{identifier_simple}})) + - match: '{{var_lookahead}}' push: [members, expect-variable] variables-without-members: - - match: (?=[$@](?:[{$^]|{{identifier_simple}})) + - match: '{{var_lookahead}}' push: [expect-variable] expect-variable: @@ -501,7 +501,7 @@ contexts: 1: punctuation.definition.variable.powershell 2: punctuation.section.interpolation.begin.powershell push: inside-variable-special-char - - match: (\$|@)(?!\{) + - match: (\$|@) captures: 1: punctuation.definition.variable.powershell 2: punctuation.section.interpolation.begin.powershell @@ -1064,6 +1064,11 @@ variables: identifier_simple: '[\p{L}\p{Nd}_?]+' identifier_special: '[^}]*[^}`]' identifier_function: '[\p{L}\p{Nd}_.-]+' + var_lookahead: |- + (?x: (?= + \$[$^{] + | [$@]{{identifier_simple}} + )) # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables var_constants: |- \b(?xi: From d641093a6f41b3f96342469f5c27c906b8b2a556 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:43:45 -0500 Subject: [PATCH 065/133] Tweak expression execution order --- PowerShell.sublime-syntax | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index cd687158..98cb5a3b 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -65,22 +65,24 @@ contexts: - include: regions - include: requires-directives - # Normal code - include: escape-sequences - include: literal-after - - include: commands - - include: constants + # Normal code - include: types - - include: hashtables - - include: variables - include: strings - include: numbers - - include: data-blocks + - include: constants + - include: variables + + - include: hashtables + - include: arrays + - include: commands + + - include: data-blocks - include: script-blocks - include: groups - - include: arrays - include: subexpressions # Consume a string with a trailing dot to prevent members with From fc87adc96cb042ee5db5db6a324b506a81f857ec Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:47:43 -0500 Subject: [PATCH 066/133] Move the ternary operator to its rightful place --- PowerShell.sublime-syntax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 98cb5a3b..c45d81f1 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -158,8 +158,6 @@ contexts: scope: keyword.control.conditional.switch.powershell - match: \b(?i:default){{kebab_break}} scope: keyword.control.conditional.default.powershell - - match: \? - scope: keyword.control.conditional.select.powershell - match: \b(?i:where(?!-object)){{kebab_break}} scope: keyword.control.conditional.select.powershell @@ -678,6 +676,8 @@ contexts: scope: keyword.operator.logical.pipe.powershell - match: \?\? scope: keyword.operator.null-coalescing.powershell + - match: '[?:]' + scope: keyword.operator.ternary.powershell - match: ; scope: punctuation.terminator.statement.powershell - match: \`(?=\n|$) From 403bf11fcb587ad15767ee64dfb87de765e48a34 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 13:59:25 -0500 Subject: [PATCH 067/133] Fix data section not popping --- PowerShell.sublime-syntax | 2 +- Tests/syntax_test_PowerShell.ps1 | 16 +--------------- Tests/syntax_test_partial-symbols.ps1 | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 Tests/syntax_test_partial-symbols.ps1 diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c45d81f1..b5d65200 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -729,7 +729,7 @@ contexts: inside-data-block: - match: \} scope: punctuation.section.block.end.powershell - pop: 1 + pop: 2 # Data sections use a subset of Pwsh, but we don't distinguish yet. - include: statements diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index bbc1f236..52e1077a 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1011,21 +1011,7 @@ switch ('this') { "It is provided free of charge to the community." "I appreciate your comments and feedback." } - - data TextMsgs { -#^^^^^^^^^^^^^^^^^^ meta.block.data.powershell -# ^^^^ keyword.control.context.powershell -# ^^^^^^^^ entity.name.section.powershell -# ^ punctuation.section.block.begin.powershell - ConvertFrom-StringData -StringData @' -# @@@@@@@@@@@@@@@@@@@@@@ reference - Text001 = Windows 7 - Text002 = Windows Server 2008 R2 -'@ - } - -$TextMsgs - +# ^ - meta # Functions and filters functioN MyFunction{} diff --git a/Tests/syntax_test_partial-symbols.ps1 b/Tests/syntax_test_partial-symbols.ps1 new file mode 100644 index 00000000..0371a95b --- /dev/null +++ b/Tests/syntax_test_partial-symbols.ps1 @@ -0,0 +1,16 @@ +# SYNTAX TEST partial-symbols "Packages/PowerShell/PowerShell.sublime-syntax" + + + data TextMsgs { +# ^^^^^^^^^^^^^^^ meta.block.data.powershell +# ^^^^ keyword.control.context.powershell +# ^^^^^^^^ entity.name.section.powershell +# ^ punctuation.section.block.begin.powershell + ConvertFrom-StringData -StringData @' +# @@@@@@@@@@@@@@@@@@@@@@ reference + Text001 = Windows 7 + Text002 = Windows Server 2008 R2 +'@ + } + + $TextMsgs From 9df6d26d18b1e6307d290be0c3445be80fcb3db0 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 14:03:48 -0500 Subject: [PATCH 068/133] Fix functions not popping fast enough --- PowerShell.sublime-syntax | 2 +- Tests/syntax_test_Class.ps1 | 4 +--- Tests/syntax_test_PowerShell.ps1 | 5 +++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index b5d65200..8fef8023 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -403,7 +403,7 @@ contexts: inside-function-body: - match: \} scope: punctuation.section.block.end.powershell - pop: 1 + pop: 2 - match: \b(?i:(?:Dynamic)?Param){{kebab_break}} scope: keyword.declaration.parameter.powershell # This scope is not standard diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index 33e28ea8..c1703196 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -103,13 +103,12 @@ class TypeName # ^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell } - +# ^ - meta.function # Static method # <- punctuation.definition.comment # ^^^^^^^^^^^^^ comment.line static [void] MemberMethod1([hashtable] $h) { #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -#^^^ meta.function.powershell # ^^^^^^ storage.modifier.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^ storage.type.powershell @@ -142,7 +141,6 @@ class TypeName # ^^^^^^^^^^^^^^^ comment.line [int] MemberMethod2([int] $i) { #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -#^^^ meta.function.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 52e1077a..3b9641bf 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1021,6 +1021,7 @@ functioN MyFunction{} # @@@@@@@@@@ definition # ^ punctuation.section.block.begin.powershell # ^ punctuation.section.block.end.powershell +# ^ - meta function My-Function {} #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell #^^^^^^^ keyword.declaration.function.powershell @@ -1276,7 +1277,8 @@ class Vehicle { # ^ punctuation.section.block.begin.powershell # ^ punctuation.section.block.end.powershell Vehicle([string]$Owner) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell # ^^^^^^^ entity.name.function.powershell # @@@@@@@ definition # ^ punctuation.section.parameters.begin.powershell @@ -1335,7 +1337,6 @@ class Vehicle { static [System.Array] GetAvailableColors() { #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -#^^^ meta.function.powershell # ^^^^^^ storage.modifier.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^^ meta.generic-name.powershell From e183fc7bc082cf8414bffd226e930ae0367e8069 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 18:51:48 -0500 Subject: [PATCH 069/133] Add naive string placeholder scopes --- PowerShell.sublime-syntax | 20 ++++++ Tests/syntax_test_strings.ps1 | 116 ++++++++++++++++++++++++++++++++-- 2 files changed, 132 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 8fef8023..44c8ea70 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -774,6 +774,7 @@ contexts: - match: \' scope: punctuation.definition.string.end.powershell pop: 1 + - include: string-placeholders double-quoted-strings: - match: '"' @@ -792,6 +793,7 @@ contexts: # # Silently eat email addresses # - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' - include: string-interpolations + - include: string-placeholders - match: '`\s*$' scope: keyword.other.powershell @@ -821,6 +823,7 @@ contexts: pop: 1 - match: "''" scope: constant.character.escape.powershell + - include: string-placeholders double-quoted-heredoc-strings: - match: \@"(?=$) @@ -836,6 +839,7 @@ contexts: scope: punctuation.definition.string.end.powershell pop: 1 - include: escape-sequences + - include: string-placeholders - include: string-interpolations inside-double-quoted-heredoc-string.syntax: @@ -868,6 +872,22 @@ contexts: - include: variables-without-members - include: immediately-pop + string-placeholders: + - match: \{ + scope: punctuation.definition.placeholder.begin.powershell + push: inside-string-placeholder + + inside-string-placeholder: + - meta_include_prototype: false + - meta_scope: constant.other.placeholder.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 1 + - match: (?=['"]) + pop: 1 + - match: '[:,;]' + scope: punctuation.separator.powershell + numbers: # Binary numbers - match: \b(0[bB])([01]*)({{int_suffix}}?{{unit_suffix}}?) diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 05690d37..c5a5ff4e 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -213,6 +213,10 @@ "{0:N2}" -f $a # ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -222,6 +226,10 @@ "{0:D8}" -f $a # ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -231,6 +239,10 @@ "{0:C2}" -f $a # ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -240,6 +252,10 @@ "{0:P0}" -f $a # ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -249,6 +265,10 @@ "{0:X0}" -f $a # ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -274,6 +294,19 @@ "{1,10} {0,10} {2,10:x}" -f "First", "Second", 255 # ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -292,6 +325,10 @@ # ^ punctuation.section.group.begin.powershell # ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -303,6 +340,11 @@ # ^ punctuation.section.group.begin.powershell # ^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -313,6 +355,10 @@ "{0:R}" -f (1mb/2.0) # ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -329,6 +375,10 @@ "{0:00.0}" -f 4.12341234 # ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -338,6 +388,10 @@ "{0:##.#}" -f 4.12341234 # ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -347,6 +401,11 @@ "{0:#,#.#}" -f 1234.121234 # ^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -356,6 +415,11 @@ "{0:##,,.000}" -f 1048576 # ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -364,20 +428,31 @@ "{this is not a #comment}" # ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell "{0:##.#E000}" -f 2.71828 # ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell # ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell + # TODO: Let placeholders contain quotes "{0:#.00'##'}" -f 2.71828 # ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -387,6 +462,12 @@ "{0:POS;NEG;ZERO}" -f -14 # ^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -394,11 +475,12 @@ # ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell "{0:$## Please}" -f 14 -# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell -# ^^^^ string.quoted.double.powershell +# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment # ^ punctuation.definition.string.begin.powershell -# ^ meta.interpolation.powershell -# ^^^^^^^^^^^ string.quoted.double.powershell +# ^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -407,6 +489,11 @@ "{0,-8:P1}" -f 1.75 # ^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -416,6 +503,23 @@ "{0,10:N3}{1,10:N3}{2,10:N3}{3,10:N3}" -f 0.2, 0.3, 0.45, 0.91 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell @@ -435,6 +539,10 @@ '{0:00000.000}' -f 7.125 # ^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell # ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell From 44d3cdf869f012d52106af7fae3ad01eae826b03 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 19:32:47 -0500 Subject: [PATCH 070/133] Drop some unlikely string rules --- PowerShell.sublime-syntax | 4 ---- 1 file changed, 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 44c8ea70..0142b8aa 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -790,12 +790,8 @@ contexts: - match: '"' scope: punctuation.definition.string.end.powershell pop: 1 - # # Silently eat email addresses - # - match: '(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,64}\b' - include: string-interpolations - include: string-placeholders - - match: '`\s*$' - scope: keyword.other.powershell single-quoted-heredoc-strings: - match: \@'(?=$) From b33a839ee5f521ef9a83f5811c27a10765486f8d Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 7 Dec 2025 19:53:11 -0500 Subject: [PATCH 071/133] Make straight and curly quotes equivalent I think this language was written by trolls. --- PowerShell.sublime-syntax | 34 ++++++++++++++++++---------------- Tests/syntax_test_strings.ps1 | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 0142b8aa..499848b7 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -762,39 +762,39 @@ contexts: - include: single-quoted-heredoc-strings single-quoted-strings: - - match: \' + - match: '{{single_quote}}' scope: punctuation.definition.string.begin.powershell push: inside-single-quoted-string inside-single-quoted-string: - meta_include_prototype: false - meta_scope: meta.string.powershell string.quoted.single.powershell - - match: "''" + - match: '{{single_quote}}{2}' scope: constant.character.escape.powershell - - match: \' + - match: '{{single_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 - include: string-placeholders double-quoted-strings: - - match: '"' + - match: '{{double_quote}}' scope: punctuation.definition.string.begin.powershell push: inside-double-quoted-string inside-double-quoted-string: - meta_include_prototype: false - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell - - match: '""' + - match: '{{double_quote}}{2}' scope: constant.character.escape.powershell - include: escape-sequences - - match: '"' + - match: '{{double_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 - include: string-interpolations - include: string-placeholders single-quoted-heredoc-strings: - - match: \@'(?=$) + - match: \@{{single_quote}}(?=$) scope: punctuation.definition.string.begin.powershell push: - inside-single-quoted-heredoc-string @@ -805,24 +805,24 @@ contexts: - match: (?={{csharp_indicator}}) set: scope:source.cs with_prototype: - - match: (?=^'@) + - match: (?=^{{single_quote}}@) pop: 1 - - match: "''" + - match: '{{single_quote}}{2}' scope: constant.character.escape.powershell - include: else-pop inside-single-quoted-heredoc-string: - meta_include_prototype: false - meta_scope: meta.string.powershell string.quoted.single.heredoc.powershell - - match: ^'@ + - match: ^{{single_quote}}@ scope: punctuation.definition.string.end.powershell pop: 1 - - match: "''" + - match: '{{single_quote}}{2}' scope: constant.character.escape.powershell - include: string-placeholders double-quoted-heredoc-strings: - - match: \@"(?=$) + - match: \@{{double_quote}}(?=$) scope: punctuation.definition.string.begin.powershell push: - inside-double-quoted-heredoc-string @@ -831,7 +831,7 @@ contexts: inside-double-quoted-heredoc-string: - meta_include_prototype: false - meta_scope: meta.string.interpolated.powershell string.quoted.double.heredoc.powershell - - match: ^"@ + - match: ^{{double_quote}}@ scope: punctuation.definition.string.end.powershell pop: 1 - include: escape-sequences @@ -843,7 +843,7 @@ contexts: - match: (?={{csharp_indicator}}) set: scope:source.cs with_prototype: - - match: (?=^"@) + - match: (?=^{{double_quote}}@) pop: 1 - include: escape-sequences - include: else-pop @@ -879,7 +879,7 @@ contexts: - match: \} scope: punctuation.definition.placeholder.end.powershell pop: 1 - - match: (?=['"]) + - match: (?={{single_quote}}|{{double_quote}}) pop: 1 - match: '[:,;]' scope: punctuation.separator.powershell @@ -1021,7 +1021,7 @@ contexts: scope: punctuation.separator.sequence.powershell escape-sequences: - - match: '`[0abenfrvt"''$`]' + - match: '`(?:[0abenfrvt$`]|{{single_quote}}|{{double_quote}})' scope: constant.character.escape.powershell - match: '`u\{\h+\}' scope: constant.character.escape.powershell @@ -1162,6 +1162,8 @@ variables: ) # Strings + single_quote: "['‘’‚]" + double_quote: '["“”„]' csharp_indicator: |- (?x: \s* (?: using\s+System[.;] diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index c5a5ff4e..9ba374eb 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -41,6 +41,13 @@ # ^ punctuation.definition.string.begin.powershell # ^ punctuation.definition.string.end.powershell + ‘curly ‘‘quotes'’ are equivalent to straight ones' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.string.end.powershell + @' # ^^ meta.string.powershell string.quoted.single.heredoc.powershell punctuation.definition.string.begin.powershell - meta.string.interpolated A 'single quoted' "heredoc" @@ -167,6 +174,13 @@ # ^ punctuation.section.interpolation.end # @@@@@@@@@@@@@@@@ reference + “curly ““quotes"” are equivalent to straight ones" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.string.end.powershell + # Double quoted here-string @" # ^^ meta.string.interpolated.powershell string.quoted.double.heredoc.powershell punctuation.definition.string.begin.powershell From 31c2aa602e9d29547caf18e88ca35a06bb3b02d0 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 10:18:05 -0500 Subject: [PATCH 072/133] Extract C# identifiers to a variable --- PowerShell.sublime-syntax | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 499848b7..df9e2e78 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -300,20 +300,20 @@ contexts: inside-using-namespace: - include: pop-eol - - match: \p{L}[\p{L}\p{N}]+(\.) + - match: '{{identifier_csharp}}(\.)' scope: meta.path.powershell captures: 1: punctuation.accessor.dot.powershell - - match: \p{L}[\p{L}\p{N}]+ + - match: '{{identifier_csharp}}' scope: meta.path.powershell inside-using-module: - include: pop-eol - - match: \p{L}[\p{L}\p{N}]+(\.) + - match: '{{identifier_csharp}}(\.)' scope: meta.path.powershell captures: 1: punctuation.accessor.dot.powershell - - match: \p{L}[\p{L}\p{N}]+ + - match: '{{identifier_csharp}}' scope: meta.path.powershell support.type.powershell ###[ CLASSES ]################################################################# @@ -1082,6 +1082,7 @@ variables: identifier_simple: '[\p{L}\p{Nd}_?]+' identifier_special: '[^}]*[^}`]' identifier_function: '[\p{L}\p{Nd}_.-]+' + identifier_csharp: '[\p{L}_][\p{L}\p{Nd}_]*' var_lookahead: |- (?x: (?= \$[$^{] From 5a8733f6e117dc935b6c473e3e2c37d70fb6901b Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 10:46:59 -0500 Subject: [PATCH 073/133] Add dedicated contexts for DSC Desired State Configuration --- PowerShell.sublime-syntax | 65 ++++++++++++++++- Tests/syntax_test_DSC.ps1 | 116 +++++++++++++++++++++++++++++++ Tests/syntax_test_PowerShell.ps1 | 16 ----- 3 files changed, 178 insertions(+), 19 deletions(-) create mode 100644 Tests/syntax_test_DSC.ps1 diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index df9e2e78..66fb4ec0 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -50,6 +50,7 @@ contexts: - include: classes - include: expressions - include: functions + - include: desired-state-configurations - match: \B\.(?= ) scope: support.function.source.powershell @@ -363,13 +364,13 @@ contexts: ###[ FUNCTIONS ]############################################################### functions: - - match: ^\s*(?i)(function|filter|configuration|workflow)(?=\s) + - match: ^\s*(?i)(function|filter|workflow)(?=\s) captures: 1: keyword.declaration.function.powershell push: [function-body, function-inline-params, function-name] function-name: - - match: (?:(global|local|script|private):)?({{identifier_function}}+) + - match: (?:(global|local|script|private):)?({{identifier_function}}) captures: 1: storage.modifier.scope.powershell 2: entity.name.function.powershell @@ -442,8 +443,11 @@ contexts: pop: 1 - include: comma-separators - include: attributes - - include: types + - include: types-without-members - include: variables-without-members + - include: literals + - match: '=' + scope: keyword.operator.assignment.powershell workflow-execution-contexts: - match: \b(?i:inlinescript){{kebab_break}} @@ -477,6 +481,61 @@ contexts: 2: keyword.operator.assignment.powershell - include: expressions +###[ DESIRED STATE CONFIGURATIONS ]############################################ + + desired-state-configurations: + - match: ^\s*(?i)(configuration)(?=\s) + captures: + 1: keyword.declaration.function.powershell + push: + - desired-state-configuration-body + - desired-state-configuration-name + + desired-state-configuration-name: + - match: '{{identifier_function}}' + scope: entity.name.function.powershell + - match: (?=[{(]) + pop: 1 + + desired-state-configuration-body: + - meta_scope: meta.function.powershell + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-desired-state-configuration-body + - include: else-pop + + inside-desired-state-configuration-body: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 2 + + - match: \b(?i:Param){{kebab_break}} + scope: keyword.declaration.parameter.powershell # This scope is not standard + push: expect-param-context + + - match: \b(?i:Node){{kebab_break}} + scope: keyword.context.block.powershell + push: expect-node-context + + - include: attributes + + expect-node-context: + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-node-context + - include: expressions + - include: else-pop + + inside-node-context: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 2 + - match: \b((?i:WindowsFeature))\s+({{identifier_csharp}}) + captures: + 1: keyword.other.powershell + 2: entity.name.label.powershell + - include: expressions + ###[ VARIABLES ]############################################################### variables: diff --git a/Tests/syntax_test_DSC.ps1 b/Tests/syntax_test_DSC.ps1 new file mode 100644 index 00000000..ff66f2e4 --- /dev/null +++ b/Tests/syntax_test_DSC.ps1 @@ -0,0 +1,116 @@ +# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" + +"<- Exit the imports context block" + + Configuration MyDscConfiguration { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.block.begin.powershell + Node "TEST-PC1" { +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^ keyword.context.block.powershell +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.block.begin.powershell + WindowsFeature MyFeatureInstance { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^ keyword.other.powershell +# ^^^^^^^^^^^^^^^^^ entity.name.label.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell + Ensure = 'Present' +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + Name = 'RSAT' + } + WindowsFeature My2ndFeatureInstance { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^ keyword.other.powershell +# ^^^^^^^^^^^^^^^^^^^^ entity.name.label.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell + Ensure = 'Present' + Name = 'Bitlocker' + } +#^^^^^^^^^^^^ meta.function.powershell meta.block.powershell +# ^ punctuation.section.braces.end.powershell + } + } + MyDscConfiguration + + + Configuration MyDscConfiguration + { + param +#^^^^^^^^^^^^ meta.function.powershell +# ^^^^^ keyword.declaration.parameter.powershell + ( + [string[]]$ComputerName='localhost' +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + ) + + Node $ComputerName + { + WindowsFeature MyFeatureInstance + { + Ensure = 'Present' + Name = 'RSAT' + } + + WindowsFeature My2ndFeatureInstance + { + Ensure = 'Present' + Name = 'Bitlocker' + } + } + } + MyDscConfiguration + + + Configuration MyDscConfiguration + { + Node @('localhost', 'Server01') +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^ keyword.context.block.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.array-expression.powershell +# ^ keyword.other.array.begin.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell + { + WindowsFeature MyFeatureInstance +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^ keyword.other.powershell +# ^^^^^^^^^^^^^^^^^ entity.name.label.powershell + { + Ensure = 'Present' + Name = 'RSAT' + } + + WindowsFeature My2ndFeatureInstance + { + Ensure = 'Present' + Name = 'Bitlocker' + } + } + } + MyDscConfiguration diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 3b9641bf..d6a87302 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1382,22 +1382,6 @@ catch { } # ^ punctuation.section.braces.begin # ^ punctuation.section.braces.end -# Reserved words -Configuration Crazyness { -#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell - Node Whatever { -# ^ punctuation.section.braces.begin - } -#^^^^ meta.function.powershell meta.block.powershell -# ^ punctuation.section.braces.end.powershell - } -#^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell - # Redirection notepad.exe > log.txt #^^^^^^^^^^ variable.function From b84c8569fb8cf731880ffe86b853e18f2b8c5cbc Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 11:09:44 -0500 Subject: [PATCH 074/133] Add dedicated contexts for workflows --- PowerShell.sublime-syntax | 43 +++++++-- Tests/syntax_test_PowerShell.ps1 | 18 ---- Tests/syntax_test_Workflow.ps1 | 155 +++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 26 deletions(-) create mode 100644 Tests/syntax_test_Workflow.ps1 diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 66fb4ec0..6015591a 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -50,6 +50,7 @@ contexts: - include: classes - include: expressions - include: functions + - include: workflows - include: desired-state-configurations - match: \B\.(?= ) @@ -364,7 +365,7 @@ contexts: ###[ FUNCTIONS ]############################################################### functions: - - match: ^\s*(?i)(function|filter|workflow)(?=\s) + - match: ^\s*(?i)(function|filter)(?=\s) captures: 1: keyword.declaration.function.powershell push: [function-body, function-inline-params, function-name] @@ -419,6 +420,7 @@ contexts: - include: statements expect-function-context: + - meta_scope: meta.block.powershell - match: \{ scope: punctuation.section.block.begin.powershell push: inside-function-context @@ -427,7 +429,7 @@ contexts: inside-function-context: - match: \} scope: punctuation.section.block.end.powershell - pop: 1 + pop: 2 - include: workflow-execution-contexts - include: statements @@ -449,12 +451,6 @@ contexts: - match: '=' scope: keyword.operator.assignment.powershell - workflow-execution-contexts: - - match: \b(?i:inlinescript){{kebab_break}} - scope: keyword.control.context.powershell - - match: \b(?i:parallel|sequence){{kebab_break}} - scope: keyword.control.flow.powershell - attributes: - match: (\[)\s*({{attributes}}) captures: @@ -481,6 +477,37 @@ contexts: 2: keyword.operator.assignment.powershell - include: expressions +###[ WORKFLOWS ]############################################################### + + workflows: + - match: ^\s*(?i)(workflow)(?=\s) + captures: + 1: keyword.declaration.function.powershell + push: [function-body, function-name] + + workflow-body: + - meta_scope: meta.function.powershell + - match: \{ + scope: punctuation.section.block.begin.powershell + push: inside-workflow-body + with_prototype: + - include: workflow-execution-contexts + - include: else-pop + + inside-workflow-body: + - match: \} + scope: punctuation.section.block.end.powershell + pop: 2 + - include: statements + + workflow-execution-contexts: + - match: \b(?i:inlinescript){{kebab_break}} + scope: keyword.control.context.powershell + push: expect-function-context + - match: \b(?i:parallel|sequence){{kebab_break}} + scope: keyword.control.flow.powershell + push: expect-function-context + ###[ DESIRED STATE CONFIGURATIONS ]############################################ desired-state-configurations: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index d6a87302..e3c11520 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1619,24 +1619,6 @@ $ScriptBlock | Out-File $file -Force # ^ punctuation.definition.variable # ^ punctuation.definition.parameter # ^^^^^^ variable.parameter.option -workflow w1 {} -#^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^ entity.name.function.powershell -# @@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -Workflow work { sequence {} } -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^ entity.name.function.powershell -# @@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^^^^^^^^ keyword.control.flow.powershell -# ^^ meta.block.powershell -# ^ punctuation.section.braces.begin.powershell -# ^ punctuation.section.braces.end.powershell -# ^ punctuation.section.block.end.powershell function get-something {} # @@@@@@@@@@@@@ definition function Out-WithYou {} diff --git a/Tests/syntax_test_Workflow.ps1 b/Tests/syntax_test_Workflow.ps1 new file mode 100644 index 00000000..dbe3d2ce --- /dev/null +++ b/Tests/syntax_test_Workflow.ps1 @@ -0,0 +1,155 @@ +# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" + +"<- Exit the imports context block" + + workflow w1 {} +#^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^ entity.name.function.powershell +# @@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + Workflow work { sequence {} } +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^ entity.name.function.powershell +# @@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^^^^^^^^^^^ meta.block.powershell +# ^^^^^^^^ keyword.control.flow.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell +# ^ punctuation.section.block.end.powershell + + workflow Test-Workflow { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell + parallel { +#^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.control.flow.powershell +# ^ punctuation.section.block.begin.powershell + Get-Process +# @@@@@@@@@@@ reference + Get-Service +#^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@ reference + } + } + + + workflow Test-Workflow { +# @@@@@@@@@@@@@ definition + $a = 3 +#^^^^^^^^^^^^^ meta.function.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + + ## Without $Using, the $a workflow variable isn't visible + ## in inline script. + inlinescript {"Inline A0 = $a"} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^ keyword.control.context.powershell +# ^ punctuation.section.block.begin.powershell +# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^ meta.interpolation.powershell variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.end.powershell +# ^ punctuation.section.block.end.powershell + + ## $Using imports the variable and its current value. + inlinescript {"Inline A1 = $Using:a"} + } + Test-Workflow +# @@@@@@@@@@@@@ reference + + + workflow Test-Workflow { +# @@@@@@@@@@@@@ definition + $a = 3 + + ## Changes to the inlinescript variable value don't + ## change the workflow variable. + inlinescript { + $a = $Using:a+1; + "Inline A = $a" + } + "Workflow A = $a" + + ## To change the variable in workflow scope, return the + ## new value. + $a = inlinescript {$b = $Using:a+1; $b} + "Workflow New A = $a" + } + Test-Workflow +# @@@@@@@@@@@@@ reference + + + workflow Test-Workflow { +# @@@@@@@@@@@@@ definition + $ie = inlinescript { + $ie = New-Object -ComObject InternetExplorer.Application -Property @{navigate2="www.microsoft.com"} +# @@@@@@@@@@ reference + + $ie.Visible = $true +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^ variable.other.member.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + } + + $ie + } + Test-Workflow +# @@@@@@@@@@@@@ reference + + + workflow Test-Workflow { +# @@@@@@@@@@@@@ definition + parallel { + Get-Process +# @@@@@@@@@@@ reference + Get-Service +#^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@ reference + + sequence { +# ^ meta.function.powershell meta.block.powershell meta.block.powershell punctuation.section.block.begin.powershell + $Hotfix = Get-Content 'D:\HotFixes\Required.txt' +# @@@@@@@@@@@ reference + foreach ($h in $Hotfix) {'D:\Scripts\Verify-Hotfix' -Hotfix $h} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.powershell meta.block.powershell +# ^^^^^^^ keyword.control.loop.for.powershell +# ^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^ keyword.control.loop.in.powershell +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.group.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.end.powershell + } + } + } From 39f0d8f507b8c64c4937ca9be7de0e532d73b1bc Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 12:02:03 -0500 Subject: [PATCH 075/133] Use named contexts for group-likes --- PowerShell.sublime-syntax | 92 ++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 6015591a..60577a0a 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -168,71 +168,81 @@ contexts: groups: - match: \( scope: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.powershell - - match: \) - scope: punctuation.section.group.end.powershell - set: members - # TODO: Move this to a foreach (X in Y) construct - - match: \b(?i:in){{kebab_break}} - scope: keyword.control.loop.in.powershell - - include: attributes - - include: expressions + push: inside-group + + inside-group: + - meta_scope: meta.group.powershell + - match: \) + scope: punctuation.section.group.end.powershell + set: members + # TODO: Move this to a foreach (X in Y) construct + - match: \b(?i:in){{kebab_break}} + scope: keyword.control.loop.in.powershell + - include: attributes + - include: expressions arrays: - match: (@)(\() captures: 1: keyword.other.array.begin.powershell 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.array-expression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: 1 - - include: expressions + push: inside-array + + inside-array: + - meta_scope: meta.group.array-expression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: 1 + - include: expressions hashtables: - match: (@)(\{) captures: 1: keyword.other.hashtable.begin.powershell 2: punctuation.section.braces.begin.powershell - push: - - meta_scope: meta.hashtable.powershell - - match: \} - scope: punctuation.section.braces.end.powershell - pop: 1 - - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* - scope: meta.hashtable.assignment.powershell - captures: - 1: punctuation.definition.string.begin.powershell - 2: variable.other.readwrite.powershell - 3: punctuation.definition.string.end.powershell - 4: keyword.operator.assignment.powershell - - include: expressions + push: inside-hashtable + + inside-hashtable: + - meta_scope: meta.hashtable.powershell + - match: \} + scope: punctuation.section.braces.end.powershell + pop: 1 + - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* + scope: meta.hashtable.assignment.powershell + captures: + 1: punctuation.definition.string.begin.powershell + 2: variable.other.readwrite.powershell + 3: punctuation.definition.string.end.powershell + 4: keyword.operator.assignment.powershell + - include: expressions subexpressions: - match: (\$)(\() captures: 1: keyword.other.variable.definition.powershell 2: punctuation.section.group.begin.powershell - push: - - meta_scope: meta.group.complex.subexpression.powershell - - match: \) - scope: punctuation.section.group.end.powershell - pop: 1 - - include: expressions + push: inside-subexpression + + inside-subexpression: + - meta_scope: meta.group.complex.subexpression.powershell + - match: \) + scope: punctuation.section.group.end.powershell + pop: 1 + - include: expressions script-blocks: - match: (%)?(\{) captures: 1: keyword.control.loop.for.powershell 2: punctuation.section.braces.begin.powershell - push: - - meta_scope: meta.block.powershell - - match: \} - scope: punctuation.section.braces.end.powershell - pop: 1 - - include: statements + push: inside-script-block + + inside-script-block: + - meta_scope: meta.block.powershell + - match: \} + scope: punctuation.section.braces.end.powershell + pop: 1 + - include: statements ###[ COMMANDS ]################################################################ From 1cb5f7cb9a89bdb457c7e27c20fbfd2148c33424 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 12:10:44 -0500 Subject: [PATCH 076/133] Update hashtable scopes --- PowerShell.sublime-syntax | 19 ++++++--- Tests/syntax_test_PowerShell.ps1 | 68 +++++++++++++++++++------------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 60577a0a..a6c049df 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -207,13 +207,22 @@ contexts: - match: \} scope: punctuation.section.braces.end.powershell pop: 1 - - match: \b(['"]?)(\w+)(['"]?)\s*(=)\s* - scope: meta.hashtable.assignment.powershell + - match: \b(({{single_quote}}){{identifier_simple}}({{single_quote}}))\s*(=)\s* captures: - 1: punctuation.definition.string.begin.powershell - 2: variable.other.readwrite.powershell + 1: meta.mapping.key.powershell string.quoted.single.powershell + 2: punctuation.definition.string.begin.powershell 3: punctuation.definition.string.end.powershell - 4: keyword.operator.assignment.powershell + 4: punctuation.separator.key-value.powershell + - match: \b(({{double_quote}}){{identifier_simple}}({{double_quote}}))\s*(=)\s* + captures: + 1: meta.mapping.key.powershell string.quoted.double.powershell + 2: punctuation.definition.string.begin.powershell + 3: punctuation.definition.string.end.powershell + 4: punctuation.separator.key-value.powershell + - match: \b({{identifier_simple}})\s*(=)\s* + captures: + 1: meta.mapping.key.powershell string.unquoted.powershell + 2: punctuation.separator.key-value.powershell - include: expressions subexpressions: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index e3c11520..42ba44a6 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -68,24 +68,25 @@ using namespace System.Management.Automation # ^^^^^^^^ variable.parameter #Requires -Modules PSWorkflow, @{ModuleName="PSScheduledJob"; ModuleVersion="1.0.0.0"} # <- punctuation.definition.keyword -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.requires +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.requires #^^^^^^^^ keyword.control.import.require # ^^^^^^^^ variable.parameter # ^ punctuation.separator -# ^^^^^^^^^^ meta.requires meta.hashtable variable.other.readwrite -# ^ meta.requires meta.hashtable -# ^^^^^^^^^^^^^^^^ meta.requires meta.hashtable string.quoted.double -# ^ meta.requires meta.hashtable punctuation.terminator.statement -# ^^^^^^^^^^^^^ meta.requires meta.hashtable variable.other.readwrite -# ^ meta.requires meta.hashtable -# ^^^^^^^^^ meta.requires meta.hashtable string.quoted.double +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.hashtable.powershell +# ^^^^^^^^^^ meta.mapping.key string.unquoted +# ^ punctuation.separator.key-value.powershell +# ^^^^^^^^^^^^^^^^ string.quoted.double +# ^ punctuation.terminator.statement +# ^^^^^^^^^^^^^ meta.mapping.key string.unquoted +# ^ punctuation.separator.key-value.powershell +# ^^^^^^^^^ string.quoted.double :label1 # ^^^^^^^ entity.name.label.powershell # ^ punctuation.definition.label.powershell throw "Do not run this file!" -# <- keyword.control +# <- keyword.control.exception # ^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double # Stop parsing @@ -241,33 +242,44 @@ $properties = @{ # ^ keyword.other.hashtable.begin # ^ punctuation.section.braces.begin Name = 'Name' - # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite - # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment - # ^ meta.hashtable string.quoted.single +#^^^^^^^^^^^^^^^^^^^^^ meta.hashtable.powershell +# ^^^^ meta.mapping.key.powershell string.unquoted.powershell +# ^ punctuation.separator.key-value.powershell +# ^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell Something = $else #^^^^^^^^^^^^^^^^^^^^ meta.hashtable.powershell -# ^^^^^^^^^^^^ meta.hashtable.assignment.powershell -# ^^^^^^^^^ variable.other.readwrite.powershell -# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^ meta.mapping.key.powershell string.unquoted.powershell +# ^ punctuation.separator.key-value.powershell # ^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell Number = 16 - # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite - # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment - # ^^ meta.hashtable meta.number.integer.decimal constant.numeric.value +#^^^^^^^^^^^^^^^^^ meta.hashtable.powershell +# ^^^^^^ meta.mapping.key.powershell string.unquoted.powershell +# ^ punctuation.separator.key-value.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell from = 'hello world' - # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite - # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment - # ^^^^^^^^^^^^^ meta.hashtable string.quoted.single +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.hashtable.powershell +# ^^^^ meta.mapping.key.powershell string.unquoted.powershell +# ^ punctuation.separator.key-value.powershell +# ^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell hash = @{ - # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite - # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment - # ^ keyword.other.hashtable.begin - # ^ punctuation.section.braces.begin +#^^^^^^^^^^^^^^^^^ meta.hashtable.powershell +# ^^^^ meta.mapping.key.powershell string.unquoted.powershell +# ^ punctuation.separator.key-value.powershell +# ^^ meta.hashtable.powershell +# ^ keyword.other.hashtable.begin.powershell +# ^ punctuation.section.braces.begin.powershell hello = 'world' - # <- meta.hashtable meta.hashtable.assignment variable.other.readwrite - # ^ meta.hashtable meta.hashtable.assignment keyword.operator.assignment - # ^^^^^^^ meta.hashtable string.quoted.single +#^^^^^^^^^^^^^^^^^^^^^^ meta.hashtable.powershell meta.hashtable.powershell +# ^^^^^ meta.mapping.key.powershell string.unquoted.powershell +# ^ punctuation.separator.key-value.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell } # <- punctuation.section.braces.end } From 057d50703dfb6a08abe5a94356421258e9041cfd Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 16:39:37 -0500 Subject: [PATCH 077/133] Rescope the source operator --- PowerShell.sublime-syntax | 11 ++++--- Tests/syntax_test_PowerShell.ps1 | 53 +++++++++++++++++--------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index a6c049df..0f3342f6 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -48,19 +48,22 @@ contexts: statements: - include: redirection - include: classes - - include: expressions - include: functions - include: workflows - include: desired-state-configurations - - match: \B\.(?= ) - scope: support.function.source.powershell - - include: exceptions - include: loops - include: flow - include: conditionals + - match: \B\.(?= ) + scope: keyword.operator.source.powershell + - match: \& + scope: keyword.operator.call.powershell + + - include: expressions + expressions: # Meta - include: labels diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 42ba44a6..ee61724b 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -91,7 +91,7 @@ throw "Do not run this file!" # Stop parsing & tool.exe /arg1 'value' /arg2 $value --% /arg3 $value /arg4 "value" # Comment -# <- keyword.operator.background +# <- keyword.operator.call # ^^^^^^^^ variable.function # ^ punctuation.definition.parameter # ^^^^^ variable.parameter.option @@ -101,7 +101,7 @@ throw "Do not run this file!" # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted - constant - variable - comment & gnutool.exe -s 'short option' --long-option --very_long_option value +plus-option -#<- keyword.operator.background +#<- keyword.operator.call # ^^^^^^^^^^^ variable.function # ^ variable.parameter.option punctuation.definition.parameter # ^ variable.parameter.option @@ -873,28 +873,33 @@ $a3[1..2] # ^ keyword.operator.logical.pipe # ^^^^^^^^^^^^^^^^ support.function -# Commands (Built-in variables) -ls *.ps1 -recurse -# ^ keyword.operator -# ^ punctuation.definition.parameter -# ^^^^^^^^ variable.parameter.option - -# Commands (executable files) -. .\scripts\Test-Foo.ps1 -parameter 'value' -# ^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell -# @@@@@@@@@@@@@@@@@@@@@@ reference -# ^^^^^^^^^^ variable.parameter.option.powershell -# ^ punctuation.definition.parameter.powershell -# ^^^^^^^ meta.string.powershell string.quoted.single.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -& tool.exe -# <- keyword.operator.background -# ^^^^^^^^ variable.function -something.cmd -#^^^^^^^^^^^^ variable.function - øyvind.com -#^^^^^^^^^^ variable.function + # Commands (Built-in variables) + ls *.ps1 -recurse +# ^ keyword.operator.arithmetic.powershell +# ^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell + + # Commands (executable files) + . .\scripts\Test-Foo.ps1 -parameter 'value' +# ^ keyword.operator.source.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + & tool.exe +# ^ keyword.operator.call.powershell +# ^^^^^^^^ variable.function.powershell + + something.cmd +# ^^^^^^^^^^^^^ variable.function.powershell + + øyvind.com +# ^^^^^^^^^^ variable.function.powershell + # switch switch ("fourteen") {} From 577e3ad71e894ac71b92ca6d276dff499a50b589 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 20:23:45 -0500 Subject: [PATCH 078/133] Rescope the variable scope colon --- PowerShell.sublime-syntax | 8 ++++---- Tests/syntax_test_PowerShell.ps1 | 9 +++++---- Tests/syntax_test_strings.ps1 | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 0f3342f6..e1a52b27 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -622,11 +622,11 @@ contexts: - match: ({{var_scope_mod}})(:) captures: 1: storage.modifier.scope.powershell - 2: punctuation.separator.sequence.powershell + 2: punctuation.accessor.colon.powershell - match: ({{identifier_simple}})(:) captures: 1: support.variable.drive.powershell - 2: punctuation.separator.sequence.powershell + 2: punctuation.accessor.colon.powershell - match: '{{identifier_simple}}' - include: immediately-pop @@ -641,11 +641,11 @@ contexts: - match: ({{var_scope_mod}})(:) captures: 1: storage.modifier.scope.powershell - 2: punctuation.separator.sequence.powershell + 2: punctuation.accessor.colon.powershell - match: ({{identifier_simple}})(:) captures: 1: support.variable.drive.powershell - 2: punctuation.separator.sequence.powershell + 2: punctuation.accessor.colon.powershell members: - match: (?=\.\.) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index ee61724b..f974c6e2 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -177,12 +177,13 @@ throw "Do not run this file!" # ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell # ^^^^^^ storage.modifier.scope.powershell -# ^ punctuation.separator.sequence.powershell +# ^ punctuation.accessor.colon.powershell $ENV:ComputerName # ^^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell # ^^^ support.variable.drive.powershell -# ^ punctuation.separator.sequence.powershell +# ^ punctuation.accessor.colon.powershell +# ^^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell ${variable} # ^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell @@ -210,7 +211,7 @@ throw "Do not run this file!" # ^ punctuation.definition.variable.powershell # ^ punctuation.section.interpolation.begin.powershell # ^^^^^^ storage.modifier.scope.powershell -# ^ punctuation.separator.sequence.powershell +# ^ punctuation.accessor.colon.powershell # ^ punctuation.section.interpolation.end.powershell @@ -1605,7 +1606,7 @@ $file = join-path $env:SystemDrive "$([System.io.path]::GetRandomFileName()).ps1 # ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell # ^^^ support.variable.drive.powershell -# ^ punctuation.separator.sequence.powershell +# ^ punctuation.accessor.colon.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell # ^ string.quoted.double.powershell punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 9ba374eb..0e1c7195 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -130,7 +130,7 @@ # ^^^^^^^^^^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell # ^^^ support.variable.drive.powershell -# ^ punctuation.separator.sequence.powershell +# ^ punctuation.accessor.colon.powershell # ^ string.quoted.double.powershell punctuation.definition.string.end.powershell # Here as well @@ -142,7 +142,7 @@ # ^ punctuation.definition.variable.powershell # ^ punctuation.section.interpolation.begin.powershell # ^^^ support.variable.drive.powershell -# ^ punctuation.separator.sequence.powershell +# ^ punctuation.accessor.colon.powershell # ^ punctuation.section.interpolation.end.powershell # ^ string.quoted.double.powershell punctuation.definition.string.end.powershell From 77014c4418f0eff3dffe57573fa500940ae8e87d Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 15:08:32 -0500 Subject: [PATCH 079/133] Recognize first statement as a command --- PowerShell.sublime-syntax | 133 +++-- Tests/syntax_test_Class.ps1 | 19 + Tests/syntax_test_PowerShell.ps1 | 802 +++++++++++++++++++++++-------- Tests/syntax_test_Workflow.ps1 | 21 +- 4 files changed, 726 insertions(+), 249 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index e1a52b27..bfe81a2f 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -46,7 +46,6 @@ contexts: - include: else-pop statements: - - include: redirection - include: classes - include: functions - include: workflows @@ -83,28 +82,43 @@ contexts: - include: hashtables - include: arrays + - include: data-blocks + - include: script-blocks + - include: groups + - include: subexpressions + + - include: future-reserved-words + + - include: operators - include: commands + expressions-without-commands: + # Meta + - include: labels + - include: regions + - include: requires-directives + + - include: escape-sequences + - include: literal-after + + # Normal code + - include: types + - include: strings + - include: numbers + - include: constants + - include: variables + + - include: hashtables + - include: arrays + - include: data-blocks - include: script-blocks - include: groups - include: subexpressions - # Consume a string with a trailing dot to prevent members with - # particular names from being recognized as keywords. - - match: \b[\w-]+(?=\.) - scope: variable.other.object.powershell - push: members - - # "Reserved for future use" - # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words - - match: \b(?i:define|from){{kebab_break}} - scope: keyword.control.powershell - - match: \b(?i:var){{kebab_break}} - scope: keyword.declaration.variable.powershell + - include: future-reserved-words - include: operators - - include: parameters literal-after: - match: \B--%\B @@ -114,6 +128,13 @@ contexts: - meta_content_scope: string.unquoted.powershell - include: pop-before-eol + future-reserved-words: + # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words + - match: \b(?i:define|from){{kebab_break}} + scope: keyword.control.powershell + - match: \b(?i:var){{kebab_break}} + scope: keyword.declaration.variable.powershell + ###[ EXCEPTIONS ]############################################################## exceptions: @@ -161,6 +182,7 @@ contexts: scope: keyword.control.conditional.else.powershell - match: \b(?i:switch){{kebab_break}} scope: keyword.control.conditional.switch.powershell + push: in-command - match: \b(?i:default){{kebab_break}} scope: keyword.control.conditional.default.powershell - match: \b(?i:where(?!-object)){{kebab_break}} @@ -189,7 +211,7 @@ contexts: captures: 1: keyword.other.array.begin.powershell 2: punctuation.section.group.begin.powershell - push: inside-array + push: [members, inside-array] inside-array: - meta_scope: meta.group.array-expression.powershell @@ -203,7 +225,7 @@ contexts: captures: 1: keyword.other.hashtable.begin.powershell 2: punctuation.section.braces.begin.powershell - push: inside-hashtable + push: [members, inside-hashtable] inside-hashtable: - meta_scope: meta.hashtable.powershell @@ -247,13 +269,14 @@ contexts: captures: 1: keyword.control.loop.for.powershell 2: punctuation.section.braces.begin.powershell - push: inside-script-block + push: [members, inside-script-block] inside-script-block: - meta_scope: meta.block.powershell - match: \} scope: punctuation.section.braces.end.powershell pop: 1 + - include: param-block - include: statements ###[ COMMANDS ]################################################################ @@ -262,6 +285,7 @@ contexts: - include: commands-verb-noun - include: commands-reserved - include: script-invocation + - include: command-freeform commands-verb-noun: # The "Verb-Noun" pattern @@ -273,17 +297,57 @@ contexts: (?:\.(?i:exe|cmd|bat|ps1))?\b # More path stuff ) scope: meta.function-call.powershell support.function.powershell + push: in-command commands-reserved: # Builtin cmdlets with reserved verbs - match: \b(?i:(?:ForEach|Where|Sort|Tee)-Object)\b scope: meta.function-call.powershell support.function.powershell + push: in-command script-invocation: - match: \b(?i:[a-z]:)?[\w.\\/-]+\.(?i:exe|com|cmd|bat|ps1)\b - scope: variable.function.powershell + scope: meta.function-call.powershell variable.function.powershell + push: in-command + + command-freeform: + - match: '{{identifier_function}}' + scope: meta.function-call.powershell variable.function.powershell + push: in-command - parameters: + in-command: + # - meta_scope: region.pinkish + - include: line-continuations + - include: pop-eol + - match: (?=[)}]) + pop: 1 + - match: ';' + scope: punctuation.terminator.statement.powershell + pop: 1 + - match: (\|)\s*\n + captures: + 1: keyword.operator.logical.pipe.powershell + push: + - match: ^ + pop: 2 + - match: \| + scope: keyword.operator.logical.pipe.powershell + pop: 1 + - include: redirection + - include: cli-parameters + - include: expressions-without-commands + - match: (?=\S) + push: + - meta_include_prototype: false + - meta_scope: string.unquoted.powershell + - match: (?=[\s#|>;,]|$) + pop: 1 + - match: '[\\/:.]' + scope: punctuation.separator.powershell + - include: escape-sequences + + + cli-parameters: # Flags/Options/Parameters - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? scope: variable.parameter.option.powershell @@ -429,9 +493,7 @@ contexts: scope: punctuation.section.block.end.powershell pop: 2 - - match: \b(?i:(?:Dynamic)?Param){{kebab_break}} - scope: keyword.declaration.parameter.powershell # This scope is not standard - push: expect-param-context + - include: param-block - match: \b(?i:Begin|Process|End|Clean){{kebab_break}} scope: keyword.context.block.powershell @@ -441,6 +503,11 @@ contexts: - include: workflow-execution-contexts - include: statements + param-block: + - match: \b(?i:(?:Dynamic)?Param){{kebab_break}} + scope: keyword.declaration.parameter.powershell # This scope is not standard + push: expect-param-context + expect-function-context: - meta_scope: meta.block.powershell - match: \{ @@ -650,9 +717,9 @@ contexts: members: - match: (?=\.\.) pop: 1 - - match: \?\.(?={{identifier_simple}}) + - match: \?\.(?=\$?{{identifier_simple}}) scope: punctuation.accessor.null-coalescing.powershell - - match: \??\.(?={{identifier_simple}}) + - match: \??\.(?=\$?{{identifier_simple}}) scope: punctuation.accessor.dot.powershell - match: ::(?={{identifier_simple}}) scope: punctuation.accessor.double-colon.powershell @@ -788,10 +855,7 @@ contexts: scope: keyword.operator.ternary.powershell - match: ; scope: punctuation.terminator.statement.powershell - - match: \`(?=\n|$) - scope: punctuation.separator.continuation.line.powershell - include: comma-separators - # TODO: Distinguish call operator from background operator - match: '&' scope: keyword.operator.background.powershell - match: \.\.(?=\-?\d|\(|\$) @@ -1124,6 +1188,19 @@ contexts: ###[ COMPONENTS ]############################################################## + line-continuations: + - match: (`)\n + captures: + 1: punctuation.separator.continuation.line.powershell + push: line-continuation-body + - match: '`(\s+)\n' + captures: + 1: invalid.illegal.unexpected-whitespace.powershell + + line-continuation-body: + - match: ^ + pop: 1 + comma-separators: - match: ',' scope: punctuation.separator.sequence.powershell @@ -1135,7 +1212,7 @@ contexts: scope: constant.character.escape.powershell pop-eol: - - match: $ + - match: $\n? pop: 1 pop-before-eol: diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index c1703196..90775389 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -347,6 +347,15 @@ class BookList { $b.Author -eq $Book.Author -and $b.PublishDate -eq $Book.PublishDate }.GetNewClosure() +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +#^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell if ([BookList]::Books.Find($FindPredicate)) { # @@@@ reference throw "Book '$Book' already in list" @@ -397,6 +406,16 @@ class BookList { param($b) $b.$Property -eq $Value }.GetNewClosure()) +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell meta.function-call.arguments.powershell +#^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell +# ^ punctuation.section.arguments.end.powershell if ($Index -ge 0) { [BookList]::Books.RemoveAt($Index) # @@@@@@@@ reference diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index f974c6e2..32283fdd 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -93,6 +93,7 @@ throw "Do not run this file!" & tool.exe /arg1 'value' /arg2 $value --% /arg3 $value /arg4 "value" # Comment # <- keyword.operator.call # ^^^^^^^^ variable.function +# @@@@@@@@ reference # ^ punctuation.definition.parameter # ^^^^^ variable.parameter.option # ^ punctuation.definition.parameter @@ -103,6 +104,7 @@ throw "Do not run this file!" & gnutool.exe -s 'short option' --long-option --very_long_option value +plus-option #<- keyword.operator.call # ^^^^^^^^^^^ variable.function +# @@@@@@@@@@@ reference # ^ variable.parameter.option punctuation.definition.parameter # ^ variable.parameter.option # ^^ variable.parameter.option punctuation.definition.parameter @@ -489,9 +491,11 @@ $a3[1..2] # ^^ meta.number.float.decimal constant.numeric.value - constant constant # ^ punctuation.separator.decimal + # BUG: Don't mark the dot as a function 1. # ^ meta.number.integer.decimal constant.numeric.value # ^ - meta.number - constant.numeric +# @ reference 1.f 1.f() # ^ meta.number.integer.decimal constant.numeric.value @@ -854,11 +858,12 @@ $a3[1..2] # ^ support.function # @@@@@@@@@@@@@@@@ reference Invoke-Something -p1 value ` -#^ support.function +#^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell #@@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option -# ^ punctuation.separator.continuation +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^ string.unquoted.powershell +# ^ punctuation.separator.continuation.line.powershell -p2 14.4 ` # ^ punctuation.definition.parameter # ^^^ variable.parameter.option @@ -874,9 +879,24 @@ $a3[1..2] # ^ keyword.operator.logical.pipe # ^^^^^^^^^^^^^^^^ support.function + Get-ChildItem | +# ^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@ reference +# ^ keyword.operator.logical.pipe.powershell + Select Name,Length +# ^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@ reference +# ^^^^ string.unquoted.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^ string.unquoted.powershell + + # Commands (Built-in variables) ls *.ps1 -recurse +# ^^ meta.function-call.powershell variable.function.powershell +# @@ reference # ^ keyword.operator.arithmetic.powershell +# ^^^^ string.unquoted.powershell # ^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell @@ -893,14 +913,16 @@ $a3[1..2] & tool.exe # ^ keyword.operator.call.powershell -# ^^^^^^^^ variable.function.powershell +# ^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@ reference something.cmd -# ^^^^^^^^^^^^^ variable.function.powershell +# ^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@ reference øyvind.com -# ^^^^^^^^^^ variable.function.powershell - +# ^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@ reference # switch switch ("fourteen") {} @@ -1139,11 +1161,20 @@ function Test-Drive([string]$roman) { # ^ punctuation.section.parameters.end.powershell # ^ punctuation.section.block.begin.powershell $roman | c:\users\Me\Documents\Programming\F#\test.exe $roman -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ keyword.operator.logical.pipe -# ^ punctuation.definition.comment -# ^^^^ comment.line +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ meta.function-call.powershell variable.function.powershell +# @ reference +# ^ keyword.operator.ternary.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^^^^^^^^^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment.powershell } #^^^^ meta.function.powershell # ^ punctuation.section.block.end.powershell @@ -1400,203 +1431,554 @@ catch { } # ^ punctuation.section.braces.begin # ^ punctuation.section.braces.end -# Redirection -notepad.exe > log.txt -#^^^^^^^^^^ variable.function -# ^ keyword.operator.redirection -notepad.exe 1> log.txt -#^^^^^^^^^^ variable.function -# ^ keyword.operator.redirection -notepad.exe *> log.txt -#^^^^^^^^^^ variable.function -# ^ keyword.operator.redirection -notepad.exe 2>&1 -#^^^^^^^^^^ variable.function -# ^^ keyword.operator.redirection -notepad.exe 3>&1 -#^^^^^^^^^^ variable.function -# ^^ keyword.operator.redirection -notepad.exe 4>&1 -#^^^^^^^^^^ variable.function -# ^^ keyword.operator.redirection -notepad.exe 5>&1 -#^^^^^^^^^^ variable.function -# ^^ keyword.operator.redirection -notepad.exe 6>&1 -#^^^^^^^^^^ variable.function -# ^^ keyword.operator.redirection -notepad.exe 2>&1> log.txt -#^^^^^^^^^^ variable.function -# ^^ keyword.operator.redirection -# ^ keyword.operator.redirection - -# Operators -if (10 -cgt 100) { } -# <- keyword.control -# ^ punctuation.section.group.begin -# ^^ meta.number.integer.decimal constant.numeric.value -# ^^^^ keyword.operator.comparison -# ^^^ meta.number.integer.decimal constant.numeric.value -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end -$a -is $b -# ^^^ keyword.operator.logical -$b -contains $c -# ^^^^^^^^^ keyword.operator.logical -$x -notcontains $c -# ^^^^^^^^^^^^ keyword.operator.logical -$c -in $b -# ^^^ keyword.operator.logical -$c -notin $x -# ^^^^^^ keyword.operator.logical -$a -match $b -# ^^^^^^ keyword.operator.logical -$a -notmatch $b -# ^^^^^^^^^ keyword.operator.logical -$x -like $c -# ^^^^^ keyword.operator.logical -100 -and 0 -# ^^^^ keyword.operator.logical -# ^ meta.number.integer.decimal constant.numeric.value -$a -ceq 4 -and $a -ine $d -or -# ^^^^ keyword.operator.comparison -# ^ meta.number.integer.decimal constant.numeric.value -# ^^^^ keyword.operator.logical -# ^ punctuation.definition.variable -# ^^^^ keyword.operator.comparison -# ^^^ keyword.operator.logical -$c -is [Type] -#^ variable.other.readwrite.powershell -# ^^^ keyword.operator.logical.powershell -# ^ punctuation.definition.keyword.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -$c -isnot [Type] -#^ variable.other.readwrite.powershell -# ^^^^^^ keyword.operator.logical.powershell -# ^ punctuation.definition.keyword.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -$c -as [Type] -#^ variable.other.readwrite.powershell -# ^^^ keyword.operator.cast.powershell -# ^ punctuation.definition.keyword.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -$k = $y -bor $k -# ^ keyword.operator.assignment -# ^ keyword.operator.bitwise -$x = $y -band $x -# ^ keyword.operator.assignment -# ^ keyword.operator.bitwise -$z = -bnot $x -# ^ keyword.operator.assignment -# ^ keyword.operator.bitwise -$l = 1 -shl 10 -# ^ keyword.operator.assignment -# ^ meta.number.integer.decimal constant.numeric.value -# ^^ meta.number.integer.decimal constant.numeric.value -# ^^^^ keyword.operator.bitwise -$r = 10 -shr 1 -# ^ keyword.operator.assignment -# ^^ meta.number.integer.decimal constant.numeric.value -# ^ meta.number.integer.decimal constant.numeric.value -# ^^^^ keyword.operator.bitwise -$k = $y -xor $b -# ^ keyword.operator.assignment -# ^ keyword.operator.logical -$k = $y -bxor $b -# ^ keyword.operator.assignment -# ^ keyword.operator.bitwise -$a -icontains $c -# ^^^^^^^^^^ keyword.operator.logical -$a -ccontains $c -# ^^^^^^^^^^ keyword.operator.logical -$a -iNotContains $c -# ^^^^^^^^^^^^^ keyword.operator.logical -$a -cNotContains $c -# ^^^^^^^^^^^^^ keyword.operator.logical -$a -cmatch $c -# ^^^^^^^ keyword.operator.logical -$x -iMatch $c -# ^^^^^^^ keyword.operator.logical -$x -iNotMatch $c -# ^^^^^^^^^^ keyword.operator.logical -$a -iLike $b -# ^^^^^^ keyword.operator.logical -$b -cLike $c -# ^^^^^^ keyword.operator.logical -"hey" -cgt "Hey" -# ^^^^ keyword.operator.comparison -"Hey" -igt "hey" -# ^^^^ keyword.operator.comparison -"hey" -cge "Hey" -# ^^^^ keyword.operator.comparison -"Hey" -ige "hey" -# ^^^^ keyword.operator.comparison -"HEY" -clt "hey" -# ^^^^ keyword.operator.comparison -"HEY" -ilt "hey" -# ^^^^ keyword.operator.comparison -"HEY" -cle "hey" -# ^^^^ keyword.operator.comparison -"HEY" -ile "hey" -# ^^^^ keyword.operator.comparison - -function Test-Function {} -# @@@@@@@@@@@@@ definition -function New-Object {} -# @@@@@@@@@@ definition -# Misc test cases - Test-Function -Class ClassName -# ^^^^^ - storage.type -#@@@@@@@@@@@@@ reference - New-Object -TypeName System.Diagnostics.Process -# ^^^^^^^ - keyword.control -#@@@@@@@@@@ reference - New-Object -TypeName System.Data -# ^^^^ - keyword.control -#@@@@@@@@@@ reference - New-Object -TypeName Sy-stem.if -# ^^ - keyword.control -#@@@@@@@@@@ reference - New-Object -TypeName S_ystem.Clean -# ^^^^^ - keyword.control -#@@@@@@@@@@ reference - New-Object -TypeName Sy_stem-.Throw -# ^^^^^ - keyword.control -#@@@@@@@@@@ reference -echo `"test`" -# ^^^^^^^^^ - string.quoted -# ^^ constant.character.escape -# ^^ constant.character.escape -@("any","array","has").foreach({ $_ }) -# <- keyword.other.array.begin -# ^ meta.group.array-expression -# ^ keyword.control -# ^ meta.block -@('any','array','has').foreach{ $_ } -# <- keyword.other.array.begin -# ^ meta.group.array-expression -# ^ keyword.control -# ^ meta.block -@("any","array","has").where({ $_.Length -gt 3 }) -# <- keyword.other.array.begin -# ^ meta.group.array-expression -# ^ keyword.control -# ^ meta.block -@("any","array","has").where{ $_.Length -gt 3 } -# <- keyword.other.array.begin -# ^ meta.group.array-expression -# ^ keyword.control -# ^ meta.block - -function join-path {} -# @@@@@@@@@ definition + # Redirection + notepad.exe > log.txt +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ keyword.operator.redirection.powershell +# ^^^^^^^ string.unquoted.powershell +# ^ punctuation.separator.powershell + notepad.exe 1> log.txt +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^ keyword.operator.redirection.powershell +# ^^^^^^^ string.unquoted.powershell +# ^ punctuation.separator.powershell + notepad.exe *> log.txt +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^ keyword.operator.redirection.powershell +# ^^^^^^^ string.unquoted.powershell +# ^ punctuation.separator.powershell + notepad.exe 2>&1 +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^^ keyword.operator.redirection.powershell +# ^ constant.numeric.decimal.file-descriptor.powershell + notepad.exe 3>&1 +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^^ keyword.operator.redirection.powershell +# ^ constant.numeric.decimal.file-descriptor.powershell + notepad.exe 4>&1 +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^^ keyword.operator.redirection.powershell +# ^ constant.numeric.decimal.file-descriptor.powershell + notepad.exe 5>&1 +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^^ keyword.operator.redirection.powershell +# ^ constant.numeric.decimal.file-descriptor.powershell + notepad.exe 6>&1 +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^^ keyword.operator.redirection.powershell +# ^ constant.numeric.decimal.file-descriptor.powershell + notepad.exe 2>&1> log.txt +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^^ keyword.operator.redirection.powershell +# ^ constant.numeric.decimal.file-descriptor.powershell +# ^ keyword.operator.redirection.powershell +# ^^^^^^^ string.unquoted.powershell +# ^ punctuation.separator.powershell + + # Operators + if (10 -cgt 100) { } +# ^^ keyword.control.conditional.if.powershell +# ^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.group.end.powershell +# ^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + $a -is $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $b -contains $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $x -notcontains $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $c -in $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $c -notin $x +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -match $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -notmatch $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $x -like $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + 100 -and 0 +# ^^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + $a -ceq 4 -and $a -ine $d -or +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell + $c -is [Type] +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell + $c -isnot [Type] +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell + $c -as [Type] +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ keyword.operator.cast.powershell +# ^ punctuation.definition.keyword.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell + $k = $y -bor $k +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $x = $y -band $x +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $z = -bnot $x +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $l = 1 -shl 10 +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + $r = 10 -shr 1 +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + $k = $y -xor $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $k = $y -bxor $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -icontains $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -ccontains $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -iNotContains $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -cNotContains $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -cmatch $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $x -iMatch $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $x -iNotMatch $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a -iLike $b +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $b -cLike $c +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + "hey" -cgt "Hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "Hey" -igt "hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "hey" -cge "Hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "Hey" -ige "hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "HEY" -clt "hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "HEY" -ilt "hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "HEY" -cle "hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "HEY" -ile "hey" +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + function Test-Function {} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell +# @@@@@@@@@@@@@ definition + function New-Object {} +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell +# @@@@@@@@@@ definition + Test-Function -Class ClassName +# ^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# ^^^^^^ variable.parameter.option.powershell - storage - keyword +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^ string.unquoted.powershell +# @@@@@@@@@@@@@ reference + New-Object -TypeName System.Diagnostics.Process +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell - keyword +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell + New-Object -TypeName System.Data +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^ string.unquoted.powershell - keyword + New-Object -TypeName Sy-stem.if +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^ string.unquoted.powershell - keyword +# ^ punctuation.separator.powershell + New-Object -TypeName S_ystem.Clean +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^ string.unquoted.powershell - keyword +# ^ punctuation.separator.powershell + New-Object -TypeName Sy_stem-.Throw +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^ string.unquoted.powershell - keyword + + echo `"test`" +# ^^^^ meta.function-call.powershell variable.function.powershell +# @@@@ reference +# ^^ constant.character.escape.powershell +# ^^^^^^ string.unquoted.powershell - string.quoted +# ^^ constant.character.escape.powershell + + @("any","array","has").foreach({ $_ }) +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.array-expression.powershell +# ^ keyword.other.array.begin.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@ reference +# ^^^^^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.section.arguments.end.powershell + @('any','array','has').foreach{ $_ } +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.array-expression.powershell +# ^ keyword.other.array.begin.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.end.powershell + @("any","array","has").where({ $_.Length -gt 3 }) +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.array-expression.powershell +# ^ keyword.other.array.begin.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^ variable.other.member.powershell +# ^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.section.arguments.end.powershell + @("any","array","has").where{ $_.Length -gt 3 } +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.array-expression.powershell +# ^ keyword.other.array.begin.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^ variable.other.member.powershell +# ^^^ keyword.operator.comparison.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.braces.end.powershell + + function join-path {} +# @@@@@@@@@ definition $file = join-path $env:SystemDrive "$([System.io.path]::GetRandomFileName()).ps1" #^^^^ variable.other.readwrite.powershell diff --git a/Tests/syntax_test_Workflow.ps1 b/Tests/syntax_test_Workflow.ps1 index dbe3d2ce..94d4e66d 100644 --- a/Tests/syntax_test_Workflow.ps1 +++ b/Tests/syntax_test_Workflow.ps1 @@ -129,8 +129,8 @@ # ^ meta.function.powershell meta.block.powershell meta.block.powershell punctuation.section.block.begin.powershell $Hotfix = Get-Content 'D:\HotFixes\Required.txt' # @@@@@@@@@@@ reference - foreach ($h in $Hotfix) {'D:\Scripts\Verify-Hotfix' -Hotfix $h} -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.powershell meta.block.powershell + foreach ($h in $Hotfix) {D:\Scripts\Verify-Hotfix.ps1 -Hotfix $h} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.powershell meta.block.powershell # ^^^^^^^ keyword.control.loop.for.powershell # ^^^^^^^^^^^^^^^ meta.group.powershell # ^ punctuation.section.group.begin.powershell @@ -140,16 +140,15 @@ # ^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell # ^ punctuation.section.group.end.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell # ^ punctuation.section.braces.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^^^^^^^ variable.parameter.option.powershell -# ^ punctuation.definition.parameter.powershell -# ^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.section.braces.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.end.powershell } } } From 644317e6b078813841f7b63ea1c9b63f216cc053 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 18:36:54 -0500 Subject: [PATCH 080/133] Extract command ending sequences to a context --- PowerShell.sublime-syntax | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index bfe81a2f..c4e4245a 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -317,6 +317,21 @@ contexts: in-command: # - meta_scope: region.pinkish + - include: command-ending-sequences + - include: redirection + - include: cli-parameters + - include: expressions-without-commands + - match: (?=\S) + push: + - meta_include_prototype: false + - meta_scope: string.unquoted.powershell + - match: (?=[\s#|>;,]|$) + pop: 1 + - match: '[\\/:.]' + scope: punctuation.separator.powershell + - include: escape-sequences + + command-ending-sequences: - include: line-continuations - include: pop-eol - match: (?=[)}]) @@ -333,19 +348,6 @@ contexts: - match: \| scope: keyword.operator.logical.pipe.powershell pop: 1 - - include: redirection - - include: cli-parameters - - include: expressions-without-commands - - match: (?=\S) - push: - - meta_include_prototype: false - - meta_scope: string.unquoted.powershell - - match: (?=[\s#|>;,]|$) - pop: 1 - - match: '[\\/:.]' - scope: punctuation.separator.powershell - - include: escape-sequences - cli-parameters: # Flags/Options/Parameters From 692cde2b65a2fc69e48549632b54a5f97e5ca929 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 16:55:43 -0500 Subject: [PATCH 081/133] Change command identifier for kicks --- PowerShell.sublime-syntax | 2 +- Tests/syntax_test_PowerShell.ps1 | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c4e4245a..cc98a79c 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -311,7 +311,7 @@ contexts: push: in-command command-freeform: - - match: '{{identifier_function}}' + - match: '{{identifier_simple}}' scope: meta.function-call.powershell variable.function.powershell push: in-command diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 32283fdd..e906f63b 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -495,7 +495,6 @@ $a3[1..2] 1. # ^ meta.number.integer.decimal constant.numeric.value # ^ - meta.number - constant.numeric -# @ reference 1.f 1.f() # ^ meta.number.integer.decimal constant.numeric.value From dec8f645ea09854938cd403c98e2bb163e92f998 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 17:04:24 -0500 Subject: [PATCH 082/133] Mark scripts as functions after & or . Even if they are quoted. --- PowerShell.sublime-syntax | 22 ++++++++++++++++++++++ Tests/syntax_test_PowerShell.ps1 | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index cc98a79c..cfef6a4f 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -58,8 +58,14 @@ contexts: - match: \B\.(?= ) scope: keyword.operator.source.powershell + push: + - include: commands-quoted + - include: else-pop - match: \& scope: keyword.operator.call.powershell + push: + - include: commands-quoted + - include: else-pop - include: expressions @@ -310,6 +316,22 @@ contexts: scope: meta.function-call.powershell variable.function.powershell push: in-command + commands-quoted: + - match: (?={{single_quote}}) + push: [in-command, expect-single-quoted-command] + - match: (?={{double_quote}}) + push: [in-command, expect-double-quoted-command] + + expect-single-quoted-command: + - meta_scope: meta.function-call.powershell variable.function.powershell + - include: single-quoted-strings + - include: immediately-pop + + expect-double-quoted-command: + - meta_scope: meta.function-call.powershell variable.function.powershell + - include: double-quoted-strings + - include: immediately-pop + command-freeform: - match: '{{identifier_simple}}' scope: meta.function-call.powershell variable.function.powershell diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index e906f63b..a074974f 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -923,6 +923,13 @@ $a3[1..2] # ^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@ reference + & ".\script name with spaces.ps1" +# ^ keyword.operator.call.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference + # switch switch ("fourteen") {} # <- keyword.control From 4ee51f077bd526cadd72baa33db17591ed06793e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 17:19:34 -0500 Subject: [PATCH 083/133] Stack function scopes over strings --- PowerShell.sublime-syntax | 48 ++++++++++++++++++++++++-------- Tests/syntax_test_PowerShell.ps1 | 15 ++++++++-- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index cfef6a4f..6bc5efee 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -318,27 +318,50 @@ contexts: commands-quoted: - match: (?={{single_quote}}) - push: [in-command, expect-single-quoted-command] + push: [in-command, single-quoted-command-string] - match: (?={{double_quote}}) - push: [in-command, expect-double-quoted-command] + push: [in-command, double-quoted-command-string] - expect-single-quoted-command: - - meta_scope: meta.function-call.powershell variable.function.powershell - - include: single-quoted-strings + single-quoted-command-string: + - match: '{{single_quote}}' + scope: punctuation.definition.string.begin.powershell + push: inside-single-quoted-command-string - include: immediately-pop - expect-double-quoted-command: - - meta_scope: meta.function-call.powershell variable.function.powershell - - include: double-quoted-strings + inside-single-quoted-command-string: + - meta_include_prototype: false + - meta_scope: meta.string.powershell string.quoted.single.powershell meta.function-call.powershell variable.function.powershell + - match: '{{single_quote}}{2}' + scope: constant.character.escape.powershell + - match: '{{single_quote}}' + scope: punctuation.definition.string.end.powershell + pop: 1 + - include: path-punctuation + + double-quoted-command-string: + - match: '{{double_quote}}' + scope: punctuation.definition.string.begin.powershell + push: inside-double-quoted-command-string - include: immediately-pop + inside-double-quoted-command-string: + - meta_include_prototype: false + - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell meta.function-call.powershell variable.function.powershell + - match: '{{double_quote}}{2}' + scope: constant.character.escape.powershell + - include: escape-sequences + - match: '{{double_quote}}' + scope: punctuation.definition.string.end.powershell + pop: 1 + - include: string-interpolations + - include: path-punctuation + command-freeform: - match: '{{identifier_simple}}' scope: meta.function-call.powershell variable.function.powershell push: in-command in-command: - # - meta_scope: region.pinkish - include: command-ending-sequences - include: redirection - include: cli-parameters @@ -349,8 +372,7 @@ contexts: - meta_scope: string.unquoted.powershell - match: (?=[\s#|>;,]|$) pop: 1 - - match: '[\\/:.]' - scope: punctuation.separator.powershell + - include: path-punctuation - include: escape-sequences command-ending-sequences: @@ -1212,6 +1234,10 @@ contexts: ###[ COMPONENTS ]############################################################## + path-punctuation: + - match: '[:/\\.]+' + scope: punctuation.separator.powershell + line-continuations: - match: (`)\n captures: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index a074974f..7dc2a098 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -923,12 +923,23 @@ $a3[1..2] # ^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@ reference - & ".\script name with spaces.ps1" + & '.\script name with spaces.ps1' # ^ keyword.operator.call.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell meta.string.interpolated.powershell string.quoted.double.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference # ^ punctuation.definition.string.begin.powershell +# ^^ punctuation.separator.powershell +# ^ punctuation.separator.powershell # ^ punctuation.definition.string.end.powershell + + & ".\script name with spaces.ps1" +# ^ keyword.operator.call.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference +# ^ punctuation.definition.string.begin.powershell +# ^^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.string.end.powershell # switch switch ("fourteen") {} From 560d5161f73ec35a0aeddbee54669f44ab03aaa1 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 18:44:47 -0500 Subject: [PATCH 084/133] Test for background operator --- Tests/syntax_test_PowerShell.ps1 | 84 ++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 7dc2a098..177344b1 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -85,33 +85,63 @@ using namespace System.Management.Automation # ^^^^^^^ entity.name.label.powershell # ^ punctuation.definition.label.powershell -throw "Do not run this file!" -# <- keyword.control.exception -# ^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double - -# Stop parsing -& tool.exe /arg1 'value' /arg2 $value --% /arg3 $value /arg4 "value" # Comment -# <- keyword.operator.call -# ^^^^^^^^ variable.function -# @@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^^^ variable.parameter.option -# ^ punctuation.definition.parameter -# ^^^^^ variable.parameter.option -# ^^^ keyword.control -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted - constant - variable - comment - -& gnutool.exe -s 'short option' --long-option --very_long_option value +plus-option -#<- keyword.operator.call -# ^^^^^^^^^^^ variable.function -# @@@@@@@@@@@ reference -# ^ variable.parameter.option punctuation.definition.parameter -# ^ variable.parameter.option -# ^^ variable.parameter.option punctuation.definition.parameter -# ^^ variable.parameter.option punctuation.definition.parameter -# ^^^^^^^^^^^^^^^^ variable.parameter.option -# ^ variable.parameter.option punctuation.definition.parameter -# ^^^^^^^^^^^ variable.parameter.option + throw "Do not run this file!" +# ^^^^^ keyword.control.exception.raise.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + + # Stop parsing + & tool.exe /arg1 'value' /arg2 $value --% /arg3 $value /arg4 "value" # Comment +# ^ keyword.operator.call.powershell +# ^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@ reference +# ^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ keyword.control.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell + + & gnutool.exe -s 'short option' --long-option --very_long_option value +plus-option +# ^ keyword.operator.call.powershell +# ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@ reference +# ^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^^^^^^^^ variable.parameter.option.powershell +# ^^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^^^ variable.parameter.option.powershell +# ^^ punctuation.definition.parameter.powershell +# ^^^^^ string.unquoted.powershell +# ^^^^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell + + $job = Get-Process -Name pwsh & +# ^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@ reference +# ^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^ string.unquoted.powershell +# ^ keyword.operator.background.powershell + Receive-Job $job -Wait +# ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@ reference +# ^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell # Constants $true From f8703f9bdbfa34c6c626330983f2dea98eb63edf Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 18:46:20 -0500 Subject: [PATCH 085/133] Test string subexpression property access --- Tests/syntax_test_strings.ps1 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 0e1c7195..9d68c1a5 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -122,6 +122,22 @@ # ^^ string.quoted.double.powershell - meta.interpolation # ^ punctuation.definition.string.end.powershell + # When used in a subexpression, still don't extend past its closing + "This is my $($variable.Name).Name!" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^ meta.interpolation.powershell +# ^^ punctuation.section.interpolation.begin.powershell +# ^^^^^^^^^^^^^^ source.powershell.embedded +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^ variable.other.member.powershell +# ^ punctuation.section.interpolation.end.powershell +# ^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.end.powershell + # $ENV:ComputerName should be highlighted "This is the name of my computer: $ENV:ComputerName" # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell From 963119f3a06fcb4abdb186e9b87012d6a16965a5 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 20:34:27 -0500 Subject: [PATCH 086/133] Allow default value in function params And refactor assignment a little --- PowerShell.sublime-syntax | 21 ++++++++--- Tests/syntax_test_Pester.ps1 | 61 ++++++++++++++++++++++++++++++++ Tests/syntax_test_PowerShell.ps1 | 2 +- Tests/syntax_test_Workflow.ps1 | 33 +++++++++++++++++ 4 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 Tests/syntax_test_Pester.ps1 diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 6bc5efee..6df19da9 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -526,6 +526,7 @@ contexts: scope: variable.parameter.powershell captures: 1: punctuation.definition.variable.begin.powershell + - include: assignment-normal function-body: - meta_scope: meta.function.powershell @@ -583,8 +584,7 @@ contexts: - include: types-without-members - include: variables-without-members - include: literals - - match: '=' - scope: keyword.operator.assignment.powershell + - include: assignment-normal attributes: - match: (\[)\s*({{attributes}}) @@ -876,8 +876,10 @@ contexts: # Symbol operators - match: \! scope: keyword.operator.logical.powershell - - match: '[+/*%-]?=' - scope: keyword.operator.assignment.powershell + - include: assignment-normal + - match: (?:[+/*%-]|\?\?)= + scope: keyword.operator.assignment.augmented.powershell + push: in-assignment - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) scope: keyword.operator.assignment.powershell - match: '[+-](?=\.?\d)' # This is sort of heuristic @@ -908,6 +910,17 @@ contexts: # This is very imprecise. Is there a syntax for 'must come after...'? scope: keyword.operator.range.powershell + assignment-normal: + - match: = + scope: keyword.operator.assignment.powershell + push: in-assignment + + in-assignment: + - include: command-ending-sequences + # INFO: Someday maybe we can nix the workflow stuff + - include: workflow-execution-contexts + - include: expressions + redirection: # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection - match: ([2-6*])(>&)(1) diff --git a/Tests/syntax_test_Pester.ps1 b/Tests/syntax_test_Pester.ps1 new file mode 100644 index 00000000..6dfbb125 --- /dev/null +++ b/Tests/syntax_test_Pester.ps1 @@ -0,0 +1,61 @@ +# SYNTAX TEST "Packages/PowerShell/PowerShell.sublime-syntax" + +BeforeAll { + # your function + function Get-Planet ([string]$Name='*') +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ keyword.operator.assignment.powershell +# ^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.parameters.end.powershell + { + $planets = @( + @{ Name = 'Mercury' } + @{ Name = 'Venus' } + @{ Name = 'Earth' } + @{ Name = 'Mars' } + @{ Name = 'Jupiter' } + @{ Name = 'Saturn' } + @{ Name = 'Uranus' } + @{ Name = 'Neptune' } + ) | foreach { [PSCustomObject]$_ } + + $planets | where { $_.Name -like $Name } + } +} + +# Pester tests +Describe 'Get-Planet' { + It "Given no parameters, it lists all 8 planets" { + $allPlanets = Get-Planet + $allPlanets.Count | Should -Be 8 + } + + Context "Filtering by Name" { + It "Given valid -Name '', it returns ''" -TestCases @( + @{ Filter = 'Earth'; Expected = 'Earth' } + @{ Filter = 'ne*' ; Expected = 'Neptune' } + @{ Filter = 'ur*' ; Expected = 'Uranus' } + @{ Filter = 'm*' ; Expected = 'Mercury', 'Mars' } + ) { + param ($Filter, $Expected) + + $planets = Get-Planet -Name $Filter + $planets.Name | Should -Be $Expected + } + + It "Given invalid parameter -Name 'Alpha Centauri', it returns `$null" { + $planets = Get-Planet -Name 'Alpha Centauri' + $planets | Should -Be $null + } + } +} diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 177344b1..e47887ca 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1423,7 +1423,7 @@ class Vehicle { # ^ punctuation.definition.variable.powershell # ^ punctuation.accessor.dot.powershell # ^^^^^^^ variable.other.member.powershell -# ^^ keyword.operator.assignment.powershell +# ^^ keyword.operator.assignment.augmented.powershell # ^^^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell diff --git a/Tests/syntax_test_Workflow.ps1 b/Tests/syntax_test_Workflow.ps1 index 94d4e66d..be0bbb72 100644 --- a/Tests/syntax_test_Workflow.ps1 +++ b/Tests/syntax_test_Workflow.ps1 @@ -66,6 +66,19 @@ ## $Using imports the variable and its current value. inlinescript {"Inline A1 = $Using:a"} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^^^^^^^^^^^^ keyword.control.context.powershell +# ^ punctuation.section.block.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^ meta.interpolation.powershell variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ storage.modifier.scope.powershell +# ^ punctuation.accessor.colon.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.end.powershell +# ^ punctuation.section.block.end.powershell } Test-Workflow # @@@@@@@@@@@@@ reference @@ -86,6 +99,26 @@ ## To change the variable in workflow scope, return the ## new value. $a = inlinescript {$b = $Using:a+1; $b} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^^^^^^^^^^^^ keyword.control.context.powershell +# ^ punctuation.section.block.begin.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ storage.modifier.scope.powershell +# ^ punctuation.accessor.colon.powershell +# ^ keyword.operator.unary.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.terminator.statement.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.block.end.powershell "Workflow New A = $a" } Test-Workflow From e1311dc81ba0e7bc43f2dac569450dba56a302cb Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 20:43:26 -0500 Subject: [PATCH 087/133] Recognize wildcards in unquoted strings --- PowerShell.sublime-syntax | 10 +++++++++- Tests/syntax_test_PowerShell.ps1 | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 6df19da9..35b861bb 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -374,6 +374,7 @@ contexts: pop: 1 - include: path-punctuation - include: escape-sequences + - include: string-wildcards command-ending-sequences: - include: line-continuations @@ -889,8 +890,9 @@ contexts: scope: keyword.operator.arithmetic.powershell - match: -(?![[:alpha:]-]) scope: keyword.operator.arithmetic.powershell - - match: \* + - match: \*(?!\.?[[:alpha:]]) scope: keyword.operator.arithmetic.powershell + # Exclude foreach shortcut - match: '%(?!\s*\{)' scope: keyword.operator.arithmetic.powershell - match: \|\||&& @@ -1115,6 +1117,12 @@ contexts: - match: '[:,;]' scope: punctuation.separator.powershell + string-wildcards: + - match: \* + scope: constant.other.wildcard.asterisk.powershell + - match: \? + scope: constant.other.wildcard.questionmark.powershell + numbers: # Binary numbers - match: \b(0[bB])([01]*)({{int_suffix}}?{{unit_suffix}}?) diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index e47887ca..ef6da678 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -924,8 +924,9 @@ $a3[1..2] ls *.ps1 -recurse # ^^ meta.function-call.powershell variable.function.powershell # @@ reference -# ^ keyword.operator.arithmetic.powershell -# ^^^^ string.unquoted.powershell +# ^^^^^ string.unquoted.powershell +# ^ constant.other.wildcard.asterisk.powershell +# ^ punctuation.separator.powershell # ^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell From e43f4aec1ee6941fd68199bb3deb52e13bc0f43e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 20:56:10 -0500 Subject: [PATCH 088/133] Scope command arguments --- PowerShell.sublime-syntax | 1 + Tests/syntax_test_PowerShell.ps1 | 221 +++++++++++++++++++------------ 2 files changed, 137 insertions(+), 85 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 35b861bb..0ac9e761 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -362,6 +362,7 @@ contexts: push: in-command in-command: + - meta_content_scope: meta.function-call.arguments.powershell - include: command-ending-sequences - include: redirection - include: cli-parameters diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index ef6da678..eebe5dab 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -96,6 +96,7 @@ using namespace System.Management.Automation # ^ keyword.operator.call.powershell # ^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^^^^ meta.string.powershell string.quoted.single.powershell @@ -112,6 +113,7 @@ using namespace System.Management.Automation # ^ keyword.operator.call.powershell # ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell @@ -131,6 +133,7 @@ using namespace System.Management.Automation # ^ keyword.operator.assignment.powershell # ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@ reference +# ^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^ string.unquoted.powershell @@ -138,6 +141,7 @@ using namespace System.Management.Automation Receive-Job $job -Wait # ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@ reference +# ^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell # ^^^^^ variable.parameter.option.powershell @@ -817,109 +821,156 @@ $a3[1..2] ###[ Commands ]################################################################ -# Commands (functions) - Invoke-Something -foobar -#^ support.function -# ^ punctuation.definition.parameter -# ^^^^^^^ variable.parameter.option -#@@@@@@@@@@@@@@@@ reference - Invoke-Something -foobar value -#^ support.function -# ^ punctuation.definition.parameter -# ^^^^^^^ variable.parameter.option -#@@@@@@@@@@@@@@@@ reference - Invoke-Something -foobar:$true -#^ support.function -#@@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^^^^^ variable.parameter.option -# ^ punctuation.definition.variable -# ^^^^ constant.language - Invoke-Something -foobar: $true -#^ support.function -#@@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^^^^^ variable.parameter.option - Invoke-Something -p1 v1 -p2 10 -p3 'value' -switch -verbose -#^ support.function -#@@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option -# ^^ meta.number.integer.decimal constant.numeric.value -# ^^^^^^ - keyword -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option - Invoke-Something (1..20 | Invoke-Something) -p2 'value' -#^ support.function -#@@@@@@@@@@@@@@@@ reference -# @@@@@@@@@@@@@@@@ reference -# ^^ keyword.operator.range - Invoke-Something -p1 v2 -p2 30 | Invoke-Something -switch -#^ support.function -# @@@@@@@@@@@@@@@@ reference -#@@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option -# ^^ meta.number.integer.decimal constant.numeric.value -# ^ keyword.operator.logical.pipe -# ^ support.function -# ^ punctuation.definition.parameter -# ^^^^^^^ variable.parameter.option - keyword - Invoke-Something -p1 { -#^ support.function -#@@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option + Invoke-Something -foobar +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell + Invoke-Something -foobar value +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^ string.unquoted.powershell Invoke-Something -foobar:$true -# ^ support.function +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^^^^^ variable.parameter.option -# ^ punctuation.definition.variable -# ^^^^ constant.language -} | Invoke-Something -# <- punctuation.section.braces.end -# ^ keyword.operator.logical.pipe -# ^ support.function +# ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^ keyword.operator.ternary.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + Invoke-Something -foobar: $true +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference - Invoke-Something -p1 value ` -#^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell -#@@@@@@@@@@@@@@@@ reference -# ^^^ variable.parameter.option.powershell -# ^ punctuation.definition.parameter.powershell -# ^^^^^ string.unquoted.powershell -# ^ punctuation.separator.continuation.line.powershell +# ^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^ keyword.operator.ternary.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + Invoke-Something -p1 v1 -p2 10 -p3 'value' -switch -verbose +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ string.unquoted.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell + Invoke-Something (1..20 | Invoke-Something) -p2 'value' +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^ keyword.operator.range.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ keyword.operator.logical.pipe.powershell +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^ punctuation.section.group.end.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + Invoke-Something -p1 v2 -p2 30 | Invoke-Something -switch +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ string.unquoted.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ keyword.operator.logical.pipe.powershell +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell + Invoke-Something -p1 { +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^ meta.function-call.arguments.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell + Invoke-Something -foobar:$true +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^ keyword.operator.ternary.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell + } | Invoke-Something +#^^^^^^^^^ meta.function-call.arguments.powershell +#^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.end.powershell +# ^ keyword.operator.logical.pipe.powershell +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference + + Invoke-Something -p1 value ` +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^ string.unquoted.powershell +# ^ punctuation.separator.continuation.line.powershell -p2 14.4 ` -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option -# ^^^^ meta.number.float.decimal constant.numeric.value -# ^ punctuation.separator.continuation +#^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell +# ^ punctuation.separator.continuation.line.powershell -p3 $value | Invoke-Something -verbose -# ^ punctuation.definition.parameter -# ^^^ variable.parameter.option +#^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.logical.pipe.powershell +# ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference -# ^ punctuation.definition.parameter -# ^^^^^^^^ variable.parameter.option -# ^ punctuation.definition.variable -# ^ keyword.operator.logical.pipe -# ^^^^^^^^^^^^^^^^ support.function +# ^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell Get-ChildItem | # ^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell # ^ keyword.operator.logical.pipe.powershell Select Name,Length # ^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@ reference +# ^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^ string.unquoted.powershell # ^ punctuation.separator.sequence.powershell # ^^^^^^ string.unquoted.powershell - # Commands (Built-in variables) ls *.ps1 -recurse # ^^ meta.function-call.powershell variable.function.powershell From 3787a872f2a3be5ac11150cc7d6bea7d4a36a831 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 20:57:45 -0500 Subject: [PATCH 089/133] Allow indented comments in line continuation --- PowerShell.sublime-syntax | 2 +- Tests/syntax_test_PowerShell.ps1 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 0ac9e761..c69559f7 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1270,7 +1270,7 @@ contexts: 1: invalid.illegal.unexpected-whitespace.powershell line-continuation-body: - - match: ^ + - match: ^(?!\s*#) pop: 1 comma-separators: diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index eebe5dab..87b38ae3 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -945,6 +945,7 @@ $a3[1..2] # ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell # ^ punctuation.separator.continuation.line.powershell + # An indented comment doesn't interrupt line continuation -p3 $value | Invoke-Something -verbose #^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^ variable.parameter.option.powershell From 82b979446ccbc78f65d69250f884073786821b23 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 8 Dec 2025 21:34:17 -0500 Subject: [PATCH 090/133] Add naive regex in single-quoted strings following regex operators --- PowerShell.sublime-syntax | 26 +++++- Tests/syntax_test_strings.ps1 | 171 ++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c69559f7..cf6e7e8c 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -850,11 +850,21 @@ contexts: scope: keyword.operator.comparison.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:[ic]?(?:not)?(?:like|match|contains|in)){{kebab_break}} + - match: \B(-)(?i:[ic]?(?:not)?(?:match)){{kebab_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:join|split|replace){{kebab_break}} + push: expect-regex-string + - match: \B(-)(?i:[ic]?(?:not)?(?:like|contains|in)){{kebab_break}} + scope: keyword.operator.logical.powershell + captures: + 1: punctuation.definition.keyword.powershell + - match: \B(-)(?i:replace){{kebab_break}} + scope: keyword.operator.string.powershell + captures: + 1: punctuation.definition.keyword.powershell + push: expect-regex-string + - match: \B(-)(?i:join|split){{kebab_break}} scope: keyword.operator.string.powershell captures: 1: punctuation.definition.keyword.powershell @@ -995,6 +1005,18 @@ contexts: - include: double-quoted-heredoc-strings - include: single-quoted-heredoc-strings + expect-regex-string: + - match: '{{single_quote}}' + scope: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell + embed: scope:source.regexp + embed_scope: meta.string.powershell source.regexp.embedded + escape: ({{single_quote}}) + escape_captures: + 1: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell + - include: comma-separators + - include: else-pop + - include: pop-eol + single-quoted-strings: - match: '{{single_quote}}' scope: punctuation.definition.string.begin.powershell diff --git a/Tests/syntax_test_strings.ps1 b/Tests/syntax_test_strings.ps1 index 9d68c1a5..05962bb2 100644 --- a/Tests/syntax_test_strings.ps1 +++ b/Tests/syntax_test_strings.ps1 @@ -238,6 +238,177 @@ "@ +###[ Regular Expressions ]##################################################### + + 'book' -match 'oo' +# ^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'big' -match 'b[iou]g' +# ^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 42 -match '[0-9][0-9]' +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'a1\ ' -match '....' +# ^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^ source.regexp.embedded keyword.other.any.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'ACCOUNT NAME: Administrator' -match 'ACCOUNT NAME:\s*\w*' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^ source.regexp.embedded +# ^^ keyword.control.character-class.regexp +# ^ keyword.operator.quantifier.regexp +# ^^ keyword.control.character-class.regexp +# ^ keyword.operator.quantifier.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'SERVER01' -match '[A-Z]+-?\d\d' +# ^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^ source.regexp.embedded +# ^^^^^ meta.set.regexp +# ^ keyword.operator.quantifier.regexp +# ^ keyword.operator.quantifier.regexp +# ^^^^ keyword.control.character-class.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + '111-222-3333' -match '\d{3}-\d{3}-\d{4}' +# ^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^ source.regexp.embedded +# ^^ keyword.control.character-class.regexp +# ^^^ keyword.operator.quantifier.regexp +# ^^ keyword.control.character-class.regexp +# ^^^ keyword.operator.quantifier.regexp +# ^^ keyword.control.character-class.regexp +# ^^^ keyword.operator.quantifier.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'fishing' -match '^fish$' +# ^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^ source.regexp.embedded +# ^ keyword.control +# ^ keyword.control +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + '3.141' -match '3\.\d{2,}' +# ^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^ source.regexp.embedded +# ^^ constant.character.escape.regexp +# ^^ keyword.control.character-class.regexp +# ^^^^ keyword.operator.quantifier.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'The last logged on user was CONTOSO\jsmith' -match '(.+was )(.+)' +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^ source.regexp.embedded +# ^ keyword.other.any.regexp +# ^ keyword.operator.quantifier.regexp +# ^ keyword.other.any.regexp +# ^ keyword.operator.quantifier.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + $string -match 'was (?.+)\\(?.+)' +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ keyword.operator.logical.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + 'Hello World' -replace '(\w+) \w+', '$1 Universe' +# ^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^^^ keyword.operator.string.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^ source.regexp.embedded +# ^^ keyword.control.character-class.regexp +# ^ keyword.operator.quantifier.regexp +# ^^ keyword.control.character-class.regexp +# ^ keyword.operator.quantifier.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + "Hello World" -replace "(\w+) \w+", "`$1 Universe" + '5.72' -replace '(.+)', '$$$1' +# ^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^^^^^^^ keyword.operator.string.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^ source.regexp.embedded +# ^ keyword.other.any.regexp +# ^ keyword.operator.quantifier.regexp +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell + "5.72" -replace "(.+)", "`$`$`$1" + ###[ String Formatting ]####################################################### "{0:N2}" -f $a From d3537a95589455f5f39b3c435f931e14e13bf989 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 09:13:31 -0500 Subject: [PATCH 091/133] Sort operators some more --- PowerShell.sublime-syntax | 67 +++++++++++++++++++------------- Tests/syntax_test_PowerShell.ps1 | 16 ++++---- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index cf6e7e8c..4d07d42c 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -363,7 +363,7 @@ contexts: in-command: - meta_content_scope: meta.function-call.arguments.powershell - - include: command-ending-sequences + - include: pop-end-of-command - include: redirection - include: cli-parameters - include: expressions-without-commands @@ -377,22 +377,28 @@ contexts: - include: escape-sequences - include: string-wildcards - command-ending-sequences: + pop-end-of-command: - include: line-continuations - include: pop-eol - match: (?=[)}]) pop: 1 + - include: pop-terminator + - include: pop-pipe + + pop-terminator: - match: ';' scope: punctuation.terminator.statement.powershell pop: 1 + + pop-pipe: - match: (\|)\s*\n captures: - 1: keyword.operator.logical.pipe.powershell + 1: keyword.operator.assignment.pipe.powershell push: - match: ^ pop: 2 - match: \| - scope: keyword.operator.logical.pipe.powershell + scope: keyword.operator.assignment.pipe.powershell pop: 1 cli-parameters: @@ -841,7 +847,22 @@ contexts: ###[ OPERATORS ]############################################################### operators: - # Word operators + - include: operator-words + - include: operator-symbols + + operator-words: + # RegExp context + - match: \B(-)(?i:[ic]?(?:not)?(?:match)){{kebab_break}} + scope: keyword.operator.logical.powershell + captures: + 1: punctuation.definition.keyword.powershell + push: expect-regex-string + - match: \B(-)(?i:replace){{kebab_break}} + scope: keyword.operator.string.powershell + captures: + 1: punctuation.definition.keyword.powershell + push: expect-regex-string + - match: \B(-)(?i:as){{kebab_break}} scope: keyword.operator.cast.powershell captures: @@ -850,20 +871,10 @@ contexts: scope: keyword.operator.comparison.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:[ic]?(?:not)?(?:match)){{kebab_break}} - scope: keyword.operator.logical.powershell - captures: - 1: punctuation.definition.keyword.powershell - push: expect-regex-string - match: \B(-)(?i:[ic]?(?:not)?(?:like|contains|in)){{kebab_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:replace){{kebab_break}} - scope: keyword.operator.string.powershell - captures: - 1: punctuation.definition.keyword.powershell - push: expect-regex-string - match: \B(-)(?i:join|split){{kebab_break}} scope: keyword.operator.string.powershell captures: @@ -885,31 +896,38 @@ contexts: captures: 1: punctuation.definition.keyword.powershell - # Symbol operators - - match: \! - scope: keyword.operator.logical.powershell + operator-symbols: + # Assignment context - include: assignment-normal - match: (?:[+/*%-]|\?\?)= scope: keyword.operator.assignment.augmented.powershell push: in-assignment + # Assignment same context + - match: \| + scope: keyword.operator.assignment.pipe.powershell - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) scope: keyword.operator.assignment.powershell - - match: '[+-](?=\.?\d)' # This is sort of heuristic + + # Heuristically guess the context with lookaheads + # Mostly to avoid matching CLI parameters + - match: '[+-](?=\.?\d)' scope: keyword.operator.unary.powershell - # Be careful about matching arithmetic with tightly following words - match: '[/+](?![[:alpha:]])' scope: keyword.operator.arithmetic.powershell - match: -(?![[:alpha:]-]) scope: keyword.operator.arithmetic.powershell - match: \*(?!\.?[[:alpha:]]) scope: keyword.operator.arithmetic.powershell + - match: \.\.(?=\-?\d|\(|\$) + scope: keyword.operator.range.powershell # Exclude foreach shortcut - match: '%(?!\s*\{)' scope: keyword.operator.arithmetic.powershell + + - match: \! + scope: keyword.operator.logical.powershell - match: \|\||&& scope: keyword.operator.logical.powershell - - match: \| - scope: keyword.operator.logical.pipe.powershell - match: \?\? scope: keyword.operator.null-coalescing.powershell - match: '[?:]' @@ -919,9 +937,6 @@ contexts: - include: comma-separators - match: '&' scope: keyword.operator.background.powershell - - match: \.\.(?=\-?\d|\(|\$) - # This is very imprecise. Is there a syntax for 'must come after...'? - scope: keyword.operator.range.powershell assignment-normal: - match: = @@ -929,7 +944,7 @@ contexts: push: in-assignment in-assignment: - - include: command-ending-sequences + - include: pop-end-of-command # INFO: Someday maybe we can nix the workflow stuff - include: workflow-execution-contexts - include: expressions diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 87b38ae3..a1f6605d 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -880,7 +880,7 @@ $a3[1..2] # ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell # ^^ keyword.operator.range.powershell # ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ keyword.operator.logical.pipe.powershell +# ^ keyword.operator.assignment.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference # ^ punctuation.section.group.end.powershell @@ -899,7 +899,7 @@ $a3[1..2] # ^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ keyword.operator.logical.pipe.powershell +# ^ keyword.operator.assignment.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference # ^^^^^^^^ meta.function-call.arguments.powershell @@ -926,7 +926,7 @@ $a3[1..2] #^^^^^^^^^ meta.function-call.arguments.powershell #^^^^^^^^ meta.block.powershell # ^ punctuation.section.braces.end.powershell -# ^ keyword.operator.logical.pipe.powershell +# ^ keyword.operator.assignment.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference @@ -952,7 +952,7 @@ $a3[1..2] # ^ punctuation.definition.parameter.powershell # ^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^ keyword.operator.logical.pipe.powershell +# ^ keyword.operator.assignment.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference # ^^^^^^^^^ meta.function-call.arguments.powershell @@ -963,7 +963,7 @@ $a3[1..2] # ^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@ reference # ^^ meta.function-call.arguments.powershell -# ^ keyword.operator.logical.pipe.powershell +# ^ keyword.operator.assignment.pipe.powershell Select Name,Length # ^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@ reference @@ -2115,7 +2115,7 @@ function out-file {} $ScriptBlock | Out-File $file -Force # <- punctuation.definition.variable # @@@@@@@@ reference -# ^ keyword.operator.logical.pipe +# ^ keyword.operator.assignment.pipe # ^ punctuation.definition.variable # ^ punctuation.definition.parameter # ^^^^^^ variable.parameter.option @@ -2128,7 +2128,7 @@ function Out-WithYou {} #@@@@@@@@@ reference # ^^^^^^^^^^^ support.function # @@@@@@@@@@@ reference -# ^ keyword.operator.logical.pipe +# ^ keyword.operator.assignment.pipe # ^ keyword.operator.redirection # ^ punctuation.definition.variable # ^ constant.language @@ -2142,7 +2142,7 @@ function get-number {} # @@@@@@@@@@ reference # @@@@@@@@@@@@@@ reference # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.powershell.embedded -# ^ keyword.operator.logical.pipe +# ^ keyword.operator.assignment.pipe # ^ meta.group.complex.subexpression punctuation.section.group.begin # ^^^^^^ storage.type # ^^ punctuation.accessor.double-colon From cfe20244d2251f649bd1e243253843e6f53e924c Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 09:31:47 -0500 Subject: [PATCH 092/133] Fix CLI args with assignment --- PowerShell.sublime-syntax | 8 +++++--- Tests/syntax_test_PowerShell.ps1 | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 4d07d42c..8f4e626d 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -403,10 +403,12 @@ contexts: cli-parameters: # Flags/Options/Parameters - - match: \B(--?|[/+])\p{L}(?:[\w-]*\w)? - scope: variable.parameter.option.powershell + - match: \B((--?|[/+])\p{L}(?:[\w-]*\w)?)([=:])? + scope: captures: - 1: punctuation.definition.parameter.powershell + 1: variable.parameter.option.powershell + 2: punctuation.definition.parameter.powershell + 3: keyword.operator.assignment.powershell ###[ DIRECTIVES ]############################################################## diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index a1f6605d..d0dfee57 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -840,7 +840,7 @@ $a3[1..2] # ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell -# ^ keyword.operator.ternary.powershell +# ^ keyword.operator.assignment.powershell # ^^^^^ constant.language.boolean.true.powershell # ^ punctuation.definition.variable.powershell Invoke-Something -foobar: $true @@ -849,7 +849,7 @@ $a3[1..2] # ^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell -# ^ keyword.operator.ternary.powershell +# ^ keyword.operator.assignment.powershell # ^^^^^ constant.language.boolean.true.powershell # ^ punctuation.definition.variable.powershell Invoke-Something -p1 v1 -p2 10 -p3 'value' -switch -verbose @@ -919,7 +919,7 @@ $a3[1..2] # ^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell -# ^ keyword.operator.ternary.powershell +# ^ keyword.operator.assignment.powershell # ^^^^^ constant.language.boolean.true.powershell # ^ punctuation.definition.variable.powershell } | Invoke-Something From 7e7f4b38ed6a5c08f9c719622185fb76d3020193 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 09:43:57 -0500 Subject: [PATCH 093/133] Move and rename the stop-parsing token --- PowerShell.sublime-syntax | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 8f4e626d..52d46e63 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -76,7 +76,7 @@ contexts: - include: requires-directives - include: escape-sequences - - include: literal-after + - include: stop-parsing-token # Normal code - include: types @@ -105,7 +105,7 @@ contexts: - include: requires-directives - include: escape-sequences - - include: literal-after + - include: stop-parsing-token # Normal code - include: types @@ -126,14 +126,6 @@ contexts: - include: operators - literal-after: - - match: \B--%\B - scope: keyword.control.powershell - push: - - meta_include_prototype: false - - meta_content_scope: string.unquoted.powershell - - include: pop-before-eol - future-reserved-words: # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words - match: \b(?i:define|from){{kebab_break}} @@ -1295,6 +1287,14 @@ contexts: ###[ COMPONENTS ]############################################################## + stop-parsing-token: + - match: \B--%\B + scope: keyword.control.powershell + push: + - meta_include_prototype: false + - meta_content_scope: string.unquoted.powershell + - include: pop-before-eol + path-punctuation: - match: '[:/\\.]+' scope: punctuation.separator.powershell From 91196f0cb5c435a277965d5a9322375fb73db631 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 10:21:43 -0500 Subject: [PATCH 094/133] Indent more of the main test file --- Tests/syntax_test_Pester.ps1 | 8 + Tests/syntax_test_PowerShell.ps1 | 1326 +++++++++++++++++------------- 2 files changed, 776 insertions(+), 558 deletions(-) diff --git a/Tests/syntax_test_Pester.ps1 b/Tests/syntax_test_Pester.ps1 index 6dfbb125..d52ea208 100644 --- a/Tests/syntax_test_Pester.ps1 +++ b/Tests/syntax_test_Pester.ps1 @@ -54,6 +54,14 @@ Describe 'Get-Planet' { } It "Given invalid parameter -Name 'Alpha Centauri', it returns `$null" { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell meta.function-call.arguments.powershell meta.block.powershell +# ^^ meta.function-call.powershell variable.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.string.end.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell $planets = Get-Planet -Name 'Alpha Centauri' $planets | Should -Be $null } diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index d0dfee57..2a3d28f2 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1024,512 +1024,660 @@ $a3[1..2] # ^ punctuation.separator.powershell # ^ punctuation.definition.string.end.powershell -# switch -switch ("fourteen") {} -# <- keyword.control -# ^ punctuation.section.group.begin -# ^ string.quoted.double -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -switch -CaseSensitive ("fourteen") {} -# <- keyword.control -# ^ punctuation.definition.parameter -# ^^^^^^^^^^^^^^ variable.parameter.option -# ^ punctuation.section.group.begin -# ^ string.quoted.double -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -switch -Regex ("fourteen") {} -# <- keyword.control -# ^ punctuation.definition.parameter -# ^^^^^^ variable.parameter.option -# ^ punctuation.section.group.begin -# ^ string.quoted.double -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -switch -Wildcard ($a) {} -# <- keyword.control -# ^ punctuation.definition.parameter -# ^^^^^^^^^ variable.parameter.option -# ^ punctuation.section.group.begin -# ^ punctuation.definition.variable -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -switch -regex -file .\somefile.txt {} -# <- keyword.control -# ^ punctuation.definition.parameter -# ^^^^^^ variable.parameter.option -# ^ punctuation.definition.parameter -# ^^^^ variable.parameter.option -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -switch (3) {} -# <- keyword.control -# ^ punctuation.section.group.begin -# ^ meta.number.integer.decimal constant.numeric.value -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -switch (4, 2) {} -# <- keyword.control -# ^ punctuation.section.group.begin -# ^ meta.number.integer.decimal constant.numeric.value -# ^ meta.number.integer.decimal constant.numeric.value -# ^ punctuation.separator -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end - -switch -Regex -File $filePath { -# <- keyword.control -# ^ punctuation.definition.parameter -# ^^^^^^ variable.parameter.option -# ^ punctuation.definition.parameter -# ^^^^ variable.parameter.option -# ^ punctuation.definition.variable -# ^ meta.block punctuation.section.braces.begin - '.' {} -# ^^^ string.quoted.single -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end - default {} -# ^^^^^^^ keyword.control -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -} -# <- meta.block punctuation.section.braces.end - -switch -Wildcard -CaseSensitive ($something) { -# <- keyword.control -# ^ punctuation.definition.parameter -# ^^^^^^^^^ variable.parameter.option -# ^ punctuation.definition.parameter -# ^^^^^^^^^^^^^^ variable.parameter.option -# ^ punctuation.section.group.begin -# ^ punctuation.definition.variable -# ^ variable.other.readwrite -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin - '.' {} -# ^^^ string.quoted.single -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end - default {} -# ^^^^^^^ keyword.control -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -} -# <- meta.block punctuation.section.braces.end - -switch ('this') { -# <- keyword.control -# ^ punctuation.section.group.begin -# ^^^^^^ string.quoted.single -# ^ punctuation.section.group.end -# ^ meta.block punctuation.section.braces.begin - 'this' {} -# ^^^^^^ string.quoted.single -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end - default {} -# ^^^^^^^ keyword.control -# ^ meta.block punctuation.section.braces.begin -# ^ meta.block punctuation.section.braces.end -} -# <- meta.block punctuation.section.braces.end - - data { - "Thank you for using my PowerShell Organize.pst script." -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.data.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell + # switch + switch ("fourteen") {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + switch -CaseSensitive ("fourteen") {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + switch -Regex ("fourteen") {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + switch -Wildcard ($a) {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.group.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + switch -regex -file .\somefile.txt {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^ string.unquoted.powershell +# ^^ punctuation.separator.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + switch (3) {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^ meta.function-call.arguments.powershell +# ^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.group.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + switch (4, 2) {} +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.sequence.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.group.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + + switch -Regex -File $filePath { +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell + '.' {} +#^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^ meta.string.powershell string.quoted.single.powershell # ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell - "It is provided free of charge to the community." - "I appreciate your comments and feedback." +# ^ punctuation.definition.string.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + default {} +#^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^^^^^ keyword.control.conditional.default.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell } -# ^ - meta - -# Functions and filters -functioN MyFunction{} -#^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -# ^ - meta -function My-Function {} -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -Function My.Function{} -#^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -function My-Function.Other{} -#^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -function Some.other.function{} -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -FUNCTION MyFunction2 {} -#^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -function New-File { } -#^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^ entity.name.function.powershell -# @@@@@@@@ definition -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -function New-File ($Name) { } -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^ entity.name.function.powershell -# @@@@@@@@ definition - New-File -#^^^^^^^^ meta.function-call.powershell support.function.powershell -#@@@@@@@@ reference -function NewFile($Name) { } -#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^ entity.name.function.powershell -# @@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell -filter myfilter($param) {} +#^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^ punctuation.section.braces.end.powershell + + switch -Wildcard -CaseSensitive ($something) { +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.group.end.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell + '.' {} +#^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + default {} +#^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^^^^^ keyword.control.conditional.default.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + } +#^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^ punctuation.section.braces.end.powershell + + switch ('this') { +# ^^^^^^ keyword.control.conditional.switch.powershell +# ^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell + 'this' {} +#^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + default {} +#^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^^^^^^^ keyword.control.conditional.default.powershell +# ^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + } +#^^^^ meta.function-call.arguments.powershell meta.block.powershell +# ^ punctuation.section.braces.end.powershell + + data { + "Thank you for using my PowerShell Organize.pst script." +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.data.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + "It is provided free of charge to the community." + "I appreciate your comments and feedback." + } +#^^^^^^^^ meta.block.data.powershell +# ^ punctuation.section.block.end.powershell + +# <- - meta + + # Functions and filters + functioN MyFunction{} +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# @@@@@@@@@@ definition +# ^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell +# ^ - meta + function My-Function {} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# @@@@@@@@@@@ definition +# ^^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + Function My.Function{} #^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^ entity.name.function.powershell -# @@@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# @@@@@@@@@@@ definition +# ^^^^^^^^^^^ entity.name.function.powershell # ^ punctuation.section.block.begin.powershell # ^ punctuation.section.block.end.powershell -Filter my-Filter ($param){} + function My-Function.Other{} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# @@@@@@@@@@@@@@@@@ definition +# ^^^^^^^^^^^^^^^^^ entity.name.function.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + function Some.other.function{} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + FUNCTION MyFunction2 {} #^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@ definition # ^ punctuation.section.block.begin.powershell # ^ punctuation.section.block.end.powershell - -# Note that the # in the path should highlight as a comment! -function Test-Drive([string]$roman) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@ definition + function New-File { } +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell +# @@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + function New-File ($Name) { } +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell +# @@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + New-File +# ^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@ reference + function NewFile($Name) { } +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + filter myfilter($param) {} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell +# @@@@@@@@ definition # ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell - $roman | c:\users\Me\Documents\Programming\F#\test.exe $roman -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell -# ^ meta.function-call.powershell variable.function.powershell -# @ reference -# ^ keyword.operator.ternary.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^^^^^^^^^^^^^^^^^ comment.line.powershell -# ^ punctuation.definition.comment.powershell - } -#^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell - -function Verb-Noun -#^^^^^^^^^^^^^^^^^ meta.function.powershell -#^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@ definition - { -#^^^^ meta.function.powershell -# ^ punctuation.section.block.begin.powershell - - Param - #^^^^^ keyword.declaration.parameter - ( -#^^^^ meta.function.powershell -# ^ punctuation.section.block.begin.powershell - # Param1 help description - # <- comment.line punctuation.definition.comment - # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line - [Parameter(Mandatory=$true, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^ support.function.attribute - # ^ punctuation.section.group.begin - # ^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^ constant.language - # ^ punctuation.separator - ValueFromPipeline=$true, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^ constant.language - # ^ punctuation.separator - ValueFromPipelineByPropertyName = $true, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^^ constant.language - # ^ punctuation.separator - ValueFromRemainingArguments=$false, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^^ constant.language - # ^ punctuation.separator - Position=0, - #^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ meta.number.integer.decimal constant.numeric.value - # ^ punctuation.separator - SupportsPaging, - #^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ punctuation.separator - ParameterSetName = 'Parameter Set 1')] - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^^^^^^^^^^^^^^^^^ string.quoted.single - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - # ^ - meta.attribute - [ValidateNotNullOrEmpty()] - #^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^^^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - [ValidateNotNull()] - #^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - [ValidateNotNullOrEmpty()] - #^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^^^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - [ValidateCount(0,5)] - #^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^ meta.number.integer.decimal constant.numeric.value - # ^ punctuation.separator - # ^ meta.number.integer.decimal constant.numeric.value - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - [ValidateSet("sun", "moon", "earth")] - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^ support.function.attribute - # ^ punctuation.section.group.begin - # ^^^^ string.quoted.double - # ^ punctuation.separator - # ^^^^^^ string.quoted.double - # ^ punctuation.separator - # ^^^^^^^ string.quoted.double - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - [Alias("p1")] - #^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^ support.function.attribute - # ^ punctuation.section.group.begin - # ^^^^ string.quoted.double - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - $Param1 - # <- punctuation.definition.variable - # ^ variable.other.readwrite - ) -#^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell - - # Do Something.... - - } -#^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell - -# Class -class Vehicle { -#^^^^^^^^^^^^^^ meta.class.powershell -#^^^^ keyword.declaration.class.powershell -# ^^^^^^^ entity.name.class.powershell -# @@@@@@@ definition -# ^ punctuation.section.block.begin.powershell - Vehicle() {} -#^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^ entity.name.function.powershell -# @@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell - Vehicle([string]$Owner) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^ entity.name.function.powershell -# @@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell # ^^^^^^ variable.parameter.powershell # ^ punctuation.definition.variable.begin.powershell # ^ punctuation.section.parameters.end.powershell # ^ punctuation.section.block.begin.powershell - $this.Owner = $Owner - } - - [int]$Mileage -# ^ storage.type -# ^ punctuation.definition.variable -# ^ variable.other.readwrite - [int]$Age -# ^ storage.type -# ^ punctuation.definition.variable -# ^ variable.other.readwrite - [string]$Owner -# ^ storage.type -# ^ punctuation.definition.variable -# ^ variable.other.readwrite +# ^ punctuation.section.block.end.powershell + Filter my-Filter ($param){} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell - [void]Drive([int]$NumberOfMiles) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^ entity.name.function.powershell -# @@@@@ definition + function Test-Drive([string]$roman) { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + $roman | c:\users\Me\Documents\Programming\F#\test.exe $roman +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.pipe.powershell +# ^ meta.function-call.powershell variable.function.powershell +# @ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^ keyword.operator.ternary.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.separator.powershell +# ^^^^^^^^^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment.powershell + $roman | c:\users\Me\Documents\Programming\F\test.exe $roman +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.pipe.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference +# ^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + } +#^^^^^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell + + function Verb-Noun +#^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@ definition + { +#^^^^^^^^ meta.function.powershell +# ^ punctuation.section.block.begin.powershell + + Param +#^^^^^^^^^^^^ meta.function.powershell +# ^^^^^ keyword.declaration.parameter.powershell + ( +#^^^^^^^^ meta.function.powershell +# ^ punctuation.section.block.begin.powershell + # Param1 help description + # <- comment.line punctuation.definition.comment + # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line + [Parameter(Mandatory=$true, +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell + ValueFromPipeline=$true, +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell + ValueFromPipelineByPropertyName = $true, +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell + ValueFromRemainingArguments=$false, +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^ constant.language.boolean.false.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell + Position=0, +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.sequence.powershell + SupportsPaging, +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ punctuation.separator.sequence.powershell + ParameterSetName = 'Parameter Set 1')] +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [ValidateNotNullOrEmpty()] +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [ValidateNotNull()] +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [ValidateNotNullOrEmpty()] +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [ValidateCount(0,5)] +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.sequence.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [ValidateSet("sun", "moon", "earth")] +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [Alias("p1")] +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + $Param1 +#^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + ) +#^^^^^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell + + # Do Something.... + + } +#^^^^^^^^ meta.function.powershell +# ^ punctuation.section.block.end.powershell + + # Class + class Vehicle { +# ^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^ keyword.declaration.class.powershell +# ^^^^^^^ entity.name.class.powershell +# @@@@@@@ definition +# ^ punctuation.section.block.begin.powershell + Vehicle() {} +#^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + Vehicle([string]$Owner) { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition # ^ punctuation.section.parameters.begin.powershell # ^ punctuation.section.brackets.begin.powershell -# ^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^^^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell - $this.Mileage += $NumberOfMiles -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell -# ^^^^^ variable.language.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^^^^ variable.other.member.powershell -# ^^ keyword.operator.assignment.augmented.powershell -# ^^^^^^^^^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + $this.Owner = $Owner +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ variable.other.member.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + } +#^^^^^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell + + [int]$Mileage +#^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + [int]$Age +#^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + [string]$Owner +#^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + [void]Drive([int]$NumberOfMiles) { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^ entity.name.function.powershell +# @@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + $this.Mileage += $NumberOfMiles +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^ variable.other.member.powershell +# ^^ keyword.operator.assignment.augmented.powershell +# ^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + + } +#^^^^^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell + + static [System.Array] GetAvailableColors() { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^ storage.modifier.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + return 'yellow', 'red' +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^^ keyword.control.flow.return.powershell +# ^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + } +#^^^^^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell } -#^^^^ meta.class.powershell meta.function.powershell +#^^^^ meta.class.powershell # ^ punctuation.section.block.end.powershell - static [System.Array] GetAvailableColors() { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^^ storage.modifier.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^ meta.generic-name.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@@@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell - return 'yellow', 'red' + $fiat.Drive(42) +#^^^ meta.class.powershell +# ^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@ reference +# ^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.arguments.end.powershell + [Vehicle]::GetAvailableColors() +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell + + # Control words + foreach ($item in $collection) { +# ^^^^^^^ keyword.control.loop.for.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^ keyword.control.loop.in.powershell +# ^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.group.end.powershell +# ^ meta.block.powershell punctuation.section.braces.begin.powershell } -} -# <- punctuation.section.block.end - -$fiat.Drive(42) -# ^^^^^ meta.function-call -# @@@@@ reference -[Vehicle]::GetAvailableColors() -# ^^^^^^^^^^^^^^^^^^ meta.function-call variable.function -# @@@@@@@@@@@@@@@@@@ reference - -# Control words -foreach ($item in $collection) { -# <- keyword.control -# ^ punctuation.section.group.begin -# ^^ keyword.control -# ^ punctuation.section.group.end -# ^ punctuation.section.braces.begin -# ^ punctuation.definition.variable -# ^ punctuation.definition.variable -} -# <- punctuation.section.braces.end - -try { } -# <- keyword.control -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end -catch { } -# <- keyword.control -# ^ punctuation.section.braces.begin -# ^ punctuation.section.braces.end +#^^^^ meta.block.powershell +# ^ punctuation.section.braces.end.powershell + + try { } +# ^^^ keyword.control.exception.try.powershell +# ^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell + catch { } +# ^^^^^ keyword.control.exception.catch.powershell +# ^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^ punctuation.section.braces.end.powershell # Redirection notepad.exe > log.txt @@ -2078,81 +2226,143 @@ catch { } # ^ punctuation.section.braces.end.powershell function join-path {} +#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^ entity.name.function.powershell # @@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell -$file = join-path $env:SystemDrive "$([System.io.path]::GetRandomFileName()).ps1" -#^^^^ variable.other.readwrite.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^^^^^ meta.function-call.powershell support.function.powershell -# @@@@@@@@@ reference -# ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell -# ^^^ support.variable.drive.powershell -# ^ punctuation.accessor.colon.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell -# ^ string.quoted.double.powershell punctuation.definition.string.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell -# ^^ punctuation.section.interpolation.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.powershell.embedded -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^^ meta.generic-name.powershell -# ^ punctuation.accessor.dot.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^ punctuation.accessor.double-colon.powershell -# ^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell -# @@@@@@@@@@@@@@@@@ reference -# ^^ meta.function-call.arguments.powershell -# ^ punctuation.section.arguments.begin.powershell -# ^ punctuation.section.arguments.end.powershell -# ^ punctuation.section.interpolation.end.powershell -# ^^^^^ string.quoted.double.powershell -# ^ punctuation.definition.string.end.powershell - -function out-file {} -# @@@@@@@@ definition -$ScriptBlock | Out-File $file -Force -# <- punctuation.definition.variable -# @@@@@@@@ reference -# ^ keyword.operator.assignment.pipe -# ^ punctuation.definition.variable -# ^ punctuation.definition.parameter -# ^^^^^^ variable.parameter.option -function get-something {} -# @@@@@@@@@@@@@ definition -function Out-WithYou {} -# @@@@@@@@@@@ definition - get-thing | Out-WithYou > $null # destroy -#^^^^^^^^^ support.function -#@@@@@@@@@ reference -# ^^^^^^^^^^^ support.function -# @@@@@@@@@@@ reference -# ^ keyword.operator.assignment.pipe -# ^ keyword.operator.redirection -# ^ punctuation.definition.variable -# ^ constant.language -# ^ punctuation.definition.comment -# ^^^^^^^^^ comment.line - -function get-number {} -# @@@@@@@@@@ definition -"When you call a method: $( get-number | %{ invoke-command $( [string]::format("Like (this{0})","what?") ) $var } )" -# ^^ punctuation.section.interpolation.begin - source.powershell.embedded -# @@@@@@@@@@ reference -# @@@@@@@@@@@@@@ reference -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.powershell.embedded -# ^ keyword.operator.assignment.pipe -# ^ meta.group.complex.subexpression punctuation.section.group.begin -# ^^^^^^ storage.type -# ^^ punctuation.accessor.double-colon -# ^^^^^^ meta.function-call variable.function -# @@@@@@ reference -# ^ meta.group.complex.subexpression punctuation.section.arguments.begin -# ^ meta.group.complex.subexpression punctuation.section.arguments.end -# ^ meta.group.complex.subexpression punctuation.section.group.end -# ^ punctuation.definition.variable -# ^ punctuation.section.interpolation.end - source.powershell.embedded + $file = join-path $env:SystemDrive "$([System.io.path]::GetRandomFileName()).ps1" +# ^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^ support.variable.drive.powershell +# ^ punctuation.accessor.colon.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell +# ^^ punctuation.section.interpolation.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.powershell.embedded +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell +# ^ punctuation.section.interpolation.end.powershell +# ^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.end.powershell + + function out-file {} +#^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^ entity.name.function.powershell +# @@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + $ScriptBlock | Out-File $file -Force +# ^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ keyword.operator.assignment.pipe.powershell +# ^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@ reference +# ^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell + function get-something {} +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + function Out-WithYou {} +#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + get-thing | Out-WithYou > $null # destroy +# ^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@ reference +# ^ meta.function-call.arguments.powershell +# ^ keyword.operator.assignment.pipe.powershell +# ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^ keyword.operator.redirection.powershell +# ^^^^^ constant.language.null.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment.powershell + + function get-number {} +#^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + "When you call a method: $( get-number | %{ invoke-command $( [string]::format("Like (this{0})","what?") ) $var } )" +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.powershell +# ^^ punctuation.section.interpolation.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.powershell.embedded +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^ meta.function-call.arguments.powershell +# ^ keyword.operator.assignment.pipe.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell +# ^ keyword.control.loop.for.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.complex.subexpression.powershell +# ^ keyword.other.variable.definition.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.arguments.end.powershell +# ^ punctuation.section.group.end.powershell +# ^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.section.interpolation.end.powershell +# ^ string.quoted.double.powershell punctuation.definition.string.end.powershell ([MyType])::Name[2] # ^^^^^^^^^^ meta.group.powershell From 1bc064d2932cb1f59a15f4f731261fdd199cde7a Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 10:25:40 -0500 Subject: [PATCH 095/133] Use better patterns for path punctuation --- PowerShell.sublime-syntax | 12 +++++++++-- Tests/syntax_test_PowerShell.ps1 | 34 ++++++++++++-------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 52d46e63..0473ceb2 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1296,8 +1296,16 @@ contexts: - include: pop-before-eol path-punctuation: - - match: '[:/\\.]+' - scope: punctuation.separator.powershell + - match: ':(?=[\\/])' + scope: punctuation.separator.path.powershell + - match: \.\.(?=[\\/]) + scope: constant.other.path.parent.powershell + - match: \.(?=[\\/]) + scope: constant.other.path.self.powershell + - match: ~(?=[\\/]) + scope: variable.language.tilde.powershell + - match: '[\\/]+' + scope: punctuation.separator.path.powershell line-continuations: - match: (`)\n diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 2a3d28f2..59302a95 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -978,7 +978,6 @@ $a3[1..2] # @@ reference # ^^^^^ string.unquoted.powershell # ^ constant.other.wildcard.asterisk.powershell -# ^ punctuation.separator.powershell # ^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell @@ -1008,20 +1007,20 @@ $a3[1..2] & '.\script name with spaces.ps1' # ^ keyword.operator.call.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell meta.function-call.powershell variable.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.string.powershell string.quoted.single.powershell meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference # ^ punctuation.definition.string.begin.powershell -# ^^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ constant.other.path.self.powershell +# ^ punctuation.separator.path.powershell # ^ punctuation.definition.string.end.powershell & ".\script name with spaces.ps1" # ^ keyword.operator.call.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell meta.function-call.powershell variable.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell meta.string.interpolated.powershell string.quoted.double.powershell meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference # ^ punctuation.definition.string.begin.powershell -# ^^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ constant.other.path.self.powershell +# ^ punctuation.separator.path.powershell # ^ punctuation.definition.string.end.powershell # switch @@ -1086,7 +1085,8 @@ $a3[1..2] # ^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^^^^^^^^^^^ string.unquoted.powershell -# ^^ punctuation.separator.powershell +# ^ constant.other.path.self.powershell +# ^ punctuation.separator.path.powershell # ^^ meta.block.powershell # ^ punctuation.section.braces.begin.powershell # ^ punctuation.section.braces.end.powershell @@ -1336,11 +1336,11 @@ $a3[1..2] # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell # ^ keyword.operator.ternary.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.path.powershell +# ^ punctuation.separator.path.powershell +# ^ punctuation.separator.path.powershell +# ^ punctuation.separator.path.powershell +# ^ punctuation.separator.path.powershell # ^^^^^^^^^^^^^^^^^ comment.line.powershell # ^ punctuation.definition.comment.powershell $roman | c:\users\Me\Documents\Programming\F\test.exe $roman @@ -1685,21 +1685,18 @@ $a3[1..2] # @@@@@@@@@@@ reference # ^ keyword.operator.redirection.powershell # ^^^^^^^ string.unquoted.powershell -# ^ punctuation.separator.powershell notepad.exe 1> log.txt # ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@ reference # ^ constant.numeric.decimal.file-descriptor.powershell # ^ keyword.operator.redirection.powershell # ^^^^^^^ string.unquoted.powershell -# ^ punctuation.separator.powershell notepad.exe *> log.txt # ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@ reference # ^ constant.numeric.decimal.file-descriptor.powershell # ^ keyword.operator.redirection.powershell # ^^^^^^^ string.unquoted.powershell -# ^ punctuation.separator.powershell notepad.exe 2>&1 # ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@ reference @@ -1738,7 +1735,6 @@ $a3[1..2] # ^ constant.numeric.decimal.file-descriptor.powershell # ^ keyword.operator.redirection.powershell # ^^^^^^^ string.unquoted.powershell -# ^ punctuation.separator.powershell # Operators if (10 -cgt 100) { } @@ -2080,8 +2076,6 @@ $a3[1..2] # ^^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell - keyword -# ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell New-Object -TypeName System.Data # ^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@ reference @@ -2094,14 +2088,12 @@ $a3[1..2] # ^^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^^^^^^^ string.unquoted.powershell - keyword -# ^ punctuation.separator.powershell New-Object -TypeName S_ystem.Clean # ^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@ reference # ^^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^^^^^^^^^^^^ string.unquoted.powershell - keyword -# ^ punctuation.separator.powershell New-Object -TypeName Sy_stem-.Throw # ^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@ reference From bf73b4293215ba95509a4b87e9fe59699b833cb8 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 10:31:49 -0500 Subject: [PATCH 096/133] Shuffle some tests --- Tests/syntax_test_Class.ps1 | 229 +++++++++++++++++++----- Tests/syntax_test_PowerShell.ps1 | 294 ------------------------------- 2 files changed, 188 insertions(+), 335 deletions(-) diff --git a/Tests/syntax_test_Class.ps1 b/Tests/syntax_test_Class.ps1 index 90775389..2b926db7 100644 --- a/Tests/syntax_test_Class.ps1 +++ b/Tests/syntax_test_Class.ps1 @@ -424,55 +424,202 @@ class BookList { } -# Example 4 - Class definition with and without Runspace affinity - -# Class definition with Runspace affinity (default behavior) -class UnsafeClass { -# @@@@@@@@@@@ definition - static [Object] ShowRunspaceId($Val) { -# @@@@@@@@@@@@@@ definition - return [pscustomobject]@{ - ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId - RunspaceId = [runspace]::DefaultRunspace.Id + # Example 4 - Class definition with and without Runspace affinity + + # Class definition with Runspace affinity (default behavior) + class UnsafeClass { + # @@@@@@@@@@@ definition + static [Object] ShowRunspaceId($Val) { + # @@@@@@@@@@@@@@ definition + return [pscustomobject]@{ + ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId + RunspaceId = [runspace]::DefaultRunspace.Id + } } } -} -$unsafe = [UnsafeClass]::new() -# @@@ reference + $unsafe = [UnsafeClass]::new() + # @@@ reference -while ($true) { - 1..10 | ForEach-Object -Parallel { -# @@@@@@@@@@@@@@ reference - Start-Sleep -ms 100 -# @@@@@@@@@@@ reference - ($Using:unsafe)::ShowRunspaceId($_) -# @@@@@@@@@@@@@@ reference + while ($true) { + 1..10 | ForEach-Object -Parallel { + # @@@@@@@@@@@@@@ reference + Start-Sleep -ms 100 + # @@@@@@@@@@@ reference + ($Using:unsafe)::ShowRunspaceId($_) + # @@@@@@@@@@@@@@ reference + } } -} -# Class definition with NoRunspaceAffinity attribute -[NoRunspaceAffinity()] -class SafeClass { -# @@@@@@@@@ definition - static [Object] ShowRunspaceId($Val) { -# @@@@@@@@@@@@@@ definition - return [pscustomobject]@{ - ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId - RunspaceId = [runspace]::DefaultRunspace.Id + # Class definition with NoRunspaceAffinity attribute + [NoRunspaceAffinity()] + class SafeClass { + # @@@@@@@@@ definition + static [Object] ShowRunspaceId($Val) { + # @@@@@@@@@@@@@@ definition + return [pscustomobject]@{ + ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId + RunspaceId = [runspace]::DefaultRunspace.Id + } } } -} -$safe = [SafeClass]::new() -# @@@ reference + $safe = [SafeClass]::new() + # @@@ reference -while ($true) { - 1..10 | ForEach-Object -Parallel { -# @@@@@@@@@@@@@@ reference - Start-Sleep -ms 100 -# @@@@@@@@@@@ reference - ($Using:safe)::ShowRunspaceId($_) -# @@@@@@@@@@@@@@ reference + while ($true) { + 1..10 | ForEach-Object -Parallel { + # @@@@@@@@@@@@@@ reference + Start-Sleep -ms 100 + # @@@@@@@@@@@ reference + ($Using:safe)::ShowRunspaceId($_) + # @@@@@@@@@@@@@@ reference + } } -} + + + class Vehicle { +# ^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^ keyword.declaration.class.powershell +# ^^^^^^^ entity.name.class.powershell +# @@@@@@@ definition +# ^ punctuation.section.block.begin.powershell + Vehicle() {} +#^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell +# ^ punctuation.section.block.end.powershell + Vehicle([string]$Owner) { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^ entity.name.function.powershell +# @@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + $this.Owner = $Owner +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ variable.other.member.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + } +#^^^^^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell + + [int]$Mileage +#^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + [int]$Age +#^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + [string]$Owner +#^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + + [void]Drive([int]$NumberOfMiles) { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^ entity.name.function.powershell +# @@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^ storage.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^ variable.parameter.powershell +# ^ punctuation.definition.variable.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + $this.Mileage += $NumberOfMiles +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^^^ variable.other.member.powershell +# ^^ keyword.operator.assignment.augmented.powershell +# ^^^^^^^^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + + } +#^^^^^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell + + static [System.Array] GetAvailableColors() { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell +# ^^^^^^ storage.modifier.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ meta.generic-name.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@@@@@@ definition +# ^ punctuation.section.parameters.begin.powershell +# ^ punctuation.section.parameters.end.powershell +# ^ punctuation.section.block.begin.powershell + return 'yellow', 'red' +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell +# ^^^^^^ keyword.control.flow.return.powershell +# ^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell +# ^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell + } +#^^^^^^^^ meta.class.powershell meta.function.powershell +# ^ punctuation.section.block.end.powershell + } +#^^^^ meta.class.powershell +# ^ punctuation.section.block.end.powershell + + $fiat.Drive(42) +#^^^ meta.class.powershell +# ^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@ reference +# ^^^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.arguments.end.powershell + [Vehicle]::GetAvailableColors() +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^ support.type.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^ punctuation.accessor.double-colon.powershell +# ^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index 59302a95..fa586f27 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1357,300 +1357,6 @@ $a3[1..2] #^^^^^^^^ meta.function.powershell # ^ punctuation.section.block.end.powershell - function Verb-Noun -#^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^ keyword.declaration.function.powershell -# ^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@ definition - { -#^^^^^^^^ meta.function.powershell -# ^ punctuation.section.block.begin.powershell - - Param -#^^^^^^^^^^^^ meta.function.powershell -# ^^^^^ keyword.declaration.parameter.powershell - ( -#^^^^^^^^ meta.function.powershell -# ^ punctuation.section.block.begin.powershell - # Param1 help description - # <- comment.line punctuation.definition.comment - # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line - [Parameter(Mandatory=$true, -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^^^^^^^^^ variable.parameter.attribute.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^ constant.language.boolean.true.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.separator.sequence.powershell - ValueFromPipeline=$true, -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell -# ^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^ constant.language.boolean.true.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.separator.sequence.powershell - ValueFromPipelineByPropertyName = $true, -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^ constant.language.boolean.true.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.separator.sequence.powershell - ValueFromRemainingArguments=$false, -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^^ constant.language.boolean.false.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.separator.sequence.powershell - Position=0, -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell -# ^^^^^^^^ variable.parameter.attribute.powershell -# ^ keyword.operator.assignment.powershell -# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ punctuation.separator.sequence.powershell - SupportsPaging, -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell -# ^^^^^^^^^^^^^^ variable.parameter.attribute.powershell -# ^ punctuation.separator.sequence.powershell - ParameterSetName = 'Parameter Set 1')] -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell -# ^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - [ValidateNotNullOrEmpty()] -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - [ValidateNotNull()] -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^^^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - [ValidateNotNullOrEmpty()] -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - [ValidateCount(0,5)] -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ punctuation.separator.sequence.powershell -# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - [ValidateSet("sun", "moon", "earth")] -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^ punctuation.separator.sequence.powershell -# ^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^ punctuation.separator.sequence.powershell -# ^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - [Alias("p1")] -#^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^ meta.attribute.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^ support.function.attribute.powershell -# ^ punctuation.section.group.begin.powershell -# ^^^^ meta.string.interpolated.powershell string.quoted.double.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^ punctuation.section.group.end.powershell -# ^ punctuation.section.brackets.end.powershell - $Param1 -#^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell - ) -#^^^^^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell - - # Do Something.... - - } -#^^^^^^^^ meta.function.powershell -# ^ punctuation.section.block.end.powershell - - # Class - class Vehicle { -# ^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^ keyword.declaration.class.powershell -# ^^^^^^^ entity.name.class.powershell -# @@@@@@@ definition -# ^ punctuation.section.block.begin.powershell - Vehicle() {} -#^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^ entity.name.function.powershell -# @@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell -# ^ punctuation.section.block.end.powershell - Vehicle([string]$Owner) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^ entity.name.function.powershell -# @@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell - $this.Owner = $Owner -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell -# ^^^^^ variable.language.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^^ variable.other.member.powershell -# ^ keyword.operator.assignment.powershell -# ^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell - } -#^^^^^^^^ meta.class.powershell meta.function.powershell -# ^ punctuation.section.block.end.powershell - - [int]$Mileage -#^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell - [int]$Age -#^^^^^^^^^^^^^^^^ meta.class.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell - [string]$Owner -#^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell - - [void]Drive([int]$NumberOfMiles) { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^ entity.name.function.powershell -# @@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^ storage.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^^^^^^^ variable.parameter.powershell -# ^ punctuation.definition.variable.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell - $this.Mileage += $NumberOfMiles -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell -# ^^^^^ variable.language.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^^^^ variable.other.member.powershell -# ^^ keyword.operator.assignment.augmented.powershell -# ^^^^^^^^^^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell - - } -#^^^^^^^^ meta.class.powershell meta.function.powershell -# ^ punctuation.section.block.end.powershell - - static [System.Array] GetAvailableColors() { -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell -# ^^^^^^ storage.modifier.powershell -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^ meta.generic-name.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell -# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell -# @@@@@@@@@@@@@@@@@@ definition -# ^ punctuation.section.parameters.begin.powershell -# ^ punctuation.section.parameters.end.powershell -# ^ punctuation.section.block.begin.powershell - return 'yellow', 'red' -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.powershell meta.function.powershell -# ^^^^^^ keyword.control.flow.return.powershell -# ^^^^^^^^ meta.string.powershell string.quoted.single.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell -# ^ punctuation.separator.sequence.powershell -# ^^^^^ meta.string.powershell string.quoted.single.powershell -# ^ punctuation.definition.string.begin.powershell -# ^ punctuation.definition.string.end.powershell - } -#^^^^^^^^ meta.class.powershell meta.function.powershell -# ^ punctuation.section.block.end.powershell - } -#^^^^ meta.class.powershell -# ^ punctuation.section.block.end.powershell - - $fiat.Drive(42) -#^^^ meta.class.powershell -# ^^^^^ variable.other.readwrite.powershell -# ^ punctuation.definition.variable.powershell -# ^ punctuation.accessor.dot.powershell -# ^^^^^ meta.function-call.powershell variable.function.powershell -# @@@@@ reference -# ^^^^ meta.function-call.arguments.powershell -# ^ punctuation.section.arguments.begin.powershell -# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ punctuation.section.arguments.end.powershell - [Vehicle]::GetAvailableColors() -# ^ punctuation.section.brackets.begin.powershell -# ^^^^^^^ support.type.powershell -# ^ punctuation.section.brackets.end.powershell -# ^^ punctuation.accessor.double-colon.powershell -# ^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell -# @@@@@@@@@@@@@@@@@@ reference -# ^^ meta.function-call.arguments.powershell -# ^ punctuation.section.arguments.begin.powershell -# ^ punctuation.section.arguments.end.powershell # Control words foreach ($item in $collection) { From 4582dd769793d45e19f676ba8b6c0536f86ff180 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 10:37:38 -0500 Subject: [PATCH 097/133] Add a meta scope for param blocks --- PowerShell.sublime-syntax | 1 + Tests/syntax_test_Function.ps1 | 364 +++++++++++++++++++-------------- 2 files changed, 215 insertions(+), 150 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 0473ceb2..ec1d3612 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -578,6 +578,7 @@ contexts: - include: else-pop inside-param-context: + - meta_scope: meta.block.parameters.powershell - match: \) scope: punctuation.section.block.end.powershell pop: 1 diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index a01002db..a3b4a922 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -80,38 +80,56 @@ function Verb-Noun { # @@@@@@@@@ definition # ^ punctuation.section.block.begin.powershell [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1', - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^ meta.attribute string.quoted.single +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell SupportsShouldProcess = $true, - # ^^^^^^^^^^^^^^^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^ meta.attribute punctuation.definition.variable - # ^^^^ meta.attribute constant.language +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell PositionalBinding = $false, - # ^^^^^^^^^^^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^ meta.attribute punctuation.definition.variable - # ^^^^^ meta.attribute constant.language +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^ constant.language.boolean.false.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell HelpUri = 'http://www.microsoft.com/', - # ^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^ meta.attribute string.quoted.single +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.separator.sequence.powershell ConfirmImpact = 'Medium')] - # ^^^^^^^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^ meta.attribute string.quoted.single - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [Alias()] - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^ meta.function.powershell +# ^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [OutputType([String])] #^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell # ^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell @@ -128,69 +146,73 @@ function Verb-Noun { # ^^^^^ keyword.declaration.parameter.powershell ( #^^^^ meta.function.powershell -# ^ punctuation.section.block.begin.powershell +# ^ meta.block.parameters.powershell punctuation.section.block.begin.powershell # Param1 help description # <- comment.line punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line [Parameter(Mandatory=$true, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^ support.function.attribute - # ^ punctuation.section.group.begin - # ^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^ constant.language - # ^ punctuation.separator +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell ValueFromPipeline=$true, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell - # ^^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^ constant.language - # ^ punctuation.separator +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell ValueFromPipelineByPropertyName = $true, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^^ constant.language - # ^ punctuation.separator +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^ constant.language.boolean.true.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell ValueFromRemainingArguments=$false, - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ punctuation.definition.variable - # ^^^^^ constant.language - # ^ punctuation.separator +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^ constant.language.boolean.false.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell Position=0, - #^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^ constant.numeric.value - # ^ punctuation.separator +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell meta.attribute.powershell +# ^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.sequence.powershell ParameterSetName = 'Parameter Set 1')] - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # ^^^^^^^^^^^^^^^^ variable.parameter.attribute - # ^ keyword.operator.assignment - # ^^^^^^^^^^^^^^^^^ string.quoted.single - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end - # ^ - meta.attribute +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell meta.attribute.powershell +# ^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [ValidateNotNullOrEmpty()] - #^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^^^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [ValidateNotNull()] - #^^^^^^^^^^^^^^^^^^ meta.attribute - # <- punctuation.section.brackets.begin - # ^^^^^^^^^^^^^^ support.function.attribute - # ^ punctuation.section.group.begin - # ^ punctuation.section.group.end - # ^ punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [ValidateNotNullOrEmpty()] #^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute # <- punctuation.section.brackets.begin @@ -302,106 +324,148 @@ function Verb-Noun { # <- comment.line punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line [Parameter(ParameterSetName='Another Parameter Set')] - #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^^^^^^^^^^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute string.quoted.single - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [ValidatePattern("[a-z]*")] - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^^^^^^^^ meta.attribute string.quoted.double - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [ValidateLength(0,15)] - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^ meta.attribute meta.number.integer.decimal constant.numeric.value - # ^ punctuation.separator - # ^^ meta.attribute meta.number.integer.decimal constant.numeric.value - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.sequence.powershell +# ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [String] -#^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^ support.type.powershell # ^ punctuation.section.brackets.end.powershell $Param3, - # <- punctuation.definition.variable - #^^^^^^ variable.other.readwrite - # ^ punctuation.separator +#^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell # Param4 help description # <- comment.line punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line [Parameter(ParameterSetName='Parameter Set 1')] - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^^^^^^^^^^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^^^^^^^^^^^^^^^^^ meta.attribute string.quoted.single - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end - [ValidateScript({Test-Path $_})] #Make sure cmdlets don't break highlighting - # @@@@@@@@@ reference - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^ meta.attribute meta.block - # ^^^^^^^^^ meta.block support.function - # ^ meta.block punctuation.definition.variable - # ^ meta.block variable.language - # ^ meta.attribute meta.block - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell + [ValidateScript({Test-Path $_})] # Make sure cmdlets don't break highlighting +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^^ meta.block.powershell +# ^ punctuation.section.braces.begin.powershell +# ^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@ reference +# ^^^ meta.function-call.arguments.powershell +# ^^ variable.language.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.section.braces.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment.powershell [string] -#^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell $Param4, - # <- punctuation.definition.variable - # ^ variable.other.readwrite - # ^ punctuation.separator +#^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^ punctuation.separator.sequence.powershell # Param5 help description # <- comment.line punctuation.definition.comment # ^^^^^^^^^^^^^^^^^^^^^^^ comment.line [Parameter(ParameterSetName='Parameter Set 1')] - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^^^^^^^^^^^^^^^^ meta.attribute variable.parameter.attribute - # ^ meta.attribute keyword.operator.assignment - # ^^^^^^^^^^^^^^^^^ meta.attribute string.quoted.single - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^^^^ variable.parameter.attribute.powershell +# ^ keyword.operator.assignment.powershell +# ^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell [ValidatePattern('(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)')] # this regex shouldn't break highlighting - # <- meta.attribute punctuation.section.brackets.begin - # ^ meta.attribute support.function.attribute - # ^ meta.attribute punctuation.section.group.begin - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute string.quoted.single - # ^ meta.attribute punctuation.section.group.end - # ^ meta.attribute punctuation.section.brackets.end - # ^ comment.line punctuation.definition.comment - # ^ comment.line +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.powershell +# ^ punctuation.section.brackets.begin.powershell +# ^^^^^^^^^^^^^^^ support.function.attribute.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ punctuation.separator.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.string.end.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.section.brackets.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment.powershell [string] -#^^^^^^^^^^^^^^^ meta.function.powershell +#^^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell # ^ punctuation.section.brackets.begin.powershell # ^^^^^^ storage.type.powershell # ^ punctuation.section.brackets.end.powershell $Param5 - # <- punctuation.definition.variable - # ^ variable.other.readwrite +#^^^^^^^^^^^^^^ meta.function.powershell meta.block.parameters.powershell +# ^^^^^^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell ) -#^^^^ meta.function.powershell +#^^^^ meta.function.powershell meta.block.parameters.powershell # ^ punctuation.section.block.end.powershell Begin From f8ddc5ef943371be310fcaf06fc21406afea4adb Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 10:52:28 -0500 Subject: [PATCH 098/133] Use regex strings in ValidatePattern --- PowerShell.sublime-syntax | 16 +++++++++++++--- Tests/syntax_test_Function.ps1 | 19 ++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index ec1d3612..9c384ef9 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -590,6 +590,13 @@ contexts: - include: assignment-normal attributes: + - match: (\[)\s*(ValidatePattern) + captures: + 1: punctuation.section.brackets.begin.powershell + 2: support.function.attribute.powershell + push: inside-attribute + with_prototype: + - include: regex-strings - match: (\[)\s*({{attributes}}) captures: 1: punctuation.section.brackets.begin.powershell @@ -1016,6 +1023,12 @@ contexts: - include: single-quoted-heredoc-strings expect-regex-string: + - include: regex-strings + - include: comma-separators + - include: else-pop + - include: pop-eol + + regex-strings: - match: '{{single_quote}}' scope: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.begin.powershell embed: scope:source.regexp @@ -1023,9 +1036,6 @@ contexts: escape: ({{single_quote}}) escape_captures: 1: meta.string.powershell string.quoted.single.powershell punctuation.definition.string.end.powershell - - include: comma-separators - - include: else-pop - - include: pop-eol single-quoted-strings: - match: '{{single_quote}}' diff --git a/Tests/syntax_test_Function.ps1 b/Tests/syntax_test_Function.ps1 index a3b4a922..ebe8c465 100644 --- a/Tests/syntax_test_Function.ps1 +++ b/Tests/syntax_test_Function.ps1 @@ -436,21 +436,10 @@ function Verb-Noun { # ^ punctuation.section.brackets.begin.powershell # ^^^^^^^^^^^^^^^ support.function.attribute.powershell # ^ punctuation.section.group.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell string.quoted.single.powershell -# ^ punctuation.definition.string.begin.powershell -# ^^^^^^^ constant.other.placeholder.powershell -# ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.definition.placeholder.end.powershell -# ^^^^^^ constant.other.placeholder.powershell -# ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.definition.placeholder.end.powershell -# ^^^^ constant.other.placeholder.powershell -# ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell -# ^ punctuation.definition.placeholder.end.powershell -# ^ punctuation.definition.string.end.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.powershell +# ^ string.quoted.single.powershell punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.regexp.embedded +# ^ string.quoted.single.powershell punctuation.definition.string.end.powershell # ^ punctuation.section.group.end.powershell # ^ punctuation.section.brackets.end.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.powershell From 0504915bcbf05305a830641e72892bd3be0579d0 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 11:42:58 -0500 Subject: [PATCH 099/133] Tighten function name restrictions --- PowerShell.sublime-syntax | 4 ++-- Tests/syntax_test_PowerShell.ps1 | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 9c384ef9..68bc39bb 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -349,7 +349,7 @@ contexts: - include: path-punctuation command-freeform: - - match: '{{identifier_simple}}' + - match: '{{identifier_function}}' scope: meta.function-call.powershell variable.function.powershell push: in-command @@ -1396,7 +1396,7 @@ variables: # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables identifier_simple: '[\p{L}\p{Nd}_?]+' identifier_special: '[^}]*[^}`]' - identifier_function: '[\p{L}\p{Nd}_.-]+' + identifier_function: '[\p{L}_][\p{L}\p{Nd}_.-]*\b' identifier_csharp: '[\p{L}_][\p{L}\p{Nd}_]*' var_lookahead: |- (?x: (?= diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index fa586f27..f4fe3d2d 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -981,6 +981,17 @@ $a3[1..2] # ^^^^^^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell + # Issue 164 + Do-Cleanup +# ^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@ reference + If-Thing +# ^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@ reference + Something-Else +# ^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@ reference + # Commands (executable files) . .\scripts\Test-Foo.ps1 -parameter 'value' # ^ keyword.operator.source.powershell From f4ab0efce2216a63cd646de8043e84e1894060a6 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 12:34:28 -0500 Subject: [PATCH 100/133] Rescope pipes again --- PowerShell.sublime-syntax | 22 ++++++++++++++-------- Tests/syntax_test_PowerShell.ps1 | 32 ++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 68bc39bb..8911a456 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -383,14 +383,18 @@ contexts: pop: 1 pop-pipe: - - match: (\|)\s*\n + - match: (?:(\|)|(\|\||&&))\s*\n captures: - 1: keyword.operator.assignment.pipe.powershell + 1: keyword.operator.pipe.powershell + 2: keyword.operator.pipe.conditional.powershell push: - match: ^ pop: 2 + - match: \|\||&& + scope: keyword.operator.pipe.conditional.powershell + pop: 1 - match: \| - scope: keyword.operator.assignment.pipe.powershell + scope: keyword.operator.pipe.powershell pop: 1 cli-parameters: @@ -899,14 +903,18 @@ contexts: 1: punctuation.definition.keyword.powershell operator-symbols: - # Assignment context + # Pipes + - match: \|\||&& + scope: keyword.operator.pipe.conditional.powershell + - match: \| + scope: keyword.operator.pipe.powershell + + # Assignment with context - include: assignment-normal - match: (?:[+/*%-]|\?\?)= scope: keyword.operator.assignment.augmented.powershell push: in-assignment # Assignment same context - - match: \| - scope: keyword.operator.assignment.pipe.powershell - match: (?:\+\+|--)(?![ \t]*\d|[[:alpha:]]) scope: keyword.operator.assignment.powershell @@ -928,8 +936,6 @@ contexts: - match: \! scope: keyword.operator.logical.powershell - - match: \|\||&& - scope: keyword.operator.logical.powershell - match: \?\? scope: keyword.operator.null-coalescing.powershell - match: '[?:]' diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index f4fe3d2d..cbcbefce 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -880,7 +880,7 @@ $a3[1..2] # ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell # ^^ keyword.operator.range.powershell # ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference # ^ punctuation.section.group.end.powershell @@ -899,7 +899,7 @@ $a3[1..2] # ^^^ variable.parameter.option.powershell # ^ punctuation.definition.parameter.powershell # ^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference # ^^^^^^^^ meta.function-call.arguments.powershell @@ -926,7 +926,7 @@ $a3[1..2] #^^^^^^^^^ meta.function-call.arguments.powershell #^^^^^^^^ meta.block.powershell # ^ punctuation.section.braces.end.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference @@ -952,7 +952,7 @@ $a3[1..2] # ^ punctuation.definition.parameter.powershell # ^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@@@@ reference # ^^^^^^^^^ meta.function-call.arguments.powershell @@ -963,7 +963,7 @@ $a3[1..2] # ^^^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@@@ reference # ^^ meta.function-call.arguments.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell Select Name,Length # ^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@ reference @@ -972,6 +972,18 @@ $a3[1..2] # ^ punctuation.separator.sequence.powershell # ^^^^^^ string.unquoted.powershell + Do-Something && ContinueOn-Success || ContinueOn-Failure +# ^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@ reference +# ^ meta.function-call.arguments.powershell +# ^^ keyword.operator.pipe.conditional.powershell +# ^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@ reference +# ^ meta.function-call.arguments.powershell +# ^^ keyword.operator.pipe.conditional.powershell +# ^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell +# @@@@@@@@@@@@@@@@@@ reference + # Commands (Built-in variables) ls *.ps1 -recurse # ^^ meta.function-call.powershell variable.function.powershell @@ -1341,7 +1353,7 @@ $a3[1..2] #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell # ^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^ meta.function-call.powershell variable.function.powershell # @ reference # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell @@ -1358,7 +1370,7 @@ $a3[1..2] #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell # ^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ reference # ^^^^^^^ meta.function-call.arguments.powershell @@ -1984,7 +1996,7 @@ $a3[1..2] $ScriptBlock | Out-File $file -Force # ^^^^^^^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@ reference # ^^^^^^^^^^^^^ meta.function-call.arguments.powershell @@ -2010,7 +2022,7 @@ $a3[1..2] # ^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@ reference # ^ meta.function-call.arguments.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@@ reference # ^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell @@ -2037,7 +2049,7 @@ $a3[1..2] # ^^^^^^^^^^ meta.function-call.powershell support.function.powershell # @@@@@@@@@@ reference # ^ meta.function-call.arguments.powershell -# ^ keyword.operator.assignment.pipe.powershell +# ^ keyword.operator.pipe.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block.powershell # ^ keyword.control.loop.for.powershell # ^ punctuation.section.braces.begin.powershell From a94d9ed20da8590dc1443568ce5bbf6cf242b6b6 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 13:29:16 -0500 Subject: [PATCH 101/133] Allow numbers to immediately follow operators Fixes #206 --- PowerShell.sublime-syntax | 29 ++++++++++++++-------------- Tests/syntax_test_PowerShell.ps1 | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 8911a456..1bc02fa3 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -858,46 +858,46 @@ contexts: operator-words: # RegExp context - - match: \B(-)(?i:[ic]?(?:not)?(?:match)){{kebab_break}} + - match: (-)(?i:[ic]?(?:not)?(?:match)){{operator_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell push: expect-regex-string - - match: \B(-)(?i:replace){{kebab_break}} + - match: (-)(?i:replace){{operator_break}} scope: keyword.operator.string.powershell captures: 1: punctuation.definition.keyword.powershell push: expect-regex-string - - match: \B(-)(?i:as){{kebab_break}} + - match: (-)(?i:as){{operator_break}} scope: keyword.operator.cast.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:[ic]?(?:eq|ne|[gl][te])){{kebab_break}} + - match: (-)(?i:[ic]?(?:eq|ne|[gl][te])){{operator_break}} scope: keyword.operator.comparison.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:[ic]?(?:not)?(?:like|contains|in)){{kebab_break}} + - match: (-)(?i:[ic]?(?:not)?(?:like|contains|in)){{operator_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:join|split){{kebab_break}} + - match: (-)(?i:join|split){{operator_break}} scope: keyword.operator.string.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:is(?:not)?){{kebab_break}} + - match: (-)(?i:is(?:not)?){{operator_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:and|or|not|xor){{kebab_break}} + - match: (-)(?i:and|or|not|xor){{operator_break}} scope: keyword.operator.logical.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:band|bor|bnot|bxor|sh[lr]){{kebab_break}} + - match: (-)(?i:band|bor|bnot|bxor|sh[lr]){{operator_break}} scope: keyword.operator.bitwise.powershell captures: 1: punctuation.definition.keyword.powershell - - match: \B(-)(?i:f){{kebab_break}} + - match: (-)(?i:f){{operator_break}} scope: keyword.operator.string-format.powershell captures: 1: punctuation.definition.keyword.powershell @@ -1174,7 +1174,7 @@ contexts: numbers: # Binary numbers - - match: \b(0[bB])([01]*)({{int_suffix}}?{{unit_suffix}}?) + - match: (0[bB])([01]*)({{int_suffix}}?{{unit_suffix}}?) scope: meta.number.integer.binary.powershell captures: 1: constant.numeric.base.powershell @@ -1182,7 +1182,7 @@ contexts: 3: constant.numeric.suffix.powershell push: members # Hexadecimal numbers - - match: \b(0[xX])(\h*)({{int_suffix}}?{{unit_suffix}}?) + - match: (0[xX])(\h*)({{int_suffix}}?{{unit_suffix}}?) scope: meta.number.integer.hexadecimal.powershell captures: 1: constant.numeric.base.powershell @@ -1215,14 +1215,14 @@ contexts: 8: constant.numeric.suffix.powershell push: members # "Decimal" numbers - - match: \b(\d+)({{dec_suffix}}{{unit_suffix}}?) + - match: (\d+)({{dec_suffix}}{{unit_suffix}}?) scope: meta.number.float.decimal.powershell captures: 1: constant.numeric.value.powershell 2: constant.numeric.suffix.powershell push: members # Integers - - match: \b(\d+)({{int_suffix}}?{{unit_suffix}}?) + - match: (\d+)({{int_suffix}}?{{unit_suffix}}?) scope: meta.number.integer.decimal.powershell captures: 1: constant.numeric.value.powershell @@ -1367,6 +1367,7 @@ contexts: variables: kebab_break: (?![\w-]) + operator_break: (?![[:alpha:]]|-\d) builtin_types: |- \b(?x: void | null | object | bool | char | string diff --git a/Tests/syntax_test_PowerShell.ps1 b/Tests/syntax_test_PowerShell.ps1 index cbcbefce..36b5618b 100644 --- a/Tests/syntax_test_PowerShell.ps1 +++ b/Tests/syntax_test_PowerShell.ps1 @@ -1643,6 +1643,39 @@ $a3[1..2] # ^ punctuation.definition.keyword.powershell # ^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell + 1 -bxor1 +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + 1-bxor1 +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + $a -bxor$a +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + $a-bxor$a +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell + -bnot1 +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell + -bnot$a +# ^^^^^ keyword.operator.bitwise.powershell +# ^ punctuation.definition.keyword.powershell +# ^^ variable.other.readwrite.powershell +# ^ punctuation.definition.variable.powershell $a -icontains $c # ^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell From bd086a39dceb5a51a01c956b3eb2001ac6ea8ffb Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 13:47:21 -0500 Subject: [PATCH 102/133] Move folders and update gitignore If we're not doing this for 5.0.0, then when? --- .gitignore | 18 +++++------------- ...g) scriptblock begin clause.sublime-snippet | 0 .../(catch) catch {...}.sublime-snippet | 0 .../(comm) comment block.sublime-snippet | 0 .../(elif) elseif {...}.sublime-snippet | 0 .../(elifi) elseif in-line.sublime-snippet | 0 .../(else) else {...}.sublime-snippet | 0 .../(elsei) else in-line.sublime-snippet | 0 ...end) scriptblock end clause.sublime-snippet | 0 .../(fil) new filter.sublime-snippet | 0 .../(fin) finally {...}.sublime-snippet | 0 .../(fun) define function.sublime-snippet | 0 ...edoc string (single quoted).sublime-snippet | 0 ...edoc string (double quoted).sublime-snippet | 0 .../(if) if {...}.sublime-snippet | 0 ...ifelse) if {...} else {...}.sublime-snippet | 0 .../(ifi) if in-line.sublime-snippet | 0 ...ydocs) path to My Documents.sublime-snippet | 0 ... scriptblock process clause.sublime-snippet | 0 ...nable script debug stepping.sublime-snippet | 0 ...(...) complex subexpression.sublime-snippet | 0 ...dir) path to current script.sublime-snippet | 0 .../(tmp) create temp file.sublime-snippet | 0 .../(try) try {...}.sublime-snippet | 0 .../PowerShell.sublime-completions | 0 {Snippets => snippets}/env.sublime-snippet | 0 {Support => support}/Comments.tmPreferences | 0 {Support => support}/Fold.tmPreferences | 0 {Support => support}/Indentation.tmPreferences | 0 .../PowerShell.sublime-build | 0 .../PowerShell.sublime-settings | 0 {Tests => tests}/syntax_test_Class.ps1 | 0 {Tests => tests}/syntax_test_DSC.ps1 | 0 {Tests => tests}/syntax_test_Function.ps1 | 0 {Tests => tests}/syntax_test_Pester.ps1 | 0 {Tests => tests}/syntax_test_PowerShell.ps1 | 0 {Tests => tests}/syntax_test_Workflow.ps1 | 0 .../syntax_test_partial-symbols.ps1 | 0 {Tests => tests}/syntax_test_reindent.ps1 | 0 {Tests => tests}/syntax_test_strings.ps1 | 0 40 files changed, 5 insertions(+), 13 deletions(-) rename {Snippets => snippets}/(beg) scriptblock begin clause.sublime-snippet (100%) rename {Snippets => snippets}/(catch) catch {...}.sublime-snippet (100%) rename {Snippets => snippets}/(comm) comment block.sublime-snippet (100%) rename {Snippets => snippets}/(elif) elseif {...}.sublime-snippet (100%) rename {Snippets => snippets}/(elifi) elseif in-line.sublime-snippet (100%) rename {Snippets => snippets}/(else) else {...}.sublime-snippet (100%) rename {Snippets => snippets}/(elsei) else in-line.sublime-snippet (100%) rename {Snippets => snippets}/(end) scriptblock end clause.sublime-snippet (100%) rename {Snippets => snippets}/(fil) new filter.sublime-snippet (100%) rename {Snippets => snippets}/(fin) finally {...}.sublime-snippet (100%) rename {Snippets => snippets}/(fun) define function.sublime-snippet (100%) rename {Snippets => snippets}/(here) heredoc string (single quoted).sublime-snippet (100%) rename {Snippets => snippets}/(hhere) heredoc string (double quoted).sublime-snippet (100%) rename {Snippets => snippets}/(if) if {...}.sublime-snippet (100%) rename {Snippets => snippets}/(ifelse) if {...} else {...}.sublime-snippet (100%) rename {Snippets => snippets}/(ifi) if in-line.sublime-snippet (100%) rename {Snippets => snippets}/(mydocs) path to My Documents.sublime-snippet (100%) rename {Snippets => snippets}/(proc) scriptblock process clause.sublime-snippet (100%) rename {Snippets => snippets}/(sd) enable script debug stepping.sublime-snippet (100%) rename {Snippets => snippets}/(sub) $(...) complex subexpression.sublime-snippet (100%) rename {Snippets => snippets}/(thisdir) path to current script.sublime-snippet (100%) rename {Snippets => snippets}/(tmp) create temp file.sublime-snippet (100%) rename {Snippets => snippets}/(try) try {...}.sublime-snippet (100%) rename Snippets/Powershell.sublime-completions => snippets/PowerShell.sublime-completions (100%) rename {Snippets => snippets}/env.sublime-snippet (100%) rename {Support => support}/Comments.tmPreferences (100%) rename {Support => support}/Fold.tmPreferences (100%) rename {Support => support}/Indentation.tmPreferences (100%) rename Support/Powershell.sublime-build => support/PowerShell.sublime-build (100%) rename {Support => support}/PowerShell.sublime-settings (100%) rename {Tests => tests}/syntax_test_Class.ps1 (100%) rename {Tests => tests}/syntax_test_DSC.ps1 (100%) rename {Tests => tests}/syntax_test_Function.ps1 (100%) rename {Tests => tests}/syntax_test_Pester.ps1 (100%) rename {Tests => tests}/syntax_test_PowerShell.ps1 (100%) rename {Tests => tests}/syntax_test_Workflow.ps1 (100%) rename {Tests => tests}/syntax_test_partial-symbols.ps1 (100%) rename {Tests => tests}/syntax_test_reindent.ps1 (100%) rename {Tests => tests}/syntax_test_strings.ps1 (100%) diff --git a/.gitignore b/.gitignore index 43cdf864..12dd925f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,5 @@ -*.pyc -*.cache - -# Editor files -*.sublime-workspace - -# Temporary/generated files -dist/ -MANIFEST -*.YAML-tmLanguage - -# Other -.idea +# Editor files +*.sublime-workspace + +# Other +.idea diff --git a/Snippets/(beg) scriptblock begin clause.sublime-snippet b/snippets/(beg) scriptblock begin clause.sublime-snippet similarity index 100% rename from Snippets/(beg) scriptblock begin clause.sublime-snippet rename to snippets/(beg) scriptblock begin clause.sublime-snippet diff --git a/Snippets/(catch) catch {...}.sublime-snippet b/snippets/(catch) catch {...}.sublime-snippet similarity index 100% rename from Snippets/(catch) catch {...}.sublime-snippet rename to snippets/(catch) catch {...}.sublime-snippet diff --git a/Snippets/(comm) comment block.sublime-snippet b/snippets/(comm) comment block.sublime-snippet similarity index 100% rename from Snippets/(comm) comment block.sublime-snippet rename to snippets/(comm) comment block.sublime-snippet diff --git a/Snippets/(elif) elseif {...}.sublime-snippet b/snippets/(elif) elseif {...}.sublime-snippet similarity index 100% rename from Snippets/(elif) elseif {...}.sublime-snippet rename to snippets/(elif) elseif {...}.sublime-snippet diff --git a/Snippets/(elifi) elseif in-line.sublime-snippet b/snippets/(elifi) elseif in-line.sublime-snippet similarity index 100% rename from Snippets/(elifi) elseif in-line.sublime-snippet rename to snippets/(elifi) elseif in-line.sublime-snippet diff --git a/Snippets/(else) else {...}.sublime-snippet b/snippets/(else) else {...}.sublime-snippet similarity index 100% rename from Snippets/(else) else {...}.sublime-snippet rename to snippets/(else) else {...}.sublime-snippet diff --git a/Snippets/(elsei) else in-line.sublime-snippet b/snippets/(elsei) else in-line.sublime-snippet similarity index 100% rename from Snippets/(elsei) else in-line.sublime-snippet rename to snippets/(elsei) else in-line.sublime-snippet diff --git a/Snippets/(end) scriptblock end clause.sublime-snippet b/snippets/(end) scriptblock end clause.sublime-snippet similarity index 100% rename from Snippets/(end) scriptblock end clause.sublime-snippet rename to snippets/(end) scriptblock end clause.sublime-snippet diff --git a/Snippets/(fil) new filter.sublime-snippet b/snippets/(fil) new filter.sublime-snippet similarity index 100% rename from Snippets/(fil) new filter.sublime-snippet rename to snippets/(fil) new filter.sublime-snippet diff --git a/Snippets/(fin) finally {...}.sublime-snippet b/snippets/(fin) finally {...}.sublime-snippet similarity index 100% rename from Snippets/(fin) finally {...}.sublime-snippet rename to snippets/(fin) finally {...}.sublime-snippet diff --git a/Snippets/(fun) define function.sublime-snippet b/snippets/(fun) define function.sublime-snippet similarity index 100% rename from Snippets/(fun) define function.sublime-snippet rename to snippets/(fun) define function.sublime-snippet diff --git a/Snippets/(here) heredoc string (single quoted).sublime-snippet b/snippets/(here) heredoc string (single quoted).sublime-snippet similarity index 100% rename from Snippets/(here) heredoc string (single quoted).sublime-snippet rename to snippets/(here) heredoc string (single quoted).sublime-snippet diff --git a/Snippets/(hhere) heredoc string (double quoted).sublime-snippet b/snippets/(hhere) heredoc string (double quoted).sublime-snippet similarity index 100% rename from Snippets/(hhere) heredoc string (double quoted).sublime-snippet rename to snippets/(hhere) heredoc string (double quoted).sublime-snippet diff --git a/Snippets/(if) if {...}.sublime-snippet b/snippets/(if) if {...}.sublime-snippet similarity index 100% rename from Snippets/(if) if {...}.sublime-snippet rename to snippets/(if) if {...}.sublime-snippet diff --git a/Snippets/(ifelse) if {...} else {...}.sublime-snippet b/snippets/(ifelse) if {...} else {...}.sublime-snippet similarity index 100% rename from Snippets/(ifelse) if {...} else {...}.sublime-snippet rename to snippets/(ifelse) if {...} else {...}.sublime-snippet diff --git a/Snippets/(ifi) if in-line.sublime-snippet b/snippets/(ifi) if in-line.sublime-snippet similarity index 100% rename from Snippets/(ifi) if in-line.sublime-snippet rename to snippets/(ifi) if in-line.sublime-snippet diff --git a/Snippets/(mydocs) path to My Documents.sublime-snippet b/snippets/(mydocs) path to My Documents.sublime-snippet similarity index 100% rename from Snippets/(mydocs) path to My Documents.sublime-snippet rename to snippets/(mydocs) path to My Documents.sublime-snippet diff --git a/Snippets/(proc) scriptblock process clause.sublime-snippet b/snippets/(proc) scriptblock process clause.sublime-snippet similarity index 100% rename from Snippets/(proc) scriptblock process clause.sublime-snippet rename to snippets/(proc) scriptblock process clause.sublime-snippet diff --git a/Snippets/(sd) enable script debug stepping.sublime-snippet b/snippets/(sd) enable script debug stepping.sublime-snippet similarity index 100% rename from Snippets/(sd) enable script debug stepping.sublime-snippet rename to snippets/(sd) enable script debug stepping.sublime-snippet diff --git a/Snippets/(sub) $(...) complex subexpression.sublime-snippet b/snippets/(sub) $(...) complex subexpression.sublime-snippet similarity index 100% rename from Snippets/(sub) $(...) complex subexpression.sublime-snippet rename to snippets/(sub) $(...) complex subexpression.sublime-snippet diff --git a/Snippets/(thisdir) path to current script.sublime-snippet b/snippets/(thisdir) path to current script.sublime-snippet similarity index 100% rename from Snippets/(thisdir) path to current script.sublime-snippet rename to snippets/(thisdir) path to current script.sublime-snippet diff --git a/Snippets/(tmp) create temp file.sublime-snippet b/snippets/(tmp) create temp file.sublime-snippet similarity index 100% rename from Snippets/(tmp) create temp file.sublime-snippet rename to snippets/(tmp) create temp file.sublime-snippet diff --git a/Snippets/(try) try {...}.sublime-snippet b/snippets/(try) try {...}.sublime-snippet similarity index 100% rename from Snippets/(try) try {...}.sublime-snippet rename to snippets/(try) try {...}.sublime-snippet diff --git a/Snippets/Powershell.sublime-completions b/snippets/PowerShell.sublime-completions similarity index 100% rename from Snippets/Powershell.sublime-completions rename to snippets/PowerShell.sublime-completions diff --git a/Snippets/env.sublime-snippet b/snippets/env.sublime-snippet similarity index 100% rename from Snippets/env.sublime-snippet rename to snippets/env.sublime-snippet diff --git a/Support/Comments.tmPreferences b/support/Comments.tmPreferences similarity index 100% rename from Support/Comments.tmPreferences rename to support/Comments.tmPreferences diff --git a/Support/Fold.tmPreferences b/support/Fold.tmPreferences similarity index 100% rename from Support/Fold.tmPreferences rename to support/Fold.tmPreferences diff --git a/Support/Indentation.tmPreferences b/support/Indentation.tmPreferences similarity index 100% rename from Support/Indentation.tmPreferences rename to support/Indentation.tmPreferences diff --git a/Support/Powershell.sublime-build b/support/PowerShell.sublime-build similarity index 100% rename from Support/Powershell.sublime-build rename to support/PowerShell.sublime-build diff --git a/Support/PowerShell.sublime-settings b/support/PowerShell.sublime-settings similarity index 100% rename from Support/PowerShell.sublime-settings rename to support/PowerShell.sublime-settings diff --git a/Tests/syntax_test_Class.ps1 b/tests/syntax_test_Class.ps1 similarity index 100% rename from Tests/syntax_test_Class.ps1 rename to tests/syntax_test_Class.ps1 diff --git a/Tests/syntax_test_DSC.ps1 b/tests/syntax_test_DSC.ps1 similarity index 100% rename from Tests/syntax_test_DSC.ps1 rename to tests/syntax_test_DSC.ps1 diff --git a/Tests/syntax_test_Function.ps1 b/tests/syntax_test_Function.ps1 similarity index 100% rename from Tests/syntax_test_Function.ps1 rename to tests/syntax_test_Function.ps1 diff --git a/Tests/syntax_test_Pester.ps1 b/tests/syntax_test_Pester.ps1 similarity index 100% rename from Tests/syntax_test_Pester.ps1 rename to tests/syntax_test_Pester.ps1 diff --git a/Tests/syntax_test_PowerShell.ps1 b/tests/syntax_test_PowerShell.ps1 similarity index 100% rename from Tests/syntax_test_PowerShell.ps1 rename to tests/syntax_test_PowerShell.ps1 diff --git a/Tests/syntax_test_Workflow.ps1 b/tests/syntax_test_Workflow.ps1 similarity index 100% rename from Tests/syntax_test_Workflow.ps1 rename to tests/syntax_test_Workflow.ps1 diff --git a/Tests/syntax_test_partial-symbols.ps1 b/tests/syntax_test_partial-symbols.ps1 similarity index 100% rename from Tests/syntax_test_partial-symbols.ps1 rename to tests/syntax_test_partial-symbols.ps1 diff --git a/Tests/syntax_test_reindent.ps1 b/tests/syntax_test_reindent.ps1 similarity index 100% rename from Tests/syntax_test_reindent.ps1 rename to tests/syntax_test_reindent.ps1 diff --git a/Tests/syntax_test_strings.ps1 b/tests/syntax_test_strings.ps1 similarity index 100% rename from Tests/syntax_test_strings.ps1 rename to tests/syntax_test_strings.ps1 From 2cb109eedb914e3ea898b3c12c598c1d0a823c40 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 15:28:52 -0500 Subject: [PATCH 103/133] Update the ISE color scheme --- ISE Nostalgia.sublime-color-scheme | 70 ++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/ISE Nostalgia.sublime-color-scheme b/ISE Nostalgia.sublime-color-scheme index c94b433a..871484f7 100644 --- a/ISE Nostalgia.sublime-color-scheme +++ b/ISE Nostalgia.sublime-color-scheme @@ -10,6 +10,7 @@ "blue5": "#0000ff", "blue6": "#6d79de", "blue7":"#21439C", + "teal": "#297a7a", "green": "#006400", "green2": "#06960e", "grey": "#a9a9a9", @@ -29,7 +30,7 @@ }, "globals": { - "foreground": "var(purple)", + "foreground": "var(grey3)", "background": "var(white)", "caret": "var(grey2)", // "invisibles": "var(grey2)", @@ -49,8 +50,8 @@ }, { "name": "Keyword", - "scope": "keyword, storage", - "foreground": "var(grey3)", + "scope": "keyword", + "foreground": "var(blue7)", }, { "name": "Number", @@ -58,35 +59,41 @@ "foreground": "var(purple2)", }, { + // ISE uses variable colors for constants, but let's not. "name": "Built-in constant", "scope": "constant.language", "foreground": "var(blue4)", }, { "name": "Variable", - "scope": "variable.language, variable.other", + "scope": "variable.other.readwrite, variable.language", "foreground": "var(red2)", }, { "name": "String", - "scope": "string", + "scope": "string.quoted", "foreground": "var(red)", }, { - "name": "String interpolation", - "scope": "constant.character.escape, string source", + "name": "String escape", + "scope": "constant.character.escape", "foreground": "var(purple3)", }, - // { - // "name": "Function name", - // "scope": "entity.name.function, support.function.any-method", - // "foreground": "var(blue5)", - // }, - // { - // "name": "Type name", - // "scope": "entity.name.type", - // "font_style": "underline", - // }, + { + "name": "Attribute", + "scope": "support.function.attribute", + "foreground": "var(blue3)", + }, + { + "name": "Function name", + "scope": "entity.name", + "foreground": "var(purple)", + }, + { + "name": "Type name", + "scope": "meta.generic-name, support.type, storage.type - punctuation.definition", + "foreground": "var(teal)", + }, // { // "name": "Inherited class name", // "scope": "entity.other.inherited-class", @@ -109,10 +116,20 @@ // "font_style": "italic", // }, { - "name": "Library function", - "scope": "support.function", + "name": "Command", + "scope": "support.function, variable.function", "foreground": "var(blue5)", }, + { + "name": "CLI option", + "scope": "variable.parameter.option", + "foreground": "var(blue7)", + }, + { + "name": "CLI value", + "scope": "string.unquoted - meta.mapping.key", + "foreground": "var(purple)", + }, // { // "name": "Library object", // "scope": "support.class, support.type", @@ -132,9 +149,14 @@ // "foreground": "var(blue7)", // }, { - "name": "PowerShell: Assignment Operator", - "scope": "keyword.operator.assignment.powershell", - "foreground": "var(grey)", + "name": "Operator", + "scope": "keyword.operator, meta.brackets.indexer punctuation.section.brackets", + "foreground": "var(grey2)", + }, + { + "name": "Argument separator", + "scope": "punctuation.separator", + "foreground": "var(grey2)", }, { "name": "Invalid", @@ -146,6 +168,6 @@ "name": "Invalid trailing whitespace", "scope": "invalid.deprecated.trailing-whitespace", "background": "var(red3)", - } - ] + }, + ], } From b199a65df4e7b82a9c536b28ebd1042647c003ed Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Tue, 9 Dec 2025 16:09:37 -0500 Subject: [PATCH 104/133] Annotate completions (#208) --- Snippets/Powershell.sublime-completions | 76 +++++++++++++++++++++---- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/Snippets/Powershell.sublime-completions b/Snippets/Powershell.sublime-completions index b3d9dd8a..63ce686e 100644 --- a/Snippets/Powershell.sublime-completions +++ b/Snippets/Powershell.sublime-completions @@ -2,16 +2,68 @@ "scope": "source.powershell", "completions": [ - { "trigger": "dict\thashtable", "contents": "@{$1$0}" }, - { "trigger": "arr\tarray", "contents": "@($0)" }, - { "trigger": "req\trequires", "contents": "#requires -$0" }, - { "trigger": "reqp\trequires", "contents": "#requires -pssnapin $0" }, - { "trigger": "reqv\trequires", "contents": "#requires -version ${0:2}" }, - { "trigger": "void", "contents": "[void] ($1)$0" }, - { "trigger": "sb", "contents": "\\${$1}$0" }, - { "trigger": "wd\twrite-debug", "contents": "write-debug -message \"$1\"$0" }, - { "trigger": "wh\twrite-host", "contents": "write-host \"$1\"" }, - { "trigger": "ww\twrite-warning", "contents": "write-warning $0" }, - { "trigger": "param", "contents": "param(\\$${1:paramName})" } - ] + { + "trigger": "dict", + "contents": "@{$1$0}", + "annotation": "hashtable", + "kind": "snippet", + }, + { + "trigger": "arr", + "contents": "@($0)", + "annotation": "array", + "kind": "snippet", + }, + { + "trigger": "req", + "contents": "#requires -$0", + "annotation": "requires", + "kind": "snippet", + }, + { + "trigger": "reqp", + "contents": "#requires -pssnapin $0", + "annotation": "requires", + "kind": "snippet", + }, + { + "trigger": "reqv", + "contents": "#requires -version ${0:2}", + "annotation": "requires", + "kind": "snippet", + }, + { + "trigger": "void", + "contents": "[void] ($1)$0", + "kind": "snippet", + }, + { + "trigger": "sb", + "contents": "\\${$1}$0", + "kind": "snippet", + }, + { + "trigger": "wd", + "contents": "write-debug -message \"$1\"$0", + "annotation": "write-debug", + "kind": "snippet", + }, + { + "trigger": "wh", + "contents": "write-host \"$1\"", + "annotation": "write-host", + "kind": "snippet", + }, + { + "trigger": "ww", + "contents": "write-warning $0", + "annotation": "write-warning", + "kind": "snippet", + }, + { + "trigger": "param", + "contents": "param(\\$${1:paramName})", + "kind": "snippet", + }, + ], } From 4030791dd4c4144535379b16b604dc2e565dbb2b Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:39:11 -0500 Subject: [PATCH 105/133] Add keymap to help writing herestrings (#209) Fixes #203 --- Default.sublime-keymap | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Default.sublime-keymap diff --git a/Default.sublime-keymap b/Default.sublime-keymap new file mode 100644 index 00000000..fe5fc622 --- /dev/null +++ b/Default.sublime-keymap @@ -0,0 +1,62 @@ +[ + { + "keys": ["\""], + "command": "chain", + "args": { + "commands": [{ + "command": "insert", + "args": {"characters": "\"\n" }, + }, { + "command": "run_macro_file", + "args": {"file": "res://Packages/Default/Delete to Hard BOL.sublime-macro"}, + }, { + "command": "insert", + "args": {"characters": "\"@" }, + }, { + "command": "move", + "args": {"by": "characters", "forward": false}, + }, { + "command": "move", + "args": {"by": "characters", "forward": false}, + }, { + "command": "move", + "args": {"by": "characters", "forward": false}, + }], + }, + "context": [ + { "key": "selection_empty", "match_all": true }, + { "key": "selector", "operand": "source.powershell - string", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "@", "match_all": true }, + ] + }, + { + "keys": ["'"], + "command": "chain", + "args": { + "commands": [{ + "command": "insert", + "args": {"characters": "'\n" }, + }, { + "command": "run_macro_file", + "args": {"file": "res://Packages/Default/Delete to Hard BOL.sublime-macro"}, + }, { + "command": "insert", + "args": {"characters": "'@" }, + }, { + "command": "move", + "args": {"by": "characters", "forward": false}, + }, { + "command": "move", + "args": {"by": "characters", "forward": false}, + }, { + "command": "move", + "args": {"by": "characters", "forward": false}, + }], + }, + "context": [ + { "key": "selection_empty", "match_all": true }, + { "key": "selector", "operand": "source.powershell - string", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "@", "match_all": true }, + ] + }, +] From ea7133f25ffbe9ccd0ffbc34f76c98977b851457 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 9 Dec 2025 19:30:20 -0500 Subject: [PATCH 106/133] Cut the expression context duplication in the obvious way --- PowerShell.sublime-syntax | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 1bc02fa3..93579cc8 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -70,32 +70,7 @@ contexts: - include: expressions expressions: - # Meta - - include: labels - - include: regions - - include: requires-directives - - - include: escape-sequences - - include: stop-parsing-token - - # Normal code - - include: types - - include: strings - - include: numbers - - include: constants - - include: variables - - - include: hashtables - - include: arrays - - - include: data-blocks - - include: script-blocks - - include: groups - - include: subexpressions - - - include: future-reserved-words - - - include: operators + - include: expressions-without-commands - include: commands expressions-without-commands: From 4b2f3d5993a9ed1144286d5b2f94fcd4fafb0500 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Wed, 10 Dec 2025 10:09:46 -0500 Subject: [PATCH 107/133] Let pipe end the stop-parsing token --- PowerShell.sublime-syntax | 38 ++++++++++++++++++-------------- tests/syntax_test_PowerShell.ps1 | 12 +++++++++- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 93579cc8..75168252 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -80,7 +80,6 @@ contexts: - include: requires-directives - include: escape-sequences - - include: stop-parsing-token # Normal code - include: types @@ -331,18 +330,21 @@ contexts: in-command: - meta_content_scope: meta.function-call.arguments.powershell - include: pop-end-of-command + - include: stop-parsing-token - include: redirection - include: cli-parameters - include: expressions-without-commands - match: (?=\S) - push: - - meta_include_prototype: false - - meta_scope: string.unquoted.powershell - - match: (?=[\s#|>;,]|$) - pop: 1 - - include: path-punctuation - - include: escape-sequences - - include: string-wildcards + push: inside-unquoted-string + + inside-unquoted-string: + - meta_include_prototype: false + - meta_scope: string.unquoted.powershell + - match: (?=[\s#|>;,]|$) + pop: 1 + - include: path-punctuation + - include: escape-sequences + - include: string-wildcards pop-end-of-command: - include: line-continuations @@ -381,6 +383,16 @@ contexts: 2: punctuation.definition.parameter.powershell 3: keyword.operator.assignment.powershell + stop-parsing-token: + - match: \B--%\B + scope: keyword.control.stop-parsing.powershell + set: + - meta_include_prototype: false + - meta_scope: meta.function-call.arguments.powershell + - meta_content_scope: string.unquoted.powershell + - include: pop-before-eol + - include: pop-pipe + ###[ DIRECTIVES ]############################################################## requires-directives: @@ -1279,14 +1291,6 @@ contexts: ###[ COMPONENTS ]############################################################## - stop-parsing-token: - - match: \B--%\B - scope: keyword.control.powershell - push: - - meta_include_prototype: false - - meta_content_scope: string.unquoted.powershell - - include: pop-before-eol - path-punctuation: - match: ':(?=[\\/])' scope: punctuation.separator.path.powershell diff --git a/tests/syntax_test_PowerShell.ps1 b/tests/syntax_test_PowerShell.ps1 index 36b5618b..41ed6262 100644 --- a/tests/syntax_test_PowerShell.ps1 +++ b/tests/syntax_test_PowerShell.ps1 @@ -106,9 +106,19 @@ using namespace System.Management.Automation # ^ punctuation.definition.parameter.powershell # ^^^^^^ variable.other.readwrite.powershell # ^ punctuation.definition.variable.powershell -# ^^^ keyword.control.powershell +# ^^^ keyword.control.stop-parsing.powershell # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell + foo --% stop parsing until pipe | echo +# ^^^ meta.function-call.powershell variable.function.powershell +# @@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^ keyword.control.stop-parsing.powershell +# ^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell +# ^ keyword.operator.pipe.powershell +# ^^^^ meta.function-call.powershell variable.function.powershell +# @@@@ reference + & gnutool.exe -s 'short option' --long-option --very_long_option value +plus-option # ^ keyword.operator.call.powershell # ^^^^^^^^^^^ meta.function-call.powershell variable.function.powershell From a461c2003380877df8a3361e27a50797f3e15a28 Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Thu, 11 Dec 2025 09:12:07 -0500 Subject: [PATCH 108/133] Simplify herestring keymap (#210) Fixes #203 better than #209. --- Default.sublime-keymap | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/Default.sublime-keymap b/Default.sublime-keymap index fe5fc622..3f1c2c76 100644 --- a/Default.sublime-keymap +++ b/Default.sublime-keymap @@ -10,17 +10,8 @@ "command": "run_macro_file", "args": {"file": "res://Packages/Default/Delete to Hard BOL.sublime-macro"}, }, { - "command": "insert", - "args": {"characters": "\"@" }, - }, { - "command": "move", - "args": {"by": "characters", "forward": false}, - }, { - "command": "move", - "args": {"by": "characters", "forward": false}, - }, { - "command": "move", - "args": {"by": "characters", "forward": false}, + "command": "insert_snippet", + "args": {"contents": "$0\n\"@" }, }], }, "context": [ @@ -40,17 +31,8 @@ "command": "run_macro_file", "args": {"file": "res://Packages/Default/Delete to Hard BOL.sublime-macro"}, }, { - "command": "insert", - "args": {"characters": "'@" }, - }, { - "command": "move", - "args": {"by": "characters", "forward": false}, - }, { - "command": "move", - "args": {"by": "characters", "forward": false}, - }, { - "command": "move", - "args": {"by": "characters", "forward": false}, + "command": "insert_snippet", + "args": {"contents": "$0\n'@" }, }], }, "context": [ From a47f35708691262a9fe50f1cf821cd7fd506e86b Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Thu, 11 Dec 2025 14:27:43 -0500 Subject: [PATCH 109/133] Move 5.1 build system to a variant (#207) --- Support/Powershell.sublime-build | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Support/Powershell.sublime-build b/Support/Powershell.sublime-build index d18a8950..11ead41f 100644 --- a/Support/Powershell.sublime-build +++ b/Support/Powershell.sublime-build @@ -5,7 +5,14 @@ "TERM": "dumb", }, - "windows": { - "cmd": ["powershell.exe", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], - } + "variants": [ + { + "name": "Windows PowerShell (<=5.1)", + "cmd": ["echo", "powershell.exe is only available on Windows. Did you want a different build variant?"], + + "windows": { + "cmd": ["powershell.exe", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], + }, + }, + ], } From 4462384037fb58ee48aa2bdec1e87ac2fd1aea8e Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 16 Dec 2025 17:16:06 -0500 Subject: [PATCH 110/133] Update ReadMe --- README.md | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f62821e4..9324f8d9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,18 @@ Adds support for the MS PowerShell programming language. -### Installing + +## Features + +- Syntax highlighting +- Symbol lookup for classes and functions +- A build system to run the current file +- Code snippets +- Comment toggle +- Indentation and code folding rules + + +## Installing 1. Install [Package Control][] for Sublime Text. 1. Install the **PowerShell** package: @@ -15,13 +26,23 @@ Adds support for the MS PowerShell programming language. 1. Select **PowerShell**. -### Developing +## Developing + +You want to contribute? Awesome! +File an issue or send us a PR. + +Run the default build system in the syntax file +to execute the regression tests. +(Ctrl+B on Windows and Linux; +Ctrl+B on Mac) + -You want to contribute? Awesome! Send us a PR. +## EditorSyntax -### EditorSyntax +This project budded [EditorSyntax][] in 2016 +and tracked it from 2018 until 2024, +when we diverged to follow Sublime Text conventions. -Syntax highlighting was originally adapted from the [EditorSyntax][] project. -[package control]: https://sublime.wbond.net/installation +[package control]: https://packagecontrol.io/installation [editorsyntax]: https://github.com/PowerShell/EditorSyntax From bf0a01575f8e878d42206e651a978d80265122dd Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 16 Dec 2025 17:37:36 -0500 Subject: [PATCH 111/133] Add an upgrade message for pre-release testers --- messages.json | 1 + messages/5.0.0-alpha.md | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 messages/5.0.0-alpha.md diff --git a/messages.json b/messages.json index d4d29c7d..3c692fdb 100644 --- a/messages.json +++ b/messages.json @@ -1,3 +1,4 @@ { + "5.0.0-alpha.01": "messages/5.0.0-alpha.md", "3.1.1": "messages/prerelease-invitation.md" } diff --git a/messages/5.0.0-alpha.md b/messages/5.0.0-alpha.md new file mode 100644 index 00000000..1ecb466b --- /dev/null +++ b/messages/5.0.0-alpha.md @@ -0,0 +1,43 @@ +# 5.0.0 Alpha + +Hello PowerShell user. Welcome to the 5.0 Alpha! + +If you find bugs, especially egregious ones that break code +highlighting further down in the file, please mention them at +https://github.com/SublimeText/PowerShell/issues and include "v5" +in the title. + +Thank you. + + +## Standout Improvements + +- Commands not in Verb-Noun format are now recognized. + +- Command arguments are more conscientiously marked, + including unquoted strings. + +- String contents are sometimes interpreted specially, + though not in all cases. Some examples: + + * Here-strings beginning with `using System` are + highlighted with C#. + + * Command argument strings recognize wildcards and + path separators. + + * Single-quoted strings in certain cases are + highlighted with Regular Expressions. + + * Other strings recognize simple format placeholders. + +- `using` imports can only come at the beginning of a file. + +- `meta` scopes are used in more places, which doesn't + typically affect highlighting, but sometimes has an + effect on ST commands. + + +## Known Issues + +- #213 The Containerfile package exceeds the context sanity check. From cf8df095f2485cacb1c24dfcd3e5a0889f66ebd7 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Tue, 16 Dec 2025 17:51:24 -0500 Subject: [PATCH 112/133] Don't nest SQL in embedded C# --- PowerShell.sublime-syntax | 4 ++-- messages/5.0.0-alpha.md | 2 +- .../embed/C# (for PowerShell).sublime-syntax | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 syntax/embed/C# (for PowerShell).sublime-syntax diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 75168252..40149c47 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1072,7 +1072,7 @@ contexts: inside-single-quoted-heredoc-string.syntax: - meta_include_prototype: false - match: (?={{csharp_indicator}}) - set: scope:source.cs + set: scope:source.cs.embedded.powershell with_prototype: - match: (?=^{{single_quote}}@) pop: 1 @@ -1110,7 +1110,7 @@ contexts: inside-double-quoted-heredoc-string.syntax: - meta_include_prototype: false - match: (?={{csharp_indicator}}) - set: scope:source.cs + set: scope:source.cs.embedded.powershell with_prototype: - match: (?=^{{double_quote}}@) pop: 1 diff --git a/messages/5.0.0-alpha.md b/messages/5.0.0-alpha.md index 1ecb466b..04f9c8bc 100644 --- a/messages/5.0.0-alpha.md +++ b/messages/5.0.0-alpha.md @@ -40,4 +40,4 @@ Thank you. ## Known Issues -- #213 The Containerfile package exceeds the context sanity check. +- [X] #213 The Containerfile package exceeds the context sanity check. diff --git a/syntax/embed/C# (for PowerShell).sublime-syntax b/syntax/embed/C# (for PowerShell).sublime-syntax new file mode 100644 index 00000000..4d2c0b5e --- /dev/null +++ b/syntax/embed/C# (for PowerShell).sublime-syntax @@ -0,0 +1,22 @@ +%YAML 1.2 +--- +scope: source.cs.embedded.powershell +# version: 2 +hidden: true + +extends: Packages/C#/C#.sublime-syntax + +contexts: + + inside_triple_quoted_raw_string_literal_syntax: + - include: immediately-pop + + inside_long_string_syntax: + - include: immediately-pop + + inside_long_format_string_syntax: + - include: immediately-pop + + immediately-pop: + - match: '' + pop: 1 From 5222ea6634c3dd4edaede870434f029149a78cde Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Fri, 19 Dec 2025 14:55:07 -0500 Subject: [PATCH 113/133] Rename the preview to a beta --- messages.json | 2 +- messages/{5.0.0-alpha.md => 5.0.0-beta.md} | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename messages/{5.0.0-alpha.md => 5.0.0-beta.md} (87%) diff --git a/messages.json b/messages.json index 3c692fdb..b493aae5 100644 --- a/messages.json +++ b/messages.json @@ -1,4 +1,4 @@ { - "5.0.0-alpha.01": "messages/5.0.0-alpha.md", + "5.0.0-beta.01": "messages/5.0.0-beta.md", "3.1.1": "messages/prerelease-invitation.md" } diff --git a/messages/5.0.0-alpha.md b/messages/5.0.0-beta.md similarity index 87% rename from messages/5.0.0-alpha.md rename to messages/5.0.0-beta.md index 04f9c8bc..144efb23 100644 --- a/messages/5.0.0-alpha.md +++ b/messages/5.0.0-beta.md @@ -1,6 +1,6 @@ -# 5.0.0 Alpha +# 5.0.0 Beta -Hello PowerShell user. Welcome to the 5.0 Alpha! +Hello PowerShell user. Welcome to the 5.0 preview! If you find bugs, especially egregious ones that break code highlighting further down in the file, please mention them at @@ -12,7 +12,7 @@ Thank you. ## Standout Improvements -- Commands not in Verb-Noun format are now recognized. +- Commands are recognized without Verb-Noun format. - Command arguments are more conscientiously marked, including unquoted strings. @@ -38,6 +38,6 @@ Thank you. effect on ST commands. -## Known Issues +## Regression tracking - [X] #213 The Containerfile package exceeds the context sanity check. From 89385a5d9ec4a4c3f24a236e473b981cf8a0253f Mon Sep 17 00:00:00 2001 From: deathaxe Date: Tue, 23 Dec 2025 15:47:57 +0100 Subject: [PATCH 114/133] Fix unquoted string argument termination This commit ... 1. ensures balanced braces within unquoted strings 2. ensures string termination if parentheses or closing brace is matched --- PowerShell.sublime-syntax | 10 ++++- tests/syntax_test_PowerShell.ps1 | 69 ++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 40149c47..053ea20a 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -340,12 +340,20 @@ contexts: inside-unquoted-string: - meta_include_prototype: false - meta_scope: string.unquoted.powershell - - match: (?=[\s#|>;,]|$) + - match: $|(?=[\s#|>;,()}]) pop: 1 + - match: \{ + push: inside-unquoted-string-brace - include: path-punctuation - include: escape-sequences - include: string-wildcards + inside-unquoted-string-brace: + - meta_include_prototype: false + - match: \} + pop: 1 + - include: inside-unquoted-string + pop-end-of-command: - include: line-continuations - include: pop-eol diff --git a/tests/syntax_test_PowerShell.ps1 b/tests/syntax_test_PowerShell.ps1 index 41ed6262..d8721da5 100644 --- a/tests/syntax_test_PowerShell.ps1 +++ b/tests/syntax_test_PowerShell.ps1 @@ -1873,6 +1873,75 @@ $a3[1..2] # ^ punctuation.definition.parameter.powershell # ^^^^^^^^^^^^^^ string.unquoted.powershell - keyword + New-Object -TypeName System(Component) +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^ string.unquoted.powershell +# ^^^^^^^^^^^ - string +# @@@@@@@@@ reference + + New-Object -TypeName System.Component) +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^ string.unquoted.powershell +# ^ - meta.function-call - string + + (New-Object -TypeName SystemComponent).run() +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group.powershell +# ^ punctuation.section.group.begin.powershell +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^ string.unquoted.powershell +# ^ punctuation.section.group.end.powershell +# ^ punctuation.accessor.dot.powershell +# ^^^ meta.function-call.powershell variable.function.powershell +# @@@ reference +# ^^ meta.function-call.arguments.powershell +# ^ punctuation.section.arguments.begin.powershell +# ^ punctuation.section.arguments.end.powershell + + New-Object -TypeName System[Component] +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^^ string.unquoted.powershell + + New-Object -TypeName System.Component] +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^^ string.unquoted.powershell + + New-Object -TypeName System{Compon{ent}} +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^^^^ string.unquoted.powershell + + New-Object -TypeName System.Component} +# ^^^^^^^^^^ meta.function-call.powershell support.function.powershell +# @@@@@@@@@@ reference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function-call.arguments.powershell +# ^^^^^^^^^ variable.parameter.option.powershell +# ^ punctuation.definition.parameter.powershell +# ^^^^^^^^^^^^^^^^ string.unquoted.powershell +# ^^ - meta.function-call - string + echo `"test`" # ^^^^ meta.function-call.powershell variable.function.powershell # @@@@ reference From e80d5903d83fa324c58a46619e9b7a8e340dcaba Mon Sep 17 00:00:00 2001 From: deathaxe Date: Fri, 12 Dec 2025 10:03:27 +0100 Subject: [PATCH 115/133] Restrict herestring bindings 1. don't trigger within comments 2. trigger only directly after `@` character, as otherwise typing quotation mark after `@foo` would also trigger the chain command. 3. trigger only if not directly followed by corresponding quotation or at-sign. --- Default.sublime-keymap | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Default.sublime-keymap b/Default.sublime-keymap index 3f1c2c76..e79b3f30 100644 --- a/Default.sublime-keymap +++ b/Default.sublime-keymap @@ -16,8 +16,9 @@ }, "context": [ { "key": "selection_empty", "match_all": true }, - { "key": "selector", "operand": "source.powershell - string", "match_all": true }, - { "key": "preceding_text", "operator": "regex_contains", "operand": "@", "match_all": true }, + { "key": "selector", "operand": "source.powershell - comment - string", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "@$", "match_all": true }, + { "key": "following_text", "operator": "not_regex_contains", "operand": "^[\"@]", "match_all": true }, ] }, { @@ -37,8 +38,9 @@ }, "context": [ { "key": "selection_empty", "match_all": true }, - { "key": "selector", "operand": "source.powershell - string", "match_all": true }, - { "key": "preceding_text", "operator": "regex_contains", "operand": "@", "match_all": true }, + { "key": "selector", "operand": "source.powershell - comment - string", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "@$", "match_all": true }, + { "key": "following_text", "operator": "not_regex_contains", "operand": "^['@]", "match_all": true }, ] }, ] From 8bcaa623200b9680fcdc4dd284169e271c666d59 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Tue, 23 Dec 2025 14:41:22 +0100 Subject: [PATCH 116/133] Fix format string placeholders This commit... 1. separates double- and single-quoted format string contexts to enable quotation marks in format-strings. 2. scopes format-spec as python 3. restricts format placeholders to brace+digit `{\d+}` to avoid false positives --- PowerShell.sublime-syntax | 90 ++++++++++++++++++++++++----- tests/syntax_test_strings.ps1 | 103 +++++++++++++++++++++++++--------- 2 files changed, 152 insertions(+), 41 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index 053ea20a..e71477fb 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -315,10 +315,10 @@ contexts: - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell meta.function-call.powershell variable.function.powershell - match: '{{double_quote}}{2}' scope: constant.character.escape.powershell - - include: escape-sequences - match: '{{double_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 + - include: escape-sequences - include: string-interpolations - include: path-punctuation @@ -1051,7 +1051,7 @@ contexts: - match: '{{single_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 - - include: string-placeholders + - include: single-quoted-string-placeholders double-quoted-strings: - match: '{{double_quote}}' @@ -1063,12 +1063,12 @@ contexts: - meta_scope: meta.string.interpolated.powershell string.quoted.double.powershell - match: '{{double_quote}}{2}' scope: constant.character.escape.powershell - - include: escape-sequences - match: '{{double_quote}}' scope: punctuation.definition.string.end.powershell pop: 1 + - include: escape-sequences - include: string-interpolations - - include: string-placeholders + - include: double-quoted-string-placeholders single-quoted-heredoc-strings: - match: \@{{single_quote}}(?=$) @@ -1096,7 +1096,7 @@ contexts: pop: 1 - match: '{{single_quote}}{2}' scope: constant.character.escape.powershell - - include: string-placeholders + - include: single-quoted-string-placeholders double-quoted-heredoc-strings: - match: \@{{double_quote}}(?=$) @@ -1112,8 +1112,8 @@ contexts: scope: punctuation.definition.string.end.powershell pop: 1 - include: escape-sequences - - include: string-placeholders - include: string-interpolations + - include: double-quoted-string-placeholders inside-double-quoted-heredoc-string.syntax: - meta_include_prototype: false @@ -1145,20 +1145,84 @@ contexts: - include: variables-without-members - include: immediately-pop - string-placeholders: - - match: \{ - scope: punctuation.definition.placeholder.begin.powershell - push: inside-string-placeholder + double-quoted-string-placeholders: + - match: \{\{|\}\} + scope: constant.character.escape.powershell + - match: (\{)(\d+) + captures: + 1: punctuation.definition.placeholder.begin.powershell + 2: meta.number.integer.decimal.powershell constant.numeric.value.powershell + push: inside-double-quoted-string-placeholder - inside-string-placeholder: + inside-double-quoted-string-placeholder: - meta_include_prototype: false - meta_scope: constant.other.placeholder.powershell - match: \} scope: punctuation.definition.placeholder.end.powershell pop: 1 - - match: (?={{single_quote}}|{{double_quote}}) + - match: (?={{double_quote}}) pop: 1 - - match: '[:,;]' + - match: ':' + scope: punctuation.separator.format-spec.powershell + push: inside-double-quoted-string-placeholder-formatspec + - include: string-placeholder-separators + - include: string-placeholder-numbers + + inside-double-quoted-string-placeholder-formatspec: + - meta_include_prototype: false + - meta_content_scope: meta.format-spec.powershell constant.other.format-spec.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 2 + - match: '{{double_quote}}{2}' + scope: constant.character.escape.powershell + - match: (?={{double_quote}}) + pop: 2 + - include: escape-sequences + - include: string-placeholder-separators + + single-quoted-string-placeholders: + - match: \{\{|\}\} + scope: constant.character.escape.powershell + - match: (\{)(\d+) + captures: + 1: punctuation.definition.placeholder.begin.powershell + 2: meta.number.integer.decimal.powershell constant.numeric.value.powershell + push: inside-single-quoted-string-placeholder + + inside-single-quoted-string-placeholder: + - meta_include_prototype: false + - meta_scope: constant.other.placeholder.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 1 + - match: (?={{single_quote}}) + pop: 1 + - match: ':' + scope: punctuation.separator.format-spec.powershell + push: inside-single-quoted-string-placeholder-formatspec + - include: string-placeholder-separators + - include: string-placeholder-numbers + + inside-single-quoted-string-placeholder-formatspec: + - meta_include_prototype: false + - meta_content_scope: meta.format-spec.powershell constant.other.format-spec.powershell + - match: \} + scope: punctuation.definition.placeholder.end.powershell + pop: 2 + - match: '{{single_quote}}{2}' + scope: constant.character.escape.powershell + - match: (?={{single_quote}}) + pop: 2 + - include: escape-sequences + - include: string-placeholder-separators + + string-placeholder-numbers: + - match: \d+ + scope: meta.number.integer.decimal.powershell constant.numeric.value.powershell + + string-placeholder-separators: + - match: '[,;]' scope: punctuation.separator.powershell string-wildcards: diff --git a/tests/syntax_test_strings.ps1 b/tests/syntax_test_strings.ps1 index 05962bb2..4bfcdbea 100644 --- a/tests/syntax_test_strings.ps1 +++ b/tests/syntax_test_strings.ps1 @@ -416,7 +416,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -429,7 +430,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -442,7 +444,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -455,7 +458,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -468,7 +472,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -506,7 +511,8 @@ # ^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -544,7 +550,8 @@ # ^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -558,7 +565,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -578,7 +586,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -591,7 +600,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -604,7 +614,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^ constant.other.format-spec.powershell # ^ punctuation.separator.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell @@ -618,7 +629,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^ constant.other.format-spec.powershell # ^^ punctuation.separator.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell @@ -627,11 +639,8 @@ # ^^^^^^^ meta.number.integer.decimal.powershell constant.numeric.value.powershell "{this is not a #comment}" -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment +# ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell - comment - constant.other.placeholder # ^ punctuation.definition.string.begin.powershell -# ^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell -# ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell "{0:##.#E000}" -f 2.71828 @@ -639,7 +648,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -647,25 +657,55 @@ # ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell - # TODO: Let placeholders contain quotes "{0:#.00'##'}" -f 2.71828 # ^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell -# ^^^^^^^ constant.other.placeholder.powershell +# ^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell # ^ punctuation.definition.keyword.powershell # ^^^^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell # ^ punctuation.separator.decimal.powershell + "{0:#.00""##""}" -f 2.71828 +# ^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^ constant.other.format-spec.powershell +# ^^ constant.character.escape.powershell +# ^^ constant.character.escape.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.string.end.powershell + + "{0:#.00`u{00b5}}" -f 2.54 +# ^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell +# ^ punctuation.definition.string.begin.powershell +# ^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell +# ^ punctuation.definition.placeholder.begin.powershell +# ^ meta.number.integer.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^^^ meta.format-spec.powershell constant.other.format-spec.powershell +# ^^^^^^^^ constant.character.escape.powershell +# ^ punctuation.definition.placeholder.end.powershell +# ^ punctuation.definition.string.end.powershell +# ^^ keyword.operator.string-format.powershell +# ^ punctuation.definition.keyword.powershell +# ^^^^ meta.number.float.decimal.powershell constant.numeric.value.powershell +# ^ punctuation.separator.decimal.powershell + "{0:POS;NEG;ZERO}" -f -14 # ^^^^^^^^^^^^^^^^^^ meta.string.interpolated.powershell string.quoted.double.powershell # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.separator.powershell # ^ punctuation.separator.powershell # ^ punctuation.definition.placeholder.end.powershell @@ -680,7 +720,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -693,7 +734,8 @@ # ^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -707,19 +749,23 @@ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.placeholder.begin.powershell # ^ punctuation.separator.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell @@ -742,7 +788,8 @@ # ^ punctuation.definition.string.begin.powershell # ^^^^^^^^^^^^^ constant.other.placeholder.powershell # ^ punctuation.definition.placeholder.begin.powershell -# ^ punctuation.separator.powershell +# ^ punctuation.separator.format-spec.powershell +# ^^^^^^^^^ constant.other.format-spec.powershell # ^ punctuation.definition.placeholder.end.powershell # ^ punctuation.definition.string.end.powershell # ^^ keyword.operator.string-format.powershell From 5bee3a110d91ecb18df94ea98204575e184023c8 Mon Sep 17 00:00:00 2001 From: God-damnit-all <53661808+God-damnit-all@users.noreply.github.com> Date: Tue, 9 Dec 2025 14:38:59 -0600 Subject: [PATCH 117/133] Fix `$__` highlighting --- PowerShell.sublime-syntax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index e71477fb..bde8c5b9 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1472,9 +1472,9 @@ variables: )\b var_language: |- (?xi: - [$^?_] + [$^?] | \b(?: - Args | ConsoleFileName | Error | Event | EventArgs + _ | Args | ConsoleFileName | Error | Event | EventArgs | EventSubscriber | ForEach | Input | LastExitCode | Matches | MyInvocation | NestedPromptLevel | PsBoundParameters | PsCmdlet | PsCulture | PsDebugContext | PsItem | Pwd | Sender | SourceArgs From fd4f0c925194e63f8fadaf2a58d32b1344bd0855 Mon Sep 17 00:00:00 2001 From: God-damnit-all <53661808+God-damnit-all@users.noreply.github.com> Date: Tue, 9 Dec 2025 15:02:10 -0600 Subject: [PATCH 118/133] Add `$PsNativeCommand` vars to syntax --- PowerShell.sublime-syntax | 1 + 1 file changed, 1 insertion(+) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index bde8c5b9..c54ff20e 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1485,6 +1485,7 @@ variables: ) Preference | Maximum (?: Alias | Drive | Error | Function | History | Variable ) Count # Maximum*Count | Log (?: Command | Engine | Provider ) (?: Health | Lifecycle ) Event # Log*Event + | PsNativeCommand (?: ArgumentPassing | UseErrorActionPreference ) # PsNativeCommand* | PsDebugContext | PsDefaultParameterValues | PsEmailServer | PsModuleAutoloadingPreference | PsSenderInfo | PsSessionApplicationName | PsSessionConfigurationName From b61d808f9bfd442bb17d387a37ec62af2152c9cd Mon Sep 17 00:00:00 2001 From: God-damnit-all <53661808+God-damnit-all@users.noreply.github.com> Date: Tue, 9 Dec 2025 17:29:31 -0600 Subject: [PATCH 119/133] Group the $PsSession vars together --- PowerShell.sublime-syntax | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c54ff20e..aedeb160 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1488,9 +1488,8 @@ variables: | PsNativeCommand (?: ArgumentPassing | UseErrorActionPreference ) # PsNativeCommand* | PsDebugContext | PsDefaultParameterValues | PsEmailServer | PsModuleAutoloadingPreference | PsSenderInfo - | PsSessionApplicationName | PsSessionConfigurationName - | PsSessionOption | ErrorView | FormatEnumerationLimit | OFS - | OutputEncoding + | PsSession (?: ApplicationName | ConfigurationName | Option ) # PsSession* + | ErrorView | FormatEnumerationLimit | OFS | OutputEncoding )\b ) var_scope_mod: (?i:global|local|private|script|using|workflow) From b8b55f3313a46bdb4ea0fa32742a9f4471255abf Mon Sep 17 00:00:00 2001 From: deathaxe Date: Fri, 12 Dec 2025 10:03:27 +0100 Subject: [PATCH 120/133] Restrict herestring bindings 1. don't trigger within comments 2. trigger only directly after `@` character, as otherwise typing quotation mark after `@foo` would also trigger the chain command. 3. trigger only if not directly followed by corresponding quotation or at-sign. --- Default.sublime-keymap | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Default.sublime-keymap b/Default.sublime-keymap index 3f1c2c76..e79b3f30 100644 --- a/Default.sublime-keymap +++ b/Default.sublime-keymap @@ -16,8 +16,9 @@ }, "context": [ { "key": "selection_empty", "match_all": true }, - { "key": "selector", "operand": "source.powershell - string", "match_all": true }, - { "key": "preceding_text", "operator": "regex_contains", "operand": "@", "match_all": true }, + { "key": "selector", "operand": "source.powershell - comment - string", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "@$", "match_all": true }, + { "key": "following_text", "operator": "not_regex_contains", "operand": "^[\"@]", "match_all": true }, ] }, { @@ -37,8 +38,9 @@ }, "context": [ { "key": "selection_empty", "match_all": true }, - { "key": "selector", "operand": "source.powershell - string", "match_all": true }, - { "key": "preceding_text", "operator": "regex_contains", "operand": "@", "match_all": true }, + { "key": "selector", "operand": "source.powershell - comment - string", "match_all": true }, + { "key": "preceding_text", "operator": "regex_contains", "operand": "@$", "match_all": true }, + { "key": "following_text", "operator": "not_regex_contains", "operand": "^['@]", "match_all": true }, ] }, ] From 4ac410c992a734ef949bc9484d677dc984dca36d Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:01:10 -0500 Subject: [PATCH 121/133] Add a 5.0 preview invitation (#212) --- messages.json | 3 +- ...tion.md => 4.0.0-prerelease-invitation.md} | 4 +- messages/5.0.0-prerelease-invitation.md | 46 +++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) rename messages/{prerelease-invitation.md => 4.0.0-prerelease-invitation.md} (89%) create mode 100644 messages/5.0.0-prerelease-invitation.md diff --git a/messages.json b/messages.json index d4d29c7d..ece23909 100644 --- a/messages.json +++ b/messages.json @@ -1,3 +1,4 @@ { - "3.1.1": "messages/prerelease-invitation.md" + "4.2.0": "messages/5.0.0-prerelease-invitation.md", + "3.1.1": "messages/4.0.0-prerelease-invitation.md" } diff --git a/messages/prerelease-invitation.md b/messages/4.0.0-prerelease-invitation.md similarity index 89% rename from messages/prerelease-invitation.md rename to messages/4.0.0-prerelease-invitation.md index 8f0fc360..20305372 100644 --- a/messages/prerelease-invitation.md +++ b/messages/4.0.0-prerelease-invitation.md @@ -6,7 +6,7 @@ languages. This means your color scheme should start highlighting similar concepts the same colors as you are used to in those other languages. -It is not perfect. And, as such, I'm inviting adventurous ST users to +It is not perfect. And as such, I'm inviting adventurous ST users to try it out ahead of time. If that sounds like you, open your Package Control Settings (usually `Cmd/Ctrl`+`Shift`+`P`, "Preferences: Package Control Settings") and add `"PowerShell"` to the array for @@ -17,4 +17,4 @@ highlighting further down in the file, please mention them at https://github.com/SublimeText/PowerShell/issues and include "v4" in the title. -Thank you. Be well. +Thank you. diff --git a/messages/5.0.0-prerelease-invitation.md b/messages/5.0.0-prerelease-invitation.md new file mode 100644 index 00000000..90a11af4 --- /dev/null +++ b/messages/5.0.0-prerelease-invitation.md @@ -0,0 +1,46 @@ +# Prelease invitation + +Hello PowerShell user. There are improvements underway to parse PS +more consistently in Sublime Test. Some of these changes have the +potential for regressions. A summary of changes is below. + +It is not perfect. And as such, I'm inviting adventurous ST users to +try it out ahead of time. If that sounds like you, open your Package +Control Settings (usually `Cmd/Ctrl`+`Shift`+`P`, "Preferences: Package +Control Settings") and add `"PowerShell"` to the array for +`install_prereleases` in the right-hand pane. + +If you find bugs, especially egregious ones that break code +highlighting further down in the file, please mention them at +https://github.com/SublimeText/PowerShell/issues and include "v5" in +the title. + +Thank you. + + +## Standout Improvements + +- Commands not in Verb-Noun format are now recognized. + +- Command arguments are more conscientiously marked, + including unquoted strings. + +- String contents are sometimes interpreted specially, + though not in all cases. Some examples: + + * Here-strings beginning with `using System` are + highlighted with C#. + + * Command argument strings recognize wildcards and + path separators. + + * Single-quoted strings in certain cases are + highlighted with Regular Expressions. + + * Other strings recognize formatting placeholders. + +- `using` imports can only come at the beginning of a file. + +- `meta` scopes are used in more places, which doesn't + typically affect highlighting, but sometimes has an + effect on ST commands. From 46a85f9baaa55ca11225cdb98855ce8dab415b1a Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Mon, 29 Dec 2025 12:53:14 -0500 Subject: [PATCH 122/133] Fix MacOS syntax test ReadMe hotkey --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9324f8d9..6c6dad0c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ File an issue or send us a PR. Run the default build system in the syntax file to execute the regression tests. (Ctrl+B on Windows and Linux; -Ctrl+B on Mac) +Cmd+B on Mac) ## EditorSyntax From 36c5e989093b102dc3af88c9f44362cedf62f12a Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 18 Jan 2026 22:55:22 -0500 Subject: [PATCH 123/133] Add a 5.0 release message --- messages.json | 1 + messages/5.0.0.md | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 messages/5.0.0.md diff --git a/messages.json b/messages.json index 6f8533da..94305797 100644 --- a/messages.json +++ b/messages.json @@ -1,4 +1,5 @@ { + "5.0.0": "messages/5.0.0.md", "5.0.0-beta.01": "messages/5.0.0-beta.md", "4.2.0": "messages/5.0.0-prerelease-invitation.md", "3.1.1": "messages/4.0.0-prerelease-invitation.md" diff --git a/messages/5.0.0.md b/messages/5.0.0.md new file mode 100644 index 00000000..b48dba39 --- /dev/null +++ b/messages/5.0.0.md @@ -0,0 +1,37 @@ +# 5.0.0 + +This is a large syntax change with substantial modification +to where some keywords are able to be used. + +If you find bugs, especially egregious ones that break code +highlighting further down in the file, please mention them at +https://github.com/SublimeText/PowerShell/issues and include +"v5" in the title. + + +## Standout improvements + +- Commands are recognized without Verb-Noun format. + +- Command arguments are more conscientiously marked, + including unquoted strings. + +- String contents are sometimes interpreted specially, + though not in all cases. Some examples: + + * Here-strings beginning with `using System` are + highlighted with C#. + + * Command argument strings recognize wildcards and + path separators. + + * Single-quoted strings in certain cases are + highlighted with Regular Expressions. + + * Other strings recognize some format placeholders. + +- `using` imports can only come at the beginning of a file. + +- `meta` scopes are used in more places, which doesn't + typically affect highlighting, but sometimes has an + effect on ST commands. From 4969d0924e3b24711d80804141ae82e84361cfc4 Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Thu, 29 Jan 2026 14:37:31 -0500 Subject: [PATCH 124/133] Allow regions anywhere comments are permitted (#217) Allow regions anywhere comments are permitted. Technically regions are only valid at BOL: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comments but since they're not interpreted by pwsh itself, we can be lenient. See #216 --- PowerShell.sublime-syntax | 4 +-- tests/syntax_test_PowerShell.ps1 | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index aedeb160..c210897b 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -19,6 +19,7 @@ first_line_match: |- contexts: prototype: + - include: regions - include: comments main: @@ -76,7 +77,6 @@ contexts: expressions-without-commands: # Meta - include: labels - - include: regions - include: requires-directives - include: escape-sequences @@ -580,7 +580,7 @@ contexts: - meta_scope: meta.block.parameters.powershell - match: \) scope: punctuation.section.block.end.powershell - pop: 1 + pop: 2 - include: comma-separators - include: attributes - include: types-without-members diff --git a/tests/syntax_test_PowerShell.ps1 b/tests/syntax_test_PowerShell.ps1 index d8721da5..469bfc6c 100644 --- a/tests/syntax_test_PowerShell.ps1 +++ b/tests/syntax_test_PowerShell.ps1 @@ -2370,6 +2370,8 @@ $a3[1..2] # ^^^^ meta.toc-list entity.name.section # @@@@ local-definition # ^ meta.fold.begin + Do-Stuff +# @@@@@@@@ reference #endregion (More comments) #<- punctuation.definition.comment.powershell #^^^^^^^^^ keyword.other.region.end.powershell @@ -2386,3 +2388,55 @@ $a3[1..2] #^^^^^^^^^ keyword.other.region.end.powershell #<- comment.line # ^ meta.fold.end + +function Process-DeploymentConfig { +# @@@@@@@@@@@@@@@@@@@@@@@@ definition + [CmdletBinding()] + param ( + [Parameter(Mandatory=$true)] + [string]$ConfigJson, + + [Parameter(Mandatory=$true)] + [hashtable]PathVariables + ) + + #region PathHelper +# ^^^^^^^^^^^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment +# ^^^^^^ keyword.other.region.begin +# ^^^^^^^^^^ meta.toc-list entity.name.section +# @@@@@@@@@@ local-definition +# ^ meta.fold.begin + + function Resolve-ConfigPath { +#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.function.powershell +# ^^^^^^^^ keyword.declaration.function.powershell +# ^^^^^^^^^^^^^^^^^^ entity.name.function.powershell +# @@@@@@@@@@@@@@@@@@ definition +# ^ punctuation.section.block.begin.powershell + [CmdletBinding()] + param ( + [Parameter(Mandatory=$true)] + [string]$Path, + + [Parameter(Mandatory=$true)] + [hashtable]$PathVariables + ) + + $Private:ResolvedPath = $Path + foreach ($key in $PathVariables.Keys) { + $ResolvedPath = $ResolvedPath.Replace($key, $PathVariables[$key]) +# @@@@@@@ reference + } + return $ResolvedPath + } + #endregion +# ^^^^^^^^^^^ comment.line.powershell +# ^ punctuation.definition.comment.powershell +# ^^^^^^^^^ keyword.other.region.end.powershell +# ^ meta.fold.end + + + Resolve-ConfigPath -Path "Foo" -PathVariables $PathVariables +# @@@@@@@@@@@@@@@@@@ reference +} From d7e0d7cc7f2421ef835f7395119f59d0ea87188f Mon Sep 17 00:00:00 2001 From: deathaxe <16542113+deathaxe@users.noreply.github.com> Date: Thu, 2 Apr 2026 16:19:23 +0000 Subject: [PATCH 125/133] Add new context names for refactored C# strings (#219) --- .../embed/C# (for PowerShell).sublime-syntax | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/syntax/embed/C# (for PowerShell).sublime-syntax b/syntax/embed/C# (for PowerShell).sublime-syntax index 4d2c0b5e..77977fd6 100644 --- a/syntax/embed/C# (for PowerShell).sublime-syntax +++ b/syntax/embed/C# (for PowerShell).sublime-syntax @@ -9,12 +9,30 @@ extends: Packages/C#/C#.sublime-syntax contexts: inside_triple_quoted_raw_string_literal_syntax: + # <=ST4202 + - meta_include_prototype: false - include: immediately-pop inside_long_string_syntax: + # <=ST4202 + - meta_include_prototype: false - include: immediately-pop inside_long_format_string_syntax: + # <=ST4202 + - meta_include_prototype: false + - include: immediately-pop + + inside_triple_quoted_raw_string_syntax: + - meta_include_prototype: false + - include: immediately-pop + + inside_verbatim_string_syntax: + - meta_include_prototype: false + - include: immediately-pop + + inside_verbatim_format_string_syntax: + - meta_include_prototype: false - include: immediately-pop immediately-pop: From 7d450de864c5531ff608cc800297a237e17e1ed3 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 19 Apr 2026 20:10:03 -0400 Subject: [PATCH 126/133] Delete upgrade messages except v5.0.0 PCC's validator is mad about them. --- messages.json | 5 +-- messages/4.0.0-prerelease-invitation.md | 20 ----------- messages/5.0.0-beta.md | 43 ----------------------- messages/5.0.0-prerelease-invitation.md | 46 ------------------------- 4 files changed, 1 insertion(+), 113 deletions(-) delete mode 100644 messages/4.0.0-prerelease-invitation.md delete mode 100644 messages/5.0.0-beta.md delete mode 100644 messages/5.0.0-prerelease-invitation.md diff --git a/messages.json b/messages.json index 94305797..633c6190 100644 --- a/messages.json +++ b/messages.json @@ -1,6 +1,3 @@ { - "5.0.0": "messages/5.0.0.md", - "5.0.0-beta.01": "messages/5.0.0-beta.md", - "4.2.0": "messages/5.0.0-prerelease-invitation.md", - "3.1.1": "messages/4.0.0-prerelease-invitation.md" + "5.0.0": "messages/5.0.0.md" } diff --git a/messages/4.0.0-prerelease-invitation.md b/messages/4.0.0-prerelease-invitation.md deleted file mode 100644 index 20305372..00000000 --- a/messages/4.0.0-prerelease-invitation.md +++ /dev/null @@ -1,20 +0,0 @@ -# Prelease invitation - -Hello PowerShell user. There are improvements underway to bring the -syntax highlighting for PS more in line with the other Sublime Text -languages. This means your color scheme should start highlighting -similar concepts the same colors as you are used to in those other -languages. - -It is not perfect. And as such, I'm inviting adventurous ST users to -try it out ahead of time. If that sounds like you, open your Package -Control Settings (usually `Cmd/Ctrl`+`Shift`+`P`, "Preferences: Package -Control Settings") and add `"PowerShell"` to the array for -`install_prereleases` in the right-hand pane. - -If you find bugs, especially egregious ones that break code -highlighting further down in the file, please mention them at -https://github.com/SublimeText/PowerShell/issues and include "v4" in -the title. - -Thank you. diff --git a/messages/5.0.0-beta.md b/messages/5.0.0-beta.md deleted file mode 100644 index 144efb23..00000000 --- a/messages/5.0.0-beta.md +++ /dev/null @@ -1,43 +0,0 @@ -# 5.0.0 Beta - -Hello PowerShell user. Welcome to the 5.0 preview! - -If you find bugs, especially egregious ones that break code -highlighting further down in the file, please mention them at -https://github.com/SublimeText/PowerShell/issues and include "v5" -in the title. - -Thank you. - - -## Standout Improvements - -- Commands are recognized without Verb-Noun format. - -- Command arguments are more conscientiously marked, - including unquoted strings. - -- String contents are sometimes interpreted specially, - though not in all cases. Some examples: - - * Here-strings beginning with `using System` are - highlighted with C#. - - * Command argument strings recognize wildcards and - path separators. - - * Single-quoted strings in certain cases are - highlighted with Regular Expressions. - - * Other strings recognize simple format placeholders. - -- `using` imports can only come at the beginning of a file. - -- `meta` scopes are used in more places, which doesn't - typically affect highlighting, but sometimes has an - effect on ST commands. - - -## Regression tracking - -- [X] #213 The Containerfile package exceeds the context sanity check. diff --git a/messages/5.0.0-prerelease-invitation.md b/messages/5.0.0-prerelease-invitation.md deleted file mode 100644 index 90a11af4..00000000 --- a/messages/5.0.0-prerelease-invitation.md +++ /dev/null @@ -1,46 +0,0 @@ -# Prelease invitation - -Hello PowerShell user. There are improvements underway to parse PS -more consistently in Sublime Test. Some of these changes have the -potential for regressions. A summary of changes is below. - -It is not perfect. And as such, I'm inviting adventurous ST users to -try it out ahead of time. If that sounds like you, open your Package -Control Settings (usually `Cmd/Ctrl`+`Shift`+`P`, "Preferences: Package -Control Settings") and add `"PowerShell"` to the array for -`install_prereleases` in the right-hand pane. - -If you find bugs, especially egregious ones that break code -highlighting further down in the file, please mention them at -https://github.com/SublimeText/PowerShell/issues and include "v5" in -the title. - -Thank you. - - -## Standout Improvements - -- Commands not in Verb-Noun format are now recognized. - -- Command arguments are more conscientiously marked, - including unquoted strings. - -- String contents are sometimes interpreted specially, - though not in all cases. Some examples: - - * Here-strings beginning with `using System` are - highlighted with C#. - - * Command argument strings recognize wildcards and - path separators. - - * Single-quoted strings in certain cases are - highlighted with Regular Expressions. - - * Other strings recognize formatting placeholders. - -- `using` imports can only come at the beginning of a file. - -- `meta` scopes are used in more places, which doesn't - typically affect highlighting, but sometimes has an - effect on ST commands. From cffe2aaa6d6dda531ea208bdefb0408b9593fcb1 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 19 Apr 2026 20:16:35 -0400 Subject: [PATCH 127/133] Add menu navigation for file overrides --- Main.sublime-menu | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Main.sublime-menu diff --git a/Main.sublime-menu b/Main.sublime-menu new file mode 100644 index 00000000..f17b7a8f --- /dev/null +++ b/Main.sublime-menu @@ -0,0 +1,33 @@ +[{ + "id": "preferences", + "children": [ + { + "id": "package-settings", + "children": [ + { + "caption": "PowerShell", + "children": [ + { + "caption": "Settings", + "id": "powershell-settings", + "command": "edit_settings", + "args": { + "base_file": "${packages}/PowerShell/support/PowerShell.sublime-settings", + "default": "/* See the left pane for the list of settings and valid values. */\n{\n\t$0\n}\n", + }, + }, + { + "caption": "Key Bindings", + "id": "powershell-keymap", + "command": "edit_settings", + "args": { + "base_file": "${packages}/PowerShell/Default.sublime-keymap", + "default": "/* See the left pane for the shipped keybindings. */\n[\n\t$0\n]\n", + }, + }, + ] + }, + ] + }, + ] +}] From 0e1921d2fb85b29a983b36308519fbdb36b3883e Mon Sep 17 00:00:00 2001 From: Michael <2701605+michaelblyons@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:20:57 -0400 Subject: [PATCH 128/133] Update C# extension to `version: 2` (#220) See https://github.com/sublimehq/Packages/pull/4504 --- .github/workflows/syntax.yml | 8 +++--- .../embed/C# (for PowerShell).sublime-syntax | 27 +++---------------- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/.github/workflows/syntax.yml b/.github/workflows/syntax.yml index 7531ebe3..3203f970 100644 --- a/.github/workflows/syntax.yml +++ b/.github/workflows/syntax.yml @@ -34,12 +34,12 @@ jobs: include: - build: latest packages: master - - build: stable - packages: binary - - build: 4107 + # - build: stable + # packages: binary + - build: 4204 packages: binary steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: SublimeText/syntax-test-action@v2 with: build: ${{ matrix.build }} diff --git a/syntax/embed/C# (for PowerShell).sublime-syntax b/syntax/embed/C# (for PowerShell).sublime-syntax index 77977fd6..4eb40f24 100644 --- a/syntax/embed/C# (for PowerShell).sublime-syntax +++ b/syntax/embed/C# (for PowerShell).sublime-syntax @@ -1,40 +1,21 @@ %YAML 1.2 --- scope: source.cs.embedded.powershell -# version: 2 +version: 2 hidden: true extends: Packages/C#/C#.sublime-syntax contexts: - inside_triple_quoted_raw_string_literal_syntax: - # <=ST4202 - - meta_include_prototype: false - - include: immediately-pop - - inside_long_string_syntax: - # <=ST4202 - - meta_include_prototype: false - - include: immediately-pop - - inside_long_format_string_syntax: - # <=ST4202 - - meta_include_prototype: false - - include: immediately-pop - inside_triple_quoted_raw_string_syntax: - meta_include_prototype: false - - include: immediately-pop + - include: immediately_pop inside_verbatim_string_syntax: - meta_include_prototype: false - - include: immediately-pop + - include: immediately_pop inside_verbatim_format_string_syntax: - meta_include_prototype: false - - include: immediately-pop - - immediately-pop: - - match: '' - pop: 1 + - include: immediately_pop From 4d9b2628f026199c67ff47f1d4985e06da2de7b9 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Sun, 19 Apr 2026 20:24:11 -0400 Subject: [PATCH 129/133] Move the settings file to the traditional path --- Main.sublime-menu | 2 +- .../PowerShell.sublime-settings => PowerShell.sublime-settings | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename support/PowerShell.sublime-settings => PowerShell.sublime-settings (100%) diff --git a/Main.sublime-menu b/Main.sublime-menu index f17b7a8f..7ac8f6b9 100644 --- a/Main.sublime-menu +++ b/Main.sublime-menu @@ -12,7 +12,7 @@ "id": "powershell-settings", "command": "edit_settings", "args": { - "base_file": "${packages}/PowerShell/support/PowerShell.sublime-settings", + "base_file": "${packages}/PowerShell/PowerShell.sublime-settings", "default": "/* See the left pane for the list of settings and valid values. */\n{\n\t$0\n}\n", }, }, diff --git a/support/PowerShell.sublime-settings b/PowerShell.sublime-settings similarity index 100% rename from support/PowerShell.sublime-settings rename to PowerShell.sublime-settings From 040d17579ab98e60256a9e7d736656130c3d5af4 Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Wed, 22 Apr 2026 11:17:35 -0400 Subject: [PATCH 130/133] Sync region scopes to upstream C# Fixes #221 --- PowerShell.sublime-syntax | 24 +++++----- support/Fold.tmPreferences | 4 +- support/Symbol List - Region.tmPreferences | 17 +++++++ tests/syntax_test_PowerShell.ps1 | 52 ++++++++++------------ 4 files changed, 53 insertions(+), 44 deletions(-) create mode 100644 support/Symbol List - Region.tmPreferences diff --git a/PowerShell.sublime-syntax b/PowerShell.sublime-syntax index c210897b..f69ebfb6 100644 --- a/PowerShell.sublime-syntax +++ b/PowerShell.sublime-syntax @@ -1297,19 +1297,17 @@ contexts: 2: punctuation.definition.label.powershell regions: - - match: ^\s*((#)\s*(region\b)(?:\s*(\S.*))?(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.begin.powershell - 4: meta.toc-list.powershell entity.name.section.powershell - 5: meta.fold.begin.powershell - - match: ^\s*((#)\s*(endregion\b).*(\n?)) - captures: - 1: comment.line.powershell - 2: punctuation.definition.comment.powershell - 3: keyword.other.region.end.powershell - 4: meta.fold.end.powershell + - match: ^\s*(#)\s*(region\b)(?:\s*(\S.*))?(\s*\n?) + captures: + 1: punctuation.definition.preprocessor.powershell + 2: keyword.control.directive.region.powershell + 3: entity.name.section.powershell + 4: meta.fold.block.begin.powershell + - match: ^\s*(#)\s*(endregion\b)(?:\s*(\S.*))?\s*\n? + captures: + 1: meta.fold.block.end.powershell punctuation.definition.preprocessor.powershell + 2: keyword.control.directive.endregion.powershell + 3: variable.other.section.powershell ###[ COMMENTS ]################################################################ diff --git a/support/Fold.tmPreferences b/support/Fold.tmPreferences index ce6f43ae..326c37c4 100644 --- a/support/Fold.tmPreferences +++ b/support/Fold.tmPreferences @@ -9,9 +9,9 @@ begin - meta.fold.begin + meta.fold.block.begin end - meta.fold.end + meta.fold.block.end begin diff --git a/support/Symbol List - Region.tmPreferences b/support/Symbol List - Region.tmPreferences new file mode 100644 index 00000000..14a08fd5 --- /dev/null +++ b/support/Symbol List - Region.tmPreferences @@ -0,0 +1,17 @@ + + + + scope + source.powershell entity.name.section + settings + + showInSymbolList + 1 + symbolTransformation + + s/\s{2,}/ /g; # collapse whitespace + s/^/#region /;# prepend "#region " to the region name + + + + diff --git a/tests/syntax_test_PowerShell.ps1 b/tests/syntax_test_PowerShell.ps1 index 469bfc6c..015ce416 100644 --- a/tests/syntax_test_PowerShell.ps1 +++ b/tests/syntax_test_PowerShell.ps1 @@ -2364,30 +2364,26 @@ $a3[1..2] #> #region Test -#<- punctuation.definition.comment -#^^^^^^ keyword.other.region.begin -#<- comment.line.powershell -# ^^^^ meta.toc-list entity.name.section -# @@@@ local-definition -# ^ meta.fold.begin +#<- punctuation.definition.preprocessor +#^^^^^^ keyword.control.directive.region +# ^^^^ entity.name.section +# @@@@ local-definition "#region Test" +# ^ meta.fold.block.begin Do-Stuff # @@@@@@@@ reference #endregion (More comments) -#<- punctuation.definition.comment.powershell -#^^^^^^^^^ keyword.other.region.end.powershell -#<- comment.line -# ^ meta.fold.end +#<- meta.fold.block.end punctuation.definition.preprocessor +#^^^^^^^^^ keyword.control.directive.endregion +# ^^^^^^^^^^^^^^^ variable.other.section.powershell #region -#<- punctuation.definition.comment -#^^^^^^ keyword.other.region.begin -#<- comment.line.powershell -# ^ meta.fold.begin +#<- punctuation.definition.preprocessor +#^^^^^^ keyword.control.directive.region +# ^ meta.fold.block.begin #endregion (More comments) -#<- punctuation.definition.comment.powershell -#^^^^^^^^^ keyword.other.region.end.powershell -#<- comment.line -# ^ meta.fold.end +#<- meta.fold.block.end punctuation.definition.preprocessor +#^^^^^^^^^ keyword.control.directive.endregion +# ^^^^^^^^^^^^^^^ variable.other.section.powershell function Process-DeploymentConfig { # @@@@@@@@@@@@@@@@@@@@@@@@ definition @@ -2401,12 +2397,11 @@ function Process-DeploymentConfig { ) #region PathHelper -# ^^^^^^^^^^^^^^^^^^^ comment.line.powershell -# ^ punctuation.definition.comment -# ^^^^^^ keyword.other.region.begin -# ^^^^^^^^^^ meta.toc-list entity.name.section -# @@@@@@@@@@ local-definition -# ^ meta.fold.begin +# ^ punctuation.definition.preprocessor +# ^^^^^^ keyword.control.directive.region +# ^^^^^^^^^^ entity.name.section +# @@@@@@@@@@ local-definition "#region PathHelper" +# ^ meta.fold.block.begin function Resolve-ConfigPath { #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.powershell meta.function.powershell @@ -2430,11 +2425,10 @@ function Process-DeploymentConfig { } return $ResolvedPath } - #endregion -# ^^^^^^^^^^^ comment.line.powershell -# ^ punctuation.definition.comment.powershell -# ^^^^^^^^^ keyword.other.region.end.powershell -# ^ meta.fold.end + #endregion PathHelper +# ^ meta.fold.block.end punctuation.definition.preprocessor +# ^^^^^^ keyword.control.directive.endregion +# ^^^^^^^^^^ variable.other.section.powershell Resolve-ConfigPath -Path "Foo" -PathVariables $PathVariables From 76a34657e54bfeb6e9f8739d68e1a550ee92245c Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Wed, 22 Apr 2026 14:02:27 -0400 Subject: [PATCH 131/133] Add a file regex to help tracebacks It tries to cram several formats together. --- support/PowerShell.sublime-build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/support/PowerShell.sublime-build b/support/PowerShell.sublime-build index 11ead41f..ed78b2d3 100644 --- a/support/PowerShell.sublime-build +++ b/support/PowerShell.sublime-build @@ -4,6 +4,8 @@ "env": { "TERM": "dumb", }, + // https://regex101.com/r/P1ZwkU/2 + "file_regex": "^[Aa]t (?:(?:.+ in|[:\\w<>-]+,) )?(.+?):(?: line )?(\\d+)(?: char:(\\d+))?", "variants": [ { From c2a19ae0617f62a6a868004313c29e830fd15fab Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Wed, 22 Apr 2026 14:15:18 -0400 Subject: [PATCH 132/133] Normalize build system capitalization --- support/PowerShell.sublime-build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/support/PowerShell.sublime-build b/support/PowerShell.sublime-build index ed78b2d3..0c17cd3f 100644 --- a/support/PowerShell.sublime-build +++ b/support/PowerShell.sublime-build @@ -1,5 +1,5 @@ { - "cmd": ["pwsh", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], + "cmd": ["pwsh", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "$file"], "selector": "source.powershell", "env": { "TERM": "dumb", @@ -13,7 +13,7 @@ "cmd": ["echo", "powershell.exe is only available on Windows. Did you want a different build variant?"], "windows": { - "cmd": ["powershell.exe", "-noprofile", "-ExecutionPolicy", "Bypass", "-file", "$file"], + "cmd": ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "$file"], }, }, ], From 71ff620a20094791c916755dd8e7403dbb6b40ea Mon Sep 17 00:00:00 2001 From: Michael Lyons Date: Wed, 22 Apr 2026 14:17:21 -0400 Subject: [PATCH 133/133] Add Pester build system Supersedes #163 Co-Authored-By: blue --- support/PowerShell.sublime-build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/support/PowerShell.sublime-build b/support/PowerShell.sublime-build index 0c17cd3f..774d9789 100644 --- a/support/PowerShell.sublime-build +++ b/support/PowerShell.sublime-build @@ -16,5 +16,9 @@ "cmd": ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "$file"], }, }, + { + "name": "Pester", + "cmd": ["pwsh", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "Invoke-Pester"], + } ], }