最近在用jedi-vim,碰到了这么个问题,花了好一会才解决,在这里记录一篇,也想请教各位有没有其他更好的处理方法。

jede是用python开发的库,能实现python补全、提示、变量查找等等,这个在开发中特别有用,代码补全可以减少输入字符数,代码提示则可以减少看文档的时间,总之,jedi-vim实在是程序员居家旅行、杀人越货的必备利器。
这是几个使用中的screenshot:
import提示
import提示1
参数提示
import提示2
代码补全
补全

不过使用虚拟环境virtualenv时,会出现jedi找不到django的问题。
首先,jedi的查找范围是sys.path,在vim中运行:

python << EOF
print(sys.path)
EOF

结果;

['/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol', '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode']

确实是没有把django所在的目录加进来。

其次。其实jedi现在也已经支持虚拟环境查找,在jedi的module.py中,实际上已经有这个函数了:

def get_sys_path():
    def check_virtual_env(sys_path):
        """ Add virtualenv's site-packages to the `sys.path`."""
        venv = os.getenv('VIRTUAL_ENV')
        if not venv:
            return
        venv = os.path.abspath(venv)
        p = os.path.join(
            venv, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages')
        sys_path.insert(0, p)

    check_virtual_env(sys.path)
    return [p for p in sys.path if p != ""]       

但是启动virtualenv后,在启动vim,观察sys.path,没有变化,所以get_sys_path函数没有运行。
最后,还存在vim使用python版本的问题。vim在运行python代码中,会使用安装vim指定的python解释器,在我的环境中是python2.7,但是我用的虚拟环境是python3.3,这行代码:

p = os.path.join(venv, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages')

得到的路径是:
/home/me/python3/lib/python2.7/site-packages
而实际上,虚拟环境的site-packages在:
/home/me/python3/lib/python2.7/site-packages
也就是说,即便vim启动时执行了jedi的get_sys_path函数,得到的结果也是错的。

最后,我参考了别人的.vimrc,弄了这个蹩脚的方法,在.vimrc中加入:

" Add the virtualenv's site-packages to vim path
if has('python')
py << EOF
import os.path
import sys
import vim
if 'VIRTUAL_ENV' in os.environ:
    project_base_dir = os.environ['VIRTUAL_ENV']
    sys.path.insert(0, os.path.join(project_base_dir, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages'))
EOF
endif

其实就是把虚拟路径地址硬编码到sys.path中。

如果拥有系统权限,其实还有个方法,就是把django直接安装到vim使用的python的库中。

最后我还是想吐槽一下jedi-vim的不足,jedi-vim的补全一定要手工Ctrl+space。我原来用的补全是根据字符串匹配的,不能根据python语法做补全和提示,但能自动弹出,如果在代码中写了很多长变量,这时候自动弹出就省了不少力气。要解决这个问题,可以试试youcompleteme,这个包含了jedi,并且引入了fuzzy匹配。


sc2222
207 声望2 粉丝

pythonfan