vim-lsp で textDocument/formatting を特定の Language Server だけで行う
vim-lsp を使いつつも Lint, Format が上手く設定できず ALE を併用してきましたが、ようやく vim-lsp で Lint, Format を設定出来る目処が立ったので、記載していきます。
背景
TypeScript のコードを保存時に Prettier でフォーマットするため、vim-lsp で補完や定義ジャンプを行いつつ diagnostics は無効にし ALE で Lint, Format を実行する環境を作っていました。
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'
let g:lsp_diagnostics_enabled = 0
Plug 'dense-analysis/ale'
let g:ale_echo_msg_format = '[%linter%] %code: %%s'
let g:ale_lint_on_text_changed = 'never'
let g:ale_fix_on_save = 1
let g:ale_fixers = {
\ 'typescript': ['eslint', 'prettier'],
\ 'typescriptreact': ['eslint', 'prettier']
\ }
しかし ALE も LSP を使うようになり、vim-lsp と役割が重複しつつあったため efm-langserver を利用して Lint, Format も vim-lsp 経由で実行する構成への変更を考えていました。
意図しない Format
以下のように vim-lsp と efm-langserver を設定し :LspDocumentFormatSync
を実行してみたのですが Prettier によるフォーマットではなく typescript-language-server によるフォーマットが実行されてしまいました。
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'
let g:lsp_diagnostics_echo_cursor = 1
let g:lsp_settings = {
\ 'efm-langserver': {
\ 'disabled': v:false
\ }
\ }
version: 2
root-markers:
- .git/
tools:
prettier: &prettier
format-command: 'npx --no-install prettier --stdin-filepath ${INPUT}'
format-stdin: true
languages:
typescript:
- <<: *prettier
typescriptreact:
- <<: *prettier
このフォーマットの制御方法が分からず、今まで vim-lsp, efm-langserver の構成に踏み切れていませんでした。
vim-lsp でのフォーマット時に server を指定
しかし vim-lsp でのフォーマット実行時に server を指定する方法があることに気づきました。
:LspDocumentFormatSync --server=efm-langserver
で efm-langserver の textDocument/formatting
が実行されます。
--server
が使えることに気づいたのは以下の issue です。
当初の目的である、保存時に Prettier によるフォーマットを適用するためには以下のような設定を行うことで実現できるようになりました。
autocmd BufWritePre *.ts,*.tsx call execute('LspDocumentFormatSync --server=efm-langserver')
まとめ
vim-lsp の :LspDocumentFormatSync
は --server=efm-langserver
のように、実行するサーバを引数で指定することが出来ます。
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'
let g:lsp_diagnostics_echo_cursor = 1
let g:lsp_settings = {
\ 'efm-langserver': {
\ 'disabled': v:false
\ },
\ }
autocmd BufWritePre *.ts,*.tsx call execute('LspDocumentFormatSync --server=efm-langserver')
version: 2
root-markers:
- .git/
tools:
prettier: &prettier
format-command: 'npx --no-install prettier --stdin-filepath ${INPUT}'
format-stdin: true
languages:
typescript:
- <<: *prettier
typescriptreact:
- <<: *prettier
Discussion