Skip to content

Instantly share code, notes, and snippets.

@neilk
Last active April 11, 2017 03:47
Show Gist options
  • Save neilk/2646d482b77729728e56f79e18f05da9 to your computer and use it in GitHub Desktop.
Save neilk/2646d482b77729728e56f79e18f05da9 to your computer and use it in GitHub Desktop.
Multiple bash hooks upon changing directories (set env var, switch node version, switch history file)
shopt -s histappend
PROMPT_COMMAND="history -a;history -c;history -r;$PROMPT_COMMAND"
SHARED_HISTORY_DIR="$HOME/.sharedhistory"
mkdir -p $SHARED_HISTORY_DIR
function __sharedhistory_chpwd() {
if [[ -n $PROJECT ]]; then
local pwd_escaped=$(echo $PWD | sed 's/[\/ ]/~/g')
HISTFILE="$SHARED_HISTORY_DIR/$PROJECT"
else
HISTFILE="$HOME/.bash_history"
fi
if [[ ! -f $HISTFILE ]]; then
touch $HISTFILE;
fi
chmod 660 $HISTFILE;
export HISTFILE
}
#timestamp all history entries
export HISTTIMEFORMAT="%h/%d - %H:%M:%S "
export HISTCONTROL=ignoredups:erasedups
export HISTSIZE=1000000
export HISTFILESIZE=1000000
shopt -s histappend ## append, no clearouts
shopt -s histverify ## edit a recalled history line before executing
shopt -s histreedit ## reedit a history substitution line if it failed
# first time
__sharedhistory_chpwd
# add shared history functionality
[[ " ${chpwd_functions[*]} " == *" __sharedhistory_chpwd "* ]] ||
chpwd_functions+=(__sharedhistory_chpwd)
export chpwd_functions;
##
# Functionality specific to avn
#
# This is slightly modified from the script in https://github.com/wbyoung/avn ;
# Specifically I stole the idea of hooks and made it general
if [[ -n "${BASH_VERSION:-}" ]]; then
true
elif [[ -n "${ZSH_VERSION:-}" ]]; then
setopt null_glob
else
printf "%b" "avn does not yet support this shell\n"
fi
export PATH="$HOME/.avn/bin:$PATH"
# plugins may add to this, it's an array of version file names
export -a __avn_files
__avn_files=(".node-version")
# the full path to the active version file, /path/to/.node-version
export __avn_active_file
# load each plugin
for plugin in $HOME/.avn/plugins/*
do
[[ -f "$plugin/load.sh" ]] && . "$plugin/load.sh"
done
# run _avn & eval results written to fd 3
function __avn_eval() {
typeset cmd actions actions_result options
cmd=$1
shift
[[ -t 1 ]] && options="--color"
actions=$(_avn ${cmd} $options "$@" 3>&1 1>&2)
actions_result=$?
if [[ $actions_result -eq 0 ]]
then
eval "$actions"
fi
}
# avn chpwd hook
function __avn_chpwd() {
local file=$(__avn_find_file)
local dir=${file%/*}
local name=${file##*/}
[[ -n "$file" ]] && [[ "$file" != "$__avn_active_file" ]] &&
__avn_eval chpwd "$dir" "$name" || true
__avn_active_file=$file
true
}
# debug that includes file lookup
function __avn_debug() {
local file=$(__avn_find_file)
local dir=${file%/*}
local name=${file##*/}
_avn explain -v "$dir" "$name"
}
# find version specification file
function __avn_find_file() {
local found
local dir=$PWD
while [[ -z "$found" ]] && [[ "$dir" != "" ]]; do
for file in "${__avn_files[@]}"; do
if [[ -f "$dir/$file" ]]; then
found="$dir/$file"
break
fi
done
if [[ "$dir" == "$HOME" ]]; then
break
fi
dir=${dir%/*}
done
echo $found
}
__avn_chpwd # run chpwd once since the shell was just loaded
##
# Hooks that will happen after the working directory is changed
#
# add avn functionality
[[ " ${chpwd_functions[*]} " == *" __avn_chpwd "* ]] ||
chpwd_functions+=(__avn_chpwd)
export chpwd_functions;
# shortcut for projects directory
[ -e "$HOME/p" ] && export PROJECTS="$HOME/p"
function __projects_chpwd() {
PROJECT=""
if [[ $PWD =~ ^$PROJECTS ]]; then
if [[ $PWD =~ ^$PROJECTS/([^/]+) ]]; then
PROJECT="${BASH_REMATCH[1]}"
fi
fi
export PROJECT
}
# add projects detection functionality
[[ " ${chpwd_functions[*]} " == *" __projects_chpwd "* ]] ||
chpwd_functions+=(__projects_chpwd)
__projects_chpwd
# switch node versions upon entering dir with .nvmrc. uses chpwd_functions.
[[ -s "$HOME/avn.sh" ]] && source "$HOME/avn.sh"
# switch history file upon entering a new $PROJECTS/* folder. uses chpwd_functions
[[ -s "$HOME/.sharedhistory.sh" ]] && source "$HOME/.sharedhistory.sh"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment