From 8eb37cc44dc318bc1dfd42544a8751d53daa0c47 Mon Sep 17 00:00:00 2001 From: MartinGC94 <42123497+MartinGC94@users.noreply.github.com> Date: Mon, 25 Jul 2022 20:17:26 +0200 Subject: [PATCH] Prevent braces from being removed when completing variables (#17751) --- .../engine/CommandCompletion/CompletionCompleters.cs | 11 ++++++----- .../Host/TabCompletion/TabCompletion.Tests.ps1 | 8 +++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index 679ad427e9..8c247de13b 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -4789,6 +4789,7 @@ namespace System.Management.Automation var lastAst = context.RelatedAsts?.Last(); var variableAst = lastAst as VariableExpressionAst; var prefix = variableAst != null && variableAst.Splatted ? "@" : "$"; + bool tokenAtCursorUsedBraces = context.TokenAtCursor is not null && context.TokenAtCursor.Text.StartsWith("${"); // Look for variables in the input (e.g. parameters, etc.) before checking session state - these // variables might not exist in session state yet. @@ -4934,7 +4935,7 @@ namespace System.Management.Automation } } - var completedName = (name.IndexOfAny(s_charactersRequiringQuotes) == -1) + var completedName = (!tokenAtCursorUsedBraces && name.IndexOfAny(s_charactersRequiringQuotes) == -1) ? prefix + provider + name : prefix + "{" + provider + name + "}"; AddUniqueVariable(hashedResults, results, completedName, name, tooltip); @@ -4957,7 +4958,7 @@ namespace System.Management.Automation if (!string.IsNullOrEmpty(name)) { name = "env:" + name; - var completedName = (name.IndexOfAny(s_charactersRequiringQuotes) == -1) + var completedName = (!tokenAtCursorUsedBraces && name.IndexOfAny(s_charactersRequiringQuotes) == -1) ? prefix + name : prefix + "{" + name + "}"; AddUniqueVariable(hashedResults, results, completedName, name, "[string]" + name); @@ -4972,7 +4973,7 @@ namespace System.Management.Automation { if (wildcardPattern.IsMatch(specialVariable)) { - var completedName = (specialVariable.IndexOfAny(s_charactersRequiringQuotes) == -1) + var completedName = (!tokenAtCursorUsedBraces && specialVariable.IndexOfAny(s_charactersRequiringQuotes) == -1) ? prefix + specialVariable : prefix + "{" + specialVariable + "}"; @@ -4998,7 +4999,7 @@ namespace System.Management.Automation var name = driveInfo.Name; if (name != null && !string.IsNullOrWhiteSpace(name) && name.Length > 1) { - var completedName = (name.IndexOfAny(s_charactersRequiringQuotes) == -1) + var completedName = (!tokenAtCursorUsedBraces && name.IndexOfAny(s_charactersRequiringQuotes) == -1) ? prefix + name + ":" : prefix + "{" + name + ":}"; @@ -5014,7 +5015,7 @@ namespace System.Management.Automation { if (scopePattern.IsMatch(scope)) { - var completedName = (scope.IndexOfAny(s_charactersRequiringQuotes) == -1) + var completedName = (!tokenAtCursorUsedBraces && scope.IndexOfAny(s_charactersRequiringQuotes) == -1) ? prefix + scope : prefix + "{" + scope + "}"; AddUniqueVariable(hashedResults, results, completedName, scope, scope); diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 index 790dbe9ecc..2134d64530 100644 --- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 +++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 @@ -358,6 +358,12 @@ switch ($x) $res.CompletionMatches[1].CompletionText | Should -BeExactly '-Functionality' } + It 'Should not remove braces when completing variable with braces' { + $Text = '"Hello${psversiont}World"' + $res = TabExpansion2 -inputScript $Text -cursorColumn $Text.IndexOf('p') + $res.CompletionMatches[0].CompletionText | Should -BeExactly '${PSVersionTable}' + } + It 'Should work for variable assignment of enum type: ' -TestCases @( @{ inputStr = '$ErrorActionPreference = '; filter = ''; doubleQuotes = $false } @{ inputStr = '$ErrorActionPreference='; filter = ''; doubleQuotes = $false } @@ -1109,7 +1115,7 @@ ConstructorTestClass(int i, bool b) @{ inputStr = '[System.Management.Automation.Runspaces.runspacef'; expected = 'System.Management.Automation.Runspaces.RunspaceFactory'; setup = $null } @{ inputStr = '[specialfol'; expected = 'System.Environment+SpecialFolder'; setup = $null } ## tab completion for variable names in '{}' - @{ inputStr = '${PSDefault'; expected = '$PSDefaultParameterValues'; setup = $null } + @{ inputStr = '${PSDefault'; expected = '${PSDefaultParameterValues}'; setup = $null } ) }