Created
March 3, 2015 13:58
-
-
Save prurigro/ef9e3a9672d8b4598b73 to your computer and use it in GitHub Desktop.
Wrapper script for the Vim Notes plugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# VimNotes: Wrapper script for the Vim Notes plugin | |
# | |
# Version: 1.0 | |
# | |
# Written by Kevin MacMartin <[email protected]> | |
# Released under the MIT license | |
# | |
VIMNOTES_FOLDER=${VIMNOTES_FOLDER:="$HOME/Notes"} | |
NOTES_SUFFIX=${NOTES_SUFFIX:='txt'} | |
declare -a documents=() | |
max_docwidth=0 | |
key="$1" | |
# Colour Scheme | |
[[ -t 1 ]] && { | |
c_d=$'\e[1;30m' # DARK GREY | |
c_r=$'\e[1;31m' # RED | |
c_g=$'\e[1;32m' # GREEN | |
c_y=$'\e[1;33m' # YELLOW | |
c_b=$'\e[1;34m' # BLUE | |
c_m=$'\e[1;35m' # VIOLET | |
c_t=$'\e[1;36m' # TEAL | |
c_w=$'\e[1;37m' # WHITE | |
c_u=$'\e[1;4;37m' # UNDERLINE WHITE | |
c_h=$'\e[1;41m' # HIGHLIGHT RED | |
c_c=$'\e[0m' # DISABLES COLOUR | |
} | |
# open a doc | |
function open_note { | |
printf '%s %s\n' "${c_y}Opening:" "$c_m${documents[$1]}$c_c" | |
[[ -n "$tty_state" ]] \ | |
&& stty "$tty_state" | |
vim -c ":Note ${documents[$1]}" | |
exit 0 | |
} | |
function prompt { | |
printf '%s ' "${c_w}Please choose a number from the list $c_d[$c_b$one_display-$upto$c_d] $c_d(${c_m}Q$c_w to quit$c_d)$c_w:$c_c" | |
} | |
function power { | |
local number="$1" power="$2" total=1 | |
for (( x=0; x<"$power"; x++ )); do | |
total=$(( total * number )) | |
done | |
printf '%s\n' "$total" | |
} | |
# Display help text | |
function help { | |
script_name="${0//*\/}" | |
printf '\n%s\n\n' "${c_m}VimNotes${c_w} - Wrapper script for the Vim Notes plugin$c_c" | |
printf '%s\n' "${c_b}USAGE$c_c" | |
printf ' %s\n\n' "$c_y$script_name $c_d[${c_r}OPTION$c_d] ${c_g}PATTERN$c_c" | |
printf '%s\n' "${c_b}OPTIONS$c_c" | |
printf ' %-38s%s\n' "$c_w-c$c_d|$c_w--create$c_c" "create new note if one with the same name doesn't exist" | |
printf ' %-38s%s\n\n' "$c_w-h$c_d|$c_w--help$c_c" "show this help text" | |
exit 0 | |
} | |
# Function to process key codes | |
function getkeycode { | |
while read -r; do | |
[[ "$REPLY" =~ ^[0-9][0-9]*\ (.*)$ ]] && { | |
printf '%s\n' "${BASH_REMATCH[1]}" | |
break | |
} | |
done <<< "$1" | |
} | |
# Define Q, q, and Return respectively | |
alpha_Q=$(getkeycode "$(printf '%s' 'Q' | od -t o1)") | |
alpha_q=$(getkeycode "$(printf '%s' 'q' | od -t o1)") | |
key_cr=$(getkeycode "$(printf '\n' | od -t o1)") | |
[[ -d "$VIMNOTES_FOLDER" ]] \ | |
|| install -d "$VIMNOTES_FOLDER" | |
# Parse for command line arguments | |
case $1 in | |
-c|--create) | |
if [[ -n "$2" ]]; then | |
vim -c ":Note $2" | |
exit $? | |
else | |
printf '%s %s\n' "${c_r}ERROR:$c_c" 'No name given for the new note' >&2 | |
exit 1 | |
fi | |
;; | |
-h|--help) | |
help | |
;; | |
esac | |
# Build the list of notes and track the longest document name | |
if [[ -n "$key" ]]; then | |
for each in "$VIMNOTES_FOLDER"/*."$NOTES_SUFFIX"; do | |
[[ "$each" =~ $key ]] && { | |
each="${each/*\/}" | |
each="${each/\.$NOTES_SUFFIX}" | |
documents=( "${documents[@]}" "$each" ) | |
(( max_docwidth < ${#each} )) \ | |
&& max_docwidth=${#each} | |
} | |
done | |
else | |
for each in "$VIMNOTES_FOLDER"/*."$NOTES_SUFFIX"; do | |
each="${each/*\/}" | |
each="${each/\.$NOTES_SUFFIX}" | |
documents=( "${documents[@]}" "$each" ) | |
(( max_docwidth < ${#each} )) \ | |
&& max_docwidth=${#each} | |
done | |
fi | |
# Exit with an error if the list of notes is empty | |
(( ${#documents[*]} )) || { | |
printf '%s\n' "Can't find $key" | |
exit 1 | |
} | |
if (( ${#documents[*]} == 1 )); then | |
[[ "${documents[0]}" =~ ^\ *\*\ *$ ]] && { | |
printf '%s %s\n' "${c_r}ERROR:$c_c" "${c_w}No notes in $c_m$VIMNOTES_FOLDER$c_c" >&2 | |
exit 1 | |
} | |
# Open the single document matching the search term | |
open_note 0 | |
else | |
# Display the multiple matching documents (or the full list if no term was passed) | |
screen_width=$(tput cols) | |
if [[ -n "$screen_width" ]]; then | |
maxcolumns=0 | |
while (( 1 )); do | |
(( (( (( max_docwidth + 8 )) * maxcolumns )) > screen_width )) && { | |
(( maxcolumns-- )) | |
break | |
} | |
(( maxcolumns++ )) | |
done | |
else | |
maxcolumns=3 | |
fi | |
# Get the number of values | |
upto=${#documents[@]} | |
# Calculate the number of digits in $upto | |
digits=1 | |
while (( 1 )); do | |
digits_power=$(power 10 $digits) | |
(( digits++ )) | |
(( (( upto / (( 10 * digits_power )) )) < 1 )) \ | |
&& break | |
done | |
unset digits_power | |
# Draw the list | |
printf '\n' | |
cnt=1 | |
for (( x=0; x<${#documents[*]}; x++ )); do | |
count_display=$(printf "%${digits}s" "$((x+1))") | |
count_display="${count_display//\ /0}" | |
(( x )) || one_display="$count_display" | |
printf "$c_b[%${digits}s]$c_c$c_u%$(( max_docwidth + 1 ))s$c_c" "$count_display" "${documents[$x]}" | |
if (( (( cnt + 1 )) > maxcolumns )); then | |
cnt=1 | |
printf '\n' | |
else | |
(( cnt++ )) | |
printf '%4s' ' ' | |
(( (( x + 1 )) >= ${#documents[*]} )) \ | |
&& printf '\n' | |
fi | |
done | |
unset cnt | |
printf '\n' | |
# Initialize the interactive entry line | |
tput init | |
prompt | |
tput sc | |
tput rc | |
# Save the tty state | |
tty_state="$(stty -g)" | |
# Trap a function to restore the tty on exit | |
trap 'stty "$tty_state"; exit' SIGINT SIGQUIT SIGTERM | |
# Begin to capture input | |
stty cs8 -icanon -echo min 1 time 1 | |
stty intr '' susp '' | |
# Loop the input loop and a set of input testing commands | |
while (( 1 )); do | |
# The input loop which accepts 0-9, q/Q/Ctrl-C to quit, Backspace and Enter | |
value='' | |
while (( 1 )); do | |
# Break out of the loop if $value is as long as the largest number to select from | |
(( ${#value} >= digits )) \ | |
&& break | |
# Wait for and accept input | |
keypress=$(getkeycode "$(dd bs=10 count=1 2> /dev/null | od -t o1)") | |
case "$keypress" in | |
'177'|'010'|'033 133 063 176') | |
# Backspace | |
[[ -n "$value" ]] && value="${value:0:$((${#value}-1))}" | |
;; | |
$alpha_q|$alpha_Q) value='-1'; break ;; | |
$key_cr) [[ -n "$value" ]] && break ;; | |
'003') value='-1'; break ;; # Ctrl-C | |
'060') value="${value}0" ;; # 0 | |
'061') value="${value}1" ;; # 1 | |
'062') value="${value}2" ;; # 2 | |
'063') value="${value}3" ;; # 3 | |
'064') value="${value}4" ;; # 4 | |
'065') value="${value}5" ;; # 5 | |
'066') value="${value}6" ;; # 6 | |
'067') value="${value}7" ;; # 7 | |
'070') value="${value}8" ;; # 8 | |
'071') value="${value}9" ;; # 9 | |
esac | |
# Redraw the input line with an up to date $value | |
tput el1 | |
tput cr | |
prompt | |
printf '%s' "$value" | |
done | |
# Quit if input was given to do so | |
(( value == -1 )) && { | |
printf '\n%s\n' "${c_r}Quitting!$c_c" | |
[[ -n "$tty_state" ]] \ | |
&& stty "$tty_state" | |
exit 0 | |
} | |
# Evaluate the numbers and exit if valid, otherwise display an error and start again | |
if (( 1 <= value && value <= upto )); then | |
printf '\n' | |
open_note $(( value - 1 )) | |
else | |
tput el1 | |
tput cr | |
printf '%s' "$c_h Invalid number: $value $c_c" | |
sleep .8 | |
tput el1 | |
tput cr | |
prompt | |
fi | |
done | |
fi | |
# Restore the tty state | |
[[ -n "$tty_state" ]] \ | |
&& stty "$tty_state" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment