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:
parent
000464bf35
commit
06e2597dd9
6 changed files with 32 additions and 12 deletions
6
.changeset/tiny-pumas-warn.md
Normal file
6
.changeset/tiny-pumas-warn.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'astro-languageserver': minor
|
||||||
|
'astro-vscode': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Adds support for import suggestions
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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'],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue