#!/bin/bash XL_PRODUCT="Vim Note System" XL_VER="v2b" # Environment Constants readonly VNS_STORE="$HOME/.local/vns" readonly VNS_KEYFILE="$VNS_STORE/.pubkey" readonly IFS=$'\n\t' set -euo pipefail readonly VNS_RED_COLOR='\033[1;31m' readonly VNS_YELLOW_COLOR='\033[1;33m' readonly VNS_RESET_COLOR='\033[0m' # Erroneous Exit Constants # Invocation Errors readonly VNS_ERR_NO_STORE=5 # The vns store needs to be initialized readonly VNS_ERR_NO_OPTS=10 # No mode argument was specified readonly VNS_ERR_NS_ARGS=11 # The specified mode requires an argument readonly VNS_ERR_NO_EDTR=15 # No editor specified in environment # Dependency Errors readonly VNS_ERR_DEPS=20 # Base error - add the following codes readonly VNS_ERR_NO_gpg2=1 # GPG is not installed readonly VNS_ERR_NO_tree=2 # Tree is not installed readonly VNS_ERR_NO_git=3 # Git is not installed # Global Variables typeset -i VNS_SID="$RANDOM" typeset -a VNS_ACTION=("") typeset -a MISSING_DEPS typeset -i VNS_EXIT=0 declare VNS_PUBKEY= # Function Definitions # vns_printError Prints an error message # vns_NoteHeader Prints standard note header to stdout # vns_checkDeps Checks the system for required dependencies # vns_checkStore Checks if $VNS_STORE exists # vns_sanityCheck Wrapper for vns_checkDeps and vns_checkStore # ---- # vns_initStore Initializes the VNS Store ( -i) # vns_printHelp Prints help page ( -h) # vns_list Lists all notes in `tree` format ( *) # vns_create Creates note; calls vns_edit() ( -c) # vns_edit Decrypts note to /tmp, calls editor, re-encrypts note ( -e) # vns_print Prints note to stdout ( -p) # vns_rm Deletes note from store ( -d) # vns_gitPassthrough Passes through all instructions to git (git) function vns_printError(){ printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\n" "$@" } function vns_NoteHeader(){ printf "%s\n%s\n" "Title:" "Date:" } function vns_checkDeps(){ local VNS_RETURN="true"; for DEP in "${VNS_DEPS[@]}"; do if test ! -e "$(which "$DEP" 2>/dev/null)"; then MISSING_DEPS+=("$DEP") VNS_RETURN="false"; fi done "$VNS_RETURN"; } function vns_checkStore(){ if [ -d "$VNS_STORE" ]; then true; else false; fi } function vns_sanityCheck { set +u if [ "$VNS_EDITOR" != "vim" ] && [ -z "$EDITOR" ]; then echo "$VNS_EDITOR" vns_printError "No editor specified in environment." VNS_EXIT="$VNS_ERR_NO_EDTR" return fi set -u if ! vns_checkDeps; then VNS_EXIT="$VNS_ERR_DEPS" for DEP in "${MISSING_DEPS[@]}"; do local VNS_DEP_EC="\$ERR_NO_$DEP" vns_printError "Dependency %s not in path." "$DEP"; VNS_EXIT+=${!VNS_DEP_EC} done fi if [ -r "$VNS_STORE/.pubkey" ]; then VNS_PUBKEY="$(cat "$VNS_STORE/.pubkey")" elif ! vns_checkStore; then if [ "$(echo "${VNS_ACTION[@]}" | awk '{print $1;}')" != "vns_initStore" ]; then vns_printError "The vns store does not exist." printf " - %s\n" "Please run \`vns -i [gpg-key]\` to initialize vns." VNS_EXIT="$VNS_ERR_NO_STORE" fi fi } #---- function vns_initStore { mkdir -p "$VNS_STORE" echo "$@" | awk '{print $1}' > "$VNS_KEYFILE" } function vns_printHelp(){ printf "%s" "usage: vns [-cedlp] " printf "\n%s%s%s" "usage: vns " "git" " ..." printf "\n%s" " vns [-hi]" printf "\n%s" " -c | --create : Create note" printf "\n%s" " -C | --config : Edit Config" printf "\n%s" " -d | --delete : Delete note" printf "\n%s" " -e | --edit : Open note for editing" printf "\n%s" " -h | --help : Display this message" printf "\n%s" " -i | --init : Write default config and initalize VNS store" printf "\n%s" " -l | --list : List all notes in NOTEBOOK" printf "\n%s" " -p | --print : Print note to console" printf "\n\n" } function vns_list(){ # Change directories to fix tree header cd "$VNS_STORE" || exit; cd .. || exit; # Print the tree tree -C --noreport --prune "$(echo "$@" | awk '{print $1}')" } function vns_rm(){ local readonly VNS_NOTE="$VNS_STORE/$(echo "$@" | awk '{print $1}').gpg" echo "Deleting $VNS_NOTE" rm -f "$VNS_NOTE" } function vns_gitPassthrough(){ cd "$VNS_STORE" || exit; git "$@"; } # ---- function vns_argParse(){ ARGS=($@) #echo "${#ARGS}" VNS_ACTION=() while getopts ":i:hc:e:p:d:" OPT; do # If an option requiring an argument was passed without an argument, # inform the user and set exit code to "$VNS_ERR_NS_ARGS" case "${ARGS[!OPTIND]}" in -i|-c|-e|-p|-d) if [ "${#ARGS}" -lt 2 ]; then vns_printError "A required argument was not given." VNS_EXIT="$VNS_ERR_NS_ARGS" return fi esac case "$OPT" in i) VNS_ACTION=("vns_initStore" "$OPTARG");; h) VNS_ACTION=("vns_printHelp");; c) VNS_ACTION=("vns_create $OPTARG");; e) VNS_ACTION=("vns_edit $OPTARG");; p) VNS_ACTION=("vns_print $OPTARG");; d) VNS_ACTION=("vns_rm $OPTARG");; esac done if [ "${#VNS_ACTION[@]}" -eq 0 ]; then if [ "$(echo "$@" | awk '{print $1}')" == "git" ]; then VNS_ACTION=($@) else if [ -d "$VNS_STORE/$*" ]; then VNS_ACTION=("vns_list" "vns/$@") else VNS_ACTION=("vns_list" "vns") fi fi fi } # Entry Point printf "%s\n%s\n" "$XL_PRODUCT" "$XL_VER" printf "\n" readonly VNS_EDITOR="vim" readonly VNS_DEPS=("vim" "gpg2" "tree" "git") function vns_create(){ VNS_NOTE="$VNS_STORE/$(echo "$@" | awk '{print $1}').gpg" # Make sure the note doesn't already exist if [ -r "$VNS_NOTE" ]; then vns_printError "Note already exists." else if [ ! -d "$(dirname $VNS_NOTE)" ]; then mkdir -p "$(dirname $VNS_NOTE)" fi vns_NoteHeader | gpg2 -e -r "$VNS_PUBKEY" -o "$VNS_NOTE" vns_edit "$@" fi } function vns_edit(){ # Make the function more readable local readonly VNS_NOTE="$VNS_STORE/$(echo "$@" | awk '{print $1}').gpg" # Edit the note vim "$VNS_NOTE" } function vns_print(){ gpg2 -d "$VNS_STORE/$(echo "$@" | awk '{print $1}')" } vns_argParse "$@" vns_sanityCheck if [ "$VNS_EXIT" -eq 0 ]; then eval "${VNS_ACTION[@]}" fi printf "\n" exit "$VNS_EXIT"