No, but seriously, NeoVim has a few features that are really interesting, but the real reason for moving is that, as a Python dev, I need to be able to look at source code and definitions very often, while hacking on my code. The wonderful jedi-vim plugin normally allows me to do just that, when it comes to my local project. But because I am using virtual environments extensively in my work, such as with virtualenv and/or pyenv , I have a problem on my hands:
Jedi-vim is painfully unaware of virtual environments.
So if I for example,
setup a virtual environments in my project dir as such:
$ virtualenv -m python 3 venv
Activate the environment:
$ source venv/bin/activate
and then install Django:
$ pip install django
Initialise a django app with:
$ django-admin startproject mysite
Open the urls file:
$ vim mysite/urls.py
Placing the cursor on an object we are importing,
such as url, and running the jedi-vim goto definition shortcut (mine is
from django.conf.urls import url from django.contrib import admin
Returns the following error:
jedi-vim: Couldn't find any definitions for this.
Spent a good amount of time googling, asking around, playing with different plugins, but nope, no joy. The internet was suggesting three things:
- Suck it up, cause similar issues were not tackled yet or at all..
- Tackle the issue myself, for which I feel I am not well versed enough (yet).
- Move to NeoVim plus Pyenv and jedi-vim, where things magically work.
So here I am with my brand new NeoVim setup. Of course I had to go through a few gotchas to get this to work, which I will share here for all those out there hacking around with this.
The first thing I did was to ditch virtualenv and use Pyenv instead. I used homebrew to do that.
$ brew update $ brew install pyenv $ brew install pyenv-virtualenv
We still need to complete the install by adding a few environment variables to our shell profiles. So depending on our preferred shell, we use ~/.bash_profile , or ~/.zshrc or whatever else:
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> <profile_file> $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> <profile_file> $ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> <profile_file>
(more info on PyEnv Github )
We can then initialize some environments and play around:
$ pyenv install 3.6.5 $ pyenv install 2.7.14 $ pyenv virtualenv 2.7.14 my_p2_project $ pyenv virtualenv 3.6.5 my_p3_project $ pyenv activate my_p3_project $ pyenv versions $ pyenv deactivate
Installing NeoVim and jedi-vim#
For NeoVim, I used, you guess it, Homebrew:
$ brew install neovim
At which point, we can run it with:
I then proceeded to install a bunch of plugins for my Python stuff. I took a great deal of inspiration from Fisa’s NeoVim configuration for that, but for the sake of this guide, we can simply install the jedi-vim plugin by adding the following to our ~/.config/nvim/init.vim :
call plug#begin('~/.config/nvim/plugged') Plug 'davidhalter/jedi-vim call plug#end()
We can then reopen
nvim and run a
Now for our gotcha part#
For being able to use Python 2/3 plugins,we will need the neovim Python module, with:
pip install neovim
But this would mean that we’d have to install the neovim plugin in all the virtual environments we create.
To get around this, we need to create 1-2 virtual environments just for neovim, and add a line in our
init.vim that will tell nvim to look into those envs for its plugin. We do the following:
pyenv virtualenv 2.7.14 neovim2 pyenv virtualenv 3.6.5 neovim3 pyenv activate neovim2 pip install neovim pyenv which python # Note the path pyenv activate neovim3 pip install neovim pyenv which python # Note the path
We will need to add also the following to our ~/.config/nvim/init.vim:
let g:python_host_prog = '/path/to/neovim2/bin/python' let g:python3_host_prog = '/path/to/neovim3/bin/python'
Run a health check in nvim to make sure all is ok:
Once this is done, we are all set with a reachable pyenv environment in our shiny new neovim setup!