Did you look at https://www.npmjs.com/package/@typescript/vfs? Its README has full instructions on how to get document highlights for a file.
They create a file called index.ts
in the virtual file system with some content, then initialize a virtualTypeScriptEnvironment
with that file, that’s all you have to do as well.
Then, instead of getting document highlights, you can call getCompletionsAtPosition
(also listed in the README). I would recommend playing around with @typescript/vfs
outside CodeMirror just to get the hang of it first.
how exactly are you replacing the normal autocomplete function
You cannot just override: [env.languageService.getCompletionsAtPosition()]
, because the completion source’s signature won’t match up this way…
This is what my autocompletion config roughly looks like:
autocompletion({
override: [(ctx) => {
const { pos } = ctx;
// tsserver is initialized using @typescript/vfs
const completions = tsserver.languageService.getCompletionsAtPosition(
"index.ts",
pos,
{}
);
if (!completions) {
log("Unable to get completions", { pos });
return null;
}
return completeFromList(
completions.entries.map(c => ({
type: c.kind,
label: c.name,
}))
)(ctx);
}]
})
could you explain what you meant by the 8th bullet in the original reply, which is talking about
ts.updateFile
?
Since you initialize tsserver with some file contents, you have to realize that tsserver has its own representation / view of the “file” you’re working with. When you change/type things in your editor, you have to tell tsserver about these changes as well so that the next time you ask something from it (like autocompletions, or type errors), it gives you the correct response. You have to keep your editor’s view in sync with tsserver’s view of the file. That’s what the updateFile
method on the tsserver
instance does.
In my case, I override the dispatch
function in my new EditorView
params this way:
const view = new EditorView({
// ...snip
dispatch: transaction => {
// Update view first
this.view.update([transaction]);
// Then tell tsserver about new file. Debounce this, I'm not doing that here for sake of clarity
if (transaction.docChanged) {
const content = doc.sliceString(0);
tsserver.updateFile("index.ts", content);
}
},
})