zsh/modules/loader.zsh

222 lines
5.1 KiB
Bash
Raw Normal View History

#################################################################################
# ZSH modular config
#################################################################################
#
# Helps you split up your config into modules and reuse modules from other
# people.
#
# Modules are stored in the "modules" folder in your configuration directory
# (default: /etc/zsh, if you want to use this in a user configuration file, set
# the variable $ZDOTDIR to your zsh configuration directory in ~/.zshenv)
#
# Each module should have a file called "init". This file is sourced, when the
# module is loaded and is responsible for sourcing any other files needed by the
# module.
#
# The module can use $MPATH variable, which contains the module's directory.
#################################
# INTERNAL MODULE LOADING STUFF #
#################################
# Path to module directory
2016-07-25 11:48:52 +00:00
if [[ -z $ZMODPATH ]]; then
ZMODPATH=( ${ZDOTDIR:+$ZDOTDIR/modules} )
[[ -d /etc/zsh/modules ]] && ZMODPATH+=/etc/zsh/modules
fi
local mod_path() {
for dir in $ZMODPATH; do
if [[ -e $dir/$1 ]]; then
echo "$dir/$1"
return 0
fi
done
return 1
}
. $(mod_path helpers.zsh)
errdetails=""
modqueue=( )
# Adds a module to the loading queue
#
# This function adds a module for later loading, if it is not already queued.
# It calls mod_deps for dependency checking. If dependencies are not satisfied,
# the module is not loaded.
#
# Parameters:
# 1: module name
# 2: if loaded as a dependency: is_dep
# otherwise empty
# 3: if loaded as a dependency: the depending module
#
mod_queue() {
local module="$1"
2016-07-25 11:48:52 +00:00
local modsource=$(mod_path $module)
if ! mod_exists "$module" ; then
if [[ "$2" == "is_dep" ]]; then
echo "$3: Unsatisfied dependency \"$module\"";
return 1
else
return 2
fi
fi
in_array "$module" "${(@)modqueue}" && return 0
if mod_deps "$modsource"; then
modqueue=( "${(@)modqueue}" "$module" )
else
case $? in
1) echo "module $module not loaded because of missing dependencies: $errdetails";;
2) echo "module $module not loaded because of blocking module: $errdetails";;
esac
fi
}
mod_exists() {
2016-07-25 11:48:52 +00:00
mod_path "$1" &> /dev/null
}
# Checks for module dependencies
#
# Reads the "depend" file for a module and tries to queue all dependencies for
# loading. If any fails, it returns 1;
#
# Parameters:
# 1: Path to module
#
mod_deps() {
modpath=$1
! [ -e $modpath/depend ] && return 0;
while read relation dep; do
mod_check_dep $modpath $relation $dep
2013-03-18 12:25:38 +00:00
[ $? -gt 0 ] && return $?;
done < "$modpath/depend"
return 0;
}
mod_check_dep() {
modpath=$1
relation=$2
dep=$3
#legacy entry compatibility
if [ -z "$dep" ]; then
dep="$relation"
relation="need"
fi
if in_array "$dep" "${(@)modqueue}" && [[ "$relation" != "block" ]]; then
return 0;
fi
case "$relation"; in
"need")
if ! mod_queue "$dep" is_dep ${modpath}; then
errdetails="$dep"
return 1;
fi
;;
"after")
2013-03-18 12:25:38 +00:00
if ([ -z "$ZMODLOAD_ONLY" ] \
2013-03-18 21:49:27 +00:00
|| in_array "$dep" "${(@)ZMODLOAD_ONLY}") \
&& ! in_array "$dep" "${(@)ZMODLOAD_BLACKLIST}"; then
mod_queue "$dep"
fi ;;
"block")
if in_array "$dep" "${(@)ZMODLOAD_ONLY}" \
|| in_array "$dep" "${(@)modqueue}"; then
errdetails="$dep"
return 2
fi;;
esac
}
# Loads all queued modules
#
# After queueing all modules and dependency modules, this function calls their
# init-scripts, if existent (if not, the module is ignored for now)
#
mod_load() {
local MPATH
for module in "${(@)modqueue}"; do
2016-07-25 11:48:52 +00:00
MPATH=$(mod_path $module)
[ -e "$(mod_path $module)/init" ] && . "$(mod_path $module)/init"
done
}
# Begins module loading procedure
#
# Queues all modules in the module directory or, if set, only modules listed in
# $ZMODLOAD_ONLY
mod_init() {
if [ -n "$ZMODLOAD_ONLY" ]; then
for module in "${(@)ZMODLOAD_ONLY}"; do
2016-07-25 11:48:52 +00:00
[ -d "$(mod_path $module)" ] && mod_queue "$module"
done
else
2016-07-25 11:48:52 +00:00
for moddir in $ZMODPATH; do
for module in $moddir/*(/N); do
if [ -z "$ZMODLOAD_BLACKLIST" ] \
|| ! in_array ${module:t} ${(@)ZMODLOAD_BLACKLIST}; then
mod_queue "${module:t}"
fi
done
done
fi
mod_load
}
# return 0 if all given modules were loaded (i.e. in the load queue)
mod_loaded() {
for i in "$@"; do
in_array $i ${(@)modqueue} || return 1
done
return 0
}
#################################################################################
# Utility functions for modules
#################################################################################
#
# Register hook functions
# see 'SPECIAL FUNCTIONS' section in zshmisc(1) for more information
#
precmd_hook() {
[[ -z $precmd_functions ]] && precmd_functions=()
precmd_functions=($precmd_functions $*)
}
chpwd_hook() {
[[ -z $chpwd_functions ]] && chpwd_functions=()
chpwd_functions=($chpwd_functions $*)
}
preexec_hook() {
[[ -z $preexec_functions ]] && preexec_functions=()
preexec_functions=($preexec_functions $*)
}
zshaddhistory_hook() {
[[ -z $zshaddhistory_functions ]] && zshaddhistory_functions=()
zshaddhistory_functions=($zshaddhistory_functions $*)
}
zshexit_hook() {
[[ -z $zshexit_functions ]] && zshexit_functions=()
zshexit_functions=($zshexit_functions $*)
}