Formatting Scala code in Visual Studio Code

Scala and JavaScript, a match made in heaven

Recently at buildo we grew tired of formatting our Scala code by hand and we started looking into Scalafmt. While discussing its adoption we identified a few non-negotiable requirements:

the CI should check that everything is properly formatted

the editor should allow the developer to format a file while working on it

The first requirement is easy to fulfill: we can write a CI task that runs scalafmt --test and it's done.

The second one is trickier: the editor is a personal choice and when talking about editors for Scala there’s usually little agreement.

No one at buildo has a taste for IDEs, so IntelliJ is not on the table (too bad, since it already had a Scalafmt plugin!). Some people use Sublime, some people Emacs, some other Vim, but there’s a good group of people using Visual Studio Code, a solid rich editor by Microsoft, which features also a good support for Ensime.

As many other modern editors, Visual Studio Code supports extensions, and they are written in TypeScript, a typed superset of JavaScript.

First attempt: invoking the scalafmt CLI

After understanding the basics of VSCode extensions, my first naive attempt was to simply “shell out” and invoke a local scalafmt process to format the file in the active text editor.

Something like scalafmt --std-out /path/to/file .

While this approach is very simple and it works, it also has a few downsides:

it requires installing scalafmt and having it available on the user's path, making the extension not self-contained.

and having it available on the user's path, making the extension not self-contained. it’s slow. Don’t get me wrong: Scalafmt is not slow per se, but spinning up a JVM for formatting a single file incurs in a very high overhead. Formatting a file while editing is an operation that should be cheap, especially if you enable it on save (like VSCode allows).

What can we do to make this faster and self-contained?

Second attempt: scalafmt… in JS?

Scalafmt already cross-compiles to Scala.js, and — if you think about it — it makes sense: its core functionality is to manipulate a string (the original source code) and return another string (the formatted source code). There’s nothing inherently JVM-specific about it, so it can work just fine in Node.js.

What was missing was an API to invoke it from JavaScript, so I rolled-up my sleeves and wrote one. The result is a Node.js package published on npm, which can be bundled in any Node application, including (surprise!) a VSCode extension.

A few nights later, here it is: https://github.com/gabro/vscode-scalafmt

You can install the extension only, it doesn’t require installing scalafmt globally. Also, it’s fast, since we’re not paying the JVM startup cost anymore! Formatting a file is an almost-immediate operation that you can do at any time without disrupting your workflow.

A word about JavaScript and Scala

Scala.js is a game changer, at least for the Scala community. It wasn’t until recently that I started thinking this, but when you look at what it makes possible, it becomes evident.

Recently I’ve talked about adding Scalameta support to AST Explorer, today I’m telling you about a VSCode extension. Tomorrow it will be something else:

a code browser?

a browser extension that formats your snippets on GitHub?

you name it

The truth is: you may not like JavaScript as a language (by the way, you should try TypeScript!), but let me state the obvious: JavaScript is the foundation of many tools we use today, ranging from the web to text editors.

Being able to integrate Scala-specific tools with these JS tools is like having superpowers.

So I’ll say it again: Scala.js is a game changer for the world of Scala tooling.

Thanks

I’d like to thank Ólafur Geirsson for authoring Scalafmt and answering my many questions on Gitter and GitHub.

A big thank you also to Sébastien Doeraene and the Scala.js team.

Finally, a shout-out to Microsoft for Visual Studio Code: it’s an incredibly solid piece of software that is a pleasure to hack on and work with.

—

If you want to work in a place where we care about the quality of our development workflow, take a look at https://buildo.io/careers