Kotaro7750's diary

低レイヤを中心とした技術ブログ、たまに日記

Neovimのpython環境を一発で自動構築する

私はメインのエディタとしてneovimを使っていますが、一部のプラグイン(deopleteなど)にはpython環境が必要なことがあります。

しかし、pythonのバージョンは使うマシンや環境によって異なるため、同時に複数のマシンで環境を揃えたり、新しいマシンを導入した際に環境構築がめんどくさかったりします。今回はpython仮想環境を用いることで、コマンド一発でneovimのpython環境を構築する方法を紹介します。

私はツールの設定ファイルや環境構築スクリプトgithubで管理しているので、全体を見たい方は下のリポジトリをご覧ください。

github.com

pyenvとvirtualenv

pythonのバージョン管理というとまず思い浮かぶのがpyenvだと思います。

pyenvは使うバージョンを記したversionファイル(globalなら~/.pyenv/version)に応じて実際に呼び出すpython実行ファイルを切り替えます。このことによって、下のように簡単なコマンドでシステム全体や特定のディレクトリ以下で使うバージョンを切り替えることができます。

$ python --version
Python 3.8.1

$ pyenv global 2.7.15

$ python --version
Python 2.7.15

しかし、neovimは設定ファイルに書かれたパスを参照してpythonを実行しているに過ぎず、このやり方では少し都合がよろしくないです。

この問題を解決するのがvirtualenvです。これは、ディレクトリの中にpythonの実行環境を閉じ込めたもので、使う実行ファイル、ライブラリを完全に固定することができます。

virtualenvを用いたpython環境の作成

neovimの使うpython環境は2系と3系の2つがあり、それぞれの仮想環境を用意していきます。前提として、python2とpython3をpyenvを用いて切り替えることのできる状態にしてあるものとします。(pyenvの導入方法は後述します)

#python3環境を~/nvim-python3ディレクトリに構築
$ pyenv global 3.8.1
$ virtualenv -p python3 ~/nvim-python3

#python2環境を~/nvim-python2ディレクトリに構築
$ pyenv global 2.7.15
$ virtualenv -p python ~/nvim-python2

このコマンドによって~ディレクトリ以下に2つのディレクトリができました。このディレクトリ内にあるactivateファイルをsourceすることでpythonコマンドがその仮想環境内のpythonコマンドを指すようになります。もとのpythonコマンドを参照するようにするためにはdeactivateコマンドを実行します。

$ which python
/home/denjo/.pyenv/shims/python

#一時的に仮想環境のpythonを使う
$ source ~/nvim-python3/bin/activate

$ which python
/home/denjo/nvim-python3/bin/python

#deactivateコマンドでもとに戻る
$ deactivate

$ which python
/home/denjo/.pyenv/shims/python

仮想環境内にneovimに必要なパッケージをインストールするには仮想環境のpythonを有効にした状態でpipを用いてインストールしてください。

$ source ~/nvim-python3/bin/activate

$ pip install pynvim

$ deactivate

同様にpython2用の仮想環境を構築してください。

neovimで使うpythonのパスを設定する

neovimの設定ファイル内に以下のコードを書いてください

let g:python3_host_prog = expand('~/nvim-python3/bin/python3')
let g:python_host_prog = expand('~/nvim-python2/bin/python2')

この状態でneovimのcheckhealthを実行すると以下のように正しく仮想環境内のpythonを見てくれていることが解ると思います。

## Python 2 provider (optional)
  - INFO: pyenv: Path: /home/denjo/.pyenv/libexec/pyenv
  - INFO: pyenv: Root: /home/denjo/.pyenv
  - INFO: Using: g:python_host_prog = "/home/denjo/nvim-python2/bin/python2"
  - INFO: Executable: /home/denjo/nvim-python2/bin/python2
  - INFO: Python version: 2.7.15
  - INFO: pynvim version: 0.4.1
  - OK: Latest pynvim is installed.

## Python 3 provider (optional)
  - INFO: pyenv: Path: /home/denjo/.pyenv/libexec/pyenv
  - INFO: pyenv: Root: /home/denjo/.pyenv
  - INFO: Using: g:python3_host_prog = "/home/denjo/nvim-python3/bin/python3"
  - INFO: Executable: /home/denjo/nvim-python3/bin/python3
  - INFO: Python version: 3.8.1
  - INFO: pynvim version: 0.4.1
  - OK: Latest pynvim is installed.

環境自動構築

以上を踏まえて、仮想環境の構築をコマンド一発で行ってくれるようにしてみます。

ここでは以下のことを行うシェルスクリプトを用いて自動構築していきます。

  1. pyenvの導入
  2. pyenvでpythonをインストール
  3. 仮想環境を構築
  4. 使うライブラリのインストール

pyenvの導入

pyenvの導入はリポジトリをクローンすることで行います。

git clone git://github.com/yyuu/pyenv.git ~/.pyenv

このままでは使えないので、使っているシェルの設定ファイルに(bashrc,zshrcなど)以下を書き込んでください。

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

私はzshrcもリポジトリで管理しているのでcloneしてくれば既に書き込みは終了しています。

pyenvでpythonをインストール

pyenv install 3.8.1
pyenv install 2.7.15

使うライブラリのインストール

仮想環境は前述のように行ったものとします。 pipはrオプションで、インストールしたいライブラリ一覧を記したファイルを読み取ってインストールしてくれます。

このファイルは手動で書いてもいいですし、既存のpipでインストールしたパッケージを複製したい場合はpip freezeコマンドでこのファイルを生成してくれます。

$ pip freeze > requirement.txt

$ cat requirement.txt
pynvim==0.4.1
#一覧ファイルを使ってインストール
pip install -r requirement.txt

結果として、自動構築スクリプトは以下のようになります。

#!/bin/bash
#install pyenv
git clone git://github.com/yyuu/pyenv.git ~/.pyenv

#install 2 and 3
pyenv install 3.8.1
pyenv install 2.7.15

#make virtualenv
pyenv global 3.8.1
pip install virtualenv
virtualenv -p python3 ~/nvim-python3

pyenv global 2.7.15
virtualenv -p python ~/nvim-python2

pyenv global system

#install requirement
source ~/nvim-python3/bin/activate
pip install -r ~/dotfiles/init/linux/python/nvim-python3-requirements.txt
deactivate

source ~/nvim-python2/bin/activate
pip install -r ~/dotfiles/init/linux/python/nvim-python2-requirements.txt
deactivate

このようなスクリプトを一回作ってしまえばどんな環境でも使いまわせるので非常に楽です。