Problem
When you are in a buffer that has multiple lsp-servers running which support formatting, all of them will be triggered when calling +format/buffer
or when configuring :editor (format +onsave)
and saving a file.
As a result, the buffer won’t be formatted correctly. For example, missing whitespaces will be added multiple times and excess whitespace will be removed multiple times.
As an example, we can have a look at a TypeScript buffer with two running lsp-servers:
ts-ls
eslint
Before saving, the buffer looks like this:
class Foo {
private bar = 'bar';
private baz = 'baz';
}
The second property should be moved two spaces to the left. When saving, the “space” will be removed twice, leaving:
class Foo {
private bar = 'bar';
ivate baz = 'baz';
}
Instead, we want only eslint
formatting, when eslint
is available. If it isn’t, we want to fall back to the default.
Solution
I found the solution in a discussion on Emacs LSP’s discord.
In short, add this to your config.el
:
;; Make sure that TypeScript files only get formatted once, with eslint when present.
(setq-hook! 'typescript-mode-hook +format-with-lsp nil)
(after! lsp-mode
(defun my/eslint-format ()
(interactive
(if-let ((eslint (-first (lambda (wks)
(eq 'eslint (lsp--client-server-id
(lsp--workspace-client wks))))
(lsp-workspaces))))
(with-lsp-workspace eslint
(lsp-format-buffer))
(lsp-format-buffer))))
(setq-hook! 'typescript-mode-hook +format-with 'my/eslint-format))
- Disable doom’s lsp formatting for TypeScript.
- Use the new function
my/eslint-format
, which uses onlyeslint
, if available, and the default behavior otherwise.
Notes
I am sure this can be done in a better way, as I am quite noob to both Emacs and Doom. Maybe with better support for more modes. But hey, it works .
I wasn’t certain which category to put this in. Could also be a guide? But there it says “curated” so I shied away .