17

I do a lot of Python and I use almost all the time a virtualenv along with virtualenvwrapper to keep my modules organised.

But when I want to use those plugin from inside vim, through an external command, it seems that the shell is not aware of that config.

I need to have access to the virtualenv because

e.g.

(venv) $ python
>> import simple_history
>> # OK here

(venv) $ vim
:!python 
>> import simple_history
ImportError: No module named simple_history

My shell is shell=/bin/zsh, I guess I need to use this setting to access my virtualenv, but I can't figure out how...

1

2 Answers 2

18

I actually fixed this myself a long time ago. The problem is that when you run !python you're starting up a new shell with your existing environment. But, this means workon xxxx wasn't called to actually activate the virtualenv. This lead to a lot of confusion for me since $VIRTUAL_ENV was set.

I got around it by adding the following to my ~/.zshenv script:

if [[ -n $VIRTUAL_ENV && -e "${VIRTUAL_ENV}/bin/activate" ]]; then
  source "${VIRTUAL_ENV}/bin/activate"
fi

Since ~/.zshenv is sourced within the current session, it's a pretty safe assumption that the $VIRTUAL_ENV wasn't activated. Now when you run !python in Vim, it should use the virtualenv interpreter. You can confirm this by running :echo system('which python').

5
  • Oh this is nice, maybe it's not the place to ask the question, but why should your snippet be in .zshenv instead of .zshrc?
    – nobe4
    Commented May 6, 2016 at 6:17
  • 2
    @Nobe4 Because .zshrc is not always sourced, while .zshenv is guaranteed to be sourced. Commented May 6, 2016 at 7:52
  • Here is further information about the load order of zsh scripts: zsh.sourceforge.net/Intro/intro_3.html
    – Tommy A
    Commented May 6, 2016 at 13:36
  • 2
    I updated the answer because $ZSHENV_PATH_SET is irrelevant to solving the OP's problem. Adding the check for $VIRTUAL_ENV in that block was the result of late night troubleshooting.
    – Tommy A
    Commented May 6, 2016 at 13:51
  • 1
    to use with fish, i created ~/.config/fish/auto_source_venv.fish ` if test -e $VIRTUAL_ENV source $VIRTUAL_ENV/bin/activate.fish end ` and added . ~/.config/fish/auto_source_venv.fish to ~/.config/fish/config.fish
    – Tshirtman
    Commented Nov 23, 2019 at 16:12
5

For neovim and pyenv (also works for other python version managers that uses $VIRTUAL_ENV such as virtualenvwrapper) users with the same problem on nvim (venv not working properly, causing errors on :checkhealth and !python, etc), I know this is a little late, but since neovim checkhealth redirects to this question, I'm putting this answer here hoping it will help someone.

I created a function to autosource $VIRTUAL_ENV before calling nvim. This is a little different from Tommy A answer because venv is activated on the entire nvim env, fixing !python but also letting nvim to successfully detect the pyenv venv (see :checkhealth).

For pyright problems, check PPS note at the bottom of this answer.

Here is how I did with fish:

Create file ~/.config/fish/functions/nvimvenv.fish and save the content below in it:

# Autosource virtualenv; Workaround for nvim
function nvimvenv
  if test -e "$VIRTUAL_ENV"; and test -f "$VIRTUAL_ENV/bin/activate.fish"
    source "$VIRTUAL_ENV/bin/activate.fish"
    command nvim $argv # Run nvim program, ignore functions, builtins and aliases
    deactivate # Must deactivate on exit, otherwise venv will still be sourced which may cause undesirable effects on your terminal.
  else
    command nvim $argv # Run nvim program, ignore functions, builtins and aliases
  end
end;

There is no need to source it.

To use this function just open a new terminal and run nvimvenv, or you can set an alias to nvim by running alias nvim=nvimvenv on terminal and call it with nvim. If you want to make it permanent run with -s option like alias -s nvim=nvimvenv.

Important: If after setting the script neovim venv still not working, check if you don't have omf pyenv installed. I found that when you have omf pyenv istalled neovim can't detect pyenv virtualenv. To uninstall just run omf remove pyenv, you don't need it to use pyenv in fish, just follow the pyenv fish installation guide and your are good.

Here is the same function for bash and zsh (you will need to put/source this on your .bashrc or .zshrc):

function nvimvenv {
  if [[ -e "$VIRTUAL_ENV" && -f "$VIRTUAL_ENV/bin/activate" ]]; then
    source "$VIRTUAL_ENV/bin/activate"
    command nvim "$@"
    deactivate
  else
    command nvim "$@"
  fi
}

alias nvim=nvimvenv

PS: Also works for vim, just replace nvim for vim in the script, but if your concern is only running the right !python Tommy answer will be enough.

PPS - Regarding pyright: Initially I erroneously mentioned that this workaround would fix pyright problems, but I found it was not true, it only fix !python and pyenv virtualenvs detection on nvim (:checkhealth). If you are facing problems with pyright you will probably have to setup a pyrightconfig.json with your venv. I created this plugin pyenv-pyright to easily setup the pyrightconfig.json with pyenv virtualenvs.

4
  • 1
    You can use command nvim in bash/zsh to force the shell to not use aliases/functions in that position. That avoids hard-coding /usr/bin/nvim, which may not be correct for everyone.
    – D. Ben Knoble
    Commented Nov 16, 2021 at 17:45
  • Didn't know about command, thank you Ben, this also works on fish. Edited. Commented Nov 16, 2021 at 17:59
  • 1
    Still doesn't work for me with nvim and pyenv. CheckHealth gives But $PATH yields this python3-config executable: Usage: /home/USERNAME/.pyenv/versions/3.12.1/envs/VENVNAME/bin/python3-config --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed Commented Jan 14 at 21:25
  • Despite the previous warnings in :CheckHealth, it works correctly with pyright without the additional plugin advertised in PPS. pyright is not signaling missing packages that are installed in the correct virtual environment. Instead, it does not work with python-lsp-server. Commented Jan 14 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.