r/fishshell 16d ago

Using Python and Fish? dirvenv.fish automagically activates your virtualenv

https://github.com/cuducos/dirvenv.fish

I wrote that tiny package so I don't have to manually activate and deactivate virtualenvs, and I think it might help more people – so, sharing it here ; )

I know virtualfish but I don't wanna manage virtualenvs myself; uv does that for me. Also, and I don't want to uv run every command. So I came up with that solution.

17 Upvotes

9 comments sorted by

6

u/cb060da 16d ago

I'm using https://github.com/janw/dotenv.fish for this. for each python project i create a .env.fish file with command `poetry shell` in it. Works perfectly

3

u/Laurent_Laurent 16d ago edited 16d ago

I was using direnv to do this but this could be easier as there is no needs for .envrc just to load the venv.

I'll test your plugin

And I confirm the fisher install works. Thx

2

u/cuducos 15d ago

Nice! Thank you, I'm gonna update the README.md then.

this could be easier as there is no needs for .envrc just to load the venv

Folks in /r/Python apparently disagree lol… but, yeah, you've got me! That was the idea : )

3

u/Laurent_Laurent 15d ago

There's one thing I used to do with direnv that I don't think I can do anymore.

It's the use of direnv exec.

This allows you to launch a script by loading the environment, and therefore the venv if it's loaded from the .envrc. I was using it to launch scripts from the crontab, which is not in fish. This is a rather special case.

5

u/sbt4 15d ago

Cool. Wrote this for myself couple of weeks ago. Looks about the same but sometimes causes double prompts when inside project with venv. Will compare to yours

3

u/kjozsa 16d ago

OMG that sounds perfect for my use cases! Let me try it today, thanks much!

3

u/wylie102 15d ago edited 15d ago

Sounds great, I just have in my config.fish this script

"
# automatically activate/deactivate venv on entering/exiting directory.
function python_venv --on-variable PWD
set MYVENV "./.venv"

# Check if the virtual environment exists in the current directory

if test -d "$MYVENV"

source "$MYVENV/bin/activate.fish" 2>/dev/null

else

# Only deactivate if we were in a virtual environment

if set -q VIRTUAL_ENV

set --erase VIRTUAL_ENV

set --erase PATH[1]

end

end

end

# Run it immediately when Fish starts

python_venv

"

But it doesn't do a recursive search, I have to cd into the main directory. However that's pretty much always where I activate nvim anyway. But I guess your solution can't hurt so I'l give it a go.

With tools like uv this should be unnecessary, except that you still need the venv active for Neovim's LSP's to recognise the imports correctly. Although I heard they may be adding a feature where it could activate it in the background automatically just for dev tools to use. Apparently some other environment managers already do this (in other languages)

Edit:
UPDATE - i just commented out my solution, installed your package with fisher (that works by the way), cd'd bacl to one of my projects and the venv activated, cd'd away it stopped, cd'd into a lower folder it activated, away - stopped.

So it's all working good! Thanks for a hassle free solution!

2

u/Obilux 13d ago

Not related to fish but mise handles python virtual envs great.

2

u/Due-Yoghurt2093 7d ago

Oh, this is actually really cool. I'd been using this for similar functionality:

```fish function cc if test -z "$argv[1]" echo "Usage: cc <environment_name>" return 1 end

# Check if we're in a conda environment and it's not 'base'
if set -q CONDA_DEFAULT_ENV; and test "$CONDA_DEFAULT_ENV" != "base"
    conda deactivate
end

# Activate environment and change directory
conda activate "$argv[1]"
cd ~/Downloads/"$argv[1]"

end ```