# --[ Functions # Usage: expand_path [] # # Outputs the absolute path of relative to or the # current directory. # # Example: # # cd /usr/local/games # expand_path ../foo # # output: /usr/local/foo # expand_path() { local REPLY; realpath.absolute "${2+"$2"}" "${1+"$1"}"; echo "$REPLY" } # --- vendored from https://github.com/bashup/realpaths realpath.dirname() { REPLY=.; ! [[ $1 =~ /+[^/]+/*$|^//$ ]] || REPLY="${1%${BASH_REMATCH[0]}}"; REPLY=${REPLY:-/}; } realpath.basename(){ REPLY=/; ! [[ $1 =~ /*([^/]+)/*$ ]] || REPLY="${BASH_REMATCH[1]}"; } realpath.absolute() { REPLY=$PWD; local eg=extglob; ! shopt -q $eg || eg=; ${eg:+shopt -s $eg} while (($#)); do case $1 in //|//[^/]*) REPLY=//; set -- "${1:2}" "${@:2}" ;; /*) REPLY=/; set -- "${1##+(/)}" "${@:2}" ;; */*) set -- "${1%%/*}" "${1##${1%%/*}+(/)}" "${@:2}" ;; ''|.) shift ;; ..) realpath.dirname "$REPLY"; shift ;; *) REPLY="${REPLY%/}/$1"; shift ;; esac; done; ${eg:+shopt -u $eg} } # Usage: has # # Returns 0 if the is available. Returns 1 otherwise. It can be a # binary in the PATH or a shell function. # # Example: # # if has curl; then # echo "Yes we do" # fi # has() { type -tP "$1" &> /dev/null } # --- # Inspired by "stdlib.sh" from "direnv" # Usage: path_add [ ...] # # Prepends the expanded to the environment variable, in order. # It prevents a common mistake where is replaced by only the new , # or where a trailing colon is left in , resulting in the current directory # being considered in the . Supports adding multiple directories at once. # The added directories must also exists, what's more, this function makes sure # the includes only once all the entries. # # Example: # # pwd # # output: /my/project # path_add PATH bin # echo $PATH # # output: /my/project/bin:/usr/bin:/bin # path_add PATH bam boum # echo $PATH # # output: /my/project/bam:/my/project/boum:/my/project/bin:/usr/bin:/bin path_add() { local path i var_name="$1" # split existing paths into an array declare -a path_array IFS=: read -ra path_array <<<"${!1-}" shift # prepend the passed paths in the right order for ((i = $#; i > 0; i--)); do full_path="$(expand_path "${!i}")" # Make sure the directories exist [ ! -d "${full_path}" ] && continue path_array=("$(expand_path "${full_path}")" ${path_array[@]+"${path_array[@]}"}) done # Remove duplicates entrie # ref: https://stackoverflow.com/questions/13648410/how-can-i-get-unique-values-from-an-array-in-bash readarray -t UniqArray < <(printf '%s\n' "${path_array[@]}" | awk '!x[$0]++') # join back all the paths path=$( IFS=: echo "${UniqArray[*]}" ) # and finally export back the result to the original variable export "$var_name=$path" } # Usage: path_rm [ ...] # # Removes directories that match any of the given shell patterns from # the environment variable. Order of the remaining directories is # preserved in the resulting . # # Bash pattern syntax: # https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html # # Example: # # echo $PATH # # output: /dontremove/me:/remove/me:/usr/local/bin/:... # path_rm PATH '/remove/*' # echo $PATH # # output: /dontremove/me:/usr/local/bin/:... path_rm() { local path i discard var_name="$1" # split existing paths into an array declare -a path_array IFS=: read -ra path_array <<<"${!1}" shift patterns=("$@") results=() # iterate over path entries, discard entries that match any of the patterns # shellcheck disable=SC2068 for path in ${path_array[@]+"${path_array[@]}"}; do discard=false # shellcheck disable=SC2068 for pattern in ${patterns[@]+"${patterns[@]}"}; do if [[ "$path" == +($pattern) ]]; then discard=true break fi done if ! $discard; then results+=("$path") fi done # join the result paths result=$( IFS=: echo "${results[*]}" ) # and finally export back the result to the original variable export "$var_name=$result" } # --[ Color VARIABLES B="" S="" I="" E="" N="" black='' BLACK='' red='' RED='' green='' GREEN='' yellow='' YELLOW='' blue='' BLUE='' magenta='' MAGENTA='' cyan='' CYAN='' white='' WHITE='' FORM1="" EFORM1="" FORM2="" EFORM2="" FORM3="" EFORM3="" FORM4="" EFORM4=""