Skip to content

Commit 687026f

Browse files
Add space to completion trigger characters
Adding space to completion triggers lets us automatically give completion results for parameter values. This also required building in some support for marking completion results as "Incomplete". This means that the client will not cache results when standard identifier characters are typed. Mainly, this solves the scenario where you type space, get file completion results, and then type `-`. You expect to then get parameter names, but without marking "Incomplete", it will instead filter the file results.
1 parent bdb8343 commit 687026f

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/PowerShellEditorServices/Services/TextDocument/Handlers/CompletionHandler.cs

+20-6
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public PsesCompletionHandler(
4646
// TODO: What do we do with the arguments?
4747
DocumentSelector = LspUtils.PowerShellDocumentSelector,
4848
ResolveProvider = true,
49-
TriggerCharacters = new[] { ".", "-", ":", "\\", "$" }
49+
TriggerCharacters = new[] { ".", "-", ":", "\\", "$", " " }
5050
};
5151

5252
public override async Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
@@ -55,13 +55,16 @@ public override async Task<CompletionList> Handle(CompletionParams request, Canc
5555
int cursorColumn = request.Position.Character + 1;
5656

5757
ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
58-
IEnumerable<CompletionItem> completionResults = await GetCompletionsInFileAsync(
58+
(bool isIncomplete, IReadOnlyList<CompletionItem> completionResults) = await GetCompletionsInFileAsync(
5959
scriptFile,
6060
cursorLine,
6161
cursorColumn,
6262
cancellationToken).ConfigureAwait(false);
6363

64-
return new CompletionList(completionResults);
64+
// Treat completions trigged by space as incomplete so that `gci `
65+
// and then typing `-` doesn't just filter the list of parameter values
66+
// (typically files) returned by the space completion
67+
return new CompletionList(completionResults, isIncomplete || request.Context.TriggerCharacter is " ");
6568
}
6669

6770
// Handler for "completionItem/resolve". In VSCode this is fired when a completion item is highlighted in the completion list.
@@ -113,7 +116,7 @@ public override async Task<CompletionItem> Handle(CompletionItem request, Cancel
113116
/// <returns>
114117
/// A CommandCompletion instance completions for the identified statement.
115118
/// </returns>
116-
internal async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
119+
internal async Task<(bool isIncomplete, IReadOnlyList<CompletionItem> matches)> GetCompletionsInFileAsync(
117120
ScriptFile scriptFile,
118121
int lineNumber,
119122
int columnNumber,
@@ -131,21 +134,32 @@ internal async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
131134

132135
if (result.CompletionMatches.Count == 0)
133136
{
134-
return Array.Empty<CompletionItem>();
137+
return (true, Array.Empty<CompletionItem>());
135138
}
136139

137140
BufferRange replacedRange = scriptFile.GetRangeBetweenOffsets(
138141
result.ReplacementIndex,
139142
result.ReplacementIndex + result.ReplacementLength);
140143

144+
bool isIncomplete = false;
141145
// Create OmniSharp CompletionItems from PowerShell CompletionResults. We use a for loop
142146
// because the index is used for sorting.
143147
CompletionItem[] completionItems = new CompletionItem[result.CompletionMatches.Count];
144148
for (int i = 0; i < result.CompletionMatches.Count; i++)
145149
{
150+
CompletionResult completionMatch = result.CompletionMatches[i];
151+
152+
// If a completion result is a variable scope like `$script:` we want to
153+
// mark as incomplete so on typing `:` completion changes.
154+
if (completionMatch.ResultType is CompletionResultType.Variable
155+
&& completionMatch.CompletionText.EndsWith(":"))
156+
{
157+
isIncomplete = true;
158+
}
159+
146160
completionItems[i] = CreateCompletionItem(result.CompletionMatches[i], replacedRange, i + 1);
147161
}
148-
return completionItems;
162+
return (isIncomplete, completionItems);
149163
}
150164

151165
internal static CompletionItem CreateCompletionItem(

0 commit comments

Comments
 (0)