NeovimではPythonを使ったプラグインがありますが、 そのPythonを仮想環境から呼んでやることも出来ます。
Pythonを使ったプラグインを使う際には
pynvim(旧neovim
)というパッケージが入っていないと
動かない場合がありエラーが出たりします。
ユーザーの全体環境に入れてしまっても良いのですが、 エラーを吐かずに気づかずに使えてない場合とかもあるので、 できれば初期設定としてどの環境でも同じにしたいところです。
そこで.vimrcの中で仮想環境がなければ作って それを使うようにしてみました。
設定
.vimrcの最初の方に、以下のようなブロックを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
以下各所の説明。
各所の説明
実行するかどうかのチェック
if has('nvim') && !filereadable(expand('~/.vim_no_python'))
Vimでもシンタックスチェックでpipで入れた実行ファイルを使いたい場合とかも ありますが、最近は dotfiles 入れる環境ではすべてNeovimを使ってるので余計なことをしないように、ということで Neovimの場合だけ。
さらに、もしこれを入れたくない環境があったらHOMEに.vim_no_pythonというファイルを 置いておけば無視するようになります。
Python3チェック
let s:python3 = system('which python3')
if strlen(s:python3) != 0
これでpython3
が環境にある場合だけ以下を行います。
インストール場所
let s:python3_dir = $HOME . '/.vim/python3'
仮想環境は~/.vim/の下にpython3
という名前で作ることにしました。
仮想環境構築
if ! isdirectory(s:python3_dir)
call system('python3 -m venv ' . s:python3_dir)
call system('source ' . s:python3_dir . '/bin/activate && pip install neovim flake8 jedi')
endif
仮想環境のディレクトリがない場合、-m venv
で新たな仮想環境を作ります。
そして、その環境下にpip
で必要なパッケージを入れます。
call system('source ' . s:python3_dir . '/bin/activate')
call system('pip install neovim flake8 jedi')
みたいに2つに分けてしまうと、2つ目では仮想環境下ではなくユーザーの通常環境への
インストールになってしまうのでまとめて(system
は恐らくサブプロセスを呼ぶだけなのでここで行ったものは維持されない。以下にあるPATH
の設定とかもsystem
の中でexport
とかしても意味が無い)。
仮想環境を使う設定
let g:python3_host_prog = s:python3_dir . '/bin/python'
let $PATH = s:python3_dir . '/bin:' . $PATH
1つ目がPythonを使うモジュールが使うPythonの指定。
g:python3_host_prog
という値に仮想環境の場所の中のPythonを指定してあげればOK。
2つ目が仮想環境下にインストールされた実行ファイル(flake8
とか)を使うための設定。
上の仮想環境を使う設定をしてもPythonを直接呼ぶだけで、いわゆる手元でactivate
した状態、とは違って
シェルのPATHとかは通らないので、インストールしたコマンドを使いたい場合には
この様に別途PATHを通す必要があります。
せっかく入れるので最優先で見るように一番前に追加。
チェック
Neovimを立ち上げて:checkhealth
コマンドを打ってみると、
## Python 3 provider (optional)
- INFO: Using: g:python3_host_prog = "/home/user/.vim/python3/bin/python"
- INFO: Executable: /home/user/.vim/python3/bin/python
- INFO: Python version: 3.8.5
- INFO: pynvim version: 0.4.1
- OK: Latest pynvim is installed.
みたいな感じの部分があるかと思います。
ここできちんとg:python3_host_prog
が指定されていて、
pynvim
のパッケージもちゃんと入っていればOK。
他のコマンド類もちゃんと使えるか、
:echo system('which flake8')
とかしてみて、ちゃんと
/home/user/.vim/python3/bin/flake8
で見つかればOK。
アップデート方法
この方法で作ると手動でアップデートするか、ディレクトリを一旦消すかしないと 仮想環境がアップデートされません。
たまに手でやってもよいのですが、 普段、Homebrewのパッケージやらなにやらを毎日cronでアップデートしていて、 その中でNeovimのプラグインもアップデートしているので その前にディレクトリを削除して再構築するようにしてみます。
1 2 3 4 5 6 7 8 9 |
|
こんな感じ。
前半部分はたまにスタックしてしまう場合があったので、 残ってたら強制削除して新たに始めるにするためのもの。
その後で仮想環境を削除して、 プラグインのアップデートを呼んでいます。
プラグインはDeinでやってるのでそのupdate
を呼んでいます。
このときにNeovimが立ち上がるのでPythonの仮想環境がインストールされます。
これを適当な時間に
30 12 * * * /path/to/update.sh
みたいに設定して呼んであげればOK(上のは毎日お昼の12:30。ずっと動かしてるサーバーとかなら深夜とか使わない時間にしたほうが良いです。)
Deinの自動インストール
同じ様な初期インストールをDeinに関しても行っています。
まとめ
この辺の初期環境構築に関しては、毎回Vim(Neovim)起動時にチェックすることになるので、 別の仕組みで行った方が良いとは思います。
ただ、最初の構築時に数秒かかる程度で、一回作ってしまえばほとんど負荷はかかりません。 それを全部.vimrcの中で出来てしまうならそれで良いかな、という感じ。
アップデートに関しても、適当なタイムスタンプ付けたファイルを作っておいて、 それ見ながらもし期限切れになってたら再構築、 みたいなことを.vimrcの中でやっても良いかな、とも思いましたが、 それはやりすぎかな、というのと、 上の様に別のところで毎日動かしてるcronがあるのでそれに乗ったほうが良いな、という感じです。
ちなみにPython2に関しては作ってないです。
大概のプラグインがPython3があればそちらを使うのでなくても問題がないので。
あと、Python2だとpip install virtualenv
する必要があったりひと手間かかるので。
今後消えゆくPython2は無理に入れる必要はないかな、と。