0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

Support for import suggestions in the languageserver (#204)

* Support for import suggestions in the languageserver

https://www.loom.com/share/21921be3ebd1403aa4aaa4f39587efdb

* Add the changeset
This commit is contained in:
Matthew Phillips 2021-05-13 11:26:40 -04:00 committed by GitHub
parent 000464bf35
commit 06e2597dd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 12 deletions

View file

@ -0,0 +1,6 @@
---
'astro-languageserver': minor
'astro-vscode': minor
---
Adds support for import suggestions

View file

@ -19,6 +19,7 @@
"astro-scripts": "0.0.1" "astro-scripts": "0.0.1"
}, },
"dependencies": { "dependencies": {
"typescript": "^4.3.1-rc",
"vscode-emmet-helper": "2.1.2", "vscode-emmet-helper": "2.1.2",
"vscode-html-languageservice": "^3.0.3", "vscode-html-languageservice": "^3.0.3",
"vscode-languageserver": "6.1.1", "vscode-languageserver": "6.1.1",

View file

@ -22,7 +22,7 @@ export function createAstroSys(getSnapshot: (fileName: string) => DocumentSnapsh
return snapshot.getFullText(); return snapshot.getFullText();
}, },
readDirectory(path, extensions, exclude, include, depth) { readDirectory(path, extensions, exclude, include, depth) {
const extensionsWithAstro = (extensions ?? []).concat(...['.astro']); const extensionsWithAstro = (extensions ?? []).concat(...['.astro', '.svelte', '.vue']);
const result = ts.sys.readDirectory(path, extensionsWithAstro, exclude, include, depth); const result = ts.sys.readDirectory(path, extensionsWithAstro, exclude, include, depth);
return result; return result;
}, },

View file

@ -26,12 +26,11 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
const fragment = await tsDoc.getFragment(); const fragment = await tsDoc.getFragment();
const offset = document.offsetAt(position); const offset = document.offsetAt(position);
const entries = const entries = lang.getCompletionsAtPosition(fragment.filePath, offset, {
lang.getCompletionsAtPosition(fragment.filePath, offset, { importModuleSpecifierPreference: 'relative',
importModuleSpecifierPreference: 'relative', importModuleSpecifierEnding: 'js',
importModuleSpecifierEnding: 'auto', quotePreference: 'single',
quotePreference: 'single', })?.entries || [];
})?.entries || [];
const completionItems = entries const completionItems = entries
.map((entry: ts.CompletionEntry) => this.toCompletionItem(fragment, entry, document.uri, position, new Set())) .map((entry: ts.CompletionEntry) => this.toCompletionItem(fragment, entry, document.uri, position, new Set()))
@ -55,7 +54,7 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
} }
const fragment = await tsDoc.getFragment(); const fragment = await tsDoc.getFragment();
const detail = lang.getCompletionEntryDetails(filePath, fragment.offsetAt(comp.position), comp.name, {}, comp.source, {}); const detail = lang.getCompletionEntryDetails(filePath, fragment.offsetAt(comp.position), comp.name, {}, comp.source, {}, undefined);
if (detail) { if (detail) {
const { detail: itemDetail, documentation: itemDocumentation } = this.getCompletionDocument(detail); const { detail: itemDetail, documentation: itemDocumentation } = this.getCompletionDocument(detail);

View file

@ -71,8 +71,12 @@ async function createLanguageService(tsconfigPath: string, workspaceRoot: string
]); ]);
let projectVersion = 0; let projectVersion = 0;
const snapshotManager = new SnapshotManager(project.fileNames, { exclude: ['node_modules', 'dist'], include: ['astro'] }, workspaceRoot || process.cwd());
const snapshotManager = new SnapshotManager(project.fileNames, {
exclude: ['node_modules', 'dist'],
include: ['src']
}, workspaceRoot || process.cwd());
const astroModuleLoader = createAstroModuleLoader(getScriptSnapshot, {}); const astroModuleLoader = createAstroModuleLoader(getScriptSnapshot, {});
const host: ts.LanguageServiceHost = { const host: ts.LanguageServiceHost = {
@ -93,10 +97,10 @@ async function createLanguageService(tsconfigPath: string, workspaceRoot: string
getProjectVersion: () => `${projectVersion}`, getProjectVersion: () => `${projectVersion}`,
getScriptFileNames: () => Array.from(new Set([...snapshotManager.getFileNames(), ...snapshotManager.getProjectFileNames()])), getScriptFileNames: () => Array.from(new Set([...snapshotManager.getFileNames(), ...snapshotManager.getProjectFileNames()])),
getScriptSnapshot, getScriptSnapshot,
getScriptVersion: (fileName: string) => getScriptSnapshot(fileName).version.toString(), getScriptVersion: (fileName: string) => getScriptSnapshot(fileName).version.toString()
}; };
const languageService = ts.createLanguageService(host); const languageService: ts.LanguageService = ts.createLanguageService(host);
const languageServiceProxy = new Proxy(languageService, { const languageServiceProxy = new Proxy(languageService, {
get(target, prop) { get(target, prop) {
return Reflect.get(target, prop); return Reflect.get(target, prop);
@ -111,6 +115,10 @@ async function createLanguageService(tsconfigPath: string, workspaceRoot: string
deleteDocument, deleteDocument,
}; };
function onProjectUpdated() {
projectVersion++;
}
function deleteDocument(filePath: string) { function deleteDocument(filePath: string) {
snapshotManager.delete(filePath); snapshotManager.delete(filePath);
} }
@ -131,6 +139,7 @@ async function createLanguageService(tsconfigPath: string, workspaceRoot: string
const currentText = document ? document.getText() : null; const currentText = document ? document.getText() : null;
const snapshot = createDocumentSnapshot(filePath, currentText, docContext.createDocument); const snapshot = createDocumentSnapshot(filePath, currentText, docContext.createDocument);
snapshotManager.set(filePath, snapshot); snapshotManager.set(filePath, snapshot);
onProjectUpdated();
return snapshot; return snapshot;
} }
@ -161,7 +170,7 @@ function getDefaultJsConfig(): {
allowSyntheticDefaultImports: true, allowSyntheticDefaultImports: true,
allowJs: true, allowJs: true,
}, },
include: ['astro'], include: ['src'],
}; };
} }

View file

@ -11405,6 +11405,11 @@ typescript@^4.2.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==
typescript@^4.3.1-rc:
version "4.3.1-rc"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.1-rc.tgz#925149c8d8514e20a6bd8d4bd7f42adac67ab59c"
integrity sha512-L3uJ0gcntaRaKni9aV2amYB+pCDVodKe/B5+IREyvtKGsDOF7cYjchHb/B894skqkgD52ykRuWatIZMqEsHIqA==
ua-parser-js@^0.7.18: ua-parser-js@^0.7.18:
version "0.7.28" version "0.7.28"
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz" resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz"