poetryを使った時のVimの開発環境を整える
April 30, 2021
仕事でPythonを書くようになったので、Vimでの開発環境を整えます。 整えると言いつつも基本的にはLSPの設定になります。 目指すことは以下が上手くできるようになることです。
- 補完
- lint
- format
補完
補完にはpyrightというツールを使っていきます。 pyrightはPythonの静的型チェックを行ってくれるツールで、Language Serverの機能も備わっているようです。
インストール
これはvim-lsp-settingsやcoc.vimなどの自動でインストールしてくれる系のツールでは必要ありません。
yarn global add pyright
設定
各々のLSPクライアントの設定してください。 基本的にはこれで動くのですが、poetryを使っていると少し工夫が必要です。 poetryでvirtualenvを使っていると、pyrightでライブラリ等の補完を使うためにvirtualenvの場所を知らせる必要があります。
poetryのvirtualenvの場所は以下方法で調べることが出来ます。
# 様々なvirtualenvの場所があるディレクトリを示す
poetry config virtualenvs.path
# 現在のディレクトリのvirtualenvの名前を示す
poetry env list
これらの変数を使ってpyrightで設定をしてください。 Neovim buildin LSPを使った場合の例を示しておきます。
local virtual_env_path = vim.trim(vim.fn.system('poetry config virtualenvs.path'))
local virtual_env_dirctory = vim.trim(vim.fn.system('poetry env list'))
local python_path = 'python'
-- 現在のディレクトリに対応するvirtualenvがあるかのチェック
if #vim.split(virtual_env_dirctory, '\n') == 1 then
python_path = string.format("%s/%s/bin/python", virtual_env_path, virtual_env_dirctory)
end
nvim_lsp.pyright.setup{
settings = {
python = {
pythonPath = python_path;
}
}
}
これでvirtualenvにインストールされているライブラリを考慮した補完が出来ます。
format & lint
pyrightのLSP機能は残念ながらformatterに対応していません。 Pythonでは独自のformatterやlinterがCLIで提供されているので、これらを使うようにします。 これらを使うにはefm-langserverを使っていきます。
ちなみにcoc.vimはこの辺をうまくやるようにcoc-pyrightにlintとformatを入れているのでcoc.vimの場合はefm-langserverを使う必要はなさそうです
efm-langserverは普通のlinterやformatterをLSPに対応させてくれる便利なツールです。 基本的な使い方は対応リポジトリのREADMEを読んでください。
今回はflake8とyapfを使った例を示します。
version: 2
tools:
python-flake8: &python-flake8
lint-command: 'flake8 --stdin-display-name ${INPUT} -'
lint-stdin: true
lint-formats:
- '%f:%l:%c: %m'
python-yapf: &python-yapf
format-command: 'yapf --quiet'
format-stdin: true
languages:
python:
- <<: *python-flake8
- <<: *python-yapf
nvim_lsp.efm.setup{
filetypes = { 'python' },
default_config = {
cmd = { 'efm-langserver', '-c', '/path/to/efm-langserver.yaml' };
}
}
これでいい感じにlinterとformatterも使えるようになります。
おまけ
neovim builtin LSPで保存時にformatterを実行する場合は以下のように書きます。
augroup lsp_formatting
au!
autocmd BufWritePre *.py lua vim.lsp.buf.formatting_sync()
augroup END
しかし、efm-langserverはCLIを通してformatterを使うのでかなり遅いです。 neovim builtin LSPはformatting_syncを100msしか待ってくれないため、保存時のformatterが実行できません。 これをうまくやる場合は以下のように時間を調整することで保存時にformatをしてくれます。
augroup lsp_formatting
au!
autocmd BufWritePre *.py lua vim.lsp.buf.formatting_sync({}, 300)
augroup END