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
Support "go to definition" for virtual files provided through language modules #2561
Comments
This work for me. const ts = require('typescript');
const path = require('path');
const volar = require('@volar/language-core');
const snapshotToMirrorMappings = new WeakMap();
/** @type {import('@volar/language-core').LanguageModule} */
module.exports = {
createFile(fileName, snapshot) {
if (fileName.endsWith('/generated-component-types.d.ts')) {
return {
fileName,
snapshot,
capabilities: {},
embeddedFiles: [],
kind: volar.FileKind.TypeScriptHostFile,
mappings: [{
data: {},
sourceRange: [0, snapshot.getLength()],
generatedRange: [0, snapshot.getLength()],
}],
mirrorBehaviorMappings: snapshotToMirrorMappings.get(snapshot),
};
}
},
updateFile(file, newSnapshot) {
file.snapshot = newSnapshot;
file.mappings = [{
data: {},
sourceRange: [0, newSnapshot.getLength()],
generatedRange: [0, newSnapshot.getLength()],
}];
file.mirrorBehaviorMappings = snapshotToMirrorMappings.get(newSnapshot);
},
proxyLanguageServiceHost(host) {
const vueTypesScript = {
projectVersion: '',
fileName: host.getCurrentDirectory() + '/generated-component-types.d.ts',
_version: 0,
_snapshot: ts.ScriptSnapshot.fromString(''),
get version() {
this.update();
return this._version;
},
get snapshot() {
this.update();
return this._snapshot;
},
update() {
if (!this._snapshot) {
return
}
if (!host.getProjectVersion || host.getProjectVersion() !== this.projectVersion) {
this.projectVersion = host.getProjectVersion?.() ?? '';
const [newText, mirrorMappings] = this.generateText();
if (newText !== this._snapshot.getText(0, this._snapshot.getLength())) {
this._version++;
this._snapshot = ts.ScriptSnapshot.fromString(newText);
snapshotToMirrorMappings.set(this._snapshot, mirrorMappings);
}
}
},
generateText() {
const mirrorMappings = [];
let code = '';
code += `declare module 'vue' {\n`;
code += `export interface GlobalComponents {\n`;
for (const fileName of host.getScriptFileNames()) {
if (fileName.endsWith('.vue')) {
const dirName = path.dirname(fileName);
const baseName = path.basename(fileName);
const componentName = baseName.replace('.vue', '');
const left = [code.length, code.length + componentName.length];
code += `${componentName}: typeof import('./${path.relative(host.getCurrentDirectory(), dirName)}/`;
const right = [code.length, code.length + baseName.length];
code += `${baseName}').default;\n`;
mirrorMappings.push({
data: [volar.MirrorBehaviorCapabilities.full, volar.MirrorBehaviorCapabilities.full],
sourceRange: left,
generatedRange: right,
});
}
}
code += `}\n`;
code += `}\n`;
code += `export { };\n`;
return [code, mirrorMappings];
},
};
return {
getScriptFileNames() {
return [
...host.getScriptFileNames(),
vueTypesScript.fileName,
];
},
getScriptVersion(fileName) {
if (fileName === vueTypesScript.fileName) {
return String(vueTypesScript.version);
}
return host.getScriptVersion(fileName);
},
getScriptSnapshot(fileName) {
if (fileName === vueTypesScript.fileName) {
return vueTypesScript.snapshot;
}
return host.getScriptSnapshot(fileName);
},
}
},
}; |
Tried to test it but things are broken now.
|
Reverted |
You can try it by @volar/vue-language-server@1.3.16 + @volar/language-core@next with johnsoncodehk/volar-starter@2ed7a7f. |
I've confirmed that that works but it doesn't work with Modified volar-starter at https://github.com/rchl/volar-starter/tree/auto-global-components-define-component (the Here are the changes that I've made to your branch: rchl/volar-starter@db0d847 |
It seems to have worked since v1.4.0. (Depend on volarjs/volar.js@d51a54d) |
Thanks. |
See #889 (comment)
How would you imagine this working? Would it have to be a custom request that provides content of the virtual file?
Ideally it would go straight to the relevant Vue file but not sure if that would be doable.
The text was updated successfully, but these errors were encountered: