Description
I'm trying to figure out the best way to set up format on save for all filetypes which have a language server. At first, I thought I could just do this, and at worst, I'd maybe have to silence warnings/errors if no language server is running:
autocmd BufWritePre * call LanguageClient#textDocument_formatting_sync()
As it turns out, this does work for filetypes which have a language server, but hangs indefinitely on save for filetypes which don't, waiting forever in this loop in LanguageClient_runSync
(presumably because the Rust bridge isn't there to respond?):
LanguageClient-neovim/autoload/LanguageClient.vim
Lines 1024 to 1026 in fb02afe
So I searched the issue tracker and found out about LanguageClient#isAlive
, which I thought I could use at runtime to determine whether LanguageClient#textDocument_formatting_sync
is safe to run (presumably, if LanguageClient#isAlive
, then the call won't hang). However, as per the suggestion in the linked comment, I would need to use LanguageClient_runSync
to run LanguageClient#isAlive
synchronously, which means we get stuck in the aforementioned while loop once again.
So I ended up devising with the following solution, which seems to be working so far:
execute 'autocmd FileType '
\ . join(keys(g:LanguageClient_serverCommands), ',')
\ . ' autocmd BufWritePre <buffer> call LanguageClient#textDocument_formatting_sync()'
In other words: install a FileType
autocommand, which sets up a per-buffer autocommand to run LSP formatting for each buffer belonging to one of the supported filetypes. To make matters worse, the whole thing has to be wrapped in an execute
, because we need determine the list of supported filetypes based on the keys of g:LanguageClient_serverCommands
.
This feels somewhat baroque and complicated, so I was wondering whether I've missed a more obvious, cleaner way, that someone better acquainted with the internals of the project might recommend over this? :)