diff --git a/src/services/completions.ts b/src/services/completions.ts index 5b11fc7a3c1..ac1133c07cb 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2847,7 +2847,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay( cancellationToken: CancellationToken, ): CodeActionsAndSourceDisplay { if (data?.moduleSpecifier) { - if (previousToken && getImportStatementCompletionInfo(contextToken || previousToken).replacementSpan) { + if (previousToken && getImportStatementCompletionInfo(contextToken || previousToken, sourceFile).replacementSpan) { // Import statement completion: 'import c|' return { codeActions: undefined, sourceDisplay: [textPart(data.moduleSpecifier)] }; } @@ -3176,7 +3176,7 @@ function getCompletionData( let flags = CompletionInfoFlags.None; if (contextToken) { - const importStatementCompletionInfo = getImportStatementCompletionInfo(contextToken); + const importStatementCompletionInfo = getImportStatementCompletionInfo(contextToken, sourceFile); if (importStatementCompletionInfo.keywordCompletion) { if (importStatementCompletionInfo.isKeywordOnlyCompletion) { return { @@ -5469,7 +5469,7 @@ export interface ImportStatementCompletionInfo { replacementSpan: TextSpan | undefined; } -function getImportStatementCompletionInfo(contextToken: Node): ImportStatementCompletionInfo { +function getImportStatementCompletionInfo(contextToken: Node, sourceFile: SourceFile): ImportStatementCompletionInfo { let keywordCompletion: TokenSyntaxKind | undefined; let isKeywordOnlyCompletion = false; const candidate = getCandidate(); @@ -5485,6 +5485,15 @@ function getImportStatementCompletionInfo(contextToken: Node): ImportStatementCo function getCandidate() { const parent = contextToken.parent; if (isImportEqualsDeclaration(parent)) { + // import Foo | + // import Foo f| + const lastToken = parent.getLastToken(sourceFile); + if (isIdentifier(contextToken) && lastToken !== contextToken) { + keywordCompletion = SyntaxKind.FromKeyword; + isKeywordOnlyCompletion = true; + return undefined; + } + keywordCompletion = contextToken.kind === SyntaxKind.TypeKeyword ? undefined : SyntaxKind.TypeKeyword; return isModuleSpecifierMissingOrEmpty(parent.moduleReference) ? parent : undefined; } diff --git a/tests/cases/fourslash/importStatementCompletions4.ts b/tests/cases/fourslash/importStatementCompletions4.ts new file mode 100644 index 00000000000..c3594525043 --- /dev/null +++ b/tests/cases/fourslash/importStatementCompletions4.ts @@ -0,0 +1,25 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////import Foo /*a*/ +//// +////function fromBar() {} + +// @Filename: /b.jsx +////import Foo /*b*/ +//// +////function fromBar() {} + +verify.completions({ + marker: ["a", "b"], + exact: { + name: "from", + sortText: completion.SortText.GlobalsOrKeywords, + }, + preferences: { + includeCompletionsForImportStatements: true, + includeInsertTextCompletions: true, + }, +});