クマーなひとときv2

雑多なメモ。twitterで書ききれないもの等。

組込版pythonを使ってvim8のif_pythonを有効化させる

今の職場、PCにインストールするパッケージが管理されているため、
python3のインストーラを使用できない。

PCによっては、管理者権限が無いため、そもそもインストーラ動かせない。

そんな環境でも、vim8のif_pythonを有効化して、denite.nvimを動かしたい。
というわけで、色々試した結果動かせたので、その時のメモ。

環境は以下の通り。

  • Windows10 64bit
  • vim8 Kaoriya版

結果だけ見る時は、最後の「まとめ」を見ればOK。

前準備

python3のパッケージを公式から取得してくる。
インストーラは使えないため、組込版を取得する。

Python Release Python 3.5.2 | Python.org

f:id:tonkuma:20161224040300j:plain

試す前に一応、:echo has('python3'):py3 print(sys.version)の結果を確認しておく。

echoは0を、printは以下を返す。

E370: Could not load library python35.dll
E263: Sorry, this command is disabled, the Python library could not be loaded.

取得したパッケージは展開しておく。また、フォルダ内にあるpython35.zipも展開しておく。

python3>ls python35.zip
python35.zip

試行1: python35.dllとvcruntime140.dllを$VIMに置く

dllだけ入れてみる。

展開したフォルダに移動し、中身を確認。

python-3.5.2-embed-amd64> ls *.dll
python35.dll  python3.dll  sqlite3.dll  vcruntime140.dll

python35.dllを$VIMにコピー。

vim8> cp ../python-3.5.2-embed-amd64/python35.dll .
vim8> ls python35.dll
python35.dll

その結果、変化はなかった。

E370: Could not load library python35.dll
E263: Sorry, this command is disabled, the Python library could not be loaded.

どうやら、以下の3.8. Python 埋め込みのための配布を読む限り、Microsoft C Runtimeが必要っぽい。

3. Windows で Python を使う — Python 3.5.2 ドキュメント

もちろんPCに入ってない。
しかし、pythonのフォルダ内にvcruntime140.dllというファイルがあったため、それを入れてみる。

vim8> cp ../python-3.5.2-embed-amd64/vcruntime140.dll .
vim8> ls vcruntime140.dll
vcruntime140.dll

その結果、:echo has('python3')は1を返した。

しかし、printを実行すると、異常終了した。

f:id:tonkuma:20161224040519j:plain

うーん。

試行2: 全部$VIM直下に突っ込む。

取得したファイルを、そのまま全部放り込んでみた。

vim8>cp -r ../python-3.5.2-embed-amd64/* .

その結果、動いた。異常終了しない…?

3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)]

一応目的達成だが、$VIM直下がファイルだらけになるのが嫌なため、他のやり方を探してみる。

試行3: python3のフォルダを$VIMに置く

展開してできたpython3のフォルダをpython3にリネームして$VIMに置き、vimrcにパスを追加してみる。

vim8>ls python3
_bz2.pyd          _hashlib.pyd          _overlapped.pyd  pyexpat.pyd   python35.zip  sqlite3.dll
_ctypes.pyd       _lzma.pyd             _socket.pyd      python.exe    pythonw.exe   unicodedata.pyd
_decimal.pyd      _msi.pyd              _sqlite3.pyd     python3.dll   pyvenv.cfg    vcruntime140.dll
_elementtree.pyd  _multiprocessing.pyd  _ssl.pyd         python35.dll  select.pyd    winsound.pyd

念の為、両方に追加。

set runtimepath+=$VIM/python3/
set path+=$VIM/python3/

その結果、python35.dllが見付からなかった。

OSのPATHじゃないと検索してくれない?

試行4: pythonthreedllを設定する

if_pythonのヘルプを読むと、pythonthreedllというのがあった。

MS-Windows ~

To use the Python interface the Python DLL must be in your search path.  In a
console window type "path" to see what directories are used.  The 'pythondll'
or 'pythonthreedll' option can be also used to specify the Python DLL.

これで使用するDLLを指定できるみたいなので、指定してみる。

set pythonthreedll=$VIM/python3/python35.dll

vcruntime140.dllも見えてないと駄目なのは試行1で判明しているため、
$VIM直下に置いておく。

vim8>ls vcruntime140.dll
vcruntime140.dll

その結果、echoは1を返し、printも動作した。
しかし、denite.nvimは動作しなかった。モジュールが見付からない模様。

[denite]   File "C:/Users/45942/prog..im8/vimfiles/dein/.cache/_vimrc/.dein~
/rplugin/python3/denite/source\file_point.py", line 9, in <module>
[denite]     from socket import gethostbyname
[denite]   File "socket.py", line 49, in <module>
[denite] ImportError: No module named '_socket'
[denite] Please execute :messages command.

もう少しっぽい。

試行5: runtimepath再設定

ヘルプを読むと、runtimepath/pythonxからモジュールを探すという記述があった。

In python vim.VIM_SPECIAL_PATH special directory is used as a replacement for 
the list of paths found in 'runtimepath': with this directory in sys.path and 
vim.path_hooks in sys.path_hooks python will try to load module from 
{rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for 
each {rtp} found in 'runtimepath'.

確認してみると、確かにruntimepathに$VIMは含まれていないため、追加してみる。

set runtimepath+=$VIM

その結果、denite.nvim動作した。やったぜ。

f:id:tonkuma:20161224041716j:plain

まとめ

組込版のpython3を使い、
vim8でif_pythonを有効化して、denite.nvimを動作させる事ができた。

まとめると、以下の手順になる。

① python3の組込版を取得。
② 取得したファイルを展開し、python3に名前変更。その中にあるpython35.zipも展開。
③ 展開してできたフォルダを$VIMに置く。
④ 上記からvcruntime140.dllだけ$VIM直下にコピー。

  • 既にOSのPATHにvcruntime140.dllが存在するならこの手順は飛ばして大丈夫。
    (家の環境がそうだった)

⑤ vimrcに以下を追加。

  • set runtimepath+=$VIM
  • set pythonthreedll=$VIM/python3/python35.dll

試してて思ったけど、vim8にもneovimのCheckHealth欲しい…欲しくない?