My knowledge management system - jaredgorski.org

My knowledge management system

meta

Cheatsheet


Command / action Description
note 'My new note' Create the file “My new note.md” from the shell, with automatic frontmatter
<leader>-w-f Search all notes with Ripgrep
<C-x><C-o> Autocomplete note filename (incremental)

Overview

My knowledge management system is built for maximum personal utility. It’s subject to change as needs arise. It’s not pure Zettelkasten1, Evergreen2, or any other system. Anything works as long as it helps me to accumulate, organize, and relate thoughts, ideas, and knowledge.

My system should be low-commitment and rather minimal. I’ll only add a feature when it seems necessary.

A pragmatic system

These are my needs and how I fill them:

  • Capture passing thoughts for later notetaking:
    • Pocket notebook
    • Phone (any notetaking app)
  • Write notes:
    • Vim (I use the VimWiki ↗ plugin)
    • Markdown format
      • I use wiki-style links because it makes linking notes by title easier
  • Make notes useful/meaningful:
  • Maintain standard metadata on note files:
  • Organize note files:
    • Flat structure (all in one directory)
      • This helps prevent hierarchies/categorization
      • VimWiki organizes files this way by default
  • Link from one note to another:
    • VimWiki has convenient built-in functionality for:
      • Creating links (supports both wiki and markdown-style links)
      • Maintaining links (:VimwikiCheckLinks scans for broken links)
    • Vim also provides the useful gf command, which navigates to the file under the cursor
  • Easily create new notes from concepts within existing notes:
    • VimWiki supports two convenient methods for this:
      • Highlight some existing text (this will be the note title), then press Enter to create the new file and follow the link to it
      • Create a new link to a file that doesn’t exist yet (wiki-style or markdown) and follow the link by pressing Enter
  • Quickly find a note by title:
    • FZF ↗ is the perfect Vim plugin for this
  • Search all notes by content:
    • Ripgrep ↗ makes this easy, and it integrates with FZF
      • Custom Vim function makes rg searches on notes easy, and provides a quickfix list for extra context
  • Parse/export note files and metadata (for analysis and static site generation):
    • I built nonplain ↗ to make it simple to parse plaintext+frontmatter notes and export to JSON
  • Calculate backlinks (with context):

Setup

  • In .vimrc, configure VimWiki to use markdown:

    let g:vimwiki_list = [{'path': '~/vimwiki/',
                          \ 'syntax': 'markdown', 'ext': '.md'}]
    
  • In .vimrc, automatically set autochdir for vimwiki filetypes to set Vim’s working directory to the vimwiki home directory when editing note files:

    autocmd FileType vimwiki set autochdir
    
    • This enables any auxiliary plugins (like FZF) to search notes files by default when currently editing a note, as well as making note filename completion possible for easy linking.

Automatic frontmatter injection when a new note is initiated 🔗

In .vimrc, create LoadFrontmatter function that injects frontmatter into the current file.

" Load new notes with frontmatter
func! LoadFrontmatter()
  " build frontmatter
  let $Frontmatter = "---\ntitle: " . expand('%:t:r')  . "\ndate: " . strftime("%Y-%m-%d") . "\n keywords: \nreferences: \n---\n"

  " echo frontmatter into file
  0r !echo $Frontmatter
endfunc

Then, silently call the LoadFrontmatter function automatically when a new markdown buffer is created in the vimwiki home directory. This autocmd should exist immediately after the LoadFrontmatter function declaration in .vimrc.

autocmd BufNewFile ~/vimwiki/*.md silent! call LoadFrontmatter()

In shell profile, register a note function to enable opening Vim and immediately initiating a vimwiki file (the first argument is the note title).

note () {
  vim -c "e ~/vimwiki/$1.md"
}

Now, anytime a new markdown file is created in the vimwiki home directory, the file basename will be automatically injected as the title, the current date will be injected as the date, and empty keywords and references declarations will be added. The frontmatter is YAML.

Vim command for searching notes 🔗

In .vimrc, create WikiRg function for searching notes with FZF and Ripgrep.

command! -bang -nargs=* WikiRg call fzf#vim#grep('rg 
      \ --column --line-number --no-heading --color=never 
      \ --smart-case --type md <q-args> "/Users/<user>/vimwiki"',
      \ 1, fzf#vim#with_preview(), <bang>0)
      
autocmd FileType vimwiki nnoremap <buffer> <leader>wf :WikiRg<Space>

This provides a quickfix list with all search matches, providing a small context window for the currently active match.

Export and deploy notes to the web 🔗

I use self-made tools ↗ for this. To see how it can be done, check out the nonplain.js 11ty-markdown-notes example ↗.

Usage

Creating a new note

  • From the terminal:
    note 'Title of new note'
    
  • From within another note, simply create a link to the new note and press Enter over the link to inject frontmatter and edit the note:
    [[Title of new note]]
    

The newly created note will look like this:

---
title: Title of new note
date: 2020-08-09
keywords:
references:
---

Writing a new note

  1. Use one of the commands above to begin a new note. The title will be generated from the string argument given and added to the frontmatter of the new note.
  2. Optionally, enter a comma-delimited list of a few keywords to describe the current note and maintain a bullet-list of external references.
  3. Write the body of the note below the frontmatter section using markdown.
  4. When finished, save and quit (:wq)
---
title: Title of new note
date: 2020-08-09
keywords: note, new, mine
references:
- Stoneman, R. (2008). Alexander the Great: A life in legend. Yale University Press.
---

My note body