Skip to content

feat(language-service): Support importing the external module's expor… #2173

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Input hashes for repository rule npm_translate_lock(name = "npm", pnpm_lock = "//:pnpm-lock.yaml").
# This file should be checked into version control along with the pnpm-lock.yaml file.
.npmrc=974837034
pnpm-lock.yaml=-300526661
yarn.lock=-2124861579
package.json=-836833037
pnpm-lock.yaml=1538625471
yarn.lock=485928896
package.json=-1986330066
pnpm-workspace.yaml=1711114604
5 changes: 5 additions & 0 deletions client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ export class AngularLanguageClient implements vscode.Disposable {
args.push('--includeCompletionsWithSnippetText');
}

const includeCompletionsForModuleExports = config.get<boolean>('angular.suggest.autoImports');
if (includeCompletionsForModuleExports) {
args.push('--includeCompletionsForModuleExports');
}

// Sort the versions from oldest to newest.
const angularVersions = (await getAngularVersionsInWorkspace(this.outputChannel))
.sort((a, b) => a.version.greaterThanOrEqual(b.version) ? 1 : -1);
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@
"default": true,
"markdownDescription": "Enable snippet completions from Angular language server. Requires using TypeScript 4.3+ in the workspace."
},
"angular.suggest.autoImports": {
"type": "boolean",
"default": true,
"markdownDescription": "Enable/disable auto import suggestions."
},
Comment on lines +146 to +150
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name of this option is a bit misleading? If I understand correctly, it doesn't enable/disable all auto imports, just the "global" completions. Can you update this description and option name?

