One of my goals for 2020 was to try zettelkasten for managing my notes. I've experimented with various approaches in the past: paper notes in folders (and all over my desk), self-hosted wikis, and custom software like OneNote or Notion.
A few years ago I started using LionWiki to manage a small personal knowledge base. It was somewhat successful, but it didn't quite fit in with my daily workflow. It also required a network connection and browser to be open, and re-organizing notes wasn't quite as quick as I would like. I really like it as a lightweight wiki solution, but for personal notes I wanted something more.
Eventually I switched to deft, an Emacs-based tool for organizing notes that is based on Notational Velocity. This summer I evaluated a number of other zettelkasten tools, but I settled on Zetteldeft as it integrated well with my existing set of notes.
zetteldeft works alongside deft and adds support for special linking syntax, as
well as a slightly different naming scheme for notes (timestamp followed by the
There are a few things I really like about deft/zetteldeft's approach:
- Text based notes – All of my notes are stored in
org-modeformat on my home computer. deft also supports plain text and markdown formats.
- Fast to find notes – With a few keystrokes (
C-c z D) I can bring up a new search, and the results are narrowed as I type.
- Fast to add notes –
C-c z nbrings up a prompt for a new note title. Once that is entered, I'm taken to the note file with the title already filled in.
- Linking to other notes is easy –
zetteldeftsupports linking to notes via a special character and the note id, which looks like this:
§2018-07-09-2115. With some modifications it can also use a special
- Fits in with my daily work – If I've found the solution to a problem, I can quickly create a note and paste the solution without having to switch to another application or open a browser tab.
The following code lives in my Emacs
init.el. It sets up
zetteldeft, along with a bunch of keyboard shortcuts.
One additional change I made is binding
C-c z p to
sodaware/deft-open-preview. This allows me to open notes in a preview window
without the list losing keyboard focus.
file-truename when setting my notes path as
zetteldeft had some
problems locating my notes when using a relative path.
(use-package deft :bind (("C-c d" . deft)) :custom ;; Set deft path to full path so that zetteldeft works. (deft-directory (file-truename "~/Documents/notes")) (deft-extensions '("md" "org")) (deft-default-extension "org") (deft-recursive t)) (use-package zetteldeft :bind ("C-c z d" . deft) ("C-c z R" . deft-refresh) ("C-c z D" . zetteldeft-deft-new-search) ("C-c z s" . zetteldeft-search-at-point) ("C-c z c" . zetteldeft-search-current-id) ("C-c z f" . zetteldeft-follow-link) ("C-c z F" . zetteldeft-avy-file-search-ace-window) ("C-c z l" . zetteldeft-avy-link-search) ("C-c z t" . zetteldeft-avy-tag-search) ("C-c z T" . zetteldeft-tag-buffer) ("C-c z i" . zetteldeft-find-file-id-insert) ("C-c z I" . zetteldeft-find-file-full-title-insert) ("C-c z o" . zetteldeft-find-file) ("C-c z n" . zetteldeft-new-file) ("C-c z N" . zetteldeft-new-file-and-link) ("C-c z p" . sodaware/deft-open-preview) ("C-c z r" . zetteldeft-file-rename) ("C-c z x" . zetteldeft-count-words) :config (defun sodaware/deft-open-preview () (interactive) (deft-open-file-other-window)) (font-lock-add-keywords 'org-mode `((,zetteldeft-id-regex . font-lock-warning-face) (,zetteldeft-tag-regex . font-lock-warning-face))))
Additional changes: the
This is one of my favourite changes - it adds a new
zdlink, which allows me to insert an
org-style link to any note via
C-l. These links can be opened like any other
org-mode link, and because
they only include the note name (not the full path) they work across machines.
This isn't very useful if you're using markdown, but for pure
org it makes
linking and navigating much easier.
;; Add custom `zdlink` to handle zettledeft links. (eval-after-load 'org (lambda () (require 'zetteldeft) (org-link-set-parameters "zdlink" :follow (lambda (str) (zetteldeft--search-filename (zetteldeft--lift-id str))) :complete #'sodaware/zd-complete-link :help-echo "Searches provided ID in Zetteldeft"))) (defun sodaware/zd-complete-link () "Link completion for `zdlink' type links." (let* ((file (completing-read "File to link to: " (deft-find-all-files-no-prefix))) (link (zetteldeft--lift-id file))) (unless link (user-error "No file selected")) (concat "zdlink:" link)))
Additional feature: zetteldeft homepage
Note: This behaviour is now part of zetteldeft core. A home note can be
assigned via the
zetteldeft-home-id variable, and then accessed with
This is a small change that allows me to open a specific note file with a keyboard shortcut. This is useful when keeping a single note that acts as a gateway to all others.
I prefer the main search buffer for finding notes, but I keep one note that lists my main projects and links to their notes.
(defun sodaware/zd-homepage () "Open Zetteldeft home file." (interactive) (zetteldeft-find-file "2020-07-10-0959 Home.org")) (global-set-key (kbd "C-c z h") #'sodaware/zd-homepage)
Additional feature: .dir-locals.el config
This is a really simple
.dir-locals.el file that lives in my main notes
directory. It adds 3 features:
- emojify-mode support – Sometimes I see fancy notion setups and want to
spice up my buffers with some emoji. I don't, but with
- whitespace-mode - This removes trailing whitespace when I save notes.
- Expands notes on opening – I normally have
org-modeheadlines collapsed as I use it for organizing my todo lists, but for notes I like to see the entire document when I open it.
((org-mode . ((mode . emojify) (mode . whitespace-cleanup) (eval . (outline-show-all)))))