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
						173337d9a2
					
				
							
								
								
									
										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-autosuggestions
 | 
				
			||||||
source-plugin zsh-history-substring-search
 | 
					source-plugin zsh-history-substring-search
 | 
				
			||||||
source-plugin zsh-syntax-highlighting
 | 
					source-plugin zsh-syntax-highlighting
 | 
				
			||||||
 | 
					source-plugin autoenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Disable non end-of-line autosuggest accept widgets
 | 
					# Disable non end-of-line autosuggest accept widgets
 | 
				
			||||||
ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line)
 | 
					ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user