Vimwiki

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.


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 you home-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.

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

ZEKAR


2025-05-22