notes utils

This commit is contained in:
2026-02-21 18:10:21 +08:00
parent 153776c54e
commit b9635a5697
2 changed files with 233 additions and 0 deletions

171
utils/.local/bin/notes Executable file
View File

@@ -0,0 +1,171 @@
#!/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

View File

@@ -0,0 +1,62 @@
#!/bin/bash
#shellcheck disable=SC2155,SC2207,SC2309,SC2034,SC2154,SC1087
set -eo pipefail
_notes_completion() {
local cur="${COMP_WORDS[COMP_CWORD]}"
local command="${COMP_WORDS[1]}"
if [[ COMP_CWORD -eq 1 ]]; then
COMPREPLY=($(compgen -W "add edit rm list" -- "$cur"))
return
fi
if [[ "$command" == "edit" || "$command" == "rm" ]]; then
local notes_dir="$HOME/notes"
local notes=()
if [[ -d "$notes_dir" ]]; then
for file in "$notes_dir"/*.md; do
if [[ -f "$file" ]]; then
notes+=("$(basename "$file")")
fi
done
fi
local IFS=$'\n'
COMPREPLY=($(compgen -W "$(printf '%s\n' "${notes[@]}")" -- "$cur"))
compopt -o filenames
return
fi
}
_notes() {
local -a commands=(
'add:Create a new note'
'edit:Open a note in editor'
'rm:Remove a note'
'list:List all notes'
)
if (( CURRENT == 2 )); then
_describe 'command' commands
elif (( CURRENT >= 3 )); then
case $words[2] in
edit|rm)
local notes_dir="$HOME/notes"
if [[ -d "$notes_dir" ]]; then
_files -W "$notes_dir" -g '*.md'
fi
;;
*)
_message 'no more arguments'
;;
esac
fi
}
if [[ -n "$BASH_VERSION" ]]; then
complete -F _notes_completion notes ./notes
fi
if [[ -n "$ZSH_VERSION" ]]; then
compdef _notes notes ./notes
fi