#!/usr/bin/env bash set -euo pipefail # Script Name: note # Description: Quick notes with tags, search, and project awareness # Usage: note "quick thought" # Add note # note -t security "found XSS" # Tagged note # note -s "search term" # Search notes # note -l # List recent notes # note -e # Edit notes file VERSION="1.0.0" # Determine notes location (project-aware) if git rev-parse --git-dir > /dev/null 2>&1; then # In a git repo - use project notes NOTES_FILE="$(git rev-parse --show-toplevel)/.notes.md" else # Global notes NOTES_FILE="$HOME/notes.md" fi # Colors readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly BLUE='\033[0;34m' readonly CYAN='\033[0;36m' readonly BOLD='\033[1m' readonly NC='\033[0m' show_help() { echo -e "\033[1mnote\033[0m - Quick Notes Tool v${VERSION}" echo echo -e "\033[1mUSAGE:\033[0m" echo " note Add a note" echo " note [OPTIONS]" echo echo -e "\033[1mOPTIONS:\033[0m" echo -e " \033[0;36m-t, --tag\033[0m Add note with tag" echo -e " \033[0;36m-s, --search\033[0m Search notes" echo -e " \033[0;36m-l, --list\033[0m List recent notes (last 10)" echo -e " \033[0;36m-e, --edit\033[0m Edit notes file" echo -e " \033[0;36m-p, --path\033[0m Show notes file path" echo -e " \033[0;36m-h, --help\033[0m Show this help message" echo echo -e "\033[1mEXAMPLES:\033[0m" echo " note \"remember to test this\"" echo " note -t security \"found XSS in login\"" echo " note -t todo \"implement feature X\"" echo " note -s \"XSS\"" echo " note -l" echo echo -e "\033[1mNOTES LOCATION:\033[0m" echo " Current: ${NOTES_FILE}" if git rev-parse --git-dir > /dev/null 2>&1; then echo -e " ${CYAN}(Project notes - in git repo)${NC}" else echo -e " ${YELLOW}(Global notes)${NC}" fi } # Add note add_note() { local text="$1" local tag="${2:-general}" # Create file if it doesn't exist if [[ ! -f "$NOTES_FILE" ]]; then echo "# Notes" > "$NOTES_FILE" echo >> "$NOTES_FILE" fi # Format: ## YYYY-MM-DD HH:MM - [TAG] timestamp=$(date '+%Y-%m-%d %H:%M') echo "## $timestamp - [$tag]" >> "$NOTES_FILE" echo >> "$NOTES_FILE" echo "$text" >> "$NOTES_FILE" echo >> "$NOTES_FILE" echo -e "${GREEN}✓${NC} Note added to: ${NOTES_FILE}" echo -e "${CYAN}Tag:${NC} $tag" } # Search notes search_notes() { local query="$1" if [[ ! -f "$NOTES_FILE" ]]; then echo -e "${YELLOW}No notes file found${NC}" >&2 exit 1 fi echo -e "${BOLD}${CYAN}Search results for: ${query}${NC}" echo # Use bat if available for syntax highlighting, otherwise grep with context if command -v bat &>/dev/null; then grep -i --color=always "$query" "$NOTES_FILE" -B 2 -A 2 || echo "No matches found" else grep -i --color=always "$query" "$NOTES_FILE" -B 2 -A 2 || echo "No matches found" fi } # List recent notes list_recent() { if [[ ! -f "$NOTES_FILE" ]]; then echo -e "${YELLOW}No notes file found${NC}" >&2 exit 1 fi echo -e "${BOLD}${CYAN}Recent Notes (last 10):${NC}" echo # Extract last 10 note entries (sections starting with ##) awk ' /^## / { if (count > 0 && count <= 10) { print section } section = $0 "\n" count++ next } count > 0 && count <= 10 { section = section $0 "\n" } END { if (count > 0 && count <= 10) { print section } } ' "$NOTES_FILE" | tail -n +2 } # Edit notes edit_notes() { if [[ ! -f "$NOTES_FILE" ]]; then echo "# Notes" > "$NOTES_FILE" echo >> "$NOTES_FILE" fi ${EDITOR:-vim} "$NOTES_FILE" } # Show path show_path() { echo "$NOTES_FILE" } # Parse arguments if [[ $# -eq 0 ]]; then show_help exit 0 fi case $1 in -h|--help) show_help ;; -t|--tag) if [[ $# -lt 3 ]]; then echo -e "${RED}Error:${NC} Tag and note text required" >&2 echo "Usage: note -t " >&2 exit 1 fi tag="$2" shift 2 text="$*" add_note "$text" "$tag" ;; -s|--search) if [[ $# -lt 2 ]]; then echo -e "${RED}Error:${NC} Search query required" >&2 exit 1 fi shift search_notes "$*" ;; -l|--list) list_recent ;; -e|--edit) edit_notes ;; -p|--path) show_path ;; *) # Default: add note with "general" tag add_note "$*" ;; esac