Usando google-java-format con VS Code

He estado haciendo algo de desarrollo Java recientemente, y mis editores preferidos rebotan entre Visual Studio Code y Neovim. Mi configuración de vim está configurada para formatear los archivos fuente de Java utilizando google-java-format, pero estaba luchando para lograr el mismo comportamiento en Visual Studio Code. Este post explora cómo formatear los archivos fuente de Java utilizando google-java-format en VS Code.

TL;DR

Instalar emeraldwalk/vscode-runonsave:

$ code --install-extension emeraldwalk.RunOnSave

Instalar google-java-format para su sistema:

# Example using Homebrew on OS X$ brew install google-java-format

Configurar RunOnSave en la configuración de Visual Studio Code:

{ "emeraldwalk.runonsave": { "commands": , },}

Fondo

Google publica una verbosa guía de estilo de Google Java así como google-java-format que reformatea el código Java de acuerdo con esa guía de estilo. El formateador está disponible como un JAR de Java y a través de gestores de paquetes populares. Por ejemplo, para instalar el formateador en OS X:

$ brew install google-java-format

Entonces, para formatear los archivos fuente de Java, pásalos como argumentos al comando:

$ google-java-format -i ./MyClass.java

Trabajo existente

Ya existen plugins populares para google-java-format para IDEs como Eclipse e IntelliJ. Desgraciadamente no existe ninguno oficial para Visual Studio Code en el momento de escribir este artículo. Antes de llegar a mi propia solución, hice algunas búsquedas en Internet.

La respuesta más popular viene de redhat-developer/vscode-java#419 que nos dirige a una página Wiki con instrucciones para editar alguna configuración de Visual Studio Code:

{ "java.format.settings.profile": "GoogleStyle", "java.format.settings.url": "https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml",}

Esto instruirá al editor para que utilice el «GoogleStyle» cuando formatee el código en lugar del estilo incorporado. Esto parecía un gran ajuste, ya que ya estoy usando el soporte de lenguaje Java de RedHat.

Aunque esto cambia el formato por defecto del código, en mis pruebas no coincidió con la salida de ejecutar google-java-format directamente desde la línea de comandos. Peor aún, modificó cosas como las cabeceras de licencia, haciéndolas inválidas.

También me topé con Dev-Snippets/vscode-google-java-format-provider, que parecía prometedor, pero no pude conseguir que se registrara como formateador (y no soy el único).

Solución

Empecé a escribir mi propio plugin de Visual Studio Code para ejecutar google-java-format como formateador. Después de unos 10 minutos en el ejercicio, me di cuenta de que este plugin iba a ser bastante tonto:

  1. Detectar si el archivo es Java
  2. Ejecutar google-java-format -i ${file}
  3. Informar de cualquier error al usuario

Esos pasos son esencialmente «ejecutar un comando al guardar», ¡y resulta que alguien ya ha escrito una extensión! emeraldwalk/vscode-runonsave lee la configuración de Visual Studio Code, hace coincidir los archivos con una expresión regular y luego ejecuta un comando suministrado por el usuario. Esto resultó ser una solución mínima pero perfecta!

Instalé RunOnSave y google-java-format en mi Mac:

$ code --install-extension emeraldwalk.RunOnSave$ brew install google-java-format

Luego configuré RunOnSave para ejecutar google-java-format en los archivos que terminan en .java en la configuración de Visual Studio Code:

{ "emeraldwalk.runonsave": { "commands": , },}

Esto requiere que google-java-format esté en mi $PATH. Si no lo estuviera, podría especificar la ruta completa al binario en su lugar:

{ "cmd": "/usr/local/bin/google-java-format --replace ${file}"}

Después de pasar unas cuantas horas intentando alcanzar la paridad entre google-java-format y el formatOnSave de Visual Studio Code, siento que he llegado a una solución perfecta.