Codemirror 6 and Typescript LSP

what exactly is tsStateField?

Ah that’s my bad for including it, it’s just the instance of tsserver that I store as a state field so I can access it everywhere. I’m not sure what your setup looks like, so just see it as the tsserver instance from the @typescript/vfs NPM package.

I’m not sure how to help you debug your code, I suppose you’ll just have to read the reference / docs. The hoverTooltip example I showed you uses the hoverTooltip import from the @codemirror/tooltip package. If you do it step-by-step, one thing at a time, you should be able to at least get the hover tooltips working without tsserver first, then add tsserver calls. It seems in your case that the tooltips themselves aren’t working (which I never really saw), so you should debug that first.

@madebysid Out of curiosity, what version of “@codemirror/tooltip” are you using? I updated to the newest version of each dependency, and I am curious if maybe that’s the issue. Once again, thanks for all your help!

I’m on @codemirror/tooltip@0.18.4 right now

Hey @madebysid, had another question, this time regarding adding custom types declarations to tsserver. An example is that I am trying to have the tsserver autocomplete for $driver. I see in one of your earlier replies, you mentioned using createFile() but I don’t see that anywhere in tsserver’s documentation, so what exactly is it? Another question is that, since I am dealing with a large declaration, is that the best way to port over those definitions? My main issue is that I cannot pull the declarations in, so tsserver can therefore not add it using addLib(), which is where I am really stuck. Just lmk if I need to clarify more.

Dropping by the thread to say thanks @madebysid for the guidance on how to integrate Typescript. I got it working fairly quickly with your suggestions, and I feel like I’d have been stuck for a while otherwise.

If anyone is still having problems with this, I was able to create a small demo based on @madebysid comment, you can find it here: https://github.com/okikio/codemirror,

Demo Link: https://okikio-codemirror.netlify.app/

4 Likes

@Retr0djmarky The createFile method is on the env that you create from https://www.npmjs.com/package/@typescript/vfs (not on env.languageService).

For custom types, I think it’d be best to upload your types to a CDN and then download them lazily when your editor loads.

FWIW My implementation is also public now, if you want to take a look: https://github.com/prisma/text-editors/

4 Likes

@madebysid @Retr0djmarky @folz Do one of you have your code up yet?

Sure, I linked my entire repo with everything I’ve been talking about up above. Here it is again: GitHub - prisma/text-editors

3 Likes

I published where I’m using CM6+TS at GitHub - folz/ent: livecoding audio/visual synthesis environment - src/components/Editor/typescript.ts is where the integration happens

2 Likes

Thank you for sharing the high level implementation steps @madebysid !

For the @codesanbox/sandpack-react package there was a discussion on how to integrate the language server with codemirror.

Here is a editable codesanbox environment show this working with lots of the steps shared @madebysid integrated

It’s running the language server in a worker. The credit goes to @danilowoz who shared this example in this thread below:

3 Likes

Hey all!

I’d like to share the progress I made on integrating the TypeScript LSP into Sandpack, which uses CodeMirror in the editor component. Fortunately, I could implement most of the features I had planned thanks to the amazing examples from @okikio and @madebysid.

Here’s the full list of feature:

  • IntelliSense;
  • Tooltip error;
  • Multiple files;
  • Support tsconfig.json;
  • Automatically dependency-types fetching (CodeSandbox CDN);
  • In-browser dependency cache;

TBH, I’m not an expert on CodeMirror even less on LSP, so I’m curious to know how I can improve this implementation and make it even better, so feel free to open PR or an issue in the main repository.

2 Likes

@danilowoz Awesome to see

@danilowoz @cliffordfajardo really awesome! The first codesandbox example you posted @cliffordfajardo works for me, but the one you posted @danilowoz gives me this error:

Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.

on line 35 of CodeEditor.tsx:

          const keys = Object.keys(localStorage);

Any ideas why?

This is really awesome. I can’t wait to get this working for mobile phone editing (that’s where Monaco completely falls apart right now).

Hey @trusktr. That’s weird, it was supposed to work correctly.

Feel free to open an issue in the repository, then we can figure out what’s going on there.

1 Like

@cliffordfajardo @danilowoz : Apologies if this is considered rude.

Did https://codesandbox.io/ switch away from CodeMirror to Monaco for it’s TypeScript/LSP editor? If so, is there a discussion somewhere of why? [I was studying your CodeMirror / TypeScript LSP example, and trying the website, but it seems the website defaults to monaco, if I’m reading the include scripts correctly.]

Hey! Actually, CodeSandbox has always used Monaco as the default editor, except for a specific mobile version where we defaulted it to CodeMirror.

But this current thread is about Sandpack, which is an embeddable library, and not about CodeSandbox itself. You can find more information here about how to implement it on Sandpack: TypeScript integration · Discussion #237 · codesandbox/sandpack · GitHub

Not to be pedantic, but it’s worth noting that tsserver / the typescript standalone worker is not LSP compatible.

Replit is working on open sourcing our LSP Client (we didn’t the microsoft packages) and a follow up to open source the LSP client + codemirror extension. Timeline TBD but should happen in 2023

1 Like

Hi all! I did my own experiment with codemirror and tsserver / @typescript/vfs. I’ve put my very very simple setup on stackblitz for anyone to check it out : https://stackblitz.com/edit/codemirror-6-typescript

Hope it can help anyone reading this thread

2 Likes

For those trying to provide a completion environment that feels like VSCode/Monaco, I found this link useful for understanding what different kinds of hints to provide: monaco-editor/languageFeatures.ts at main · microsoft/monaco-editor · GitHub. There is also the original VSCode typescript plugin but I found that less useful because it is tied more closely to VSCode’s built in handling of different types of suggestions

In Monaco, there are actually two different kinds of popup hints: SignatureHelpAdapter and SuggestAdapter. To test both of these features, try slowly typing out console.log(. I believe SuggestAdapter shows possible globals as you type console, methods when you type . and then SignatureHelpAdapter shows parameter types with the current parameter highlighted when you type (. Additionally, this file also shows how other features such as formatting, renaming, and goto definition can be used with typescript (although they are slightly different from how you would use @typescript/vfs).

When looking for other examples of these features implemented in a LSP, I also came across a codemirror repository that implements the ui for these two methods: GitHub - qualified/lsps: Use Language Servers with in-browser editors. Monorepo of editor agnostic packages and CodeMirror client.

2 Likes