Add autoenv, automatic environment setup
Using a hook, automatically detect when `.enter` and `.exit` scripts and source them when changing the shells current directory.
This commit is contained in:
		
							parent
							
								
									d58e543c78
								
							
						
					
					
						commit
						19e4a2b3c8
					
				
							
								
								
									
										104
									
								
								autoenv/autoenv.plugin.zsh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								autoenv/autoenv.plugin.zsh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
			
		||||
# Automatically update the environment when the current working directory
 | 
			
		||||
# changes, this is a reimplementation of the ideas found in the repository
 | 
			
		||||
# https://github.com/Tarrasch/zsh-autoenv stripped down to suit my specific
 | 
			
		||||
# needs.
 | 
			
		||||
 | 
			
		||||
# Global entered directories array.
 | 
			
		||||
_autoenv_entered=()
 | 
			
		||||
 | 
			
		||||
# Check if the given file is authorized, if not prompt the user to authorize,
 | 
			
		||||
# ignore, or view the file. Authorized files and their modified times are
 | 
			
		||||
# stored in the ~/.cache/autoenv/authorized file to make authorization
 | 
			
		||||
# persistant.
 | 
			
		||||
_autoenv_authorized() {
 | 
			
		||||
  local file=$1
 | 
			
		||||
  # If autoenv cache directory does not exist, create it.
 | 
			
		||||
  local cache_dir=~/.config/autoenv
 | 
			
		||||
  ! [ -d $cache_dir ] && mkdir -p $cache_dir
 | 
			
		||||
  local authorized_file=$cache_dir/authorized
 | 
			
		||||
  # Define the associative array to hold authorized key value pairs.
 | 
			
		||||
  # If the authorized file exists, load it into an associative array.
 | 
			
		||||
  typeset -A authorized=()
 | 
			
		||||
  [ -f $authorized_file ] && typeset -A authorized=(`cat $authorized_file`)
 | 
			
		||||
  # If the given file has been authorized, return.
 | 
			
		||||
  local modified_time=`zstat +mtime $file`
 | 
			
		||||
  [ "$authorized[$file]" = "$modified_time" ] && return
 | 
			
		||||
  # Prompt to authorize file.
 | 
			
		||||
  while true; do
 | 
			
		||||
    read "answer?Authorize $file [Y/n/v]? "
 | 
			
		||||
    case "$answer" in
 | 
			
		||||
      y|Y|yes|'')             # Authorize the file.
 | 
			
		||||
        authorized[$file]=$modified_time; break ;;
 | 
			
		||||
      n|N|no) return 1 ;;     # Do not authorize the file.
 | 
			
		||||
      v|V|view) cat $file ;;  # View the file.
 | 
			
		||||
    esac
 | 
			
		||||
  done
 | 
			
		||||
  # Store authorized associative array in authorized file.
 | 
			
		||||
  echo ${(kv)authorized} > $authorized_file
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Source an enter script and add its directory to the global entered
 | 
			
		||||
# directories array.
 | 
			
		||||
_autoenv_enter() {
 | 
			
		||||
  local entered=$1
 | 
			
		||||
  # If entered exists in the entered directories array, return.
 | 
			
		||||
  (( ${+_autoenv_entered[${_autoenv_entered[(i)$entered]}]} )) && return
 | 
			
		||||
  # If the enter script is not authorized, return.
 | 
			
		||||
  _autoenv_authorized $entered/.enter || return
 | 
			
		||||
  # Source the enter script.
 | 
			
		||||
  source $entered/.enter
 | 
			
		||||
  # Add the entered directory to the global entered array.
 | 
			
		||||
  _autoenv_entered+=$entered
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Source an exit script and remove its directory from the global entered
 | 
			
		||||
# directories array.
 | 
			
		||||
_autoenv_exit() {
 | 
			
		||||
  local entered=$1
 | 
			
		||||
  # If the exit script is not authorized, return.
 | 
			
		||||
  _autoenv_authorized $entered/.exit || return
 | 
			
		||||
  # Source the exit script.
 | 
			
		||||
  source $entered/.exit
 | 
			
		||||
  # Remove the entered directory from the global entered array.
 | 
			
		||||
  _autoenv_entered[${_autoenv_entered[(i)$entered]}]=()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Find a directory containing a .enter file by searching up the directory tree
 | 
			
		||||
# starting in the current directory.
 | 
			
		||||
_autoenv_find_enter() {
 | 
			
		||||
  local current=$PWD
 | 
			
		||||
  # If an enter script is found in the current directory, return it.
 | 
			
		||||
  [ -f "$current/.enter" ] && echo $current
 | 
			
		||||
  # Loop until an enter script or the root directory is found.
 | 
			
		||||
  while true; do
 | 
			
		||||
    # Go up one directory and make the path absolute.
 | 
			
		||||
    local next=$current/..; local next=${next:A}
 | 
			
		||||
    # If the current directory equals the next directory, return.
 | 
			
		||||
    [[ $current == $next ]] && return || local current=$next
 | 
			
		||||
    # If an enter script is found in the current directory, return it.
 | 
			
		||||
    [ -f $current/.enter ] && echo $current
 | 
			
		||||
  done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# A chpwd hook function which automatically sources enter and exit scripts to
 | 
			
		||||
# setup local environments for directory and its subdirectories.
 | 
			
		||||
_autoenv_chpwd() {
 | 
			
		||||
  local entered
 | 
			
		||||
  # Loop over the entered directory stack.
 | 
			
		||||
  for entered in $_autoenv_entered; do
 | 
			
		||||
    # If the the current directory was previously entered then exit.
 | 
			
		||||
    # TODO: Verify what this condition expression actually does.
 | 
			
		||||
    ! [[ $PWD/ == $entered/* ]] && _autoenv_exit $entered
 | 
			
		||||
  done
 | 
			
		||||
  # Find the nearest enter script directory.
 | 
			
		||||
  local enter=`_autoenv_find_enter`
 | 
			
		||||
  # If the enter directory exists, enter it.
 | 
			
		||||
  [ -d "$enter" ] && _autoenv_enter $enter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Register the autoenv chpwd hook.
 | 
			
		||||
autoload -U add-zsh-hook
 | 
			
		||||
add-zsh-hook chpwd _autoenv_chpwd
 | 
			
		||||
 | 
			
		||||
# Ensure autoenv is activated in the current directory on first load.
 | 
			
		||||
_autoenv_chpwd
 | 
			
		||||
							
								
								
									
										1
									
								
								zshrc
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								zshrc
									
									
									
									
									
								
							@ -12,6 +12,7 @@ source-plugin() {
 | 
			
		||||
source-plugin zsh-autosuggestions
 | 
			
		||||
source-plugin zsh-history-substring-search
 | 
			
		||||
source-plugin zsh-syntax-highlighting
 | 
			
		||||
source-plugin autoenv
 | 
			
		||||
 | 
			
		||||
# Disable non end-of-line autosuggest accept widgets
 | 
			
		||||
ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user