{ pkgs, config, lib, ... }: with lib; let calwatcher = (pkgs.writeShellApplication { name = "calwatcher"; runtimeInputs = [ pkgs.inotify-tools pkgs.khal pkgs.jq ]; text = '' # in parts ripped from https://git.sr.ht/~whynothugo/dotfiles/tree/3768ec57/item/home/.local/lib/waybar-khal render() { # Find events starting in two minutes. # So if my current event ends in two minutes and another one starts, the # widget is already updated with what's upcoming. SINCE="$(date -d 'now +2 min' '+%FT%H:%M:%S')" UNTIL="1d" EVENT="$( khal list "$SINCE" "$UNTIL" \ --day-format 'SKIPME' \ --format "{start-end-time-style} {title:.31}{repeat-symbol}" | grep -v SKIPME | # filter out headers grep -v -P '↦|↔ |⇥' | # filter out continuing all day events grep -v '^ ' | # exclude full-day events head -n 1 # show just the first )" if [ -z "$EVENT" ]; then TEXT=" (nothing upcoming)" CLASS="no-event" else TEXT=" $EVENT" CLASS="event" fi jq --compact-output \ --null-input \ --arg text "$TEXT" \ --arg class "$CLASS" \ --arg tooltip "$(khal list today 7d --day-format '{name} {date-long}')" \ '{"text": $text, "class": $class, "tooltip": $tooltip}' } render # Render once for initial state. # In order to make sure events are updated as time passes, this re-renderes # every two minutes. That aside, whenever a calendar event changes, we alreays # re-render immediately. # # It would be ideal to determine _when_ the current event ends, and set the # timeout accordinly. That would require parsing khal's output a bit more. while true; do # (inotifywait \ # --event modify \ # --event create \ # --event delete \ # --event close_write \ # --event moved_to \ # --event move \ # --monitor \ # --timeout 120 \ # --recursive \ # "$HOME/.calendars" 2> /dev/null) || true | \ # while read -r _; do # TODO: fix inotify stuff render sleep 30 # timeout 3 cat || true # debounce for 3s, https://stackoverflow.com/a/69945839 # done done ''; }) + "/bin/calwatcher"; in lib.mkIf (config.xyno.user-services.khal.enable) { xyno.desktop.waybar.config = { "custom/cal" = { exec = calwatcher; restart-interval = 5; return-type = "json"; "on-click" = "${pkgs.foot}/bin/footclient --app-id floating-alacritty ${pkgs.khal}/bin/ikhal"; }; modules-right = mkOrder 1999 [ "custom/cal" ]; # left of clock, right of everything else }; }