Setting Up VimWiki with when
: My Minimalist Agenda Workflow
I haven’t written a blog post in a while, so… yeah, here we are again.
This time, I’m sharing how I’ve set up a minimal personal agenda system using vimwiki
and when
, a lean calendar application that fits the Unix philosophy—do one thing, and do it well.
⚠️ This isn’t a guide, just me documenting my setup, quirks and all. Nonetheless, read on.
Why when
?
We’ll be using when
instead of something like calcurse
. I tried calcurse for a bit but… Meh, its interface isn’t for me. I wanted something simpler, something that plays well with vimwiki
.
Directory Layout
Here’s the folder structure for my life/
directory, which I sync via Syncthing:
~/Documents/life/
├── diary/
│ └── 2025-05-21.md
├── calendar/ # Symlinked from $XDG_CONFIG_HOME/when/
│ ├── overrides.wiki
│ └── calendar.wiki
└── scripts/
└── agenda.sh # Used to insert `when` output into vimwiki
The goal here is to keep everything related to my notes, schedule, and life in one tidy place. And of course, sync it across devices seamlessly.
Declarative Symlinks with Home Manager
Sure, I could create a symlink manually:
ln -s ~/Documents/life/calendar ~/.config/when
But come on—we’re on NixOS. We don’t do imperative here. Here’s how to make it declarative with home-manager
:
{
home.activation.symlinkWhen = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
target="$HOME/Documents/life/calendar"
link="$HOME/.config/when"
if [ -L "$link" ] || [ -e "$link" ]; then
rm -rf "$link"
fi
ln -s "$target" "$link"
'';
}
Breakdown
-
home.activation.symlinkWhen
: Custom activation step that runs when youhome-manager switch
. -
lib.hm.dag.entryAfter [ "writeBoundary" ]
: Ensures the symlink is created after files are written. -
Shell logic:
- Set variables:
target="$HOME/Documents/life/calendar"
link="$HOME/.config/when"
- If the link (or file) exists, remove it.
- Create the new symlink.
- Set variables:
Result: After activation, ~/.config/when
is a symlink to your calendar folder.
When Tools Ignore Their Own Man Pages
So, according to when
’s man page, config files can live in several places, following the XDG spec:
${WHEN_CONFIG_HOME}/preferences
${XDG_CONFIG_HOME}/when/preferences
$HOME/.config/when/preferences
$HOME/.when/preferences
Great! So I created the file:
touch ~/.config/when/preferences
Then ran:
when
And got this prompt:
You can now set up your calendar. This involves creating a directory ~/.when...
Wait, what?
Maybe it’s because the file is empty? So I went ahead and let when
create its stuff the way it wants to:
when
y
nvim
Then moved it manually:
mv ~/.when/* ~/.config/when
Verified contents:
ls ~/.config/when
# calendar preferences
Tried again:
when
# Still prompts to create ~/.when
Sigh.
Maybe the Environment Variable?
export WHEN_CONFIG_HOME="$HOME/.config/when"
when
# Still no luck
Goodbye XDG
So yeah, despite what the man page says, when
doesn’t seem to honor XDG_CONFIG_HOME
or WHEN_CONFIG_HOME
. Back to messy $HOME
we go.
To keep things working, I updated the symlink to point to ~/.when
instead:
{
home.activation.symlinkWhen = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
target="$HOME/Documents/life/calendar"
link="$HOME/.when"
if [ -L "$link" ] || [ -e "$link" ]; then
rm -rf "$link"
fi
ln -s "$target" "$link"
'';
}
Despite the hiccups, I still love when
. It’s minimal, extensible, and scriptable. I just wish its advertised XDG support worked. (If you know a fix—please reach out!)
A Test Event: Does This Actually Work?
Time to see if the setup behaves as expected.
Added this line to calendar
:
w=Fri, 12:00 Class with Mr Thompson
Then ran:
when c m
Output:
tomorrow 2025 May 23 12:00 Class with Mr Thompson
Fri 2025 May 30 12:00 Class with Mr Thompson
Perfect.
Integrating when
with VimWiki
To display this in my vimwiki
, I’m adding a == Calendar ==
section in index.wiki
. Then I use a script to inject the output from when
.
Here’s the script:
#!/bin/sh
# File to modify
file="../index.wiki"
# Generate calendar output
custom_text="$(when c m)"
# Find line number for '== Calendar =='
line_num=$(grep -n '== Calendar ==' "$file" | cut -d: -f1 | tail -n 1)
if [ -n "$line_num" ]; then
tmp_file="$(mktemp)"
head -n "$line_num" "$file" >"$tmp_file"
echo >>"$tmp_file"
echo "$custom_text" >>"$tmp_file"
mv "$tmp_file" "$file"
else
echo "No line containing '== Calendar ==' found." >&2
exit 1
fi
After running this, the calendar section in my wiki updates automatically.
Conclusion
That’s it! My little setup for a VimWiki + when
calendar integration is complete.
It’s:
- Minimal
- Scriptable
- Easy to sync
- Fits into my notes without clutter
I’ll improve it as I go—and if any big changes come, maybe I’ll write a follow-up post.
Btw, being such a simple, useful and underground tool. I might as well do a Rust rewrite. Let’s add it to the TODO list on our VimWiki :::::v