diff --git a/bin/fsw b/bin/fsw index 71d177a..3103046 100755 --- a/bin/fsw +++ b/bin/fsw @@ -1,11 +1,68 @@ #!/usr/bin/env bash -# Some examples in case you forget: -# Elixir: fsw "mix run" ./**/*.{ex,exs} -# Run bash file on any event (note single quotes): fsw 'bash ${__FSW_FILENAME}' ./**/*.bash +_VERSION="0.2.0" -SHELL_COMMAND="${1}" -shift -inotifywait -q -m -e close_write -r "${@}" | while read -r __FSW_FILENAME __FSW_EVENT; do - eval "${SHELL_COMMAND}" +function help() { + I=" " + cat < [filter] [dirs...] + +${I}command - the specified bash command to eval +${I}filter - an optional filename filter +${I}dirs - the directories to watch (defaults to current directory) + +Advanced: +${I}Command Variables: +${I}${I}Your commands have runtime access to some variables associated with the +${I}${I}${I}inotifywait event enabling further extensibility: +${I}${I}+ FSW_FILENAME - the name of the file +${I}${I}+ FSW_DIR - the directory containing the file +${I}${I}+ FSW_PATH - the full relative path of the file +${I}${I}+ FSW_FILE_EVENTS - a comma-separated list of the inotify events +${I}Environment: +${I}${I}Some customization options exist using environment variables +${I}${I}${I}due to their uncommon usage. +${I}${I}+ FSW_EVENTS - the list of events to have inotifywait observe + +References: +${I}+ Filter works with grep -P +${I}+ See inotifywait(1) for FSW_EVENTS options. + +Examples: +${I}fsw 'make' '\.c$' +${I}fsw 'bash \$filename' '\.bash$' +${I}fsw 'mix test --failed' '.exs?$' lib test +${I}FSW_EVENTS=open,access fsw 'espeak "Intruder Alert!"' \\ +${I}${I}${I}'.*' /etc/secrets \$HOME/.secrets +USAGE +} + +if [[ $1 = '-h' ]] || [[ $1 = '--help' ]] || [[ -z $1 ]]; then + help + exit 0 +fi + +FSW_EVENTS="${FSW_EVENTS:-close_write}" +SHELL_COMMAND="${1}"; shift +FILTER="${1}"; shift +DIRS=("${1:-.}"); shift +while [[ ! -z $1 ]]; do + DIRS+=("$1"); shift +done +inotifywait -m -e "${FSW_EVENTS}" -r "${DIRS[@]}" 2>&1 \ + | grep --line-buffered -v ' Beware: since -r was given, this may take a while!' \ + | while read -r dir events filename; do + if [[ "$dir $events" = "Watches established." ]]; then + echo "Ready." + else + export FSW_FILENAME="$filename" + export FSW_DIR="$dir" + export FSW_PATH="$dir$filename" + export FSW_FILE_EVENTS="$events" + <<< "$FSW_PATH" grep -P + eval "${SHELL_COMMAND}" + fi done diff --git a/shell/bash/prompt b/shell/bash/prompt index 6123afe..45bb9f5 100644 --- a/shell/bash/prompt +++ b/shell/bash/prompt @@ -1,43 +1,36 @@ #!/usr/bin/env bash COLOR_RESET='\[\e[0m\]' +# TODO: if root, background instead? PROMPT_SUCCESS_COLOR='\[\e[0;34m\]' PROMPT_FAILURE_COLOR='\[\e[0;31m\]' DIR_COLOR='\[\e[0;35m\]' +MAX_PATH_PIECE_CHARS=3 + # prompt rendering functions preprocess_pwd() { - name="$PWD" - # if we're in the home directory, replace it with tilde - # [[ "$name" =~ ^"$NICE_HOME"(/|$) ]] && name="~${name#$NICE_HOME}" - [[ "$name" == "${NICE_HOME}" ]] && name="~" - - # replace all non-basename parts of the PWD with only the first two letters - curdir=$(echo "$PWD" | sed -r 's|.*/(.+)$|\1|g') - name=$(echo "$name" | sed -r 's|/(...)[^/]*|/\1|g' | sed -r 's|(.*/)(.+)$|\1|g') - - # if we're just in the home or root directory, don't show any path stuff - [[ "$name" == "/" ]] && curdir="" - [[ "$name" == "~" ]] && curdir="" - - # return our transformed PWD - echo "$name$curdir" + p="$PWD" + [[ "$p" == "/" ]] && echo "/" && return 1 + [[ "$p" == "${NICE_HOME}" ]] && echo "~" && return 0 + # with ellipsis + # echo "$(<<< "$p" cut -c2- | awk '{split($0,p,"/");for(k in p){if(length(p[k])>'"$((MAX_PATH_PIECE_CHARS+1))"'){printf "/%.'"$((MAX_PATH_PIECE_CHARS))"'s…",p[k]}else{printf "/%s",p[k]}}}')" + # without ellipsis + echo "$(<<< "$p" cut -c2- | awk '{split($0,p,"/");for(k in p){printf "/%.'"$MAX_PATH_PIECE_CHARS"'s",p[k]}}')" } export -f "preprocess_pwd" prompt_command_func() { - # commit history to prevent data loss from edge cases - history -a RET=$? - # set the color of the user and host based on the result of the previous - # command - if [ $RET -eq 0 ]; then + history -a # commit history to prevent data loss from edge cases + # set the color of user@host based on the result of the previous command + if [[ $RET -eq 0 ]]; then STATUS_COLOR=$PROMPT_SUCCESS_COLOR else STATUS_COLOR=$PROMPT_FAILURE_COLOR - fi; - PS1="$STATUS_COLOR\u@\h$COLOR_RESET $DIR_COLOR$(eval "preprocess_pwd")$COLOR_RESET " + fi + PS1="$STATUS_COLOR\u@\h$COLOR_RESET $DIR_COLOR$(preprocess_pwd)$COLOR_RESET " } export -f "prompt_command_func" export PROMPT_COMMAND="prompt_command_func"