Build A Killer Note-taking System
Tags: notetaking, script, cli, productivity
Published: 2019-04-07 15:26:05

---
title: Build A Killer Note-taking System
published: true
description: The proverb says, "The palest ink is better than the best memory". Note-taking is certainly an essential part of knowledge learning, information collecting and retaining....
tags: notetaking, script, cli, productivity
---
<img src="https://thepracticaldev.s3.amazonaws.com/i/k9g5yk2nsb7vfgz12msc.jpg"/>

The proverb says, "The palest ink is better than the best memory". Note-taking is certainly an essential part of knowledge learning, information collecting and retaining. In the fast-changing digital era, pen, ink and paper may not be able to fulfill the important job of note-taking anymore. So, what's a killer note-taking system nowadays?

### My requirements?

My dream system must be _Easy_, _Efficient_ and _Flexible_:

- Know where & how to write notes easily without hesitations
- Find right notes & roll back to old changes efficiently without hassles
- Convert notes to other formats and share them flexibly without troubles

### Build it!

#### Note format

I love taking notes with markdown. Why markdown?

- It's clean for writing and reading
- It's efficient, almost like writing plain texts
- It's flexible to convert to any other formats


#### Note taking & organization app

I like doing everything in the terminal, so naturally, Vim is the best note-taking editor for me.

For organizing notes, in the beginning, I set up different folders for different notes. But it's not quite close to what I want. Especially, searching note is not a straightforward task, it needs to `find` or `grep` for a while. Then I wrote a handy script [pynote](https://github.com/KevCui/pynote) for helping note organization, it worked and only at "it works" level... Recently, I switched to the amazing [Notational Velocity for Vim](https://github.com/alok/notational-fzf-vim), a plugin to port famous [Notational Velocity](http://notational.net/) into Vim. The whole note-taking experience never becomes so smooth! :massage:

#### Note version-control system

It's easy. Git is the only reasonable option I can think of. `¯\_(ツ)_/¯`

`git init`, make note changes, `git add`, `git commit` or `git revert`... All the fancy version control things are already familiar under my hands.

#### Note auto backup system

Google Drive? OneDrive? Dropbox? Nah, they are not really Git-compatible by default. However, I got inspired by [SparkleShare](https://github.com/hbons/SparkleShare), an open-source file sync app powered by Git, it adds file changes and pushes them to Github or GitLab automatically.

I may achieve the same functionality by using a simple script. The idea is to run [fswatch](https://github.com/emcrisostomo/fswatch) in the background and keep monitoring file changes. When file changes are happening, fswatch will trigger Git commands to add and push changes automatically.

Here is a snippet of Bash script:

```
#!/usr/bin/env bash
...
function notesync() {
  fswatch -r -0 -d "$1" -e '\.git' -m "inotify_monitor" --event=Created --event=Updated --event=Removed | xargs -0 -n 1 zsh -c "source ~/.zshrc; cd $1; git add -A; git commit -m 'Update file'; git push" &
}
notesync "<folder_path>"
notesync "<another_folder_path>"
...
```

**fswatch part** is to monitor file changes, filter out correct file change events and send the signal:

```
fswatch -r -0 -d "$1" -e '\.git' -m "inotify_monitor" --event=Created --event=Updated --event=Removed | ... &
```

- -r: watch subdirectories recursively
- -0: pass NUL as delimiter (no idea why it's need.....)
- -d: directory to monitor, the target folder full of notes
- -e: exude paths matching regex, here I don't want to trigger Git commands when any changes are happening in `.git`
- -m: monitor, type `fswatch -M` to see available monitors, more details of all available monitors: [here](https://emcrisostomo.github.io/fswatch/doc/1.14.0/fswatch.html/Monitors.html#Available-Monitors)
- --event: filter event by event flag, mainly using events related to file changes, all available events: [here](https://emcrisostomo.github.io/fswatch/doc/1.14.0/fswatch.html/Invoking-fswatch.html#Event-Flags-1)
- &: last but not least, don't forget it at the end, because it provides the ability to run fswatch command in background and detach the process

**xargs part** is to get signal from fswatch and execute specific commands:

```
... | xargs -0 -n 1 ...
```

- -0: input items are terminated by null, not whitespace (no idea why it's needed...)
- -n: maximum argument, `1` it is

**zsh command part** is to run Git commands:


```
... zsh -c "source ~/.zshrc; cd $1; git add -A; git commit -m 'Update file'; git push" ...
```

- zsh -c: execute following commands in `zsh`
- source ~/.zshrc: all my SSH keys are declared in `.zshrc` file, this command will load configurations from `.zshrc` file. Otherwise, push to remove Git repository may get permission denied
- git add -A...: Git commands to add changes and push to remote repository. Some optimization ideas: 1) `git pull` first, in case it's a shared repository; 2) Put some specific texts in commit messages, maybe also including file names


#### Sumup

This is my killer note-taking system. It's easy, efficient and flexible:

```
Note format: Markdown
Note taking & organization app: Vim + Notational Velocity for Vim
Note version-control system: Git
Note auto backup system: fswatch + GitHub
```

So far I'm quite happy with this system. I enjoy using it not only for taking some private notes with my dirty secrets, but also for sharing notes with colleagues in my day-to-day work, like notes for [exploratory testing](https://kevcui.github.io/2017/04/17/how-i-do-exploratory-testing/). Oh, I almost forget, guess what I'm using now for wring this blog post?

How does your note-taking system look like? Share with me your awesome ideas?