[ANN] Editor Plugin for VSCode and VIM officially released!

Hey everyone,

We are pleased to announce the official release of our VSCode & VIM plugins.

This blog post was kept minimalistic for a reason, so I wanted to expand in a little bit more on the technical details, even though this all might be subject to change.

Establishing a Development Process

First things first: The 1.0 release for VSCode was the first stepping stone of taking over the work that has originally started in the Reason Language Server and to establish a coordinated release pipeline that moves in the same speed as the syntax, compiler and documentation. It was important to us to make the plugin experience almost plug-and-play, without any configuration / installation steps if possible.

It took us some time understanding the characteristics of each editor (vim, vscode, sublime), and I even taught myself VIML development just to be able to build a plugin that theoretically doesn’t need any other plugin to work properly. Maybe let’s highlight our core philosophy we put behind our plugin development:

Create a toolchain that is built around ReScript’s Compile Time Speed

The ReScript compiler is pretty much an “instant-compiler”, so we wanted to build our tooling around the compilation speeds to spare us a lot of headaches with caches etc.

There were a few concerns we had with pre-existing tooling:

  • Caches caused a lot of bad UX
  • Long running language servers caused memory leaks, which required lots of annoying manual restarts and hogged multiple GB of memory after a few hours
  • Huge files caused huge delays on code completion, type hints etc.
  • The existing tools had too many features and we didn’t understand what’s going on (especially when the tooling is a monolithic lsp server)
  • Finding the right setup for beginners was a nightmare (“just give me one official plugin so i can get to work”)

So how did we tackle these problems?

Type Hints, Jump to Definition, Autocomplete

We created a pretty lean binary that is able to get all the required type-hint / autocompletion information in a short-lived subprocess call that returns relevant JSON data. Cristiano fine tuned it to be fast (also for complex React modules), and our goal is to keep it fast. Our LSP (the one provided with rescript-vscode) is essentially a thin wrapper around this. To give you more context on “fast”: It’s perfectly fine to type-hint in VIM without any async call, it’s fast enough to run on the main thread and still offers nice UX, even in huge / complex ReScript files.

This system is extremely easy to use, since the binary is optimized to ReScript project structures, and knows exactly where to find the build-artifacts etc. It is an internal tool that will eventually be shipped directly within the ReScript npm package if the design turns out to be successful.

That said, we might change our opinion on the approach, for now this seems like the most sensible way from a development process / engineering angle, and the results are pretty good so far. So don’t rely on any tooling internals.

Compiler Output Diagnostics

We also kinda formalized the Error Diagnostics protocol, that all our tools rely on. That means we have a very easy time implementing the error, warning, build state parsing mechanism in different languages without getting out of sync.

The VSCode LSP and the vanilla vim extension both implement the same parsing logic in JS and VIML. It’s pretty easy to read and understand, which improved the whole collaboration process between the compiler / editor teams by a huge margin. Better quality, and more reliable tests for our editor plugins!

Make our Plugins Self Sustained

All our plugins are one-stop-shops, which means you just install the plugin, and you are set. Our VSCode plugin has no switches, no toggles, you just open your ReScript workspace, and the tool will do its job. No separate toolchains, no concepts wrangling, just you and your code.

VIM is a little bit more complex, because everyone has essentially a different setup. We made sure that the plugin brings all the stuff you need, so you can stitch together all the functionality you need in your vimrc file. E.g. we included all binaries / LSP stuff you need to setup coc-vim without any extra tools.

Remove all Unnecessary Functionality

The original RLS had a lot of bells and whistles that we actually didn’t need. So we just used the stuff we found useful. That means that you will notice some differences between your previous and new setup, and maybe you will miss some functionality. For now, the biggest upside is a more reliable setup, that is easy to debug and easy to understand (and no memory leaks).

As soon as we are feeling more comfortable with the problem domain, we will add back functionality as we go. The codebases got way simpler, so we are positive to move fast in the future.

Things to Watch Out for When Using our Plugins

Since we removed a lot of stuff, we also temporarily removed functionality, e.g. extracting types for incomplete programs. That means whenever you want to get type hint, jump-to-definition or autocompletion functionality, you’ll need to first make sure to save / build the file you are currently working on.

Building the file (no matter if there’s a type error or not), will create the necessary build artifacts, which will be used to extract all the information we need to provide said functionality.

So whenever you are not getting any type hints, make sure that your current buffer does actually compile.

Conclusion

This was a long post, but since it took us a while to get something worth shipping, we thought we provide you with a little bit more background knowledge. The team is getting really comfortable with the current solution, and we are looking forward improving the experience in the future.

Please try the new plugins and report any issues you find either in the rescript-vscode, vim-rescript or rescript-sublime repositories.

Enjoy!

18 Likes

Another Note Regarding Syntax Highlighting

We adapted the original TextMate grammar in a way that makes it parse all important syntax constructs in a semantically correct way. The syntax itself is really complex (maybe even more complex than JS, which is kinda weird), so we had to make some trade-offs not making the syntax as colorful as e.g. the Reason syntax version.

If your syntax highlighting is completely busted, make sure to try out different themes, because themes sometimes intentionally leave out particular token colors as well.

We recommend Dark+ on VSCode, and Mariana in Sublime. VIM does implement a different highlighting logic, since VIM is… well, VIM, so trial and error is inevitable :slight_smile:

I think there are missing steps for the vim plugin installation instructions. I installed using vim-plug and added the coc configuration. Coc notified me that rescript language server failed 5 times within 3 minutes.
I tried running the server manually to see what might be wrong and it crashes with

Error: Cannot find module 'vscode-languageserver-protocol'

I had to go to the plugin and npm install manually in all the directories. Then it started working.

The plugin also adds around 15 seconds to the vim startup time which is weird. I understand that it’s hard with vim as this can be due to conflicts with some other plugins that I have installed. Just wonder if anybody else noticed this. Removing the plugin brings the startup time back to instant

Oh okay, probably forgot to check in all dependencies…will have a look at it tomorrow!
Regarding startup times I would need more context about your vim setup. Maybe let’s open an issue for that to discuss the details? (note: it shouldn’t add such long startup times, at least that’s something I never observed on my machine)

@alexeygolev I just released a new tagged v1.0.1 version on vim-rescript… can you clean your previous installation and try this Plug instruction?

  Plug 'rescript-lang/vim-rescript', {'tag': 'v1.0.1'}

This should fix the LSP dependency issue.

Not sure if this will fix your 15s issue though, since I believe this is caused by some weird vim plugin combinations, or at least caused by vim-coc… our vim plugin actually does nothing computation intensive, nor does it mess with your global configuration.

1 Like

what an amazing release!! and thank you so much for the clear communication! excited to see this community mature.going to try this all out on the weekend.

4 Likes

This is fantastic news @ryyppy. Thank you and the team so much for your work!

Had a go with this yesterday evening. Fantastic stuff. Thanks very much

Am I the only one that has issues with the VSCode plugin?

I tried on Windows 10 and MacOS Sierra and in both cases the plugin is crushing immediately.

The moment I open .res file:

image

undefined:1



SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\server\out\RescriptEditorSupport.js:58:31
    at ChildProcess.exithandler (child_process.js:311:5)
    at ChildProcess.emit (events.js:223:5)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
[Info  - 20:51:01] Connection to server got closed. Server will restart.
[Error - 20:51:01] Request textDocument/hover failed.
Error: Connection got disposed.
	at Object.dispose (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\main.js:904:25)
	at Object.dispose (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-languageclient\lib\client.js:74:35)
	at LanguageClient.handleConnectionClosed (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-languageclient\lib\client.js:2309:42)
	at LanguageClient.handleConnectionClosed (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-languageclient\lib\main.js:155:15)
	at closeHandler (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-languageclient\lib\client.js:2296:18)
	at CallbackList.invoke (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\events.js:62:39)
	at Emitter.fire (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\events.js:121:36)
	at closeHandler (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\main.js:240:26)
	at CallbackList.invoke (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\events.js:62:39)
	at Emitter.fire (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\events.js:121:36)
	at IPCMessageReader.fireClose (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\messageReader.js:111:27)
	at ChildProcess.<anonymous> (c:\Users\Mickey\.vscode\extensions\chenglou92.rescript-vscode-1.0.0\client\node_modules\vscode-jsonrpc\lib\messageReader.js:213:45)
	at ChildProcess.emit (events.js:228:7)
	at maybeClose (internal/child_process.js:1021:16)
	at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)

I have opened an issue https://github.com/rescript-lang/rescript-vscode/issues/25 2 days ago.

Am I doing something wrong?

Thank you.

The plugin works now. The startup delay isn’t there for anymore…maybe it was a fluke:) Thank you!

Try to build first. There’s a fix for this case in master.

@cristianoc, what do you mean?

npm run build

Does not help. Same errors.

The issue observed with Windows is tracked here: https://github.com/rescript-lang/rescript-vscode/issues/25
The fix will be applied in the forthcoming bug-fix release.

The issue observed with Windows is tracked here: https://github.com/rescript-lang/rescript-vscode/issues/25
The fix will be applied in the forthcoming bug-fix release.

Some first impression feedback (I have shared that on Discord first before I remembered that we want to focus discussion on here):

Pro:

  • Blazing fast
  • Really helpful error messages (esp. for things like misspelled poly variants, also the suggestions for primitive type conversion are pure gold)
  • Navigates exactly where I expect so far (even deep into node_modules & *.re files)
  • Great global autocompletion
  • Record autocompletion ( :heart: )
  • The automatic build runner for VSCode is really convenient
  • Everything works / completes / navigates perfectly fine with ppx involvement

Cons / Problems:

  • None so far, just works
    ( - Just found one tiny thing: missing some auto completion inside the scope of an open statement, no big deal)

Things that would hit it right out of the park in the future:

  • Autocompletion of JSX props
  • Go to definition for JSX props
  • Autocompletion for Js.t inside the [""] where possible (probably a lot of work for not too much benefit?)
  • Autocompletion for poly variants if the type is known and properly constrained (for example inside a switch / function argument)
  • Type info / go to definition Js.t inside the [""]
  • Autocompletion for (at least the default ones for bindings) @ annotations like @module

To summarize: Holy cow guys - this is how it was supposed to feel like all along - love it.

Edit: Good news, installing the *.vsix directly into Onivim 2 works flawlessly as well (even the build runner popup, that’s pretty cool).

8 Likes

100% agree with @jsiebern, exceeds expectations! I think this is a huge step in the right direction. We converted our whole codebase to .res already!

Another point that would improve the editor experience (which is a slight regression) is the ability to work not only after save but also while typing.

3 Likes

You can achieve this behaviour with a little workaround:

2 Likes

Is anyone able to get this working in a mono repo using yarn workspaces?

Language server works just fine, but the RescriptFormat command will not work:

rescript format returned an error

If anyone else is having this issue, I believe I have a quick fix PR up that will allow your workspaces project to work :slight_smile:

Let me know if you have any issues or if this fixes your issue!

Update: https://github.com/rescript-lang/vim-rescript/pull/19

Plug 'rescript-lang/vim-rescript', {'branch': 'monorepo-support'}