2026-04-30
First things first: It is a pleasure to once again participate in a Vim Carnival, created and hosted by the fabulous Hyde.
Though the topic of the Vim Carnival - April 2026 is: “How do you use Neovim/Vim to build your knowledge management?”, let me state upfront: This article is going to be more about personal knowledge management (PKM) than about Vim. After all, Vim is “just” an editor, which is per se agnostic to what it is employed for – be it writing todo lists, emails, books, doing PKM or whatever. So honestly, I am somewhat stretching the idea of the Vim Carnival with this contribution. For the short (and maybe a bit disappointing) answer to the above prompt, you can jump directly to the section And what about Vim? at the very end.
A short note regarding terminology: In this article I will use “Vim” as a placeholder for vi-like editors in general. In particular, it includes both Vim and Neovim, but even plain vi1.
Actually, this Vim carnival is a welcome prompt for a subject I intended to write about since a long time, but never came around to doing: That is, how I do PKM.
I won’t delve into the “theory” of PKM in any detail here. There is a lot to say about PKM, and a lot has already been said about it in the past and will be said about it in the future (and I am no expert at all in this matter). The risk in writing an article like this one is to completely get lost in the many aspects and facets of PKM. So I deliberately try not to let that happen and will focus on very few aspects – mostly on the technical implementation of my PKM system – in the hope of not ending up with a complete mess of an article.
So, here we go…
I have long dabbled with the challenge of PKM (long before I even knew a term existed for it and a large and active community has developed around it) – that is the challenge of how to manage knowledge (i.e. not just to store it, but to actively use it and engange with it in a meaningful way): Be it storing ideas for later reference, short notes, how-tos, trivia, inspirational quotes or whatever one considers worth remembering or needs to remember.
While implementing an analog PKM system (i.e. a system not relying on a computer) is very well possible – after all, people have been doing it for hundreds if not thousands of years –, the advent of computers has certainly opened up new possibilites, like organizing documents in different fashions, searching in them and filtering them according to certain criteria. I will not discuss the advantages and disadvantages of analog and digital forms of PKM here and instead, without further explanation, focus on digital PKM systems from here on.2
The question then is: How to implement a PKM system on a computer? While dedicated tools – from simple to highly sophisticated and complex – abound, I have always had a certain aversion to them. I guess it stems from the fact that I have always thought that there must be a really simple way to implement such a system, a way that is efficient and so robust that it can stand the test of time (and the coming and going of software tools…).
This does not mean that there are no good tools around for implementing a PKM system. Even when taking into account some of my basic requirements, like
there is still a respectable number of tools which satisfy these. Yet, I have never come to really like them. Even Obsidian, a tool which has many dedicated fans and which I really appreciate, is not for me, mostly for two reasons (which are directly connected to the requirements above): It is too complex for my taste and offers way more features than I would ever need, and – no matter how successful and widely used it is today –, it will most likely be gone someday.3
Therefore, I have always preferred to build my own PKM systems, tailored to my specific needs (which sounds more grandiose than it actually is; hold on).
But first, let us take a step back. The simplest system for storing notes – the one most people have used decades ago, and in particular before the advent of graphical user interfaces – is storing them in plain text files, one per note, in some directory (or directory structure). There is basically just one ingredient necessary for setting up such a system on a computer (apart from rather obvious things like a file system): A text editor for creating and editing notes.
With nothing more than this, working with the system is somewhat limited. But as soon as basic tools available (and usually preinstalled) on essentially all Unix-like operating systems are taken into account, we already gain quite a bit:
less lets us view notes.grep lets us search notes.ln lets us link notes (for creating aliases, for instance)and so on.
And honestly, I still feel that not much more is needed for implementing a PKM system on a computer. While I tend to spend much time thinking about how to best implement things, sooner or later I usually feel myself drawn to very simple solutions with few dependencies. Here, as in many other cases, the danger lies in spending so much time setting up and administrating the system that one does not really use it at all.
There are basically just two things I would really miss with a pure plain text
approach like this one: The ability to tag and to link notes. While tagging
would be possible by, for instance, prepending tags with a certain prefix like
“#” and then using grep to find notes containing them, that would be a little
cumbersome. But I have not been able to find a good solution for linking notes
(in particular linking from a specific point in a note) with this approach.
Here HTML comes to the rescue – or rather leightweight markup languages like Markdown or AsciiDoc which translate to HTML.
Before explaining the system I am currently using, however, let me briefly mention three of the many self-built systems I have used over the years. I have chosen these because of the different ideas and concepts they were based on.
A self-written simple static site generator where notes were written in AsciiDoc and included front-matter for metadata like tags etc. (actually, it was a derivate of a static site generator I built for my website). Since the output format was HTML, linking between notes was easy. Since the output was static, though, it was only possible to filter for single tags; dynamical filtering was simply not possible. This may be fine for a personal website, for instance, but it is definitely a drawback for a PKM system.
A pure plain-text system where notes were stored as plain-text files without any structured markup (like Markdown or AsciiDoc) at all. Tags were implemented via symbolic links to (empty) directories named like the given tag, and links between notes were implemented via symbolic links between these notes (I got the idea of using symbolic links for implementing tags by the great article “The Case Against Everything Buckets” by Alex Payne, which unfortunately is no longer available online to my knowledge). What I really liked about this system was that it depended only on tools which are already available on any Unix-like system (an editor, a pager, symbolic linking etc.). All the linking was somewhat cumbersome, however, and in particular error-prone. Therefore, I wrote a simple shell script which provided convenience functions for viewing, editing, tagging and linking of notes (and in particular for carrying out all the linking). A major disadvantage of this system was that linking was only possible on the level of the notes themselves (i.e. you could link note A to note B, but you could not link from a specific point in note A to note B).
Another pure plain-text system with unstructured plain-text notes where tags of notes, links between notes and other metadata was stored in a JSON file (thereby separating metadata of notes from the notes themselves). This was meant to solve the problem that I did not want to have metadata directly in my notes, as well as the problem of having to create all those symbolic links in the system mentioned above. A Ruby script provided convenience functions similar to the ones mentioned above (and in particular for managing the JSON file, which would have been rather impractical and error-prone to do manually). In addition, notes were stored in a Git repository, and the script automatically committed changes to the repository when creating or editing notes. The main disadvantage of this system probably was that, while it was designed with the idea in mind that everything should be doable without special tools like my Ruby script, editing the JSON file and committing to the Git repository was cumbersome and error-prone and could easily be forgotten when done manually. So, while having a separate file for storing metadata information for my notes was more robust than employing symbolic links, I felt that the problems were only shifted to different areas.
While all these systems worked and did what they were meant to do, I was never really satisfied with them. The main problem was that I never really worked with them. They were based on certain ideas and principles I had in mind, but it turned out that the theory of conceiving them and the practice of using them diverged.
The system I am currently using is the one I am most happy with so far. It does not solve all problems, but it is the one which currently works best for me.
The main design goals of my system are (and have pretty much always been):
All my notes are stored in a single directory called, well, notes (this is not
different from practically all the other systems I have used in the past, like
the ones mentioned above). Notes are Markdown-formatted plain text files.5
There is (almost) no metadata contained in my notes. In particular, there is no
front-matter (i.e. structured metadata) at the top of a note. While front-matter
makes it easy to parse metadata programmatically, it somewhat clutters the notes
and is not so easy to parse without specific tools (which contradicts the first
of my design goals).
There are only two special syntactical constructs which extend Markdown and have a special interpretation in my system:
# at the beginning of a note are interpreted as tags.[[<note>]] or [[<title>|<note>]] are
interpreted as internal links, i.e. links to other notes.The system is perfectly usable with nothing more than this (note in particular that the syntax for the two special constructs for tags and internal links mentioned above is so unobtrusive yet self-explanatory that they would even work without rendering the notes). In particular, it satisfies my first design goal; for instance, some basic operations could be done like this:
less <note>vim <note>grep <string> *grep -l -e "#<tag1>" -e "#<tag2>"grep -l "\[\[<note>\]\]" *grep -o "\[\[.*\]\]" <note>Note the small number of tools needed to achieve these operations.
However, to be able to efficiently use tags and links (which are integral ingredients in a PKM system), it is convenient render notes as HTML and view them in a browser. In my system, the preprocessing and rendering of the notes is facilitated by a small Ruby program I wrote.6 Since the notes are written in Markdown, it is easy to convert them to HTML by employing standard libraries or APIs available in most programming languages. The tool provides a simple web application employing the Sinatra web framework. This in particular facilitates serving content dynamically (in contrast to the static site generator I used as a PKM system in the past; see above). This makes it possible, for instance, to filter for several tags, since the code determines the matching notes dynamially before they are getting rendered and served.
While the notes are mostly simply translated from Markdown to HTML, marks and links are preprocessed as follows:
A note can then be reached via the path /note/<note> and viewed in the browser
by entering the corresponding URL (i.e. the host – localhost if run locally –
plus this path). This is what a rendered note might look
like in the browser.
There is also an index page listing all the notes available (and also one for listing all the tags defined), so it is easy to directly navigate to them instead of having to enter the URL manually.
Note that, according to my second design goal above, things should be simple.
Therefore, there is basically no explicit user interface for doing things like
filtering (after all, I am the only one using the system…). Instead, the
filtering can be done by appending query parameters to the corresponding path.
For instance, the path for filtering notes on tags “tag1” and “tag2” would be:
/?tag=tag1,tag2
In addition, there are a few endpoints for doing certain consistency checks, like whether there exist links to non-existing notes, which is then reported so that it can be fixed.
Note that it is not possible to create, modify or delete notes in any way using
the web interface (it works in a purely functional way, one might say). This is
a deliberate choice: Deleting and renaming can easily be done using rm and
mv on the command line, and editing is exclusively done using my editor of
choice – that is, of course, Vim (so, I have finally turned things around and
arrived at the actual subject of this article - yay!).
So much about the technical implementation of the system. Regarding its organization: It is more or less based on the Zettelkasten approach7, but I will not go into any detail about it here. I am trying to write notes which are atomic, i.e. which entail a single idea or concept, and to link them to create semantic connections to similar of related ideas or concepts (though I often fail at doing this in a good fashion, I think). As mentioned in the beginning, though, this is not the focus of this article, so I will just refer to the many good resources about the organizational aspects of PKM in general, and the Zettelkasten method in particular, available out there.
So, I have written a lot already, but rarely mentioned Vim at all. Considering that this is a contribution to a Vim Carnival, the question “Where does Vim come into play?” imposes itself.
The – somewhat trivial – answer to this question is: Where it always comes into play when I work with plain text files. I use it, obviously, to edit my notes – just as I use it to edit any other kind of text file.
So, I hope Hyde will forgive me for somewhat abusing this Vim Carnival for my ramblings about PKM. Let me close this article, however, by emphasizing that, while there is nothing special in my using of Vim for PKM, it does play an extremely important role in it. It’s a simple syllogism:
I want to be able to edit text files as smoothly and efficiently as possible: That is why I use Vim – for PKM and everything else that comes as plain text.
I know it sounds somewhat strange to call plain vi “Vim”. Then again, this is an article for a Vim Carnival, so what… ↩
Examples of analog PKM systems are commonplace books, which have been around for centuries, and the Zettelkasten method, probably most famously employed by Niklas Luhmann, which is often used in an analog way (though it can also be implemented on a computer). ↩
I know: Since notes are stored in Markdown-formatted plain text, they can even be used if Obsidian (or whatever other tool) is gone someday. Yet, I prefer to depend as little as possible on external software. It is a rather mild case of vendor lock-in – much less so than with many other applications –, but I like to not only own my data, but also the software which operates on it (which, of course, is only possible in rather few cases). ↩
This basically means that my system would fall back to the basic plain text approach I sketched earlier. My notes would still contain markup in the form of Markdown, but one of the nice properties of Markdown (even more so than with other markup languages like AsciiDoc) is that Markdown does not distract much from the text; it integrates rather seamlessly into it. So even if Markdown would cease to exist, along with every tool to generate HTML from it, it would still be viable as some kind of self-explanatory plain-text markup. ↩
In the past, I have mostly used AsciiDoc. I switched to Markdown because I do not need all the power of AsciiDoc, and the markup of Markdown is less intrusive than that of AsciiDoc (which is more intrusive precisely because it is more powerful), thereby making it even more readable. ↩
The tool can be found here: https://codeberg.org/thorstenzoeller/noted. Note, however, that it is not quite up-to-date; in particular, this version only works with AsciiDoc-formatted notes (not with Markdown-formatted notes). An updated version will (hopefully) be provided soon. ↩
Some good ressources for starters are:
And no, I actually do not like footnotes that much, even though it very much seems to be exactly so. I just usually fail not to extensively make use of them. Fortunately, you have now made it to the last footnote of this article… ↩