Blog: zettelkasten

Zettelkasten IDs

They are many different opinions on how your zettelkasten ID could be structured. I think the one idea that everyone agrees on is that every zettelkasten ID should be unique. I use zettelkasten IDs for two things my actual zettelkasten notes and my blog posts. The ID structure for both is the same. I am able to differentiate between the two by file extensions.

Here is an example ID zettelkastenid-2020-05-12-2221 The first part of the ID is a simple word or combination of words to help me find that ID on the same day I create it for editing purposes. When I create a note I may want to go back in a hour or so and change it slightly. Using Vim's auto completion it is much easier to find the note that I worked on previously in the day with the alpha part of the ID. If I am searching for notes on a particular subject I will use FZF and Silver Search to search for tags or particular words or phrases. The second part of the ID is simply a time stamp of when the file was created. The format is year-month-date-time. I believe going down to the second will provide a unique enough number for a primary key. I inserted the hyphens to make the ID more readable. You certainly don't need the hyphens but it helps me see quickly when the note was originally created.

The zettelkasten ID is the same as the actual file name except for the file name includes an extension. For blog posts I use .md and for notes I use .markdown. This helps me to quickly differentiate between the two on the command line.

Again there are many ways to create a unique ID and I believe there are many right ways to do it. This is just the method that works for me.

Zettelkasten ID zettelkastenid-2020-05-12-2221

Linking Zettelkasten Notes

For several years I have been keeping a journal and notes in Vimwiki. While Vimwiki is a great plugin, I wanted more control over how things were done, so I decided to develop my own system while still using Vim. The system is a work in progress. There are two things I have committed to. The first being the format will be plain text using markdown syntax. The second being the notes part of the system will be using the idea of zettelkasten for the actual taking of notes.

At this point I should tell you what zettelkasten is but I am not. That is for another post. Today I am going to talk about how to link notes together.

One of the sites I find very helpful about using Vim with zettelkasten is Edwin Wenick's Blog. His article titled Creating and Linking Zettelkasten Notes in Vim has been very helpful. This article would be not possible without it.

Edwin created some vim script that uses CtrlP to link the current note you are editing to a previous note. A reader, Fernando, created script that did the same thing except it used fzf and he posted it in the comments. I mentioned I wanted to build on that idea and add Silver Searcher to the linking script so it would be easier to find the previous note by searching on the text of all the notes rather than just file names. Well, before I could get around to it another reader, hbenevides, created a script that uses Ripgrep to search on the text of all the notes to create a link to a particular note and posted it. His script can be found also in the comments of the above article.

Rather than create something new for silver searcher, I built off hbenvides script.

Here is the modified script:

" make_note_link: List -> Str
" returned string: [Title](YYYYMMDDHH.md)
function! s:make_note_link(l)
        " fzf#vim#complete returns a list with all info in index 0
        let line = split(a:l[0], ':')
        let ztk_id = l:line[0]
    try
        let ztk_title = substitute(l:line[2], '\#\+\s\+', '', 'g')
catch

        let ztk_title = substitute(l:line[1], '\#\+\s\+', '', 'g')
endtry
        let mdlink = "[" . ztk_title ."](". ztk_id .")"
        return mdlink
endfunction

" mnemonic link zettel
inoremap <expr> <c-l>z fzf#vim#complete({
  \ 'source':  'rg --no-heading --smart-case  .',
  \ 'reducer': function('<sid>make_note_link'),
  \ 'options': '--multi --reverse --margin 15%,0',
  \ 'up':    5})
" mnemonic link ag
inoremap <expr> <c-l>a fzf#vim#complete(fzf#vim#with_preview({
  \ 'source':  'ag --smart-case  .',
  \ 'reducer': function('<sid>make_note_link'),
  \ 'options': '--multi --reverse --margin 15%,0',

What does this script do? This script has two different hot keys, one for Ripgrep and another for Silver Searcher. If you have both search tools installed you can use both and decide which one you like best. I left hbenevides original Ripgrep search alone except for one change. The script was originally designed to only search headers. I changed the search to also include all text. If you only want to search only headers you can start your search with the hashtag or modify the script back to the original search.

The script for Silver Search behaves much the same way but presents at the bottom of the page, which can be changed. The Silver Searcher script includes the fzf-vim preview window. If you use RipGrep and want the preview window that could certainly be added to the script for Ripgrep.

To use the RipGrep search in insert mode the key mapping is z and to use the Silver Searcher in insert mode the mapping is a

Hopefully someone besides me finds it helpful.

I am new to Vim Script so use at your own risk.

You may notice this article has a Zettelkasten ID. This is not a zettelkasten note but I am expanding the ID idea to many of my other text documents.

Zettelkasten ID linkingzettelkasten-2020-05-11-0735