@@ -2,11 +2,24 @@ import * as vscode from 'vscode';
2
2
3
3
export class PowerShellVariableInlineValuesProvider implements vscode . InlineValuesProvider {
4
4
5
- provideInlineValues ( document : vscode . TextDocument , viewport : vscode . Range , context : vscode . InlineValueContext ) : vscode . ProviderResult < vscode . InlineValue [ ] > {
5
+ // Known constants
6
+ private readonly knownConstants = / ^ \$ (?: t r u e | f a l s e | n u l l ) $ / i;
7
+
8
+ // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-5.1#scope-modifiers
9
+ private readonly supportedScopes = / ^ (?: g l o b a l | l o c a l | s c r i p t | p r i v a t e | u s i n g | v a r i a b l e ) $ / i;
10
+
11
+ // Variable patterns
12
+ // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables?view=powershell-5.1#variable-names-that-include-special-characters
13
+ private readonly alphanumChars = / (?: \p{ Lu} | \p{ Ll} | \p{ Lt} | \p{ Lm} | \p{ Lo} | \p{ Nd} | [ _ ? ] ) / . source ;
14
+ private readonly variableRegex = new RegExp ( [
15
+ '(?:\\$\\{(?<specialName>.*?)(?<!`)\\})' , // Special characters variables. Lazy match until unescaped }
16
+ `(?:\\$\\w+:${ this . alphanumChars } +)` , // Scoped variables
17
+ `(?:\\$${ this . alphanumChars } +)` , // Normal variables
18
+ ] . join ( '|' ) , 'giu' ) ; // u flag to support unicode char classes
19
+
20
+ provideInlineValues ( document : vscode . TextDocument , viewport : vscode . Range , context : vscode . InlineValueContext ) : vscode . ProviderResult < vscode . InlineValue [ ] > {
6
21
const allValues : vscode . InlineValue [ ] = [ ] ;
7
22
8
- const ignoredVariables = / ^ \$ (?: t r u e | f a l s e | n u l l ) $ / i;
9
-
10
23
for ( let l = 0 ; l <= context . stoppedLocation . end . line ; l ++ ) {
11
24
const line = document . lineAt ( l ) ;
12
25
@@ -15,26 +28,26 @@ export class PowerShellVariableInlineValuesProvider implements vscode.InlineValu
15
28
continue ;
16
29
}
17
30
18
- const variableMatches = / (?: \$ { ( .* ) } ) | (?: \$ \S + : \S + ) | (?: \$ \S + ) / gi;
19
- for ( let match = variableMatches . exec ( line . text ) ; match ; match = variableMatches . exec ( line . text ) ) {
20
- // If we're looking at an "anything goes" variable, that has a capture group so use that instead
31
+ for ( let match = this . variableRegex . exec ( line . text ) ; match ; match = this . variableRegex . exec ( line . text ) ) {
32
+ // If we're looking at special characters variable, use the extracted variable name in capture group
21
33
let varName = match [ 0 ] [ 1 ] === '{'
22
- ? '$' + match [ 1 ]
34
+ ? '$' + match . groups ?. specialName ?. replace ( / ` ( . ) / g , '$1' ) // Remove backticks used as escape char for curly braces, unicode etc.
23
35
: match [ 0 ] ;
24
36
25
37
// If there's a scope, we need to remove it
26
38
const colon = varName . indexOf ( ':' ) ;
27
39
if ( colon !== - 1 ) {
28
- varName = '$' + varName . substring ( colon + 1 ) ;
29
- }
40
+ // If invalid scope, ignore
41
+ const scope = varName . substring ( 1 , colon ) ;
42
+ if ( ! this . supportedScopes . test ( scope ) ) {
43
+ continue ;
44
+ }
30
45
31
- // These characters need to be trimmed off
32
- if ( [ ';' , ',' , '-' , '+' , '/' , '*' ] . includes ( varName [ varName . length - 1 ] ) ) {
33
- varName = varName . substring ( 0 , varName . length - 1 ) ;
46
+ varName = '$' + varName . substring ( colon + 1 ) ;
34
47
}
35
48
36
49
// If known PowerShell constant, ignore
37
- if ( ignoredVariables . test ( varName ) ) {
50
+ if ( this . knownConstants . test ( varName ) ) {
38
51
continue ;
39
52
}
40
53
0 commit comments