8000 Add tooltips for hashtable key completions by MartinGC94 · Pull Request #17864 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Add tooltips for hashtable key completions #17864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Mar 25, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -2368,6 +2368,16 @@ private static void NativeCommandArgumentCompletion(
break;
}

case "ConvertTo-Html":
{
if (parameterName.Equals("Property", StringComparison.OrdinalIgnoreCase))
{
NativeCompletionMemberName(context, result, commandAst, boundArguments?[parameterName]);
}

break;
}

case "New-Object":
{
if (parameterName.Equals("TypeName", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -5292,12 +5302,16 @@ private static List<CompletionResult> CompleteRequires(CompletionContext context

// Produce completions for all parameters that begin with the prefix we've found,
// but which haven't already been specified in the line we need to complete
foreach (KeyValuePair<string, string> parameter in s_requiresParameters)
foreach (string parameter in s_requiresParameters)
{
if (parameter.Key.StartsWith(currentParameterPrefix, StringComparison.OrdinalIgnoreCase)
&& !context.CursorPosition.Line.Contains($" -{parameter.Key}", StringComparison.OrdinalIgnoreCase))
if (parameter.StartsWith(currentParameterPrefix, StringComparison.OrdinalIgnoreCase)
&& !context.CursorPosition.Line.Contains($" -{parameter}", StringComparison.OrdinalIgnoreCase))
{
results.Add(new CompletionResult(parameter.Key, parameter.Key, CompletionResultType.ParameterName, parameter.Value));
string toolTip = ResourceManagerCache.GetResourceString(
typeof(CompletionCompleters).Assembly,
"System.Management.Automation.resources.TabCompletionStrings",
$"Requires{parameter}ParameterDescription");
results.Add(new CompletionResult(parameter, parameter, CompletionResultType.ParameterName, toolTip));
}
}

Expand All @@ -5322,11 +5336,15 @@ private static List<CompletionResult> CompleteRequires(CompletionContext context
// Complete PSEdition parameter values
if (currentParameterMatch.Value.Equals("PSEdition", StringComparison.OrdinalIgnoreCase))
{
foreach (KeyValuePair<string, string> psEditionEntry in s_requiresPSEditions)
foreach (string psEditionEntry in s_requiresPSEditions)
{
if (psEditionEntry.Key.StartsWith(currentValue, StringComparison.OrdinalIgnoreCase))
if (psEditionEntry.StartsWith(currentValue, StringComparison.OrdinalIgnoreCase))
{
results.Add(new CompletionResult(psEditionEntry.Key, psEditionEntry.Key, CompletionResultType.ParameterValue, psEditionEntry.Value));
string toolTip = ResourceManagerCache.GetResourceString(
typeof(CompletionCompleters).Assembly,
"System.Management.Automation.resources.TabCompletionStrings",
$"RequiresPsEdition{psEditionEntry}Description");
results.Add(new CompletionResult(psEditionEntry, psEditionEntry, CompletionResultType.ParameterValue, toolTip));
}
}

Expand Down Expand Up @@ -5354,7 +5372,7 @@ private static List<CompletionResult> CompleteRequires(CompletionContext context
hashtableKeyMatches = Regex.Matches(hashtableString, @"(@{|;)\s*(?:'|\""|\w*)\w*");

// Build the list of keys we might want to complete, based on what's already been provided
var moduleSpecKeysToComplete = new HashSet<string>(s_requiresModuleSpecKeys.Keys);
var moduleSpecKeysToComplete = new HashSet<string>(s_requiresModuleSpecKeys);
bool sawModuleNameLast = false;
foreach (Match existingHashtableKeyMatch in hashtableKeyMatches)
{
Expand Down Expand Up @@ -5410,35 +5428,39 @@ private static List<CompletionResult> CompleteRequires(CompletionContext context
{
if (moduleSpecKey.StartsWith(currentValue, StringComparison.OrdinalIgnoreCase))
{
results.Add(new CompletionResult(moduleSpecKey, moduleSpecKey, CompletionResultType.ParameterValue, s_requiresModuleSpecKeys[moduleSpecKey]));
string toolTip = ResourceManagerCache.GetResourceString(
typeof(CompletionCompleters).Assembly,
"System.Management.Automation.resources.TabCompletionStrings",
$"RequiresModuleSpec{moduleSpecKey}Description");
results.Add(new CompletionResult(moduleSpecKey, moduleSpecKey, CompletionResultType.ParameterValue, toolTip));
}
}
}

return results;
}

private static readonly IReadOnlyDictionary<string, string> s_requiresParameters = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase)
private static readonly string[] s_requiresParameters = new string[]
{
{ "Modules", "Specifies PowerShell modules that the script requires." },
{ "PSEdition", "Specifies a PowerShell edition that the script requires." },
{ "RunAsAdministrator", "Specifies that PowerShell must be running as administrator on Windows." },
{ "Version", "Specifies the minimum version of PowerShell that the script requires." },
"Modules",
"PSEdition",
"RunAsAdministrator",
"Version"
};

private static readonly IReadOnlyDictionary<string, string> s_requiresPSEditions = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase)
private static readonly string[] s_requiresPSEditions = new string[]
{
{ "Core", "Specifies that the script requires PowerShell Core to run." },
{ "Desktop", "Specifies that the script requires Windows PowerShell to run." },
"Core",
"Desktop"
};

private static readonly IReadOnlyDictionary<string, string> s_requiresModuleSpecKeys = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase)
private static readonly string[] s_requiresModuleSpecKeys = new string[]
{
{ "ModuleName", "Required. Specifies the module name." },
{ "GUID", "Optional. Specifies the GUID of the module." },
{ "ModuleVersion", "Specifies a minimum acceptable version of the module." },
{ "RequiredVersion", "Specifies an exact, required version of the module." },
{ "MaximumVersion", "Specifies the maximum acceptable version of the module." },
"ModuleName",
"GUID",
"ModuleVersion",
"RequiredVersion",
"MaximumVersion"
};

private static readonly char[] s_hashtableKeyPrefixes = new[]
Expand Down Expand Up @@ -5483,7 +5505,7 @@ private static List<CompletionResult> CompleteCommentHelp(CompletionContext cont
replacementIndex = context.TokenAtCursor.Extent.StartOffset + lineKeyword.Index;
replacementLength = lineKeyword.Value.Length;

var validKeywords = new HashSet<String>(s_commentHelpKeywords.Keys, StringComparer.OrdinalIgnoreCase);
var validKeywords = new HashSet<string>(s_commentHelpKeywords, StringComparer.OrdinalIgnoreCase);
foreach (Match keyword in usedKeywords)
{
if (keyword == lineKeyword || s_commentHelpAllowedDuplicateKeywords.Contains(keyword.Value))
Expand All @@ -5499,7 +5521,11 @@ private static List<CompletionResult> CompleteCommentHelp(CompletionContext cont
{
if (keyword.StartsWith(lineKeyword.Value, StringComparison.OrdinalIgnoreCase))
{
result.Add(new CompletionResult(keyword, keyword, CompletionResultType.Keyword, s_commentHelpKeywords[keyword]));
string toolTip = ResourceManagerCache.GetResourceString(
typeof(CompletionCompleters).Assembly,
"System.Management.Automation.resources.TabCompletionStrings",
$"CommentHelp{keyword}KeywordDescription");
result.Add(new CompletionResult(keyword, keyword, CompletionResultType.Keyword, toolTip));
}
}

Expand Down Expand Up @@ -5559,23 +5585,23 @@ private static List<CompletionResult> CompleteCommentHelp(CompletionContext cont
return null;
}

private static readonly IReadOnlyDictionary<string, string> s_commentHelpKeywords = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "SYNOPSIS", "A brief description of the function or script. This keyword can be used only once in each topic." },
{ "DESCRIPTION", "A detailed description of the function or script. This keyword can be used only once in each topic." },
{ "PARAMETER", ".PARAMETER <Parameter-Name>\nThe description of a parameter. Add a .PARAMETER keyword for each parameter in the function or script syntax." },
{ "EXAMPLE", "A sample command that uses the function or script, optionally followed by sample output and a description. Repeat this keyword for each example." },
{ "INPUTS", "The .NET types of objects that can be piped to the function or script. You can also include a description of the input objects." },
{ "OUTPUTS", "The .NET type of the objects that the cmdlet returns. You can also include a description of the returned objects." },
{ "NOTES", "Additional information about the function or script." },
{ "LINK", "The name of a related topic. Repeat the .LINK keyword for each related topic. The .Link keyword content can also include a URI to an online version of the same help topic." },
{ "COMPONENT", "The name of the technology or feature that the function or script uses, or to which it is related." },
{ "ROLE", "The name of the user role for the help topic." },
{ "FUNCTIONALITY", "The keywords that describe the intended use of the function." },
{ "FORWARDHELPTARGETNAME", ".FORWARDHELPTARGETNAME <Command-Name>\nRedirects to the help topic for the specified command." },
{ "FORWARDHELPCATEGORY", ".FORWARDHELPCATEGORY <Category>\nSpecifies the help category of the item in .ForwardHelpTargetName" },
{ "REMOTEHELPRUNSPACE", ".REMOTEHELPRUNSPACE <PSSession-variable>\nSpecifies a session that contains the help topic. Enter a variable that contains a PSSession object." },
{ "EXTERNALHELP", ".EXTERNALHELP <XML Help File>\nThe .ExternalHelp keyword is required when a function or script is documented in XML files." }
private static readonly string[] s_commentHelpKeywords = new string[]
{
"SYNOPSIS",
"DESCRIPTION",
"PARAMETER",
"EXAMPLE",
"INPUTS",
"OUTPUTS",
"NOTES",
"LINK",
"COMPONENT",
"ROLE",
"FUNCTIONALITY",
"FORWARDHELPTARGETNAME",
"FORWARDHELPCATEGORY",
"REMOTEHELPRUNSPACE",
"EXTERNALHELP"
};

private static readonly HashSet<string> s_commentHelpAllowedDuplicateKeywords = new(StringComparer.OrdinalIgnoreCase)
Expand Down Expand Up @@ -7358,7 +7384,7 @@ internal static List<CompletionResult> CompleteHashtableKey(CompletionContext co
parentAst = parentAst.Parent;
}

ExitWhileLoop:
ExitWhileLoop:

bool hashtableIsNested = nestedHashtableKeys.Count > 0;
int cursorOffset = completionContext.CursorPosition.Offset;
Expand All @@ -7381,7 +7407,7 @@ internal static List<CompletionResult> CompleteHashtableKey(CompletionContext co
}

var result = new List<CompletionResult>();
foreach (var key in s_requiresModuleSpecKeys.Keys)
foreach (var key in s_requiresModuleSpecKeys)
{
if (excludedKeys.Contains(key)
|| (wordToComplete is not null && !key.StartsWith(wordToComplete, StringComparison.OrdinalIgnoreCase))
Expand All @@ -7390,7 +7416,13 @@ internal static List<CompletionResult> CompleteHashtableKey(CompletionContext co
{
continue;
}
result.Add(new CompletionResult(key, key, CompletionResultType.Property, s_requiresModuleSpecKeys[key]));

string toolTip = ResourceManagerCache.GetResourceString(
typeof(CompletionCompleters).Assembly,
"System.Management.Automation.resources.TabCompletionStrings",
$"RequiresModuleSpec{key}Description");

result.Add(new CompletionResult(key, key, CompletionResultType.Property, toolTip));
}

return result;
Expand Down Expand Up @@ -7492,7 +7524,10 @@ internal static List<CompletionResult> CompleteHashtableKey(CompletionContext co
case "Sort-Object":
return GetSpecialHashTableKeyMembers(excludedKeys, wordToComplete, "Expression", "Ascending", "Descending");
case "Group-Object":
case "Compare-Object":
return GetSpecialHashTableKeyMembers(excludedKeys, wordToComplete, "Expression");
case "ConvertTo-Html":
return GetSpecialHashTableKeyMembers(excludedKeys, wordToComplete, "Expression", "Label", "Width", "Alignment");
case "Format-Table":
return GetSpecialHashTableKeyMembers(excludedKeys, wordToComplete, "Expression", "FormatString", "Label", "Width", "Alignment");
case "Format-List":
Expand Down Expand Up @@ -7642,7 +7677,12 @@ private static List<CompletionResult> GetSpecialHashTableKeyMembers(HashSet<stri
{
if ((string.IsNullOrEmpty(wordToComplete) || key.StartsWith(wordToComplete, StringComparison.OrdinalIgnoreCase)) && !excludedKeys.Contains(key))
{
result.Add(new CompletionResult(key, key, CompletionResultType.Property, key));
string toolTip = ResourceManagerCache.GetResourceString(
typeof(CompletionCompleters).Assembly,
"System.Management.Automation.resources.TabCompletionStrings",
$"{key}HashtableKeyDescription");

result.Add(new CompletionResult(key, key, CompletionResultType.Property, toolTip));
}
}

Expand Down
Loading
0