2023-06-12 23:21:24 +02:00
|
|
|
# khal config loader is sensitive to leading space !
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.programs.khal;
|
|
|
|
|
2023-08-30 11:57:47 +02:00
|
|
|
iniFormat = pkgs.formats.ini { };
|
|
|
|
|
2023-06-12 23:21:24 +02:00
|
|
|
khalCalendarAccounts =
|
|
|
|
filterAttrs (_: a: a.khal.enable) config.accounts.calendar.accounts;
|
|
|
|
|
2024-03-03 18:12:42 +01:00
|
|
|
# a contact account may have multiple collections, each a separate calendar
|
|
|
|
expandContactAccount = name: acct:
|
|
|
|
if acct.khal.collections != null then
|
|
|
|
listToAttrs (map (c: {
|
|
|
|
name = "${name}-${c}";
|
|
|
|
value = recursiveUpdate acct { khal.thisCollection = c; };
|
|
|
|
}) acct.khal.collections)
|
|
|
|
else {
|
|
|
|
${name} = acct;
|
|
|
|
};
|
|
|
|
|
|
|
|
khalContactAccounts = concatMapAttrs expandContactAccount
|
|
|
|
(mapAttrs (_: v: recursiveUpdate v { khal.type = "birthdays"; })
|
|
|
|
(filterAttrs (_: a: a.khal.enable) config.accounts.contact.accounts));
|
2023-06-12 23:21:24 +02:00
|
|
|
|
|
|
|
khalAccounts = khalCalendarAccounts // khalContactAccounts;
|
|
|
|
|
|
|
|
primaryAccount = findSingle (a: a.primary) null null
|
2024-03-03 18:12:42 +01:00
|
|
|
(mapAttrsToList (n: v: v // { name = n; }) khalCalendarAccounts);
|
2023-06-12 23:21:24 +02:00
|
|
|
|
|
|
|
definedAttrs = filterAttrs (_: v: !isNull v);
|
|
|
|
|
|
|
|
toKeyValueIfDefined = attrs: generators.toKeyValue { } (definedAttrs attrs);
|
|
|
|
|
|
|
|
genCalendarStr = name: value:
|
|
|
|
concatStringsSep "\n" ([
|
|
|
|
"[[${name}]]"
|
|
|
|
"path = ${
|
|
|
|
value.local.path + "/"
|
|
|
|
+ (optionalString (value.khal.type == "discover") value.khal.glob)
|
2024-03-03 18:12:42 +01:00
|
|
|
+ (optionalString
|
|
|
|
(value.khal.type == "birthdays" && value.khal ? thisCollection)
|
|
|
|
value.khal.thisCollection)
|
2023-06-12 23:21:24 +02:00
|
|
|
}"
|
|
|
|
] ++ optional (value.khal.readOnly) "readonly = True" ++ [
|
|
|
|
(toKeyValueIfDefined (getAttrs [ "type" "color" "priority" ] value.khal))
|
|
|
|
] ++ [ "\n" ]);
|
|
|
|
|
2023-07-01 00:35:51 +02:00
|
|
|
localeFormatOptions = let
|
|
|
|
T = lib.types;
|
|
|
|
suffix = ''
|
|
|
|
Format strings are for Python `strftime`, similarly to
|
|
|
|
{manpage}`strftime(3)`.
|
|
|
|
'';
|
|
|
|
in {
|
|
|
|
dateformat = mkOption {
|
|
|
|
type = T.str;
|
|
|
|
default = "%x";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
khal will display and understand all dates in this format.
|
|
|
|
|
|
|
|
${suffix}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
timeformat = mkOption {
|
|
|
|
type = T.str;
|
|
|
|
default = "%X";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
khal will display and understand all times in this format.
|
|
|
|
|
|
|
|
${suffix}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
datetimeformat = mkOption {
|
|
|
|
type = T.str;
|
|
|
|
default = "%c";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
khal will display and understand all datetimes in this format.
|
|
|
|
|
|
|
|
${suffix}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
longdateformat = mkOption {
|
|
|
|
type = T.str;
|
|
|
|
default = "%x";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
khal will display and understand all dates in this format.
|
|
|
|
It should contain a year (e.g. `%Y`).
|
|
|
|
|
|
|
|
${suffix}
|
|
|
|
'';
|
|
|
|
};
|
2023-06-12 23:21:24 +02:00
|
|
|
|
2023-07-01 00:35:51 +02:00
|
|
|
longdatetimeformat = mkOption {
|
|
|
|
type = T.str;
|
|
|
|
default = "%c";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
khal will display and understand all datetimes in this format.
|
|
|
|
It should contain a year (e.g. `%Y`).
|
|
|
|
|
|
|
|
${suffix}
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
|
|
|
};
|
2023-07-01 00:35:51 +02:00
|
|
|
};
|
2023-06-12 23:21:24 +02:00
|
|
|
|
|
|
|
localeOptions = let T = lib.types;
|
|
|
|
in localeFormatOptions // {
|
2023-07-01 00:35:51 +02:00
|
|
|
unicode_symbols = mkOption {
|
2023-06-12 23:21:24 +02:00
|
|
|
type = T.bool;
|
|
|
|
default = true;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
By default khal uses some Unicode symbols (as in "non-ASCII") as
|
2023-06-12 23:21:24 +02:00
|
|
|
indicators for things like repeating events.
|
|
|
|
If your font, encoding etc. does not support those symbols, set this
|
2023-07-01 00:35:51 +02:00
|
|
|
to false (this will enable ASCII-based replacements).
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2023-07-01 00:35:51 +02:00
|
|
|
default_timezone = mkOption {
|
2023-06-12 23:21:24 +02:00
|
|
|
type = T.nullOr T.str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-06-12 23:21:24 +02:00
|
|
|
Default for new events or if khal does not understand the timezone
|
|
|
|
in an ical file.
|
2023-07-01 00:35:51 +02:00
|
|
|
If `null`, the timezone of your computer will be used.
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2023-07-01 00:35:51 +02:00
|
|
|
local_timezone = mkOption {
|
2023-06-12 23:21:24 +02:00
|
|
|
type = T.nullOr T.str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-06-12 23:21:24 +02:00
|
|
|
khal will show all times in this timezone.
|
2023-07-01 00:35:51 +02:00
|
|
|
If `null`, the timezone of your computer will be used.
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2023-07-01 00:35:51 +02:00
|
|
|
firstweekday = mkOption {
|
2023-06-12 23:21:24 +02:00
|
|
|
type = T.ints.between 0 6;
|
|
|
|
default = 0;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
The first day of the week, where Monday is 0 and Sunday is 6.
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2023-07-01 00:35:51 +02:00
|
|
|
weeknumbers = mkOption {
|
2023-06-12 23:21:24 +02:00
|
|
|
type = T.enum [ "off" "left" "right" ];
|
|
|
|
default = "off";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 00:35:51 +02:00
|
|
|
Enable week numbers in calendar and interactive (ikhal) mode.
|
|
|
|
As those are ISO week numbers, they only work properly if
|
|
|
|
{option}`firstweekday` is set to 0.
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
in {
|
|
|
|
options.programs.khal = {
|
2023-07-02 01:45:18 +02:00
|
|
|
enable = mkEnableOption "khal, a CLI calendar application";
|
2023-08-30 11:57:47 +02:00
|
|
|
|
2023-06-12 23:21:24 +02:00
|
|
|
locale = mkOption {
|
2023-07-01 00:35:51 +02:00
|
|
|
type = lib.types.submodule { options = localeOptions; };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2024-03-03 18:12:42 +01:00
|
|
|
khal locale settings.
|
2023-06-12 23:21:24 +02:00
|
|
|
'';
|
2023-08-12 17:21:13 +02:00
|
|
|
default = { };
|
2023-06-12 23:21:24 +02:00
|
|
|
};
|
2023-08-30 11:57:47 +02:00
|
|
|
|
|
|
|
settings = mkOption {
|
|
|
|
type = iniFormat.type;
|
|
|
|
default = { };
|
|
|
|
example = literalExpression ''
|
|
|
|
{
|
|
|
|
default = {
|
|
|
|
default_calendar = "Calendar";
|
|
|
|
timedelta = "5d";
|
|
|
|
};
|
|
|
|
view = {
|
|
|
|
agenda_event_format =
|
|
|
|
"{calendar-color}{cancelled}{start-end-time-style} {title}{repeat-symbol}{reset}";
|
|
|
|
};
|
|
|
|
}'';
|
|
|
|
description = ''
|
|
|
|
Configuration options to add to the various sections in the configuration file.
|
|
|
|
'';
|
|
|
|
};
|
2023-06-12 23:21:24 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
home.packages = [ pkgs.khal ];
|
|
|
|
|
|
|
|
xdg.configFile."khal/config".text = concatStringsSep "\n" ([ "[calendars]" ]
|
|
|
|
++ mapAttrsToList genCalendarStr khalAccounts ++ [
|
2023-08-30 11:57:47 +02:00
|
|
|
(generators.toINI { } (recursiveUpdate cfg.settings {
|
2023-08-12 17:21:13 +02:00
|
|
|
locale = definedAttrs (cfg.locale // { _module = null; });
|
2023-06-12 23:21:24 +02:00
|
|
|
|
|
|
|
default = optionalAttrs (!isNull primaryAccount) {
|
2023-07-04 12:14:47 +02:00
|
|
|
highlight_event_days = true;
|
2023-06-12 23:21:24 +02:00
|
|
|
default_calendar = if isNull primaryAccount.primaryCollection then
|
|
|
|
primaryAccount.name
|
|
|
|
else
|
|
|
|
primaryAccount.primaryCollection;
|
|
|
|
};
|
2023-08-30 11:57:47 +02:00
|
|
|
}))
|
2023-06-12 23:21:24 +02:00
|
|
|
]);
|
|
|
|
};
|
|
|
|
}
|