"angular.forceStrictTemplates": {
"type": "boolean",
"default": false,
Expand Down Expand Up @@ -269,7 +274,7 @@
"test:legacy-syntaxes": "yarn compile:syntaxes-test && yarn build:syntaxes && jasmine dist/syntaxes/test/driver.js"
},
"dependencies": {
"@angular/language-service": "^20.0.0-rc.2",
"@angular/language-service": "^20.1.0-next.0",
"typescript": "^5.8.1",
"vscode-html-languageservice": "^4.2.5",
"vscode-jsonrpc": "6.0.0",
Expand Down
12 changes: 6 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"ngserver": "./bin/ngserver"
},
"dependencies": {
"@angular/language-service": "20.0.0-rc.2",
"@angular/language-service": "^20.1.0-next.0",
Copy link
Collaborator

@atscott atscott Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can revert this change now (if you rebase)

"vscode-html-languageservice": "^4.2.5",
"vscode-jsonrpc": "6.0.0",
"vscode-languageserver": "7.0.0",
Expand Down
2 changes: 2 additions & 0 deletions server/src/cmdline_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ interface CommandLineOptions {
tsdk: string|null;
includeAutomaticOptionalChainCompletions: boolean;
includeCompletionsWithSnippetText: boolean;
includeCompletionsForModuleExports: boolean;
forceStrictTemplates: boolean;
disableBlockSyntax: boolean;
disableLetSyntax: boolean;
Expand All @@ -55,6 +56,7 @@ export function parseCommandLine(argv: string[]): CommandLineOptions {
includeAutomaticOptionalChainCompletions:
hasArgument(argv, '--includeAutomaticOptionalChainCompletions'),
includeCompletionsWithSnippetText: hasArgument(argv, '--includeCompletionsWithSnippetText'),
includeCompletionsForModuleExports: hasArgument(argv, '--includeCompletionsForModuleExports'),
forceStrictTemplates: hasArgument(argv, '--forceStrictTemplates'),
disableBlockSyntax: hasArgument(argv, '--disableBlockSyntax'),
disableLetSyntax: hasArgument(argv, '--disableLetSyntax'),
Expand Down
3 changes: 3 additions & 0 deletions server/src/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export interface NgCompletionOriginData {

filePath: string;
position: lsp.Position;

tsData?: ts.CompletionEntryData;
}

/**
Expand Down Expand Up @@ -135,6 +137,7 @@ export function tsCompletionEntryToLspCompletionItem(
kind: 'ngCompletionOriginData',
filePath: scriptInfo.fileName,
position,
tsData: entry.data,
} as NgCompletionOriginData;
return item;
}
Expand Down
1 change: 1 addition & 0 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function main() {
logToConsole: options.logToConsole,
includeAutomaticOptionalChainCompletions: options.includeAutomaticOptionalChainCompletions,
includeCompletionsWithSnippetText: options.includeCompletionsWithSnippetText,
includeCompletionsForModuleExports: options.includeCompletionsForModuleExports,
forceStrictTemplates: isG3 || options.forceStrictTemplates,
disableBlockSyntax: options.disableBlockSyntax,
disableLetSyntax: options.disableLetSyntax,
Expand Down
18 changes: 14 additions & 4 deletions server/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface SessionOptions {
logToConsole: boolean;
includeAutomaticOptionalChainCompletions: boolean;
includeCompletionsWithSnippetText: boolean;
includeCompletionsForModuleExports: boolean;
forceStrictTemplates: boolean;
disableBlockSyntax: boolean;
disableLetSyntax: boolean;
Expand All @@ -49,7 +50,7 @@ const EMPTY_RANGE = lsp.Range.create(0, 0, 0, 0);
const setImmediateP = promisify(setImmediate);

const defaultFormatOptions: ts.FormatCodeSettings = {};
const defaultPreferences: ts.UserPreferences = {};
let defaultPreferences: ts.UserPreferences = {};

const htmlLS = getHTMLLanguageService();

Expand All @@ -70,6 +71,7 @@ export class Session {
private readonly openFiles = new MruTracker();
private readonly includeAutomaticOptionalChainCompletions: boolean;
private readonly includeCompletionsWithSnippetText: boolean;
private readonly includeCompletionsForModuleExports: boolean;
private snippetSupport: boolean|undefined;
private diagnosticsTimeout: NodeJS.Timeout|null = null;
private isProjectLoading = false;
Expand All @@ -86,8 +88,13 @@ export class Session {
this.includeAutomaticOptionalChainCompletions =
options.includeAutomaticOptionalChainCompletions;
this.includeCompletionsWithSnippetText = options.includeCompletionsWithSnippetText;
this.includeCompletionsForModuleExports = options.includeCompletionsForModuleExports;
this.logger = options.logger;
this.logToConsole = options.logToConsole;
defaultPreferences = {
...defaultPreferences,
includeCompletionsForModuleExports: options.includeCompletionsForModuleExports,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
includeCompletionsForModuleExports: options.includeCompletionsForModuleExports,
includeCompletionsForModuleExports: options.includeCompletionsForModuleExports ?? true,

I think the absence of this option should then be true, right? I'm noticing that if I update the upstream @angular/language-service version without this PR, then I no longer get any completions for items not already in the component imports. So effectively, the auto import feature is entirely broken/turned off. I don't know if that was the intent, but at the very least, if it's supposed to default to true, then the default should also exist in the @angular/language-server so extensions for other IDEs don't regress in the ability to provide completions and automatic imports.

With the above, should the @angular/language-service fall back to the old behavior when this option is false or not present? Or use the old behavior if not present and the new behavior of only providing completions for items already in the imports if it's explicitly false?

};
// Create a connection for the server. The connection uses Node's IPC as a transport.
this.connection = lsp.createConnection({
// cancelUndispatched is a "middleware" to handle all cancellation requests.
Expand Down Expand Up @@ -150,6 +157,7 @@ export class Session {
// We don't want the AutoImportProvider projects to be created. See
// https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/#smarter-auto-imports
includePackageJsonAutoImports: 'off',
includeCompletionsForModuleExports: this.includeCompletionsForModuleExports,
},
watchOptions: {
// Used as watch options when not specified by user's `tsconfig`.
Expand Down Expand Up @@ -1234,12 +1242,14 @@ export class Session {
let options: ts.GetCompletionsAtPositionOptions = {};
const includeCompletionsWithSnippetText =
this.includeCompletionsWithSnippetText && this.snippetSupport;
if (this.includeAutomaticOptionalChainCompletions || includeCompletionsWithSnippetText) {
if (this.includeAutomaticOptionalChainCompletions || includeCompletionsWithSnippetText ||
this.includeCompletionsForModuleExports) {
options = {
includeAutomaticOptionalChainCompletions: this.includeAutomaticOptionalChainCompletions,
includeCompletionsWithSnippetText: includeCompletionsWithSnippetText,
includeCompletionsWithInsertText:
this.includeAutomaticOptionalChainCompletions || includeCompletionsWithSnippetText,
includeCompletionsForModuleExports: this.includeCompletionsForModuleExports,
};
}

Expand Down Expand Up @@ -1269,8 +1279,8 @@ export class Session {

const offset = lspPositionToTsPosition(scriptInfo, position);
const details = languageService.getCompletionEntryDetails(
filePath, offset, item.insertText ?? item.label, undefined, undefined, undefined,
undefined);
filePath, offset, item.insertText ?? item.label, undefined, undefined, defaultPreferences,
data.tsData);
if (details === undefined) {
return item;
}
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@
uuid "^8.3.2"
yargs "^17.0.0"

"@angular/language-service@^20.0.0-rc.2":
version "20.0.0-rc.2"
resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-20.0.0-rc.2.tgz#97b99c19872a1996ecfe8025db33fcdb77985fc7"
integrity sha512-2XVMORuIdUKSAR6Df8eOLlU0oFGDGxpz9DZquaEG8sI2sH/4hyHEZWuBtwTeCeZSEBhVbF75Y+eWXViaOGrClA==
"@angular/language-service@^20.1.0-next.0":
version "20.1.0-next.0"
resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-20.1.0-next.0.tgz#d294576dee2c2be966020a8dc8ef0bc073e71487"
integrity sha512-CH2Oj7ytaEXl/4W0CzCgO3gC71uzU+gHOnM8NdAnM0ccEjzOeq1ty0PaQzQbf2psKed7V0KRfpWT+0xOO38V4A==

"@assemblyscript/loader@^0.10.1":
version "0.10.1"
Expand Down
Loading