lazy_importとインテリセンス(続き)
15日に書いた記事( lazy_importとインテリセンス - wonderful_pandaの日記 )の記事について、ありがたいことにVimに詳しい方々から色々と突っ込みをいただきました。
pythoncomplete.vimの改善(lazy_importの解釈) · Issue #110 · vim-jp/issues · GitHub
その中で、「Pythonなんだからpythoncomplete.vimを直接さわらなくてもいけるんじゃないの」という指摘がありまして、とりいそぎやってみました。
pythoncomplete.vimでlazy_importでインポートしたモジュールも補完できるようにする · GitHub
:python <<EOS # coding=utf8 import re from types import MethodType # lazy_importブロックを検出するための正規表現(適当) re_lazy_import = re.compile( ur'''^lazy_import\s*\(globals\(\)\s*,\s*("""|\'\'\') # lazy_import(globals(), """ (?P<contents>[^"\']*) # inside here document \1\s*\) # """) ''', re.M|re.X) # 各行のインデントを検出するための正規表現 re_indent = re.compile(ur'^[ \t]+', re.M) class PyCmpPatchForBzr(object): """ lazy_importでインポートされたモジュールの補完をpythoncompleteで行うための モンキーパッチ """ def strip_lazyimport(self, source): """ソース内のlazy_importを通常のimportに置換する""" def unindent(text): return re_indent.sub('', text) return re_lazy_import.sub( lambda m:unindent(m.group('contents')), source) def apply(self): """モンキーパッチ適用""" if hasattr(Completer, 'evalsource_orig'): return Completer.evalsource_orig = Completer.evalsource def evalsource(cmpl, text, line): cmpl.evalsource_orig(self.strip_lazyimport(text), line) Completer.evalsource = MethodType(evalsource, None, Completer) def restore(self): """モンキーパッチ解除""" if not hasattr(Completer, 'evalsource_orig'): return Completer.evalsource = Completer.evalsource_orig delattr(Completer, 'evalsource_orig') pycmp_patch_for_bzr = PyCmpPatchForBzr() EOS " lazy_importの補完をpythoncompleteで有効にする function! pycmp_for_bazaar#apply() :python <<EOS pycmp_patch_for_bzr.apply() EOS endfunction " lazy_importの補完をpythoncompleteで無効にする function! pycmp_for_bazaar#restore() :python <<EOS pycmp_patch_for_bzr.restore() EOS endfunction
このファイルをVimに読み込んだ後、
- :call pycmp_for_bazaar#apply() で機能を有効にして、
- :call pycmp_for_bazaar#restore() で元に戻すことができます。
もう一工夫すればもっと汎用的にできそうですね。