Rescript emacs support with rescript-vscode


I got rescript-vscode working with emacs.

I’ve not pushed it yet, if any emacs users here want to use this: if you let me know you exist it’ll encourage me to finish it off!

I changed two things to get it working:

  • Add support to rescript-vscode’s server.ts to add a --stdio switch. I used vscode-jsonrpc to implement that. In my patch, VS code and vim clients would still use process.on etc., the changes are quite localised – does that sound an acceptable approach to you @chenglou ? (will put up a PR later but I need to clean it up first)
  • Copy-paste things out of reason-mode.el to make a rescript-mode.el and tweak some things e.g. for multi-line string syntax changes

Also, not needed to be pushed upstream to make it work, but I’ll do if the rescript-vscode changes are accepted:

  • Add the server definition to lsp-mode.el default config
  • Probably will be some minimal config for spacemacs users too (I use spacemacs)

Things I know are broken:

  • Currently I have to force the prompt to trigger a build rather than just having that happen on opening a file
  • I should test the stuff about empty responses does what it’s supposed to (the code is clear, I just need to read it and test)
  • Check if refmt is exposed over LSP and see if that works
  • I have to copy over some more stuff from reason-mode.el – notably tab doesn’t do the right thing yet
  • Syntax highlighting (font-lock) for plain backtick multiline strings (the kind without the j) is broken
  • Syntax highlighting (font-lock) for assignment to quoted keywords is broken (like \"try" = true)

This sounds awesome, I would really like to give this a try when it is available publicly. I’ve been grudgingly using VSCode and looking forward to having a language server that works with Emacs.


It depends on how much complexity this introduces. If vscode-jsonrpc pulls in a whole bunch of other dependencies, I am not sure. I’d generally be interested in having a --stdio mode, but I also understand e.g. Cheng’s concern on keeping the LSP compact (stability over features right now).

I can have a look on the patch if you want.

Thanks for the effort. We don’t officially support emacs, so no promises regarding catering to it in our vscode plugin. The fact that our plugin uses LSP under the hood is an implementation detail we don’t really guarantee.

vscode-jsonrpc is already a dependency of rescript-vscode.

The changes are localised to replacing process.on, process.send – the patch basically does:

+ let onMessage = (func: any) => {
+   process.on("message", (msg: m.Message) => {
+     func(process.send!, process.send!, msg);
+   })
+ };
-process.on("message", (msg: m.Message) => {
+onMessage((sendResponse: any, send: any, msg: m.Message) => {

plus an alternative implementation of onMessage that writes to stdio using vscode-jsonrpc.

Thanks! I’ll get it into a reviewable state.

I’m a Doom Emacs user, awesome work! I would very much appreciate a ReScript module, is there anything I can help with(my elisp is weak though)?

Thanks for putting your hand up and encouraging me, I just need to tidy things up. I worked on it today, I realized while fixing a bug that I can make the server changes even simpler, I’ll put that in a PR soon.

If that’s accepted then I think when I’ve copied over the old reason-mode.el code into rescript-mode.el to make the tab key work it’ll be useable, with types, compiler errors and completion (plus non-LSP font-lock syntax highlighting like ordinary emacs modes, apparently doing that in LSP is a new thing and rescript-vscode in VS code doesn’t use LSP for that either). So I’ll do some sort of release.

Will take more time: refmt-style formatting (works but needs minor lsp-mode.el fix), font-lock bugs, nice elisp packaging, easy config. As will the “Start a build?” feature (requires an lsp-mode.el change that may not be accepted upstream since it’s dependent on undocumented VS code client behaviour I think) – but you can just start a build yourself as workaround.

Before doing that I recommend opening an issue first to gauge if the changes are wanted.