mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Add QuoteCompletionText method to CompletionHelpers class (#25180)
Unifies how quoting a given completion text works.
This commit is contained in:
+12
-137
@@ -524,17 +524,7 @@ namespace System.Management.Automation
|
||||
+ moduleInfo.ModuleType.ToString() + "\r\nPath: "
|
||||
+ moduleInfo.Path;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, toolTip));
|
||||
}
|
||||
@@ -1844,23 +1834,8 @@ namespace System.Management.Automation
|
||||
{
|
||||
string realEntry = entry;
|
||||
string completionText = entry;
|
||||
if (quote == string.Empty)
|
||||
{
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(entry))
|
||||
{
|
||||
realEntry = CodeGeneration.EscapeSingleQuotedStringContent(entry);
|
||||
completionText = "'" + realEntry + "'";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (quote.Equals("'", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
realEntry = CodeGeneration.EscapeSingleQuotedStringContent(entry);
|
||||
}
|
||||
|
||||
completionText = quote + realEntry + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, entry, CompletionResultType.ParameterValue, entry));
|
||||
}
|
||||
@@ -3220,17 +3195,7 @@ namespace System.Management.Automation
|
||||
var completionText = eventLog.Log.ToString();
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
if (pattern.IsMatch(listItemText))
|
||||
{
|
||||
@@ -3311,17 +3276,7 @@ namespace System.Management.Automation
|
||||
var completionText = psJob.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3386,17 +3341,7 @@ namespace System.Management.Automation
|
||||
var completionText = psJob.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3526,17 +3471,7 @@ namespace System.Management.Automation
|
||||
continue;
|
||||
|
||||
uniqueSet.Add(completionText);
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
// on macOS, system processes names will be empty if PowerShell isn't run as `sudo`
|
||||
if (string.IsNullOrEmpty(listItemText))
|
||||
@@ -3579,17 +3514,7 @@ namespace System.Management.Automation
|
||||
var completionText = providerInfo.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3627,17 +3552,7 @@ namespace System.Management.Automation
|
||||
var completionText = driveInfo.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3678,17 +3593,7 @@ namespace System.Management.Automation
|
||||
var completionText = serviceInfo.DisplayName;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3709,17 +3614,7 @@ namespace System.Management.Automation
|
||||
var completionText = serviceInfo.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3815,17 +3710,7 @@ namespace System.Management.Automation
|
||||
var completionText = aliasInfo.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
@@ -3878,17 +3763,7 @@ namespace System.Management.Automation
|
||||
var completionText = trace.Name;
|
||||
var listItemText = completionText;
|
||||
|
||||
if (CompletionHelpers.CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
var quoteInUse = quote == string.Empty ? "'" : quote;
|
||||
if (quoteInUse == "'")
|
||||
completionText = completionText.Replace("'", "''");
|
||||
completionText = quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
else
|
||||
{
|
||||
completionText = quote + completionText + quote;
|
||||
}
|
||||
completionText = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
|
||||
result.Add(new CompletionResult(completionText, listItemText, CompletionResultType.ParameterValue, listItemText));
|
||||
}
|
||||
|
||||
@@ -36,9 +36,7 @@ namespace System.Management.Automation
|
||||
{
|
||||
if (pattern.IsMatch(value))
|
||||
{
|
||||
string completionText = quote == string.Empty
|
||||
? value
|
||||
: quote + value + quote;
|
||||
string completionText = QuoteCompletionText(value, quote);
|
||||
|
||||
string listItemText = value;
|
||||
|
||||
@@ -140,5 +138,34 @@ namespace System.Management.Automation
|
||||
|
||||
private static bool ContainsCharsToCheck(ReadOnlySpan<char> text)
|
||||
=> text.ContainsAny(s_defaultCharsToCheck);
|
||||
|
||||
/// <summary>
|
||||
/// Quotes a given completion text.
|
||||
/// </summary>
|
||||
/// <param name="completionText">
|
||||
/// The text to be quoted.
|
||||
/// </param>
|
||||
/// <param name="quote">
|
||||
/// The quote character to use for enclosing the text. Defaults to a single quote if not provided.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The quoted <paramref name="completionText"/>.
|
||||
/// </returns>
|
||||
internal static string QuoteCompletionText(string completionText, string quote)
|
||||
{
|
||||
if (!CompletionRequiresQuotes(completionText))
|
||||
{
|
||||
return quote + completionText + quote;
|
||||
}
|
||||
|
||||
string quoteInUse = string.IsNullOrEmpty(quote) ? "'" : quote;
|
||||
|
||||
if (quoteInUse == "'")
|
||||
{
|
||||
completionText = CodeGeneration.EscapeSingleQuotedStringContent(completionText);
|
||||
}
|
||||
|
||||
return quoteInUse + completionText + quoteInUse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,70 @@ namespace PSTests.Parallel
|
||||
{
|
||||
public class CompletionHelpersTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("", "'", "''")]
|
||||
[InlineData("", "\"", "\"\"")]
|
||||
[InlineData("'", "'", "''''")]
|
||||
[InlineData("", "", "''")]
|
||||
[InlineData("", null, "''")]
|
||||
[InlineData("word", "'", "'word'")]
|
||||
[InlineData("word", "\"", "\"word\"")]
|
||||
[InlineData("word's", "'", "'word''s'")]
|
||||
[InlineData("already 'quoted'", "'", "'already ''quoted'''")]
|
||||
[InlineData("multiple 'quotes' in 'text'", "'", "'multiple ''quotes'' in ''text'''")]
|
||||
[InlineData("\"word\"", "'", "'\"word\"'")]
|
||||
[InlineData("'word'", "'", "''word''")]
|
||||
[InlineData("word", "", "word")]
|
||||
[InlineData("word", null, "word")]
|
||||
[InlineData("\"word\"", "\"", "\"\"word\"\"")]
|
||||
[InlineData("'word'", "\"", "\"'word'\"")]
|
||||
[InlineData("word with space", "'", "'word with space'")]
|
||||
[InlineData("word with space", "\"", "\"word with space\"")]
|
||||
[InlineData("word\"with\"quotes", "'", "'word\"with\"quotes'")]
|
||||
[InlineData("word'with'quotes", "\"", "\"word'with'quotes\"")]
|
||||
[InlineData("while", "'", "'while'")]
|
||||
[InlineData("while", "", "while")]
|
||||
[InlineData("while", "\"", "\"while\"")]
|
||||
[InlineData("$variable", "'", "'$variable'")]
|
||||
[InlineData("$variable", "", "$variable")]
|
||||
[InlineData("$variable", "\"", "\"$variable\"")]
|
||||
[InlineData("key$word", "'", "'key$word'")]
|
||||
[InlineData("key$word", "", "'key$word'")]
|
||||
[InlineData("key$word", "\"", "\"key$word\"")]
|
||||
public void TestQuoteCompletionText(
|
||||
string completionText,
|
||||
string quote,
|
||||
string expected)
|
||||
{
|
||||
string result = CompletionHelpers.QuoteCompletionText(completionText, quote);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("normaltext", false)]
|
||||
[InlineData("$variable", false)]
|
||||
[InlineData("abc def", true)]
|
||||
[InlineData("while", false)] // PowerShell keyword
|
||||
[InlineData("key$word", true)]
|
||||
[InlineData("abc`def", true)]
|
||||
[InlineData("normal-text", false)]
|
||||
[InlineData("\"doublequotes\"", false)]
|
||||
[InlineData("'singlequotes'", false)]
|
||||
[InlineData("normal 'text'", true)]
|
||||
[InlineData("normal \"text\"", true)]
|
||||
[InlineData("text with ' and \"", true)]
|
||||
[InlineData("text\"with\"quotes", false)]
|
||||
[InlineData("text'with'quotes", false)]
|
||||
[InlineData("\"key$", true)]
|
||||
[InlineData("\"", true)]
|
||||
[InlineData("'", true)]
|
||||
[InlineData("", true)]
|
||||
public void TestCompletionRequiresQuotes(string completion, bool expected)
|
||||
{
|
||||
bool result = CompletionHelpers.CompletionRequiresQuotes(completion);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "", "")]
|
||||
[InlineData("\"", "", "\"")]
|
||||
|
||||
Reference in New Issue
Block a user