_ ____ _ _
/ \ | __ )| | __ _ _ __ __| |
/ _ \ | _ \| |/ _` | '_ \ / _` |
/ ___ \ | |_) | | (_| | | | | (_| |
/_/ \_\ |____/|_|\__,_|_| |_|\__,_|
_ __ _ _ ____
| |/ /_ __ _____ _| | ___ __| | __ _ ___ | __ ) __ _ ___ ___
| ' /| '_ \ / _ \ \ /\ / / |/ _ \/ _` |/ _` |/ _ \ | _ \ / _` / __|/ _ \
| . \| | | | (_) \ V V /| | __/ (_| | (_| | __/ | |_) | (_| \__ \ __/
|_|\_\_| |_|\___/ \_/\_/ |_|\___|\__,_|\__, |\___| |____/ \__,_|___/\___|
|___/
_ __ ___
(_)_ __ \ \ / (_)_ __ ___
| | '_ \ \ \ / /| | '_ ` _ \
| | | | | \ V / | | | | | | |
|_|_| |_| \_/ |_|_| |_| |_|
I have notes on lots of things. When you write notes in markdown itβs called βa knowledge baseβ, which sounds classy. So now I have lots of knowledge bases, and I strive to keep them bland and featureless.
A good knowledge base has no fancy features. Features are bad[i]. They tie you down to particular software, or one workflow. Everything βintegratedβ with the notes also holds onto your notes, jealously.
Proprietary solutions are prone to the usual abuse[ii], but many open source note apps[iii] arenβt much better - they have their own oddities, and special markdown abilities, which wonβt work in other contexts. This leaves you unable to publish notes, as that special in-line image format from a fancy app wonβt work on a website.
The websites are no better. I publish with Hugo, and itβs great, but every theme also invites you to place special snippets for graphs or video
`{{ .video | youtube.com/?url=thing }}`
It looks harmless, but itβs a trap. The video link wonβt work on other web compilers, or gemini, so the knowledge base will be tied to that particular software.
Hence Vim. Vim is harmless. It wonβt tell you how to write or organize your notes. It just makes editing easy. Because vim is easy[iv].
The collection of text notes on how to do stuff in Linux has grown and become opinionated. Iβm slowly going over the pages to try and tag every single page with knowledge dependencies, i.e. what you need to know before reading the page.
Hereβs the head of one page on editing files encrypted with GPG:
---
title: Edit gpg encrypted files with vim
tags:
- vim
- data
- gpg
- comfy
requires:
- data/gpg.md
- writing/vim.md
---
The `vim-gnupg` plugin lets vim edit gpg-encrypted files as if they were unencrypted.
[...]
That βrequiresβ tag means I can generate a note at the top of the pages saying what you need to know before reading the page.
I have not tagged all pages yet, but once I do, the website[v] will state whatβs required to read an article at the front. This will make me happy, because documentation should not have links in the body[vi].
Vim with a Knowledge Base
File Navigation
Open & Search
Open a file at line 20:
Open the file while searching for the word βDelete`:
vim writing/ed.md +/Delete
Buffers & Tabs
You can open multiple files with Vim and navigate with βbuffersβ (the word still feels strange).
The command :ls shows the buffer, and b2 takes you to buffer 2 (writing/vim.md) in this case.
:ls
1 %a "writing/ed.md" line 1
2 "writing/vim.md" line 0
3 "writing/vim_tricks.md" line 0
:b2
You can also cycle through them.
- Select the next buffer with :bNext (or :bn).
- Select the previous buffer with :bPrevious (or :bp).
- Select the last buffer on the list with :bLast (or :bl).
Tabs are similar, but you can see the tabs at the top.
Open files in tabs with -p.
Then use :tabedit % to open a new tab.
Go-to-File
If you put the cursor on a fileβs name, you can go to the file immediately with gf. This is excellent, as it lets you wander your own knowledge base as if a palace.
Weird markdown formats, like Gollum sometimes demand that you leave out the .md suffix in links, so your link to [GPG](gpg.md) wonβt work. You have to write [GPG](gpg). Vim lets you navigate to gpg.md anyway by adding a standard suffix:
Now you can go to the word gpg and press gf, and instantly enter that file.
If the file is in another directory, you can link to it like this:
Check [the standard editor](writing/ed.md) for why `sed` works like this.
But you might want to link to it like this:
Check [the standard editor](ed.md) for why `sed` works like this.
In this case, you can still navigate to it by adding all the other directories to the path where Vim checks. Just add this to your vimrc file:
Edit Jumps
- g; to go to the last place you edited.
- g, to jump back through edit-locations.
Netwr Navigator
On rare occasions, Iβll use the in-built navigator: Netwr. Thereβs an excellent setup guide here[vii] as itβs not very good βout-of-the-boxβ.
Editing
Mapping Keys to Output
Notes on Linux means lots of code-blocks, which look like this:
This is boring to type, so now I just type βcommaβ then βgraveβ, and vim produces the code block. You can map the keypress by sticking this in ~/.vim/vimrc:
map ,` o```<Enter>```<Esc>kA
Interactive Find and Replace
Sometimes you want to find and replace a word in a lot of files, but also confirm each change. Vim lets you do this by starting up with a βfind and replaceβ command:
vim -c "%s/${nano}/${vim}/gc" -c 'wq' **/*.md
Vim can run a command and type out the results for you:
:r!date
Thu 16 Apr 13:08:48 CEST 2026
Writing with Markdown
Set up a Spell Checker
I have the standard spell-checking commands in my vimrc, but the command to actually use the spell-checker hides in the markdown-only file, because you donβt always want a spell-checker on.
set spelllang=en_gb
set complete+=kspell
hi clear SpellBad
hi SpellBad cterm=underline
hi SpellCap cterm=underline
hi SpellLocal cterm=underline
hi SpellRare cterm=underline
All those hi-light commands make Vimβs spell-highlights less nauseating.
In the markdown-only setting, add this to actually use those spell-checking commands:
Once you have the spell-checker working, it just has a few commands:
- z= asks the wordlist for suggestions on better spelling.
- zg accepts a word as a word, and adds it to your dictionary in ~/.vim/spell/.
- zug removes a word which is not a word.
If, like me, you speak a kind of English which people describe as βnot defaultβ, you should share this spelling file with all your computers, so you donβt have to rebuilt it every time.
This next command is amazing. Once you start using it, you wonβt stop, and may look back on all the years you never had it and weep.
inoremap <C-l> <c-g>u<Esc>[s1z=`]a<c-g>u
If you type a typo, you can press Control + L to jump back, fix the typo (with Vimβs first guess at the correct spelling) and then jump back, all during insert mode.
Formatting Text Lines
I still donβt know how to do this. On the one hand, writing one sentence per line helps when using git, and feels natural. But it feels less natural to read.
As an example, that last paragraph has a new line on each sentence:
I still don't know how to do this.
On the one hand, writing one sentence per line helps when using `git`, and feels natural.
But it feels less natural to read.
Option 1: have a separate markdown reader.[1] Markdown is supposed to wrap lines for you, so you can break anywhere.
Option 2: wrap the lines with vim.
I can press gq2j to reformat two lines down, and it looks better.
I still don't know how to do this. On the one hand, writing one sentence per
line helps when using `git`, and feels natural. But it feels less natural to
read.
However, every time you edit, you need to wrap the lines again.
Not Vim with a Knowledge Base
The best thing about using Vim is not using Vim. After all, itβs just a text editor. As mentioned above, features are bad[viii]. Vim happily works with other tools by integrating those command. Like the Tao, it does nothing, and accomplishes everything.
Link Checks
Having plain text means easy parsing. I have a little bash script which searches markdown files for links, and checks to see if they work, then spits out a list of dead links. Iβll stick the script at the end in case anyone wants to use it for their weighty collection of markdown files.
Make Stuff
The Makefile at the root of knowledge base automates the standard commands. The first command is a help menu. I want the project to be friendly in case anyone else wants to join me in my quest[ix] to rid documentation of links inside the body.
make
article Write a new article
clean Remove all generated files
database Make a recfiles database
help Print the help message
map Show knowledge dependency map
make article will create a standard article template then commit it to the git repository.
The Dependencies Map
Each setup guide and note lists what you need to understand before starting. If you have graph-easy installed, you can run make map and see a full graph of dependencies (example at the end).
Recfiles
Recfiles[x] are plain-text files which are also a relational database. They look like this:
%rec: guide
%key: title
%type: requires rec guide
%type: provides rec guide
%type: wordcount int
%sort: wordcount
file: data/gpg.md
title: gpg
tag: data
tag: gpg
wordcount: 13
file: hardware/brightness.md
title: brightness
tag: hardware
tag: laptop
wordcount: 16
[...]
This file is a record of every file in the knowledge base, along with the word-count.
The Commands List
Recently, Iβve begun another recfile database for commands. I have a boat-load of little commands that donβt merit their own page/post/article, and really just exist so I can search for them quickly.
$ recsel ~/LK/command.rec -q qr
aim: Make a QR Code image:
cmd: qrencode 'https://play.google.com/store/apps/details?id=org.briarproject.briar.android' -o "$FILE".png
bin: qrencode
tag: qr
aim: Make a QR Coded message in the terminal:
cmd: qrencode -t ansi "Hello World"
bin: qrencode
tag: qr
aim: Read a QR Code image:
cmd: zbarimg $FILE
bin: qrencode
tag: qr
aim: Show wifi QR code (only with Network Manager):
cmd: nmcli device wifi show-password
bin: qrencode
tag: qr
tag: wifi
If you want to check the project, itβs available over ssh:
ssh -p 2222 soft.dmz.rs -t lk
β¦or at Gitlab[xi].
Thanks to the lazy bear[xii] for hosting a Vim carnival on knowledge bases. I canβt wait to see what the other posts look like.
Link Check Script
#!/bin/sh
set -e
timeout=4
find_links(){
echo "$1"
sed '/```/,//d' "$1" | \
sed -nr 's/.*\[.+\]\(([^ )]+).*/\1/p ; s/^\[[^\^]*\]:\s(.*)/\1/p'
}
check_link(){
while read link; do
if "${link##*:*}"; then
check_file "$link" "$file"
else
prefix="${link%%:*}"
case "${prefix}" in
http) check_http_link "$link"
;;
https) check_http_link "$link"
;;
gemini) check_gemini_link "$link"
;;
mailto) echo "ignoring email: $link"
;;
magnet) echo "ignoring torrent: $link"
;;
*) echo "$file: unknown protocol $link"
;;
esac
fi || dead_link_error "$link" "$file"
done
}
dead_link_error(){
echo "$2: $1"
}
check_file(){
path="${1#/}"
path="${path%#*}"
test -f "$path" \
|| test -f "$path".md \
|| (
cd "$(dirname "$2")" && \
test -f "$path" || test -f "$path".md
)
}
check_gemini_link(){
gemget --max-time "$timeout" "$1" -o- >/dev/null
}
check_http_link(){
timeout=$(( timeout + 1 ))
curl --connect-timeout "$timeout" -Is "$1" >/dev/null
}
check_markdown_links(){
find_links "$1" | check_link
}
#################
test -z "$1" && targets="*.md" || targets="$@"
for file in $targets; do
test "${file##*.}" != "md" || check_markdown_links "$file" &
done
wait
The Dependencies Map
A lot of work remains, but right now the dependencies map looks like this:
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β GPG Basics β ββ> β pass β ββ> β pass with otp β
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β
β
β¨
ββββββββββββββββββββββββ
ββββββββββββββββββββββββ> β gpg with vim β
β ββββββββββββββββββββββββ
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β β Kubernetes Setup β ββ> β Kubernetes Basics β ββ> β Kubernetes Docs β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β β
β β
β β¨
β ββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β β virtualbox β <ββ β Managing Groups β β Proxy API β
β ββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β β
β β
β β¨
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β β Docker β ββ> β Ansible with Docker β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β β LaTeX Packages β ββ> β Calendar β β nginx logs with recfiles β <ββββββββββββββββββββββββββββββββββββ
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β§ β
β β β
β β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ β
β β Makefile β ββ> β Recfile Bibliography for TeX β <ββ β TeX β β β ββ> β Board Games with Recfiles β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ β β ββββββββββββββββββββββββββββββ β
β β§ β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Recfiles β β
β β β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β β ββββββββββββββββββββββββββββββ β
β β Makefiles β ββ> β Python Projects with Makefiles β β β ββ> β IP Addresses with Recfiles β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ β
β β β
β β β
β β¨ β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β Shell Scripts β ββ> β Newsraft β β Recfixes β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β
β β Taskwarrior β ββ> β Taskwarrior Configuration β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β
β β β
β β β
β β¨ β
β ββββββββββββββββββββββββ β
β β Taskwarrior Contexts β β
β ββββββββββββββββββββββββ β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β
β β certbot β ββ> β radicale and nginx β <ββββββ β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β β
β β cron β ββ> β Search System β β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β β
β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ β
β β β β¨ β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β β ββ> β Soft Serve Maintenance β <ββ β β ββ> β Soft Serve through https β β
β β β ββββββββββββββββββββββββββββββββββ β β ββββββββββββββββββββββββββββ β
β β β β β β
β β git β βββββββββββββββββββββββββββββββββββββββββ β nginx β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β β β β
β β β ββββββββββββββββββββββββββββββββββ β β β ββββββββββββββββββββββββββββ
β β β ββ> β git stash β β β β ββ> β Soft-Serve β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ β ββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β β β β§
β β βββββββββββββββββββββββββββββββββ
β β¨
β ββββββββββββββββββββββββ
β β git-lfs β
β ββββββββββββββββββββββββ
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β β partitions β ββ> β Install Arch β <ββ β time β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β¨
β ββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β β ssh-tricks β <ββ β ssh β ββ> β Ansible Basics β β sshfs β
β ββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β β
β β
β β¨
β ββββββββββββββββββββββββ
β β fail2ban β
β ββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββ
β
ββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β vim linewrap β <ββ β β ββ> β How to Learn `vim` β
ββββββββββββββββββ β β ββββββββββββββββββββββ
ββββββββββββββββββ β β ββββββββββββββββββββββ
β vim navigation β <ββ β vim basics β ββ> β find and replace β
ββββββββββββββββββ β β ββββββββββββββββββββββ
ββββββββββββββββββ β β ββββββββββββββββββββββ
β vim windows β <ββ β β ββ> β sc-im β
ββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ
β β
β β
β¨ β¨
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β vim completion β β vim in bash β
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
[i]
[ii]
[iii]
[iv]
[v]
[vi]
[vii]
[viii]
[ix]
[x]
[xi]
[xii]
~~~~~~~~
[1] My favourite reader is mdless (which is just a link to mdcat -p).