diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 52f956d1..174a7d36 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -506,4 +506,10 @@ github = "britter"; githubId = 1327662; }; + zorrobert = { + name = "zorrobert"; + email = "zorrobert@mailbox.org"; + github = "zorrobert"; + githubId = 118135271; + }; } diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 5a40f60c..849ac942 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1436,6 +1436,13 @@ in { A new module is available: 'programs.ranger'. ''; } + + { + time = "2024-03-13T13:28:22+00:00"; + message = '' + A new module is available: 'programs.joplin-desktop'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index ec2af169..fc8154e9 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -124,6 +124,7 @@ let ./programs/jq.nix ./programs/jujutsu.nix ./programs/joshuto.nix + ./programs/joplin-desktop.nix ./programs/just.nix ./programs/k9s.nix ./programs/kakoune.nix diff --git a/modules/programs/joplin-desktop.nix b/modules/programs/joplin-desktop.nix new file mode 100644 index 00000000..fe46ebad --- /dev/null +++ b/modules/programs/joplin-desktop.nix @@ -0,0 +1,124 @@ +{ config, lib, pkgs, ... }: + +let + + cfg = config.programs.joplin-desktop; + + jsonFormat = pkgs.formats.json { }; + + # config path is the same for linux and mac + configPath = "${config.xdg.configHome}/joplin-desktop/settings.json"; + +in { + meta.maintainers = [ lib.maintainers.zorrobert ]; + + options.programs.joplin-desktop = { + enable = lib.mkEnableOption "joplin-desktop"; + + package = lib.mkPackageOption pkgs "joplin-desktop" { }; + + extraConfig = lib.mkOption { + type = lib.types.attrs; + default = { }; + example = { + "newNoteFocus" = "title"; + "markdown.plugin.mark" = true; + }; + description = '' + Use this to add other options to the Joplin config file. Settings are + written in JSON, so `"sync.interval": 600` would be written as + `"sync.interval" = 600`. + ''; + }; + + ### General + general = { + editor = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "kate"; + description = '' + The editor command (may include arguments) that will be used to open a + note. If none is provided Joplin will try to auto-detect the default + editor. + ''; + }; + }; + + ### Sync + sync = { + target = lib.mkOption { + type = lib.types.enum [ + null + "none" + "file-system" + "onedrive" + "nextcloud" + "webdav" + "dropbox" + "s3" + "joplin-server" + "joplin-cloud" + ]; + default = null; + example = "dropbox"; + description = "What is the type of sync target."; + }; + + interval = lib.mkOption { + type = + lib.types.enum [ null "disabled" "5m" "10m" "30m" "1h" "12h" "1d" ]; + default = null; + example = "10m"; + description = '' + Set the synchronisation interval. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ cfg.package ]; + + home.activation = { + activateJoplinDesktopConfig = let + newConfig = jsonFormat.generate "joplin-settings.json" + (lib.attrsets.filterAttrs (n: v: (v != null) && (v != "")) ({ + # TODO: find a better way to convert nix attribute names to strings: + # sync.interval = ... -> "sync.interval" = ... + + "editor" = cfg.general.editor; + + "sync.target" = { + "none" = 0; + "file-system" = 2; + "onedrive" = 3; + "nextcloud" = 5; + "webdav" = 6; + "dropbox" = 7; + "s3" = 8; + "joplin-server" = 9; + "joplin-cloud" = 10; + }.${cfg.sync.target} or null; + + "sync.interval" = { + "disabled" = 0; + "5m" = 300; + "10m" = 600; + "30m" = 1800; + "1h" = 3600; + "12h" = 43200; + "1d" = 86400; + }.${cfg.sync.interval} or null; + } // cfg.extraConfig)); + in lib.hm.dag.entryAfter [ "linkGeneration" ] '' + # Ensure that settings.json exists. + touch ${configPath} + # Config has to be written to temporary variable because jq cannot edit files in place. + config="$(jq -s '.[0] + .[1]' ${configPath} ${newConfig})" + printf '%s\n' "$config" > ${configPath} + unset config + ''; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 5084d2d1..84ea67de 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -88,6 +88,7 @@ in import nmtSrc { ./modules/programs/i3status ./modules/programs/irssi ./modules/programs/jujutsu + ./modules/programs/joplin-desktop ./modules/programs/k9s ./modules/programs/kakoune ./modules/programs/khal diff --git a/tests/modules/programs/joplin-desktop/basic-configuration.json b/tests/modules/programs/joplin-desktop/basic-configuration.json new file mode 100644 index 00000000..63e105ae --- /dev/null +++ b/tests/modules/programs/joplin-desktop/basic-configuration.json @@ -0,0 +1,6 @@ +{ + "newNoteFocus": "title", + "richTextBannerDismissed": true, + "sync.interval": 600, + "sync.target": 7 +} diff --git a/tests/modules/programs/joplin-desktop/basic-configuration.nix b/tests/modules/programs/joplin-desktop/basic-configuration.nix new file mode 100644 index 00000000..9f986798 --- /dev/null +++ b/tests/modules/programs/joplin-desktop/basic-configuration.nix @@ -0,0 +1,23 @@ +{ + programs.joplin-desktop = { + enable = true; + sync = { + target = "dropbox"; + interval = "10m"; + }; + extraConfig = { + "richTextBannerDismissed" = true; + "newNoteFocus" = "title"; + }; + }; + + test.stubs.joplin-desktop = { }; + + nmt.script = '' + assertFileContains activate \ + '/home/hm-user/.config/joplin-desktop/settings.json' + + generated="$(grep -o '/nix/store/.*-joplin-settings.json' $TESTED/activate)" + diff -u "$generated" ${./basic-configuration.json} + ''; +} diff --git a/tests/modules/programs/joplin-desktop/default.nix b/tests/modules/programs/joplin-desktop/default.nix new file mode 100644 index 00000000..3ccd7320 --- /dev/null +++ b/tests/modules/programs/joplin-desktop/default.nix @@ -0,0 +1 @@ +{ joplin-desktop-basic-configuration = ./basic-configuration.nix; }