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