From 9feb535acecac26338f481812eebb5368071ac34 Mon Sep 17 00:00:00 2001 From: Arpit Chakladar Date: Sat, 10 Oct 2026 05:35:42 +0530 Subject: feat(office/khal): support multiple calendars --- modules/office/khal/assertions.nix | 20 ++++++++++++++ modules/office/khal/default.nix | 56 ++++++++++++++++++++++++++++++++++---- users/arpit/default.nix | 3 ++ 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 modules/office/khal/assertions.nix diff --git a/modules/office/khal/assertions.nix b/modules/office/khal/assertions.nix new file mode 100644 index 0000000..bda7797 --- /dev/null +++ b/modules/office/khal/assertions.nix @@ -0,0 +1,20 @@ +# Validates the configured khal calendars. +{ config, lib, ... }: +let + cfg = config.office.khal; + primaryCalendars = builtins.filter (calendar: calendar.primary) (builtins.attrValues cfg.calendars); +in +{ + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = cfg.calendars != { }; + message = "office.khal.enable requires at least one office.khal.calendars entry."; + } + { + assertion = builtins.length primaryCalendars == 1; + message = "Exactly one office.khal.calendars entry must set primary = true."; + } + ]; + }; +} diff --git a/modules/office/khal/default.nix b/modules/office/khal/default.nix index 8d924f5..307641f 100644 --- a/modules/office/khal/default.nix +++ b/modules/office/khal/default.nix @@ -10,8 +10,27 @@ let icons = config.desktop.icons.apps; calendarPath = "${config.xdg.dataHome}/khal/calendars"; base16Colors = import ../../colors/base16 { inherit config lib pkgs; }; + calendarNames = builtins.attrNames cfg.calendars; + usableColors = with base16Colors.colorsWithHashPrefix; [ + base08 + base09 + base0A + base0B + base0C + base0D + base0E + base0F + ]; + calendarColors = builtins.listToAttrs ( + lib.imap0 (index: name: { + inherit name; + value = builtins.elemAt usableColors (lib.mod index (builtins.length usableColors)); + }) calendarNames + ); in { + imports = [ ./assertions.nix ]; + options.office.khal = { enable = lib.mkEnableOption "khal, a CLI calendar application"; package = lib.mkOption { @@ -20,6 +39,28 @@ in default = config.programs.khal.package; description = "The khal package to use."; }; + calendars = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: { + options = { + read-only = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether khal may modify this calendar."; + }; + primary = lib.mkOption { + type = lib.types.bool; + default = name == "personal"; + description = "Whether khal should use this calendar for new events by default."; + }; + }; + } + ) + ); + default.personal = { }; + description = "Named vdir calendars managed by khal."; + }; }; config = lib.mkIf cfg.enable { @@ -33,10 +74,10 @@ in longdatetimeformat = "%Y-%m-%d %H:%M"; }; settings.default = { - default_calendar = "personal"; default_dayevent_duration = "1d"; default_event_duration = "1h"; enable_mouse = true; + highlight_event_days = false; timedelta = "2d"; }; settings.view.theme = "dark"; @@ -44,13 +85,18 @@ in accounts.calendar = { basePath = calendarPath; - accounts.personal = { + accounts = lib.mapAttrs (_name: calendar: { + primary = calendar.primary; khal = { enable = true; - color = base16Colors.colorsWithHashPrefix.base0D; + color = calendarColors.${_name}; + readOnly = calendar.read-only; }; - local.type = "filesystem"; - }; + local = { + path = "${calendarPath}/${_name}"; + type = "filesystem"; + }; + }) cfg.calendars; }; xdg.desktopEntries."khal" = lib.mkIf (config.terminal.kitty.enable && cfg.package != null) { diff --git a/users/arpit/default.nix b/users/arpit/default.nix index de168be..5c7eb32 100644 --- a/users/arpit/default.nix +++ b/users/arpit/default.nix @@ -67,6 +67,9 @@ # Office office.khal.enable = true; + office.khal.calendars.personal = { + primary = true; + }; office.zathura.enable = true; # Security -- cgit v1.2.3