Add autoenv, automatic environment setup
Using a hook, automatically detect when `.enter` and `.exit` scripts and source them when changing the shells current directory. Fixes #3.
This commit is contained in:
		
							parent
							
								
									d58e543c78
								
							
						
					
					
						commit
						9f7367c550
					
				
							
								
								
									
										108
									
								
								autoenv/autoenv.plugin.zsh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								autoenv/autoenv.plugin.zsh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| # 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 bare essentials. | ||||
| # | ||||
| # The secret sauce can be found at the bottom of this file, where the `chpwd` | ||||
| # hook function `_autoenv_chpwd` is added. | ||||
| 
 | ||||
| # 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 | ||||
| # persistent. | ||||
| _autoenv_authorized() { | ||||
|   local file=$1 | ||||
|   # If autoenv cache directory does not exist, create it. | ||||
|   local cache_dir=~/.cache/autoenv | ||||
|   ! [ -d $cache_dir ] && mkdir -p $cache_dir | ||||
|   local authorized_file=$cache_dir/authorized | ||||
|   # Define a map to hold authorized key value pairs. | ||||
|   typeset -A authorized=() | ||||
|   # If the authorized file exists, load it into the map. | ||||
|   [ -f $authorized_file ] && typeset -A authorized=(`cat $authorized_file`) | ||||
|   # If the given file has been authorized, i.e. the modified time matches that | ||||
|   # held in the authorized file, 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 all directories containing a .enter file by searching up the directory | ||||
| # tree starting in the current directory. | ||||
| _autoenv_find_enter_directories() { | ||||
|   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 an enter script is found in the current directory, return it. | ||||
|     [ -f $next/.enter ] && echo $next | ||||
|     # If the current directory equals the next directory we are done, otherwise | ||||
|     # update the current directory. | ||||
|     [[ $current == $next ]] && return || local current=$next | ||||
|   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 reversed entered directory array. | ||||
|   for entered in ${(aO)_autoenv_entered}; do | ||||
|     # If the the current directory was previously entered then exit. | ||||
|     ! [[ $PWD/ == $entered/* ]] && _autoenv_exit $entered | ||||
|   done | ||||
|   # Find all enter script directories, store them in an array. | ||||
|   local enter_dirs=(`_autoenv_find_enter_directories`) | ||||
|   # Loop over reversed enter script directories array, so enter scripts found | ||||
|   # last are sourced first, then source all enter scripts. | ||||
|   for enter in ${(aO)enter_dirs}; do _autoenv_enter $enter; done | ||||
| } | ||||
| 
 | ||||
| # 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