diff --git a/dot_config/fish/conf.d/zz_03_interactive.fish b/dot_config/fish/conf.d/zz_03_interactive.fish index 9c99aa4..2b8b0fd 100644 --- a/dot_config/fish/conf.d/zz_03_interactive.fish +++ b/dot_config/fish/conf.d/zz_03_interactive.fish @@ -36,4 +36,11 @@ if status is-interactive printf '\e[6 q' end end + + # Auto-activate Python virtualenvs on `cd` (any repo with a .venv). Required + # because we use mise --shims, which don't run the cd hook that mise's + # python.uv_venv_auto relies on. The function autoloads from + # ~/.config/fish/functions/__auto_venv.fish; calling it here loads the file + # (registering its --on-variable PWD handler) and activates the start dir. + __auto_venv end diff --git a/dot_config/fish/functions/__auto_venv.fish b/dot_config/fish/functions/__auto_venv.fish new file mode 100644 index 0000000..3173aec --- /dev/null +++ b/dot_config/fish/functions/__auto_venv.fish @@ -0,0 +1,33 @@ +function __auto_venv --on-variable PWD --description 'Auto-activate the nearest Python .venv on cd' + # Auto-activate Python virtualenvs on `cd` for any repo that has a .venv — + # including uv projects: mise's python.uv_venv_auto only fires through the + # `mise activate` HOOK, which we don't run (we use --shims), so this function + # owns ALL interactive venv activation. Activates the nearest ancestor .venv, + # deactivates on leaving its tree, and never touches a venv we didn't activate + # (manual / mise) — we only ever deactivate the one we started (__auto_venv_dir). + # + # Autoloaded: zz_03_interactive.fish calls __auto_venv once, which loads this + # file (registering the --on-variable PWD handler) and activates the start dir. + set -l found + set -l dir $PWD + while true + if test -e "$dir/.venv/bin/activate.fish" + set found "$dir/.venv" + break + end + test "$dir" = / ; and break + set dir (path dirname $dir) + end + + if test -n "$found" + test "$VIRTUAL_ENV" = "$found"; and return # already active + if test -z "$VIRTUAL_ENV"; or set -q __auto_venv_dir + functions -q deactivate; and deactivate # swap out our previous one + source "$found/bin/activate.fish" + set -g __auto_venv_dir "$found" + end + else if set -q __auto_venv_dir + functions -q deactivate; and deactivate + set -e __auto_venv_dir + end +end diff --git a/dot_config/mise/config.toml.tmpl b/dot_config/mise/config.toml.tmpl index d31fbf5..bb27945 100644 --- a/dot_config/mise/config.toml.tmpl +++ b/dot_config/mise/config.toml.tmpl @@ -1,9 +1,17 @@ {{ if contains "dev" .tags -}} +# NOTE: python intentionally NOT a global tool. mise shims fall through to the +# next binary on PATH when a tool isn't configured, so leaving python out here +# makes `python3`/`pip` resolve to /usr/bin/python3 everywhere by default — +# which is what pacman/paru packages (#!/usr/bin/env python3, e.g. virt-manager, +# needs system gi/PyGObject) expect. Opt into mise python per-project via a +# .mise.toml (`mise use python@`), or ad-hoc with `mise shell python@latest`. [tools] bun = "latest" node = "latest" rust = "latest" go = "latest" java = "latest" -python = "latest" + +[settings] +idiomatic_version_file_enable_tools = ["node", "python", "go", "ruby", "java", "rust"] {{ end -}}