feat(fish): Add custom env management system
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -11,6 +11,12 @@
|
||||
|
||||
!fish
|
||||
!fish/config.fish
|
||||
!fish/functions
|
||||
!fish/functions/env.fish
|
||||
!fish/environments
|
||||
!fish/environments/templates
|
||||
!fish/environments/templates/*
|
||||
|
||||
|
||||
!ranger
|
||||
!ranger/rc.conf
|
||||
|
||||
@@ -125,7 +125,10 @@ function check_directory_for_new_repository
|
||||
end
|
||||
|
||||
function check_and_source_activate
|
||||
if test -f (pwd)/activate.fish
|
||||
if test -f (pwd)/.fish/activate.fish
|
||||
echo (set_color green)"Found .fish/activate.fish in current directory, sourcing..."(set_color normal)
|
||||
source (pwd)/.fish/activate.fish
|
||||
else if test -f (pwd)/activate.fish
|
||||
echo (set_color green)"Found activate.fish in current directory, sourcing..."(set_color normal)
|
||||
source (pwd)/activate.fish
|
||||
end
|
||||
|
||||
71
fish/environments/templates/README.md
Normal file
71
fish/environments/templates/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Exported Fish Environment: {{ENV_NAME}}
|
||||
|
||||
This directory contains a self-contained Fish shell environment that can be used
|
||||
without requiring the original Fish configuration.
|
||||
|
||||
## Files Structure
|
||||
```
|
||||
.fish/
|
||||
├── activate.fish # Main environment configuration
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Automatic Activation (Recommended)
|
||||
The environment will automatically activate when you `cd` into this directory
|
||||
if your Fish shell is configured with the auto-activation feature that checks
|
||||
for `.fish/activate.fish`.
|
||||
|
||||
### Manual Activation
|
||||
To manually activate the environment, run from the project root:
|
||||
```bash
|
||||
source ./.fish/activate.fish
|
||||
```
|
||||
|
||||
### Deactivation
|
||||
To deactivate the environment, run:
|
||||
```bash
|
||||
env deactivate
|
||||
```
|
||||
|
||||
Or simply `cd` to a different directory if using auto-activation.
|
||||
|
||||
## What This Environment Provides
|
||||
|
||||
- Custom prompt showing the environment name
|
||||
- Environment-specific aliases and functions
|
||||
- Custom environment variables
|
||||
- Automatic cleanup when deactivated
|
||||
|
||||
## Requirements
|
||||
|
||||
- Fish shell
|
||||
- If this is a ROS2 environment: `bass` plugin (`fisher install edc/bass`)
|
||||
|
||||
## Sharing
|
||||
|
||||
This environment is completely self-contained. You can:
|
||||
1. Copy this directory to another machine
|
||||
2. Share it with other Fish shell users
|
||||
3. Version control it with your project (add .fish/ to your repo)
|
||||
|
||||
The environment will work on any system with Fish shell, regardless of whether
|
||||
they have the original environment management system installed.
|
||||
|
||||
## Auto-activation Setup
|
||||
|
||||
To enable auto-activation for .fish/activate.fish, add this to your Fish config.fish:
|
||||
```fish
|
||||
function check_and_source_activate
|
||||
if test -f (pwd)/.fish/activate.fish
|
||||
source (pwd)/.fish/activate.fish
|
||||
elif test -f (pwd)/activate.fish
|
||||
source (pwd)/activate.fish
|
||||
end
|
||||
end
|
||||
|
||||
function cd
|
||||
builtin cd $argv && check_and_source_activate
|
||||
end
|
||||
```
|
||||
49
fish/environments/templates/basic.fish
Normal file
49
fish/environments/templates/basic.fish
Normal file
@@ -0,0 +1,49 @@
|
||||
# Basic environment with custom prompt
|
||||
# Environment: {{ENV_NAME}}
|
||||
|
||||
# Check if a previous initialization has occurred
|
||||
if test -n "$__ENV_INITIALIZED"
|
||||
echo (set_color yellow)"Environment already initialized"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
# Mark as initialized
|
||||
set -gx __ENV_INITIALIZED "1"
|
||||
set -gx CURRENT_ENV "{{ENV_NAME}}"
|
||||
|
||||
# Save the original prompt function if it exists
|
||||
# Only save if we don't already have a backup or if current prompt is not from an environment
|
||||
if not functions -q __env_orig_prompt
|
||||
if functions -q fish_prompt
|
||||
functions -c fish_prompt __env_orig_prompt
|
||||
else
|
||||
function __env_orig_prompt
|
||||
echo -n (whoami)'@'(prompt_hostname)' '(set_color $fish_color_cwd)(prompt_pwd)(set_color normal)'> '
|
||||
end
|
||||
end
|
||||
else
|
||||
# If we already have a backup, we're switching environments
|
||||
# No need to create a new backup
|
||||
end
|
||||
|
||||
# Define new prompt with environment prefix
|
||||
function fish_prompt
|
||||
echo -n (set_color green)'({{ENV_NAME}})'(set_color normal)' '
|
||||
__env_orig_prompt
|
||||
end
|
||||
|
||||
# Add custom environment variables here
|
||||
# set -gx MY_CUSTOM_VAR "value"
|
||||
|
||||
# Add custom paths here
|
||||
# fish_add_path /path/to/custom/bin
|
||||
|
||||
# Custom initialization commands
|
||||
echo (set_color green)"Activated environment: {{ENV_NAME}}"(set_color normal)
|
||||
|
||||
# Optional: Define custom deactivation function
|
||||
function __env_custom_deactivate
|
||||
# Add any cleanup commands here
|
||||
# unset custom variables, restore paths, etc.
|
||||
echo (set_color blue)"Custom cleanup for {{ENV_NAME}} completed"(set_color normal)
|
||||
end
|
||||
69
fish/environments/templates/conda.fish
Normal file
69
fish/environments/templates/conda.fish
Normal file
@@ -0,0 +1,69 @@
|
||||
# Conda environment wrapper
|
||||
# Environment: {{ENV_NAME}}
|
||||
|
||||
# Check if a previous initialization has occurred
|
||||
if test -n "$__ENV_INITIALIZED"
|
||||
echo (set_color yellow)"Environment already initialized"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
# Mark as initialized
|
||||
set -gx __ENV_INITIALIZED "1"
|
||||
set -gx CURRENT_ENV "{{ENV_NAME}}"
|
||||
|
||||
# Save the original prompt function if it exists
|
||||
# Only save if we don't already have a backup or if current prompt is not from an environment
|
||||
if not functions -q __env_orig_prompt
|
||||
if functions -q fish_prompt
|
||||
functions -c fish_prompt __env_orig_prompt
|
||||
else
|
||||
function __env_orig_prompt
|
||||
echo -n (whoami)'@'(prompt_hostname)' '(set_color $fish_color_cwd)(prompt_pwd)(set_color normal)'> '
|
||||
end
|
||||
end
|
||||
else
|
||||
# If we already have a backup, we're switching environments
|
||||
# No need to create a new backup
|
||||
end
|
||||
|
||||
# Define new prompt with environment prefix
|
||||
function fish_prompt
|
||||
echo -n (set_color blue)'({{ENV_NAME}})'(set_color normal)' '
|
||||
__env_orig_prompt
|
||||
end
|
||||
|
||||
# Conda-specific setup
|
||||
if type -q conda
|
||||
# Look for environment.yml or conda-env.yml
|
||||
if test -f ./environment.yml
|
||||
echo (set_color blue)"Found environment.yml - use 'conda env create -f environment.yml'"(set_color normal)
|
||||
end
|
||||
|
||||
if test -f ./conda-env.yml
|
||||
echo (set_color blue)"Found conda-env.yml - use 'conda env create -f conda-env.yml'"(set_color normal)
|
||||
end
|
||||
else
|
||||
echo (set_color yellow)"Warning: conda not found in PATH"(set_color normal)
|
||||
end
|
||||
|
||||
# Conda aliases
|
||||
alias ce="conda env"
|
||||
alias cel="conda env list"
|
||||
alias cea="conda env create"
|
||||
alias cer="conda env remove"
|
||||
alias ca="conda activate"
|
||||
alias cd="conda deactivate"
|
||||
alias ci="conda install"
|
||||
alias cu="conda update"
|
||||
alias cr="conda remove"
|
||||
alias cl="conda list"
|
||||
|
||||
echo (set_color green)"Activated Conda environment: {{ENV_NAME}}"(set_color normal)
|
||||
|
||||
# Custom deactivation function
|
||||
function __env_custom_deactivate
|
||||
# Remove Conda aliases
|
||||
functions -e ce cel cea cer ca cd ci cu cr cl 2>/dev/null
|
||||
|
||||
echo (set_color blue)"Conda environment cleanup completed"(set_color normal)
|
||||
end
|
||||
65
fish/environments/templates/node.fish
Normal file
65
fish/environments/templates/node.fish
Normal file
@@ -0,0 +1,65 @@
|
||||
# Node.js development environment
|
||||
# Environment: {{ENV_NAME}}
|
||||
|
||||
# Check if a previous initialization has occurred
|
||||
if test -n "$__ENV_INITIALIZED"
|
||||
echo (set_color yellow)"Environment already initialized"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
# Mark as initialized
|
||||
set -gx __ENV_INITIALIZED "1"
|
||||
set -gx CURRENT_ENV "{{ENV_NAME}}"
|
||||
|
||||
# Save the original prompt function if it exists
|
||||
# Only save if we don't already have a backup or if current prompt is not from an environment
|
||||
if not functions -q __env_orig_prompt
|
||||
if functions -q fish_prompt
|
||||
functions -c fish_prompt __env_orig_prompt
|
||||
else
|
||||
function __env_orig_prompt
|
||||
echo -n (whoami)'@'(prompt_hostname)' '(set_color $fish_color_cwd)(prompt_pwd)(set_color normal)'> '
|
||||
end
|
||||
end
|
||||
else
|
||||
# If we already have a backup, we're switching environments
|
||||
# No need to create a new backup
|
||||
end
|
||||
|
||||
# Define new prompt with environment prefix
|
||||
function fish_prompt
|
||||
echo -n (set_color yellow)'({{ENV_NAME}})'(set_color normal)' '
|
||||
__env_orig_prompt
|
||||
end
|
||||
|
||||
# Node.js specific setup
|
||||
if test -f ./package.json
|
||||
echo (set_color blue)"Found package.json - Node.js project detected"(set_color normal)
|
||||
end
|
||||
|
||||
# Add node_modules/.bin to PATH if it exists
|
||||
if test -d ./node_modules/.bin
|
||||
fish_add_path ./node_modules/.bin
|
||||
echo (set_color blue)"Added ./node_modules/.bin to PATH"(set_color normal)
|
||||
end
|
||||
|
||||
# Node.js aliases
|
||||
alias nr="npm run"
|
||||
alias ni="npm install"
|
||||
alias nid="npm install --save-dev"
|
||||
alias nig="npm install --global"
|
||||
alias nu="npm uninstall"
|
||||
alias nug="npm uninstall --global"
|
||||
alias nt="npm test"
|
||||
alias ns="npm start"
|
||||
alias nb="npm run build"
|
||||
|
||||
echo (set_color green)"Activated Node.js environment: {{ENV_NAME}}"(set_color normal)
|
||||
|
||||
# Custom deactivation function
|
||||
function __env_custom_deactivate
|
||||
# Remove Node.js aliases
|
||||
functions -e nr ni nid nig nu nug nt ns nb 2>/dev/null
|
||||
|
||||
echo (set_color blue)"Node.js environment cleanup completed"(set_color normal)
|
||||
end
|
||||
73
fish/environments/templates/python.fish
Normal file
73
fish/environments/templates/python.fish
Normal file
@@ -0,0 +1,73 @@
|
||||
# Python development environment
|
||||
# Environment: {{ENV_NAME}}
|
||||
|
||||
# Check if a previous initialization has occurred
|
||||
if test -n "$__ENV_INITIALIZED"
|
||||
echo (set_color yellow)"Environment already initialized"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
# Mark as initialized
|
||||
set -gx __ENV_INITIALIZED "1"
|
||||
set -gx CURRENT_ENV "{{ENV_NAME}}"
|
||||
|
||||
# Save the original prompt function if it exists
|
||||
# Only save if we don't already have a backup or if current prompt is not from an environment
|
||||
if not functions -q __env_orig_prompt
|
||||
if functions -q fish_prompt
|
||||
functions -c fish_prompt __env_orig_prompt
|
||||
else
|
||||
function __env_orig_prompt
|
||||
echo -n (whoami)'@'(prompt_hostname)' '(set_color $fish_color_cwd)(prompt_pwd)(set_color normal)'> '
|
||||
end
|
||||
end
|
||||
else
|
||||
# If we already have a backup, we're switching environments
|
||||
# No need to create a new backup
|
||||
end
|
||||
|
||||
# Define new prompt with environment prefix
|
||||
function fish_prompt
|
||||
echo -n (set_color cyan)'({{ENV_NAME}})'(set_color normal)' '
|
||||
__env_orig_prompt
|
||||
end
|
||||
|
||||
# Python-specific environment setup
|
||||
set -gx PYTHONPATH (pwd)
|
||||
set -gx VIRTUAL_ENV_DISABLE_PROMPT 1
|
||||
|
||||
# Check for Python virtual environment
|
||||
if test -d ./venv
|
||||
set -gx VIRTUAL_ENV (pwd)/venv
|
||||
fish_add_path $VIRTUAL_ENV/bin
|
||||
echo (set_color blue)"Using Python virtual environment: ./venv"(set_color normal)
|
||||
elif test -d ./.venv
|
||||
set -gx VIRTUAL_ENV (pwd)/.venv
|
||||
fish_add_path $VIRTUAL_ENV/bin
|
||||
echo (set_color blue)"Using Python virtual environment: ./.venv"(set_color normal)
|
||||
end
|
||||
|
||||
# Python aliases
|
||||
alias py="python"
|
||||
alias pip="python -m pip"
|
||||
alias pytest="python -m pytest"
|
||||
alias black="python -m black"
|
||||
alias isort="python -m isort"
|
||||
alias mypy="python -m mypy"
|
||||
|
||||
echo (set_color green)"Activated Python environment: {{ENV_NAME}}"(set_color normal)
|
||||
|
||||
# Custom deactivation function
|
||||
function __env_custom_deactivate
|
||||
# Remove Python-specific paths and variables
|
||||
if test -n "$VIRTUAL_ENV"
|
||||
set -e VIRTUAL_ENV
|
||||
end
|
||||
set -e PYTHONPATH
|
||||
set -e VIRTUAL_ENV_DISABLE_PROMPT
|
||||
|
||||
# Remove Python aliases
|
||||
functions -e py pip pytest black isort mypy 2>/dev/null
|
||||
|
||||
echo (set_color blue)"Python environment cleanup completed"(set_color normal)
|
||||
end
|
||||
71
fish/environments/templates/ros2.fish
Normal file
71
fish/environments/templates/ros2.fish
Normal file
@@ -0,0 +1,71 @@
|
||||
# ROS2 development environment (requires distrobox)
|
||||
# Environment: {{ENV_NAME}}
|
||||
|
||||
# Check if a previous initialization has occurred
|
||||
if test -n "$__ENV_INITIALIZED"
|
||||
echo (set_color yellow)"Environment already initialized"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
# Mark as initialized
|
||||
set -gx __ENV_INITIALIZED "1"
|
||||
set -gx CURRENT_ENV "{{ENV_NAME}}"
|
||||
|
||||
# Check if running inside distrobox
|
||||
if test -f /run/.containerenv; or test -n "$CONTAINER_ID"
|
||||
# Source ROS2 setup files using bass
|
||||
if type -q bass
|
||||
bass source /opt/ros/jazzy/setup.bash
|
||||
if test -f ./install/setup.bash
|
||||
bass source ./install/setup.bash
|
||||
end
|
||||
else
|
||||
echo (set_color red)"Error: bass is required for ROS2 environment. Install with: fisher install edc/bass"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
# Set environment variable for the prompt prefix
|
||||
set -gx ROS2_ACTIVE 1
|
||||
|
||||
# Save the original prompt function if it exists
|
||||
# Only save if we don't already have a backup or if current prompt is not from an environment
|
||||
if not functions -q __env_orig_prompt
|
||||
if functions -q fish_prompt
|
||||
functions -c fish_prompt __env_orig_prompt
|
||||
else
|
||||
function __env_orig_prompt
|
||||
echo -n (whoami)'@'(prompt_hostname)' '(set_color $fish_color_cwd)(prompt_pwd)(set_color normal)'> '
|
||||
end
|
||||
end
|
||||
else
|
||||
# If we already have a backup, we're switching environments
|
||||
# No need to create a new backup
|
||||
end
|
||||
|
||||
# Define new prompt with ROS2 prefix
|
||||
function fish_prompt
|
||||
echo -n (set_color magenta)'({{ENV_NAME}})'(set_color normal)' '
|
||||
__env_orig_prompt
|
||||
end
|
||||
|
||||
# ROS2 aliases and functions
|
||||
alias cb="colcon build"
|
||||
alias cbs="colcon build --symlink-install"
|
||||
alias cbt="colcon build --packages-select"
|
||||
alias ct="colcon test"
|
||||
alias ctr="colcon test-result"
|
||||
|
||||
echo (set_color green)"Activated ROS2 environment: {{ENV_NAME}}"(set_color normal)
|
||||
else
|
||||
echo (set_color red)"This ROS2 environment should only be run inside a distrobox container"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
# Custom deactivation function
|
||||
function __env_custom_deactivate
|
||||
# Remove ROS2-specific variables and aliases
|
||||
set -e ROS2_ACTIVE
|
||||
functions -e cb cbs cbt ct ctr 2>/dev/null
|
||||
|
||||
echo (set_color blue)"ROS2 environment cleanup completed"(set_color normal)
|
||||
end
|
||||
485
fish/functions/env.fish
Normal file
485
fish/functions/env.fish
Normal file
@@ -0,0 +1,485 @@
|
||||
|
||||
# Environment management system configuration
|
||||
set -g __ENV_BASE_DIR "$HOME/.config/fish/environments"
|
||||
set -g __ENV_CONFIGS_DIR "$__ENV_BASE_DIR/configs"
|
||||
set -g __ENV_TEMPLATES_DIR "$__ENV_BASE_DIR/templates"
|
||||
|
||||
function env -d "Environment management system"
|
||||
set -l subcommand $argv[1]
|
||||
|
||||
if test -z "$subcommand"
|
||||
__env_help
|
||||
return 0
|
||||
end
|
||||
|
||||
switch $subcommand
|
||||
case create new
|
||||
__env_create $argv[2..]
|
||||
case list ls
|
||||
__env_list $argv[2..]
|
||||
case activate use
|
||||
__env_activate $argv[2..]
|
||||
case deactivate exit
|
||||
__env_deactivate $argv[2..]
|
||||
case remove rm delete
|
||||
__env_remove $argv[2..]
|
||||
case link ln
|
||||
__env_link $argv[2..]
|
||||
case info show
|
||||
__env_info $argv[2..]
|
||||
case edit
|
||||
__env_edit $argv[2..]
|
||||
case copy clone
|
||||
__env_copy $argv[2..]
|
||||
case export
|
||||
__env_export $argv[2..]
|
||||
case help h --help -h
|
||||
__env_help $argv[2..]
|
||||
case "*"
|
||||
echo (set_color red)"'$subcommand': Unknown subcommand (see env help)"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
# Internal functions (prefixed with __ to indicate they're private)
|
||||
function __env_help -d "Show help for env command"
|
||||
echo (set_color blue)"Environment Management System"(set_color normal)
|
||||
echo
|
||||
echo "usage: env <subcommand> [options]"
|
||||
echo
|
||||
echo (set_color green)"Subcommands:"(set_color normal)
|
||||
echo " create, new <name> [template] Create a new environment"
|
||||
echo " list, ls List all environments"
|
||||
echo " activate, use <name> Activate an environment"
|
||||
echo " deactivate, exit Deactivate current environment"
|
||||
echo " remove, rm <name> Remove an environment"
|
||||
echo " link, ln <name> [dir] Link environment to directory"
|
||||
echo " info, show <name> Show environment information"
|
||||
echo " edit <name> Edit environment configuration"
|
||||
echo " copy, clone <src> <dest> Copy an environment"
|
||||
echo " export <name> [dir] Export environment to directory"
|
||||
echo " help, h Show this help"
|
||||
echo
|
||||
echo (set_color green)"Templates:"(set_color normal)
|
||||
__env_list_templates
|
||||
echo
|
||||
echo (set_color green)"Examples:"(set_color normal)
|
||||
echo " env create myproject python # Create Python environment"
|
||||
echo " env activate myproject # Activate environment"
|
||||
echo " env link myproject ./myapp # Link to directory"
|
||||
echo " env export myproject ./myapp # Export self-contained env to directory"
|
||||
echo " env list # Show all environments"
|
||||
echo " env deactivate # Deactivate current environment"
|
||||
end
|
||||
|
||||
function __env_create -d "Create a new environment"
|
||||
set -l env_name $argv[1]
|
||||
set -l template_type $argv[2]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env create <name> [template]"
|
||||
echo "available templates:"
|
||||
__env_list_templates
|
||||
return 1
|
||||
end
|
||||
|
||||
if test -z "$template_type"
|
||||
set template_type basic
|
||||
end
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
set -l template_file "$__ENV_TEMPLATES_DIR/$template_type.fish"
|
||||
|
||||
if test -d "$env_dir"
|
||||
echo (set_color yellow)"'$env_name': environment already exists"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
if not test -f "$template_file"
|
||||
echo (set_color red)"'$template_type': template not found"(set_color normal)
|
||||
echo "Available templates:"
|
||||
__env_list_templates
|
||||
return 1
|
||||
end
|
||||
|
||||
# Create environment directory
|
||||
mkdir -p "$env_dir"
|
||||
|
||||
# Copy template and customize
|
||||
sed "s/{{ENV_NAME}}/$env_name/g" "$template_file" >"$env_dir/activate.fish"
|
||||
chmod +x "$env_dir/activate.fish"
|
||||
|
||||
# Create environment config file
|
||||
echo "# Environment: $env_name" >"$env_dir/config.toml"
|
||||
echo "name = \"$env_name\"" >>"$env_dir/config.toml"
|
||||
echo "template = \"$template_type\"" >>"$env_dir/config.toml"
|
||||
echo "created = \"$(date --iso-8601)\"" >>"$env_dir/config.toml"
|
||||
echo "# Add custom environment variables here" >>"$env_dir/config.toml"
|
||||
echo "# [env]" >>"$env_dir/config.toml"
|
||||
echo "# CUSTOM_VAR = \"value\"" >>"$env_dir/config.toml"
|
||||
|
||||
echo (set_color green)"environment '$env_name' ($template_type) created"(set_color normal)
|
||||
echo "environment directory: $env_dir"
|
||||
echo "to activate: env activate $env_name"
|
||||
end
|
||||
|
||||
function __env_list -d "List all available environments"
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR"
|
||||
|
||||
if not test -d "$env_dir"
|
||||
echo (set_color yellow)"no environments found"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
# Check if directory exists but is empty
|
||||
set -l env_count (count $env_dir/*)
|
||||
if test $env_count -eq 0
|
||||
echo (set_color yellow)"no environments found"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
echo (set_color blue)"available environments:"(set_color normal)
|
||||
echo
|
||||
|
||||
for env_path in $env_dir/*
|
||||
if test -d "$env_path"
|
||||
set env_name (basename "$env_path")
|
||||
set config_file "$env_path/config.toml"
|
||||
|
||||
if test -f "$config_file"
|
||||
set template (grep "template =" "$config_file" | cut -d'"' -f2)
|
||||
set created (grep "created =" "$config_file" | cut -d'"' -f2)
|
||||
echo (set_color green)" $env_name"(set_color normal)" (template: $template, created: $created)"
|
||||
else
|
||||
echo (set_color green)" $env_name"(set_color normal)" (no config found)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if test -n "$CURRENT_ENV"
|
||||
echo
|
||||
echo (set_color cyan)"'$CURRENT_ENV': currently active"(set_color normal)
|
||||
end
|
||||
end
|
||||
|
||||
function __env_activate -d "Activate an environment"
|
||||
set -l env_name $argv[1]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env activate <name>"
|
||||
echo "available environments:"
|
||||
__env_list
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
set -l activate_file "$env_dir/activate.fish"
|
||||
|
||||
if not test -f "$activate_file"
|
||||
echo (set_color red)"'$env_name': environment not found"(set_color normal)
|
||||
echo "available environments:"
|
||||
__env_list
|
||||
return 1
|
||||
end
|
||||
|
||||
# Check if another environment is already active
|
||||
if test -n "$CURRENT_ENV"
|
||||
echo (set_color yellow)"'$CURRENT_ENV': deactivating current environment"(set_color normal)
|
||||
__env_deactivate
|
||||
end
|
||||
|
||||
echo (set_color green)"'$env_name': activating environment"(set_color normal)
|
||||
source "$activate_file"
|
||||
end
|
||||
|
||||
function __env_deactivate -d "Deactivate the current environment"
|
||||
if test -z "$CURRENT_ENV"
|
||||
echo (set_color yellow)"no environment currently active"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
|
||||
echo (set_color blue)"'$CURRENT_ENV': deactivating environment"(set_color normal)
|
||||
|
||||
# Restore original prompt if it was saved
|
||||
if functions -q __env_orig_prompt
|
||||
# Remove current fish_prompt first, then restore the original
|
||||
functions -e fish_prompt
|
||||
functions -c __env_orig_prompt fish_prompt
|
||||
functions -e __env_orig_prompt
|
||||
end
|
||||
|
||||
# Clear environment-specific variables
|
||||
set -e CURRENT_ENV
|
||||
set -e __ENV_INITIALIZED
|
||||
|
||||
# Call custom deactivation function if it exists
|
||||
if functions -q __env_custom_deactivate
|
||||
__env_custom_deactivate
|
||||
functions -e __env_custom_deactivate
|
||||
end
|
||||
|
||||
echo (set_color green)"environment deactivated"(set_color normal)
|
||||
end
|
||||
|
||||
function __env_remove -d "Remove an environment"
|
||||
set -l env_name $argv[1]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env remove <name>"
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
|
||||
if not test -d "$env_dir"
|
||||
echo (set_color red)"'$env_name': environment not found"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
# Check if this environment is currently active
|
||||
if test "$CURRENT_ENV" = "$env_name"
|
||||
echo (set_color yellow)"deactivating environment before removal..."(set_color normal)
|
||||
__env_deactivate
|
||||
end
|
||||
|
||||
# Confirm removal
|
||||
echo (set_color yellow)"are you sure you want to remove environment '$env_name'? [y/N]"(set_color normal)
|
||||
read -l confirm
|
||||
|
||||
if test "$confirm" = y -o "$confirm" = Y
|
||||
rm -rf "$env_dir"
|
||||
echo (set_color green)"Environment '$env_name' removed"(set_color normal)
|
||||
else
|
||||
echo (set_color blue)"Removal cancelled"(set_color normal)
|
||||
end
|
||||
end
|
||||
|
||||
function __env_link -d "Link current directory to an environment"
|
||||
set -l env_name $argv[1]
|
||||
set -l target_dir $argv[2]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env link <env_name> [target_directory]"
|
||||
return 1
|
||||
end
|
||||
|
||||
if test -z "$target_dir"
|
||||
set target_dir (pwd)
|
||||
end
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
set -l activate_file "$env_dir/activate.fish"
|
||||
|
||||
if not test -f "$activate_file"
|
||||
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l target_activate "$target_dir/activate.fish"
|
||||
|
||||
if test -f "$target_activate"
|
||||
echo (set_color yellow)"Warning: activate.fish already exists in $target_dir"(set_color normal)
|
||||
echo "Overwrite? [y/N]"
|
||||
read -l confirm
|
||||
if test "$confirm" != y -a "$confirm" != Y
|
||||
echo (set_color blue)"Link cancelled"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
ln -sf "$activate_file" "$target_activate"
|
||||
echo (set_color green)"Linked environment '$env_name' to $target_dir"(set_color normal)
|
||||
echo "The environment will be activated automatically when you cd into this directory"
|
||||
end
|
||||
|
||||
function __env_info -d "Show environment information"
|
||||
set -l env_name $argv[1]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env info <name>"
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
set -l config_file "$env_dir/config.toml"
|
||||
|
||||
if not test -f "$config_file"
|
||||
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
echo (set_color blue)"Environment: $env_name"(set_color normal)
|
||||
echo "Config file: $config_file"
|
||||
echo
|
||||
cat "$config_file"
|
||||
end
|
||||
|
||||
function __env_edit -d "Edit environment configuration"
|
||||
set -l env_name $argv[1]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env edit <name>"
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
set -l activate_file "$env_dir/activate.fish"
|
||||
|
||||
if not test -f "$activate_file"
|
||||
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
$EDITOR "$activate_file"
|
||||
end
|
||||
|
||||
function __env_copy -d "Copy an environment"
|
||||
set -l src_name $argv[1]
|
||||
set -l dest_name $argv[2]
|
||||
|
||||
if test -z "$src_name" -o -z "$dest_name"
|
||||
echo (set_color red)"Error: Source and destination names required"(set_color normal)
|
||||
echo "usage: env copy <source> <destination>"
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l src_dir "$__ENV_CONFIGS_DIR/$src_name"
|
||||
set -l dest_dir "$__ENV_CONFIGS_DIR/$dest_name"
|
||||
|
||||
if not test -d "$src_dir"
|
||||
echo (set_color red)"Error: Source environment '$src_name' not found"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
if test -d "$dest_dir"
|
||||
echo (set_color yellow)"Warning: Destination environment '$dest_name' already exists"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
# Copy the entire environment directory
|
||||
cp -r "$src_dir" "$dest_dir"
|
||||
|
||||
# Update the activate.fish file to use the new name
|
||||
sed -i "s/$src_name/$dest_name/g" "$dest_dir/activate.fish"
|
||||
|
||||
# Update the config file
|
||||
sed -i "s/name = \"$src_name\"/name = \"$dest_name\"/" "$dest_dir/config.toml"
|
||||
sed -i "s/# Environment: $src_name/# Environment: $dest_name/" "$dest_dir/config.toml"
|
||||
echo "copied_from = \"$src_name\"" >>"$dest_dir/config.toml"
|
||||
echo "copied_date = \"$(date --iso-8601)\"" >>"$dest_dir/config.toml"
|
||||
|
||||
echo (set_color green)"Copied environment '$src_name' to '$dest_name'"(set_color normal)
|
||||
end
|
||||
|
||||
function __env_export -d "Export environment to a self-contained directory"
|
||||
set -l env_name $argv[1]
|
||||
set -l target_dir $argv[2]
|
||||
|
||||
if test -z "$env_name"
|
||||
echo (set_color red)"environment name required"(set_color normal)
|
||||
echo "usage: env export <name> [target_directory]"
|
||||
return 1
|
||||
end
|
||||
|
||||
if test -z "$target_dir"
|
||||
set target_dir (pwd)
|
||||
end
|
||||
|
||||
# Convert relative path to absolute path
|
||||
set target_dir (realpath "$target_dir")
|
||||
|
||||
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
||||
set -l activate_source "$env_dir/activate.fish"
|
||||
|
||||
if not test -f "$activate_source"
|
||||
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
if not test -d "$target_dir"
|
||||
echo (set_color red)"Error: Target directory '$target_dir' does not exist"(set_color normal)
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l fish_dir "$target_dir/.fish"
|
||||
set -l target_activate "$fish_dir/activate.fish"
|
||||
set -l target_readme "$fish_dir/README.md"
|
||||
|
||||
# Create .fish directory
|
||||
if not test -d "$fish_dir"
|
||||
mkdir -p "$fish_dir"
|
||||
end
|
||||
|
||||
if test -f "$target_activate"
|
||||
echo (set_color yellow)"Warning: .fish/activate.fish already exists in $target_dir"(set_color normal)
|
||||
echo "Overwrite? [y/N]"
|
||||
read -l confirm
|
||||
if test "$confirm" != y -a "$confirm" != Y
|
||||
echo (set_color blue)"Export cancelled"(set_color normal)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
# Create a self-contained activate.fish in .fish directory
|
||||
echo "# Self-contained environment: $env_name" >"$target_activate"
|
||||
echo "# Exported on: $(date)" >>"$target_activate"
|
||||
echo "# Original environment from: $env_dir" >>"$target_activate"
|
||||
echo "" >>"$target_activate"
|
||||
|
||||
# Copy the original activate.fish content but make it self-contained
|
||||
cat "$activate_source" | sed 's/{{ENV_NAME}}/'"$env_name"'/g' >>"$target_activate"
|
||||
|
||||
# Make it executable
|
||||
chmod +x "$target_activate"
|
||||
|
||||
# Create a README from template
|
||||
set -l readme_template "$__ENV_TEMPLATES_DIR/README.md"
|
||||
if test -f "$readme_template"
|
||||
sed "s/{{ENV_NAME}}/$env_name/g" "$readme_template" >"$target_readme"
|
||||
else
|
||||
echo "# Exported Fish Environment: $env_name" >"$target_readme"
|
||||
echo "" >>"$target_readme"
|
||||
echo "README template not found. Please create $readme_template for custom documentation." >>"$target_readme"
|
||||
end
|
||||
|
||||
echo (set_color green)"Environment '$env_name' exported to: $target_dir"(set_color normal)
|
||||
echo (set_color blue)"Files created:"(set_color normal)
|
||||
echo " - $target_activate (main environment)"
|
||||
echo " - $target_readme (documentation)"
|
||||
echo
|
||||
echo (set_color cyan)"To use this environment:"(set_color normal)
|
||||
echo " cd $target_dir"
|
||||
echo " source ./.fish/activate.fish"
|
||||
end
|
||||
|
||||
function __env_list_templates -d "List available templates with descriptions"
|
||||
set -l template_dir "$__ENV_TEMPLATES_DIR"
|
||||
|
||||
if not test -d "$template_dir"
|
||||
echo " (no templates found)"
|
||||
return 0
|
||||
end
|
||||
|
||||
for template_file in "$template_dir"/*.fish
|
||||
if test -f "$template_file"
|
||||
set template_name (basename "$template_file" .fish)
|
||||
|
||||
# Extract description from first comment line (skip shebang if present)
|
||||
set description "No description"
|
||||
set first_comment_line (head -n 5 "$template_file" | grep -E "^#[^!]" | head -n 1 | sed 's/^# *//')
|
||||
|
||||
if test -n "$first_comment_line"
|
||||
set description "$first_comment_line"
|
||||
end
|
||||
|
||||
# Format with proper alignment
|
||||
printf " %-12s %s\n" "$template_name" "$description"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user