mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Add completion for Using keywords (#16514)
This commit is contained in:
@@ -423,6 +423,12 @@ namespace System.Management.Automation
|
||||
case TokenKind.Identifier:
|
||||
if (!tokenAtCursor.TokenFlags.HasFlag(TokenFlags.TypeName))
|
||||
{
|
||||
result = CompleteUsingKeywords(completionContext.CursorPosition.Offset, _tokens, ref replacementIndex, ref replacementLength);
|
||||
if (result is not null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = GetResultForIdentifier(completionContext, ref replacementIndex, ref replacementLength, isQuotedString);
|
||||
}
|
||||
|
||||
@@ -774,6 +780,12 @@ namespace System.Management.Automation
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = CompleteUsingKeywords(completionContext.CursorPosition.Offset, _tokens, ref replacementIndex, ref replacementLength);
|
||||
if (result is not null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((tokenAtCursor.TokenFlags & TokenFlags.Keyword) != 0)
|
||||
{
|
||||
completionContext.WordToComplete = tokenAtCursor.Text;
|
||||
@@ -998,6 +1010,7 @@ namespace System.Management.Automation
|
||||
result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty, ref replacementIndex, ref replacementLength, out _);
|
||||
break;
|
||||
}
|
||||
|
||||
case TokenKind.Break:
|
||||
case TokenKind.Continue:
|
||||
{
|
||||
@@ -1008,6 +1021,10 @@ namespace System.Management.Automation
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TokenKind.Using:
|
||||
return CompleteUsingKeywords(completionContext.CursorPosition.Offset, _tokens, ref replacementIndex, ref replacementLength);
|
||||
|
||||
case TokenKind.Dot:
|
||||
case TokenKind.ColonColon:
|
||||
case TokenKind.QuestionDot:
|
||||
@@ -1956,10 +1973,10 @@ namespace System.Management.Automation
|
||||
|
||||
private static List<CompletionResult> GetResultForIdentifier(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
|
||||
{
|
||||
List<CompletionResult> result = null;
|
||||
var tokenAtCursor = completionContext.TokenAtCursor;
|
||||
var lastAst = completionContext.RelatedAsts.Last();
|
||||
|
||||
List<CompletionResult> result = null;
|
||||
var tokenAtCursorText = tokenAtCursor.Text;
|
||||
completionContext.WordToComplete = tokenAtCursorText;
|
||||
|
||||
@@ -2487,5 +2504,81 @@ namespace System.Management.Automation
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<CompletionResult> CompleteUsingKeywords(int cursorOffset, Token[] tokens, ref int replacementIndex, ref int replacementLength)
|
||||
{
|
||||
var result = new List<CompletionResult>();
|
||||
Token tokenBeforeCursor = null;
|
||||
Token tokenAtCursor = null;
|
||||
|
||||
for (int i = tokens.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (tokens[i].Extent.EndOffset < cursorOffset && tokens[i].Kind != TokenKind.LineContinuation)
|
||||
{
|
||||
tokenBeforeCursor = tokens[i];
|
||||
break;
|
||||
}
|
||||
else if (tokens[i].Extent.StartOffset <= cursorOffset && tokens[i].Extent.EndOffset >= cursorOffset && tokens[i].Kind != TokenKind.LineContinuation)
|
||||
{
|
||||
tokenAtCursor = tokens[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenBeforeCursor is not null && tokenBeforeCursor.Kind == TokenKind.Using)
|
||||
{
|
||||
string wordToComplete = null;
|
||||
if (tokenAtCursor is not null)
|
||||
{
|
||||
replacementIndex = tokenAtCursor.Extent.StartOffset;
|
||||
replacementLength = tokenAtCursor.Extent.Text.Length;
|
||||
wordToComplete = tokenAtCursor.Text;
|
||||
}
|
||||
else
|
||||
{
|
||||
replacementIndex = cursorOffset;
|
||||
replacementLength = 0;
|
||||
}
|
||||
|
||||
foreach (var keyword in s_usingKeywords)
|
||||
{
|
||||
if (string.IsNullOrEmpty(wordToComplete) || keyword.StartsWith(wordToComplete, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Add(new CompletionResult(keyword, keyword, CompletionResultType.Keyword, GetUsingKeywordToolTip(keyword)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.Count > 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetUsingKeywordToolTip(string keyword)
|
||||
{
|
||||
switch (keyword)
|
||||
{
|
||||
case "assembly":
|
||||
return TabCompletionStrings.AssemblyKeywordDescription;
|
||||
case "module":
|
||||
return TabCompletionStrings.ModuleKeywordDescription;
|
||||
case "namespace":
|
||||
return TabCompletionStrings.NamespaceKeywordDescription;
|
||||
case "type":
|
||||
return TabCompletionStrings.TypeKeywordDescription;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly string[] s_usingKeywords = new string[]
|
||||
{
|
||||
"assembly",
|
||||
"module",
|
||||
"namespace",
|
||||
"type"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,4 +329,28 @@
|
||||
<data name="shrOperatorDescription" xml:space="preserve">
|
||||
<value>Shift Right bit operator. Inserts zero in the left-most bit position. For signed values, sign bit is preserved.</value>
|
||||
</data>
|
||||
<data name="AssemblyKeywordDescription" xml:space="preserve">
|
||||
<value>Specifies the path to a .NET assembly to load.
|
||||
|
||||
using assembly <.NET-assembly-path></value>
|
||||
</data>
|
||||
<data name="ModuleKeywordDescription" xml:space="preserve">
|
||||
<value>Specifies a PowerShell module to load classes from.
|
||||
|
||||
using module <ModuleName or Path>
|
||||
|
||||
using module <ModuleSpecification hashtable></value>
|
||||
</data>
|
||||
<data name="NamespaceKeywordDescription" xml:space="preserve">
|
||||
<value>Specifies a .NET namespace to resolve types from or a namespace alias.
|
||||
|
||||
using namespace <.NET-namespace>
|
||||
|
||||
using namespace <AliasName> = <.NET-namespace></value>
|
||||
</data>
|
||||
<data name="TypeKeywordDescription" xml:space="preserve">
|
||||
<value>Specifies an alias for a .NET Type.
|
||||
|
||||
using type <AliasName> = <.NET-type></value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -341,11 +341,25 @@ switch ($x)
|
||||
$res.CompletionMatches.Count | Should -BeGreaterThan 0
|
||||
}
|
||||
|
||||
It 'Should complete keyword' -Skip {
|
||||
It 'Should complete keyword with partial input' {
|
||||
$res = TabExpansion2 -inputScript 'using nam' -cursorColumn 'using nam'.Length
|
||||
$res.CompletionMatches[0].CompletionText | Should -BeExactly 'namespace'
|
||||
}
|
||||
|
||||
It 'Should complete keyword with no input' {
|
||||
$res = TabExpansion2 -inputScript 'using ' -cursorColumn 'using '.Length
|
||||
$res.CompletionMatches.CompletionText | Should -BeExactly 'assembly','module','namespace','type'
|
||||
}
|
||||
|
||||
It 'Should complete keyword with no input after line continuation' {
|
||||
$InputScript = @'
|
||||
using `
|
||||
|
||||
'@
|
||||
$res = TabExpansion2 -inputScript $InputScript -cursorColumn $InputScript.Length
|
||||
$res.CompletionMatches.CompletionText | Should -BeExactly 'assembly','module','namespace','type'
|
||||
}
|
||||
|
||||
It 'Should first suggest -Full and then -Functionality when using Get-Help -Fu<tab>' -Skip {
|
||||
$res = TabExpansion2 -inputScript 'Get-Help -Fu' -cursorColumn 'Get-Help -Fu'.Length
|
||||
$res.CompletionMatches[0].CompletionText | Should -BeExactly '-Full'
|
||||
|
||||
Reference in New Issue
Block a user