Using google-java-format with VS Code
I have been doing some Java development recently, and my preferred editors of choice bounce between Visual Studio Code and Neovim. My vim setup is configured to format Java source files using google-java-format, but I was struggling to achieve the same behavior in Visual Studio Code. This post explores how to format Java source files using google-java-format in VS Code.
TL;DR
Install emeraldwalk/vscode-runonsave:
$ code --install-extension emeraldwalk.RunOnSave
Install google-java-format for your system:
# Example using Homebrew on OS X
$ brew install google-java-format
Configure RunOnSave in Visual Studio Code settings:
{
"emeraldwalk.runonsave": {
"commands": [
{
"match": "\\.java$",
"cmd": "google-java-format --replace ${file}"
},
],
},
}
Background
Google publishes a verbose Google Java style guide as well as google-java-format which reformats Java code according to that style guide. The formatter is available as a Java JAR and via popular package managers. For example, to install the formatter on OS X:
$ brew install google-java-format
Then, to format Java source files, pass them as arguments to the command:
$ google-java-format -i ./MyClass.java
Existing work
There are already popular plugins for google-java-format for IDEs like Eclipse and IntelliJ. Unfortunately no official ones exist for Visual Studio Code at the time of this writing. Before coming up with my own solution, I did some Internet searching.
The most popular answer comes from redhat-developer/vscode-java#419 which directs us to a Wiki page with instructions to edit some Visual Studio Code configuration:
{
"java.format.settings.profile": "GoogleStyle",
"java.format.settings.url": "https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml",
}
This will instruct the editor to use the "GoogleStyle" when formatting code instead of the built-in style. This seemed like a great fit, since I am already using RedHat's Java Language Support.
While this does change the default format of the code, in my testing it did not match the output of running google-java-format
directly from the command line. Worse, it modified things like license headers, rendering them invalid.
I also stumbled across Dev-Snippets/vscode-google-java-format-provider, which seemed promising, but I was unable to get it to register as a formatter (and I am not the only one).
Solution
I started down the path of writing my own Visual Studio Code plugin to run google-java-format
as a formatter. After about 10 minutes into the exercise, I realized that this plugin was going to be quite dumb:
- Detect if the file is Java
- Run
google-java-format -i ${file}
- Report any errors back to the user
Those steps are essentially "run a command on save", and it turns out someone has already written an extension! emeraldwalk/vscode-runonsave reads Visual Studio Code settings, matches files on a regular expression, and then runs a user-supplied command. This proved to be a minimal but perfect solution!
I installed RunOnSave and google-java-format
on my Mac:
$ code --install-extension emeraldwalk.RunOnSave
$ brew install google-java-format
Then I configured RunOnSave to run google-java-format
on files that end in .java
in Visual Studio Code settings:
{
"emeraldwalk.runonsave": {
"commands": [
{
"match": "\\.java$",
"cmd": "google-java-format --replace ${file}"
},
],
},
}
This requires google-java-format
to be in my $PATH
. If it was not, I could specify the full path to the binary instead:
{
"cmd": "/usr/local/bin/google-java-format --replace ${file}"
}
After spending a few hours trying to reach parity between google-java-format and Visual Studio Code's formatOnSave
, I feel like I have reached a perfect solution.
Hopefully this post was helpful. If you have questions or comments, please reach to me at @sethvargo Twitter.
About Seth
Seth Vargo is a Distinguished Software Engineer at Google. Previously he worked at HashiCorp, Chef Software, CustomInk, and some Pittsburgh-based startups. He is the author of Learning Chef and is passionate about reducing inequality in technology. When he is not writing, working on open source, teaching, or speaking at conferences, Seth advises non-profits.