$ \def\Vec#1{\mathbf{#1}} \def\vt#1{\Vec{v}_{#1}(t)} \def\v#1{\Vec{v}_{#1}} \def\vx#1{\Vec{x}_{#1}} \def\av{\bar{\Vec{v}}} \def\vdel{\Vec{\Delta}} $

Harald Kirsch

about this blog
2024-02-19

Configuring Java formatting with Emacs lsp-mode

Continuing the series about of configuring Emacs as a Java development IDE, lets talk about code formatting.

Emacs' lsp-mode uses the Eclipse language server to stay informed about the Java code being edited. This also includes the server's service to format part or all of the Java code according to some rules. It employs Eclipse's code formatter which has lots of options. When using the Eclipse UI, these can be tweaked visually in an extensive settings screen.

To use these settings with the language server, one can export the settings file and use it with lsp-java. The following describes the steps.

Create the configuration file

To create the configuration file it seems easiest to start a recent version of Eclipse and navigate to Window -> Preferences -> Formatter. If you need this very description, you'll likely see only one profile, select Edit, adapt the rules as needed, change the name to, say, blablub-format to unlock the Export button and save the file to, say, ~/.emacs.d/eclipse-formatter.xml.

Activating the format configuration in lsp-java

There are two variables of lsp-java which need to be customized:

You know how to customize variables in Emacs, right? As a reminder, you can use M-x customize-variable and type in the name to get to the customization buffer. Alternatively use M-x customize-group, type in lsp-mode and find the variables by their nice names which are easily derivable from the code names above.

Restart the language server

Switch to a Java buffer which is managed by the language server and use M-x lsp-restart-workspace or s-l w r. For a try, use s-l = = to format the whole Java buffer. If nothing happens, either your formatting is already along the rules or something went wrong. To quickly check you could toggle, for example,

  <setting
    id="org.eclipse.jdt.core.formatter.brace_position_for_block"
    value="end_of_line"
  />

between end_of_line and next_line by editing the formatter file. Make sure to restart the language server after changes, as these do not seem to be picked up automatically.

To avoid the detour through Eclipse it may sometimes be enough to find a configuration value in the Eclipse documentation, but the best bet is probably to store the format settings file in a VCS and import, change and export it with Eclipse.

Debugging

At one point I thought that the format file should show up in the argument list of the jdt.ls Java process. But this is not the case. The settings are shoved into the language server via the language server protocol. One thing that worked to at least verify that the file was touched was to watch it with inotifywait.