notes utils
This commit is contained in:
171
utils/.local/bin/notes
Executable file
171
utils/.local/bin/notes
Executable 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
|
||||||
62
utils/.local/bin/notes-completion
Normal file
62
utils/.local/bin/notes-completion
Normal 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
|
||||||
Reference in New Issue
Block a user