Smart Python virtual environment switching for Zsh
A powerful Zsh plugin that automatically detects and switches between Python virtual environments based on project files. Unlike other tools, venvswitch creates local virtual environments in your project directories, keeping your development environment clean and organized.
- π Automatic Switching: Detects and switches virtual environments when entering directories
- π Local Environments: Creates virtual environments directly in project folders
- π οΈ Multi-tool Support: Works with
virtualenv
,pipenv
,poetry
, andconda
- β‘ Performance Optimized: Intelligent caching system for fast directory scanning
- ποΈ Highly Configurable: Extensive customization options via environment variables
- π‘οΈ Robust Error Handling: Comprehensive validation and error recovery
- π¨ Beautiful Output: Colorized messages with customizable formatting
- π Smart Detection: Recognizes project types from multiple indicator files
- Installation
- Quick Start
- Usage
- Configuration
- Commands
- Examples
- Troubleshooting
- Advanced Usage
- Compatibility
- Contributing
- License
- Zsh (v5.0 or later)
- Oh My Zsh framework
- Python (3.6+ recommended)
- At least one Python environment tool:
virtualenv
,pipenv
,poetry
, orconda
-
Clone the repository:
git clone https://github.com/murapadev/venvswitch.git ~/.oh-my-zsh/custom/plugins/venvswitch
-
Add to your
~/.zshrc
:plugins=(... venvswitch)
-
Restart your terminal:
source ~/.zshrc
-
Verify installation:
venvswitch_config
# Create a new Python project
mkdir my-awesome-project
cd my-awesome-project
# Create and activate a virtual environment
mkvenv
# You're now in an isolated Python environment!
# The .venv directory is created locally in your project
# Install packages
pip install requests flask
# Work on your project...
python app.py
# When done, clean up
rmvenv
venvswitch automatically detects Python projects by looking for these files:
Tool | Indicator Files | Priority |
---|---|---|
Poetry | poetry.lock , pyproject.toml |
π Highest |
Pipenv | Pipfile , Pipfile.lock |
π High |
Conda | environment.yml , conda-environment.yml |
π Medium |
Virtualenv | .venv/ , requirements.txt , setup.py |
π Low |
# Enable automatic switching
enable_venvswitch
# Disable automatic switching
disable_venvswitch
# Check current status
venvswitch_config
# Clear scan cache
venvswitch_clear_cache
Customize behavior with environment variables in your ~/.zshrc
:
# Virtual environment directory name
export VENVSWITCH_VENV_DIR=".venv" # Default: ".venv"
# Scanning behavior
export VENVSWITCH_MAX_DEPTH="10" # Default: 10 levels up
export VENVSWITCH_IGNORE_DIRS="node_modules .git .svn .cache"
# Performance
export VENVSWITCH_CACHE_ENABLED="true" # Default: true
export VENVSWITCH_CACHE_TTL="30" # Cache TTL in seconds
# Tool preferences (order matters!)
export VENVSWITCH_PREFERRED_TOOLS="poetry pipenv conda virtualenv"
# Python version
export VENVSWITCH_DEFAULT_PYTHON="python3.9"
# Project detection
export VENVSWITCH_PROJECT_FILES="Pipfile poetry.lock environment.yml requirements.txt setup.py pyproject.toml"
# Output control
export VENVSWITCH_SILENT="" # Set to suppress messages
export VENVSWITCH_MESSAGE_FORMAT="π Switching to %venv_type: %venv_name (%py_version)"
# Installation behavior
export VENVSWITCH_PIPINSTALL="FULL" # "FULL" for pip install . vs -e .
export VENVSWITCH_DEFAULT_REQUIREMENTS="$HOME/.default-requirements.txt"
Command | Description |
---|---|
mkvenv [options] |
Create virtual environment in current directory |
rmvenv |
Remove virtual environment from current directory |
enable_venvswitch |
Enable automatic environment switching |
disable_venvswitch |
Disable automatic environment switching |
venvswitch_config |
Show current configuration |
venvswitch_clear_cache |
Clear the scan cache |
mkdir django-project
cd django-project
# Create virtual environment with Python 3.9
mkvenv --python=python3.9
# Install Django
pip install django
# Create Django project
django-admin startproject myproject .
# The .venv directory is created locally
ls -la
# drwxr-xr-x .venv/
# -rw-r--r-- manage.py
# drwxr-xr-x myproject/
# Initialize Poetry project
poetry init
# Install dependencies and create environment
mkvenv
# Poetry environment is created and activated
poetry env list
# /path/to/project/.venv (Activated)
# Create Pipenv project
pipenv install flask requests
# Setup environment
mkvenv
# Pipenv environment is activated
pipenv --venv
# /path/to/project/.venv
# Create environment.yml
cat > environment.yml << EOF
name: data-science
dependencies:
- python=3.9
- numpy
- pandas
- jupyter
EOF
# Create conda environment
mkvenv
# Environment is activated
conda info --envs
# data-science * /path/to/project/.venv
# Use 'venv' instead of '.venv'
export VENVSWITCH_VENV_DIR="venv"
# Prefer conda over virtualenv
export VENVSWITCH_PREFERRED_TOOLS="poetry pipenv conda virtualenv"
# Custom activation message
export VENVSWITCH_MESSAGE_FORMAT="π Activated %venv_name (%py_version)"
# Reload configuration
source ~/.zshrc
# Check if plugin is in your plugins list
grep "venvswitch" ~/.zshrc
# Verify Oh My Zsh is working
omz --version
# Check for syntax errors
zsh -n ~/.oh-my-zsh/custom/plugins/venvswitch/venvswitch.plugin.zsh
# Clear cache and retry
venvswitch_clear_cache
# Check configuration
venvswitch_config
# Verify project files exist
ls -la | grep -E "(Pipfile|poetry\.lock|environment\.yml|\.venv)"
# Check if directory is ignored
echo $VENVSWITCH_IGNORE_DIRS
# Reduce scan depth
export VENVSWITCH_MAX_DEPTH="3"
# Add more ignore patterns
export VENVSWITCH_IGNORE_DIRS=".git node_modules .cache __pycache__"
# Disable caching if needed
export VENVSWITCH_CACHE_ENABLED="false"
# Check directory permissions
ls -ld /path/to/project
# Fix permissions if needed
chmod 755 /path/to/project
# For conda, ensure proper initialization
conda init zsh
# Check for conflicting plugins
plugins=(... venvswitch) # Ensure venvswitch is loaded last
# Disable other virtualenv plugins temporarily
# plugins=(... ) # Remove conflicting plugins
# Enable verbose output
export VENVSWITCH_SILENT=""
# Check what the plugin detects
cd /path/to/project
venvswitch_config
# Monitor cache usage
venvswitch_clear_cache
# Navigate directories and check cache status
Extend project detection for custom workflows:
# Add custom project files
export VENVSWITCH_PROJECT_FILES="$VENVSWITCH_PROJECT_FILES custom-project.json"
# Create custom detection logic in your .zshrc
function my_custom_detector() {
if [[ -f "custom-project.json" ]]; then
# Custom environment setup
export CUSTOM_VAR="value"
fi
}
# Hook into directory changes
add-zsh-hook chpwd my_custom_detector
# .envrc file
export DATABASE_URL="postgresql://localhost/myproject"
export SECRET_KEY="your-secret-key"
# venvswitch handles Python, direnv handles other env vars
# Fuzzy search Python environments
function fzf-venv() {
local venv_dir=$(find . -name ".venv" -type d 2>/dev/null | fzf)
if [[ -n "$venv_dir" ]]; then
source "$venv_dir/bin/activate"
fi
}
# Automatically activate environment in new tmux panes
if [[ -n "$TMUX" ]]; then
# tmux-specific configuration
export VENVSWITCH_AUTO_ACTIVATE="true"
fi
# For GitHub Actions or similar
export VENVSWITCH_VENV_DIR="venv"
export VENVSWITCH_CACHE_ENABLED="false"
# Create environment for CI
mkvenv --python=python3.9
pip install -r requirements.txt
- Linux: β Fully supported
- macOS: β Fully supported
- Windows:
β οΈ Requires WSL or similar
Tool | Version | Status |
---|---|---|
virtualenv | 16.0+ | β |
pipenv | 2018.11.26+ | β |
poetry | 1.0+ | β |
conda | 4.6+ | β |
mamba | 0.15+ | β |
- Zsh 5.0+: β Full support
- Zsh 4.x:
β οΈ Limited support (upgrade recommended) - Oh My Zsh: β Required
- Prezto: β Not supported
We welcome contributions! Please see our Contributing Guide for details.
# Fork and clone the repository
git clone https://github.com/yourusername/venvswitch.git
cd venvswitch
# Create development environment
mkvenv --python=python3.9
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
./test/run_tests.sh
# Check code style
./scripts/lint.sh
- Check existing issues on GitHub
- Use the issue template
- Include:
- Your Zsh version (
zsh --version
) - Oh My Zsh version (
omz --version
) - Python version and environment tool versions
- Steps to reproduce
- Expected vs actual behavior
- Your Zsh version (
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Update documentation
- Submit PR with clear description
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for a complete list of changes and version history.
This project builds upon the foundational concepts from the excellent zsh-autoswitch-virtualenv project by Michael Aquilina. While venvswitch shares the core idea of automatic virtual environment switching, it has been completely rewritten with significant enhancements and improvements.
Special thanks to:
- Michael Aquilina for the original zsh-autoswitch-virtualenv concept
- The Oh My Zsh community for the framework
- The Python and Zsh communities for their amazing tools
Built with β€οΈ for developers who want clean, organized Python environments.
- π Documentation
- π Issue Tracker
- π¬ Discussions
Made with β€οΈ by murapadev