From a270be4f2f1236d9bc1b31b6214f1672096788b7 Mon Sep 17 00:00:00 2001 From: Allison Chou Date: Wed, 27 Sep 2023 13:17:11 -0700 Subject: [PATCH] Fix completion bugs (#6441) --- l10n/bundle.l10n.json | 1 + .../provisionalCompletionOrchestrator.ts | 3 +- .../completion/razorCompletionItemProvider.ts | 45 ++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index e7ee67d46..a4601403c 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -110,6 +110,7 @@ "Unexpected error when attaching to C# preview window.": "Unexpected error when attaching to C# preview window.", "Razor C# copied to clipboard": "Razor C# copied to clipboard", "Copy C#": "Copy C#", + "{0} Keyword": "{0} Keyword", "Unexpected completion trigger kind: {0}": "Unexpected completion trigger kind: {0}", "1 reference": "1 reference", "{0} references": "{0} references", diff --git a/src/razor/src/completion/provisionalCompletionOrchestrator.ts b/src/razor/src/completion/provisionalCompletionOrchestrator.ts index 62d446ac3..28d171482 100644 --- a/src/razor/src/completion/provisionalCompletionOrchestrator.ts +++ b/src/razor/src/completion/provisionalCompletionOrchestrator.ts @@ -134,7 +134,8 @@ export class ProvisionalCompletionOrchestrator { htmlPosition, provisionalPosition, completionContext, - projection.languageKind + projection.languageKind, + newDocument ); // We track when we add provisional dots to avoid doing unnecessary work on commonly invoked events. diff --git a/src/razor/src/completion/razorCompletionItemProvider.ts b/src/razor/src/completion/razorCompletionItemProvider.ts index c0b11440d..39a65dbf1 100644 --- a/src/razor/src/completion/razorCompletionItemProvider.ts +++ b/src/razor/src/completion/razorCompletionItemProvider.ts @@ -30,7 +30,8 @@ export class RazorCompletionItemProvider extends RazorLanguageFeatureBase implem hostDocumentPosition: vscode.Position, projectedPosition: vscode.Position, context: vscode.CompletionContext, - language: LanguageKind + language: LanguageKind, + razorDocument: vscode.TextDocument ) { if (projectedUri) { // "@" is not a valid trigger character for C# / HTML and therefore we need to translate @@ -86,6 +87,11 @@ export class RazorCompletionItemProvider extends RazorLanguageFeatureBase implem // In the code behind it's represented as __o = DateTime. const completionCharacterOffset = projectedPosition.character - hostDocumentPosition.character; for (const completionItem of completionItems) { + // vscode.CompletionItemKind is off by one compared to the LSP CompletionItemKind. + if (completionItem.kind !== undefined) { + completionItem.kind = completionItem.kind - 1; + } + const doc = completionItem.documentation as vscode.MarkdownString; if (doc && doc.value) { // Without this, the documentation doesn't get rendered in the editor. @@ -166,6 +172,8 @@ export class RazorCompletionItemProvider extends RazorLanguageFeatureBase implem } } + this.addUsingKeyword(language, razorDocument, hostDocumentPosition, completionItems); + const isIncomplete = completions instanceof Array ? false : completions ? completions.isIncomplete : false; return new vscode.CompletionList(completionItems, isIncomplete); } @@ -221,7 +229,8 @@ export class RazorCompletionItemProvider extends RazorLanguageFeatureBase implem position, projection.position, context, - projection.languageKind + projection.languageKind, + document ); return completionList; @@ -278,6 +287,38 @@ export class RazorCompletionItemProvider extends RazorLanguageFeatureBase implem return item; } + + private static addUsingKeyword( + language: LanguageKind, + razorDocument: vscode.TextDocument, + hostDocumentPosition: vscode.Position, + completionItems: vscode.CompletionItem[] + ) { + // This is an ugly hack, but it's needed to get the "using" keyword to show up in the completion list. + // The reason it doesn't show up is because the C# generated document puts the position of the cursor + // at '__o = [||]', which isn't a valid location for a using statement. + if (language == LanguageKind.CSharp) { + const line = razorDocument.lineAt(hostDocumentPosition.line); + const lineText = line.text.substring(0, hostDocumentPosition.character); + if ( + lineText.endsWith('@') || + lineText.endsWith( + '@u' || + lineText.endsWith('@us') || + lineText.endsWith('@usi') || + lineText.endsWith('@usin') || + lineText.endsWith('@using') + ) + ) { + const usingItem = new vscode.CompletionItem('using', vscode.CompletionItemKind.Keyword); + + // Matching Roslyn's documentation behavior + (usingItem).documentation = vscode.l10n.t('{0} Keyword', 'using'); + + completionItems.push(usingItem); + } + } + } } function getTriggerKind(triggerKind: vscode.CompletionTriggerKind): CompletionTriggerKind {