#!/usr/bin/sh
# snotes-1.0 by v4hn / 2009-2013
# See LICENSE file for copyright and license details.

info(){
    echo "$0: Info: $1" >&2
}

die(){
    echo "$0: Error: $1" >&2
    exit 1
}

while [ -n "$1" ]; do
    case "$1" in
    "-s"|"--search")
        SNOTES_SEARCH="yes"
        shift;;
    *)
        echo "usage: $0 [-s|--search]"
        die "unknown parameter '$1'"
        ;;
    esac
done

if [ ! -d "$HOME/.snotes" ]; then
    info "creating config folder ~/.snotes"
    mkdir $HOME/.snotes || die "Could not create $HOME/.snotes"
    cat > $HOME/.snotes/config <<'EOF'
SNOTES_EDITOR="xterm -e ${VISUAL:-${EDITOR:-vi}}"

SNOTES_DB="$HOME/.snotes/notes"

# clean trailing whitespace from file automatically
SNOTES_CLEANUP="yes"

# how many commits should be shown for "changed:note"
SNOTES_CHANGED_COMMITS=2
EOF
fi

. "$HOME/.snotes/config" ||
    die "config ~/.snotes/config messed up"

type dmenu >/dev/null 2>&1 ||
    die "dmenu not available"

type git >/dev/null 2>&1 ||
    die "git not in PATH"

if [ ! -d "$SNOTES_DB" ]; then
    info "creating notes database '$SNOTES_DB'"
    git init -q "$SNOTES_DB" || die "cannot create '$SNOTES_DB'"
    cd "${SNOTES_DB}"
    # changed:note assumes a predecessor for each non-empty commit
    git commit -q --allow-empty -m "root commit"
    cat > "introduction to snotes" <<'EOF'
Welcome to snotes 1.0
~~~~~~~~~~~~~~~~~~~~~

You're reading the first note in your newly created notes system.
If you don't like it, just remove all content from the note and
save. snotes automatically removes empty notes.

As you've already found out, running `snotes` allows you to type
or select the name of a note using dmenu. It then opens the note
and you can write/edit/rewrite it to your heart's content.
When you're done, save the note, close the editor and go on working.

Not impressive, is it? But I can assure you, it's useful!
AND it neither depends on Mono (not even on GTK/Qt) nor is it bound
to one specific editor, which some people consider to be an OS.
It's simply about 250 lines of shell code.

So you can create, edit and remove notes already. What else do you
need to know? You can invoke snotes with the '-s/--search' flag.
This way an empty dmenu pops up and you can enter any string/regular
expression you like. snotes then looks through all your notes and
presents you with all notes that match your query. If you're as
forgetful as I am, you will quickly appreciate this. This mechanism
also allows you to use something like tags with snotes by simply
adding keywords to the individual notes.

You might have noticed snotes' git dependency. All your notes
and edits are stored in a git repository. This allows you to keep
track of your changes easily. For example, if you add " changed" or " c"
after the name of a note in `snotes` you want to look at, snotes will present you
with a diff of recent changes you applied to that specific note.
Adding " blame" or " b" after the name of a note will on the other hand
provide you with a detailed `git blame` of that note. Technically, the git
repository also makes it quite easy to synchronize your notes from different
platforms.

You can also use the command line interface of snotes directly, if you
prefer this to dmenu. Simply invoke `snotes-open` with some parameter.
Possible parameters are "note:foo", which opens/creates the note foo,
"changed:foo", which presents you with recent changes of foo,
"blame:foo", which gives you a full blame of the note, and "commit:hash"
which opens one specific commit (with the index "hash") of the note database.
This last one is especially useful with the first word of the "blame:foo"
output and with "note:foo" you can easily refer to notes from within other notes.

This is it. If you wish to change some of the defaults of snotes (e.g. the editor),
you can edit these in ~/.snotes/config . If you wish to add features: go ahead,
it's just a bit of shell script.

On a different note, it makes sense to add key bindings for the different commands.
This is what I use with dwm:

{ MODKEY|ShiftMask,             XK_n,      spawn,          SHCMD("snotes-open \"\`sselp\`\"")},
{ MODKEY,                       XK_n,      spawn,          SHCMD("snotes")},
{ MODKEY,                       XK_m,      spawn,          SHCMD("snotes -s")},

If you enjoy or improved snotes, I would be glad to hear from you!

v4hn / me at v4hn dot de
EOF
    git add "introduction to snotes"
    git commit -q -m "created note 'introduction to snotes'"
fi

cd "$SNOTES_DB"

if [ "${SNOTES_SEARCH}" = "yes" ]; then
    regex=`echo | dmenu ${DMENU_ARGS}`
    [ -n "$regex" ] || die "regex empty"
    select="`(grep -sil $regex *; find . -path ./.git -prune -o -regex ".*$regex.*" -exec basename \{\} \; ) | sort -u | dmenu`"
else
    select=`ls | dmenu ${DMENU_ARGS}`
fi

if [ -z "$select" ]; then
    exit 0
fi

case "${select##* }" in
blame|b)
    file="blame:${select% *}"
    ;;
changed|c)
    file="changed:${select% *}"
    ;;
*)
    file="note:${select}"
esac

exec snotes-open "$file"
