#!/bin/sh set -o errexit set -o nounset readonly EXIT_SUCCESS=0 readonly NOTES_DIR_BASE="${HOME}/.t" readonly NOTES_DIR="${NOTES_DIR_BASE}/${t:-default}" TAB="$(printf -- '\t')" readonly TAB cmd_help() { echo "USAGE T script for fast notes t - Show notes in format '[INDEX] NOTE NAME (LINES)' t show - Show notes in format '[INDEX] NOTE NAME (LINES)' t (INDEX) - Show note content t add (X X X) - Add note with name X X X t edit (INDEX) - Edit note with INDEX by \$EDITOR t done (INDEX) [INDEX] ... - Delete notes with INDEXes t namespaces - Show namespaces t --help - Show this message t a - alias for add t e - alias for edit t d - alias for done t delete - alias for done t ns - alias for namespaces NAMESPACES t namespaces # show namespaces t=work t a fix bug 211 # add note in workspace 'work' t=work t # show notes in workspace 'work'" } die() { echo "$(basename "${0}"): Error: ${1}" 1>&2 exit "${2:-${EXIT_SUCCESS}}" } get_notes_sorted_by_access_time() { find "${NOTES_DIR}" -maxdepth 1 -type f -printf '%C@ %p\n' \ | sort -k1 -r \ | cut -d" " -f2- \ | tr '\n' "${IFS}" } get_notes_with_indexes() { SAVEIFS="${IFS}" IFS=';' index=1 for note in $(IFS="${IFS}" get_notes_sorted_by_access_time) do note_lines="$(wc -l < "${note}")" if [ "${note_lines}" -gt 0 ]; then note_lines="$((note_lines+1))" fi if [ "${note_lines}" -gt 70 ]; then note_lines="..." elif [ "${note_lines}" -eq 0 ]; then note_lines="-" fi note_name="$(basename -- "${note}")" if ${_TO_SHOW:-false}; then if [ "${#note_name}" -gt "$(($(tput cols)/2))" ]; then note_name="$(echo "${note_name}" | cut -c -$(($(tput cols)/2-4)) )..." fi fi printf -- '[%d]\t%s\t(%s)\n' "${index}" "${note_name}" "${note_lines}" index="$((index+1))" done IFS="${SAVEIFS}" } _remove_first_and_last_element() { cut -d"${TAB}" -f2 } find_note_name_by_index() { note_index="${1}" grep "^\[${note_index}\]" | _remove_first_and_last_element } cmd_add_note() { note="${NOTES_DIR}/$*" touch "${note}" exit "${EXIT_SUCCESS}" } cmd_delete_note() { current_notes="$(get_notes_with_indexes)" for note_index in "$@" do note="$(echo "${current_notes}" | find_note_name_by_index "${note_index}")" note_to_remove="${NOTES_DIR}/${note}" if [ ! -f "${note_to_remove}" ]; then die "Note with index ${note_index} not found" 1 fi rm "${note_to_remove}" done exit "${EXIT_SUCCESS}" } cmd_edit_note() { note_index="${1}" note="$(get_notes_with_indexes | find_note_name_by_index "${note_index}")" note_to_edit="${NOTES_DIR}/${note}" if [ ! -f "${note_to_edit}" ]; then die "Note with index ${note_index} not found" 1 fi ${EDITOR} "${note_to_edit}" exit "${EXIT_SUCCESS}" } cmd_cat_note() { note_index="${1}" note="$(get_notes_with_indexes | find_note_name_by_index "${note_index}")" note_to_cat="${NOTES_DIR}/${note}" if [ ! -f "${note_to_cat}" ]; then die "Note with index ${note_index} not found" 1 fi printf '\033[1m# %s\033[0m\n\n' "$(basename "${note_to_cat}")" cat "${note_to_cat}" exit "${EXIT_SUCCESS}" } prettify() { column -t -s "${TAB}" } cmd_show_namespaces() { ( for namespace in $(find "${NOTES_DIR_BASE}/" -mindepth 1 -maxdepth 1 -type d | sort -n) do namespace_notes_count="$(find "${namespace}" -type f | wc -l)" printf -- '%s\t(%s)\n' "$(basename "${namespace}")" "${namespace_notes_count}" done ) | prettify } cmd_show_notes() { _TO_SHOW=true get_notes_with_indexes | prettify } remove_empty_namespaces() { find "${NOTES_DIR_BASE}" -type d -empty -exec rm -r {} \; 2>/dev/null || true } trap remove_empty_namespaces EXIT if [ ! -d "${NOTES_DIR}" ]; then mkdir -p "${NOTES_DIR}" fi if [ -z "${1+x}" ]; then cmd_show_notes exit "${EXIT_SUCCESS}" fi case "${1}" in show) shift; cmd_show_notes ;; ns|namespaces) shift; cmd_show_namespaces ;; a|add) shift; cmd_add_note "$@" ;; d|done|delete) shift; cmd_delete_note "$@" ;; e|edit) shift; cmd_edit_note "$@" ;; --help) shift; cmd_help ;; *) cmd_cat_note "$@" ;; esac exit "${EXIT_SUCCESS}"