powershellLanguage top-level constant

Grammar const powershellLanguage

PowerShell. Keywords and operators are case-insensitive.

Implementation

const powershellLanguage = Grammar(
  name: 'powershell',
  aliases: ['ps1', 'pwsh', 'ps', 'posh'],
  fileExtensions: ['ps1', 'psm1', 'psd1'],
  shebangs: ['pwsh', 'powershell'],
  caseInsensitive: true,
  signatures: [
    r'\b(?:Get|Set|New|Remove|Write|Invoke|Import|Test)-[A-Z][a-zA-Z]+',
    r'^\s*param\s*\(',
    r'\$(?:PSScriptRoot|PSVersionTable|env:\w+)',
    r'\s-(?:eq|ne|like|match|notmatch)\s',
    r'\[CmdletBinding\(',
  ],
  rules: [
    TokenRule(r'^#!.*$', scope: Scopes.meta),
    BlockComment('<#', '#>'),
    LineComment('#'),
    // Here-strings: `@"` … `"@` expands variables, `@'` … `'@` does not.
    RegionRule(
      begin: r'@"(?=[ \t]*$)',
      end: r'^"@',
      scope: Scopes.string,
      rules: [IncludeRule('expandable')],
    ),
    RegionRule(begin: r"@'(?=[ \t]*$)", end: r"^'@", scope: Scopes.string),
    // The escape character is the backtick.
    QuotedString(
      '"',
      escape: '`',
      multiline: true,
      rules: [IncludeRule('expandable')],
    ),
    QuotedString("'", escape: null, doubled: true, multiline: true),
    IncludeRule('variables'),
    // Attributes: `[CmdletBinding()]`, `[Parameter(Mandatory)]`.
    TokenRule(r'(?<=\[)[A-Za-z_][\w.]*(?=\()', scope: Scopes.meta),
    // Type literals: `[string]`, `[System.IO.Path]`, `[int[]]`.
    TokenRule(r'\[[A-Za-z_][\w.]*(?:\[\])?\](?!\()', scope: Scopes.type),
    // Comparison and logical operators, then other `-Parameters`.
    TokenRule(
      r'(?<![\w$])-(?:c|i)?(?:eq|ne|gt|ge|lt|le|like|notlike|match|notmatch|'
      r'contains|notcontains|in|notin|replace|split|join|is|isnot|as)\b|'
      r'(?<![\w$])-(?:and|or|not|xor|band|bor|bxor|bnot|shl|shr|f)\b',
      scope: Scopes.operator,
    ),
    TokenRule(r'(?<![\w$])-[A-Za-z][A-Za-z0-9]*', scope: Scopes.attribute),
    Numbers(octal: false, separator: null, suffix: r'(?:[kmgtp]b)?[ld]?'),
    // Cmdlets and functions named `Verb-Noun`.
    TokenRule(
      r'(?<![\w$-])[A-Za-z]+-[A-Za-z][A-Za-z0-9]*(?![\w-])',
      scope: Scopes.function,
    ),
    TokenRule(r'(?<=::)[A-Za-z_]\w*', scope: Scopes.function),
    _memberCall,
    CommonRules.member,
    KeywordRule(
      {
        Scopes.keyword: [
          'begin', 'break', 'catch', 'class', 'clean', 'configuration', //
          'continue', 'data', 'define', 'do', 'dynamicparam', 'else',
          'elseif', 'end', 'enum', 'exit', 'filter', 'finally', 'for',
          'foreach', 'from', 'function', 'hidden', 'if', 'in',
          'inlinescript', 'parallel', 'param', 'process', 'return',
          'sequence', 'static', 'switch', 'throw', 'trap', 'try', 'until',
          'using', 'var', 'while', 'workflow',
        ],
      },
      otherwise: [
        TokenRule(r'(?<=\bfunction\s)[A-Za-z_][\w-]*', scope: Scopes.function),
      ],
    ),
    Operators('+-*/%=<>!|,'),
  ],
  repository: {
    'variables': [
      TokenRule(r'\$(?:true|false|null)\b', scope: Scopes.literal),
      TokenRule(r'\$this\b', scope: Scopes.variableLanguage),
      TokenRule(r'\$\{[^}\n]*\}', scope: Scopes.variable),
      TokenRule(
        r'[$@](?:(?:global|local|script|private|using|env|variable):)?'
        r'[A-Za-z_]\w*|\$[_?^$]',
        scope: Scopes.variable,
      ),
    ],
    // Inside double quotes: variables and `$( … )` subexpressions.
    'expandable': [
      RegionRule(
        begin: r'\$\(',
        end: r'\)',
        scope: Scopes.interpolation,
        rules: [IncludeRule('parens'), IncludeRule.self],
      ),
      IncludeRule('variables'),
    ],
    'parens': [
      RegionRule(
        begin: r'\(',
        end: r'\)',
        rules: [IncludeRule('parens'), IncludeRule.self],
      ),
    ],
  },
);