Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

pythonでvim pluginを書く時にファイル分割する

$
0
0

背景

Pythonでvim pluginを書く

上記リンクの記事を参考にVim(Neovim)のpluginを作っています。
Pythonファイルが大きくなり分割しようとしたところ、少しつまずいたので解決法を共有します。

この記事では、例としてrequestsモジュールを用いてWebページのタイトルを表示するプラグインを作ってみます。

ディレクトリ構成とファイルの中身

sample-vim-plugin
  plugin/
    sample_vim_plugin.vim
  src/
    sample_vim_plugin.py
    requests_caller.py
plugin/sample_vim_plugin.vim
scriptencoding utf-8if exists('g:loaded_sample_vim_plugin')finishendifletg:loaded_sample_vim_plugin=1lets:save_cpo=&cpo
set cpo&vim

py3file <sfile>:h:h/src/sample_vim_plugin.pyfunction! sample_vim_plugin#print_title(url)py3 sample_vim_plugin_print_title(vim.eval('a:url'))endfunctionlet&cpo =s:save_cpo
unlet s:save_cpo
src/sample_vim_plugin.py
importvimimportrequests_callerdefsample_vim_plugin_print_title(url):print(requests_caller.get_title(url))
requests_caller.py
importrequestsfrombs4importBeautifulSoupdefget_title(url):response=requests.get(url)soup=BeautifulSoup(response.text,'lxml')returnsoup.title.text

私はdeinでプラグインを管理しているので、tomlファイルに上記のプラグインを追加しneovimを起動すると
ModuleNotFoundError: No module named 'requests_caller'
と言われます。

このモジュール見つからない問題を解決したいと思います。

「Python における 'runtimepath' の処理」

Python では、'runtimepath' のパスのリストを使う代わりに、vim.VIM_SPECIAL_PATH
という特別なディレクトリが使われます。このディレクトリが sys.path 内で使われる
とき、そして vim.path_hooks が sys.path_hooks 内で使われるとき、'runtimepath'
の各パス {rtp} に対して {rtp}/python2 (or python3) と {rtp}/pythonx (両バー
ジョンで読み込まれる) のモジュールがロードされます。

とあります。

よって、二つの方法が考えられます。

解決法1: ディレクトリの名前を変更する

runtimepathの直下にpython2,python3,pythonxのディレクトリがあればロードされるとのことなので、srcディレクトリをpython3にリネームします。
当然読み込む部分を変える必要があるので、下記のように変更します

plugin/sample_vim_plugin.vim
- py3file <sfile>:h:h/src/sample_vim_plugin.py
+ py3file <sfile>:h:h/python3/sample_vim_plugin.py

解決法2: sys.pathに追加する

ディレクトリの名前を変えたくない場合は、直接sys.pathに追加します。

plugin/sample_vim_plugin.vim
+ let s:sample_vim_plugin_root_dir = expand('<sfile>:p:h:h')
  py3file <sfile>:h:h/src/sample_vim_plugin.py
src/sample_vim_plugin.py
  import vim
+ import sys
+ import os
+ plugin_python_dir = os.path.join(vim.eval('s:sample_vim_plugin_root_dir'), 'src')
+ sys.path.append(plugin_python_dir)
  import requests_caller

まとめ

  • python2, python3, pythonxディレクトリにPythonファイルを置く
  • sys.pathにPythonファイルをおいたディレクトリを追加する

という二つの方法でプラグインが動くようになります。

有名どころで言うと、davidhalter/jedi-vimでは解決法1(pythonx)を使っているみたいです。
ソースコードをチラ見しただけですが、Shougo/denite.nvimShougo/deoplete.nvimでは解決法2を使っているように見えます。


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>