172 lines
3.5 KiB
Bash
Executable File
172 lines
3.5 KiB
Bash
Executable File
#!/bin/bash
|
|
#shellcheck disable=SC2155,SC2207
|
|
set -eo pipefail
|
|
|
|
NOTES_DIR="$HOME/notes"
|
|
EDITOR="${EDITOR:-nano}"
|
|
mkdir -p "$NOTES_DIR"
|
|
|
|
show_usage() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") <command> [options]
|
|
|
|
Commands:
|
|
add Create a new note
|
|
edit Open a note in editor
|
|
rm Remove a note
|
|
list List all notes
|
|
|
|
Options for 'add':
|
|
-n, --name <name> Custom note name (default: <unixtime>-untitled-note.md)
|
|
-t, --title <title> Custom note title (default: "Untitled note")
|
|
--no-time Don't add creation timestamp
|
|
--no-edit Don't open editor
|
|
|
|
Options for 'edit':
|
|
<name> Note filename to edit
|
|
|
|
Options for 'rm':
|
|
<name> Note filename to remove
|
|
|
|
Options for 'list':
|
|
(none)
|
|
|
|
EOF
|
|
}
|
|
|
|
cmd_add() {
|
|
local name="untitled-note"
|
|
local title="Untitled note"
|
|
local add_time=true
|
|
local new_edit=true
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-n|--name) name="$2"; shift 2 ;;
|
|
-t|--title) title="$2"; shift 2 ;;
|
|
--no-time) add_time=false; shift ;;
|
|
--no-edit) new_edit=false; shift ;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
local filename="$(date +%s)-${name}.md"
|
|
local filepath="$NOTES_DIR/$filename"
|
|
|
|
{
|
|
echo "# $title"
|
|
echo
|
|
if [[ "$add_time" == true ]]; then
|
|
echo
|
|
echo "Created at $(date '+%Y-%m-%d %H:%M:%S')"
|
|
echo
|
|
fi
|
|
echo "---"
|
|
echo
|
|
} > "$filepath"
|
|
|
|
echo "Created note: $filepath"
|
|
|
|
if [[ "$new_edit" == true ]]; then
|
|
$EDITOR "$filepath"
|
|
fi
|
|
}
|
|
|
|
cmd_edit() {
|
|
if [[ $# -lt 1 ]]; then
|
|
echo "Error: Note name required"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
|
|
local filename="$1"
|
|
local filepath="$NOTES_DIR/$filename"
|
|
|
|
if [[ ! -f "$filepath" ]]; then
|
|
echo "Error: Note not found: $filename"
|
|
exit 1
|
|
fi
|
|
|
|
$EDITOR "$filepath"
|
|
}
|
|
|
|
cmd_rm() {
|
|
if [[ $# -lt 1 ]]; then
|
|
echo "Error: Note name required"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
|
|
local filename="$1"
|
|
local filepath="$NOTES_DIR/$filename"
|
|
|
|
if [[ ! -f "$filepath" ]]; then
|
|
echo "Error: Note not found: $filename"
|
|
exit 1
|
|
fi
|
|
|
|
rm -v "$filepath"
|
|
}
|
|
|
|
cmd_list() {
|
|
local count=0
|
|
printf "%-40s %s\n" "Filename" "Title"
|
|
printf "%-40s %s\n" "--------" "-----"
|
|
|
|
# Use nullglob to handle empty directory case
|
|
local shopt_save
|
|
shopt_save=$(shopt -p nullglob)
|
|
shopt -s nullglob
|
|
|
|
local files=("$NOTES_DIR"/*.md)
|
|
|
|
# Restore original nullglob setting
|
|
eval "$shopt_save"
|
|
|
|
for file in "${files[@]}"; do
|
|
if [[ -f "$file" ]]; then
|
|
local filename=$(basename "$file")
|
|
local title=$(sed -n 's/^# \([^#].*\)/\1/p' "$file" | head -n1)
|
|
|
|
if [[ -z "$title" ]]; then
|
|
title="Untitled note"
|
|
fi
|
|
|
|
printf "%-40s # %s\n" "$filename" "$title"
|
|
((count++))
|
|
fi
|
|
done
|
|
|
|
if [[ $count -eq 0 ]]; then
|
|
echo "No notes found"
|
|
else
|
|
echo ""
|
|
echo "Total: $count note(s)"
|
|
fi
|
|
}
|
|
|
|
if [[ $# -lt 1 ]]; then
|
|
cmd_list "$@"
|
|
exit 0
|
|
fi
|
|
|
|
command="$1"
|
|
shift
|
|
|
|
case "$command" in
|
|
add) cmd_add "$@" ;;
|
|
edit) cmd_edit "$@" ;;
|
|
rm) cmd_rm "$@" ;;
|
|
list) cmd_list "$@" ;;
|
|
-h|--help|help) show_usage ;;
|
|
*)
|
|
echo "Unknown command: $command"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|