2024-11-15 10:15:05 +03:00

196 lines
4.7 KiB
Bash
Executable File

#!/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)-12))" ]; then
note_name="$(echo "${note_name}" | colrm $(($(tput cols)-12)))..."
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}"