----------------------------------------
CLI Tricks: n - note taking
March 21st, 2018
----------------------------------------

This is the first in a series of phlog entries where I will share
some of my command line tricks, tips and scripts.


## n ##

Note-taking in the terminal is a big deal for me. Whether I'm in
a meeting or someone stops by for a quick interruption, I need to
be able to jot down notes quickly and get at them again easily. To
handle this I have built a helper function called "n". 

Note: If you are familiar with my dotfiles [0] then you know
I keep all these scripts in a folder called ~/.functions and
source them as part of my .bash_profile.


### The Idea ###

When I'm on the command line I enter the command "n" and it pops
up a list of all my notes using the FZF [1] fuzzy finder. These
have a nice preview window to the side so I can quickly scan what
I'm looking for as I type in parts of the name. If I see what
I need in the preview I can either hit ESC to quit back to my
shell or ENTER to open up the note in my EDITOR.

Creating a new note is easy:

  $ n monkeys

  > creates a new note in my NOTE_DIR called monkeys.md (I default
  > all my notes to markdown) and opens it in EDITOR

Want to categorize them? Add a folder path:

  $ n animals/monkeys

  > creates a new note at $NOTE_DIR/animals/monkeys.md and opens
  > it in EDITOR

You can search foldernames as part of the fuzzy-finding.

The script also has bash-completion built-in. If you don't want to
use FZF to browse for the file, just type part of the word and hit
tab, like so:

  $ n mo

  > n monkeys


### Requirements ###

This requires FZF [1], a fantastic utility for fuzzy-finding. I'm
sure you could port it to another tool if you really wanted,
though.

This also requires that you have an environment variable set
called NOTE_DIR. For me that points to Dropbox where I have a
notes folder. This means all my notes are generated and stored
there and are shared across systems. I can even get at them 
with my phone.


### The Source ###

  #!/usr/bin/env bash

  # Note taking function and command completion
  _n() {
    local lis cur
    lis=$(find "${NOTE_DIR}" -name "*.md" | \
      sed -e "s|${NOTE_DIR}/||" | \
      sed -e 's/\.md$//')
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(compgen -W "$lis" -- "$cur") )
  }
  n() {
    : "${NOTE_DIR:?'NOTE_DIR ENV Var not set'}"
    if [ $# -eq 0 ]; then
      local file
      file=$(find "${NOTE_DIR}" -name "*.md" | \
        sed -e "s|${NOTE_DIR}/||" | \
        sed -e 's/\.md$//' | \
        fzf \
          --multi \
          --select-1 \
          --exit-0 \
          --preview="cat ${NOTE_DIR}/{}.md" \
          --preview-window=right:70%:wrap)
      [[ -n $file ]] && \
        ${EDITOR:-vim} "${NOTE_DIR}/${file}.md"
    else
      case "$1" in
        "-d")
          rm "${NOTE_DIR}"/"$2".md
          ;;
        *)
          ${EDITOR:-vim} "${NOTE_DIR}"/"$*".md
          ;;
      esac
    fi
  }
  complete -F _n n


[0] tomasino's dotfiles
[1] FZF