最近在用jedi-vim,碰到了这么个问题,花了好一会才解决,在这里记录一篇,也想请教各位有没有其他更好的处理方法。
jede是用python开发的库,能实现python补全、提示、变量查找等等,这个在开发中特别有用,代码补全可以减少输入字符数,代码提示则可以减少看文档的时间,总之,jedi-vim实在是程序员居家旅行、杀人越货的必备利器。
这是几个使用中的screenshot:
import提示
参数提示
代码补全
不过使用虚拟环境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匹配。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。