From 0e8f5b3fbea5caf3118c0a9b0040d4b06ac32569 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Tue, 18 Feb 2025 11:28:14 +0000 Subject: [PATCH] Add obsidian home-manager module Signed-off-by: Nikolaos Karaolidis --- flake.lock | 6 +- .../configs/user/gui/obsidian/default.nix | 2 - .../configs/user/gui/obsidian/options.nix | 516 ------------------ submodules/home-manager | 2 +- 4 files changed, 4 insertions(+), 522 deletions(-) delete mode 100644 hosts/common/configs/user/gui/obsidian/options.nix diff --git a/flake.lock b/flake.lock index 4fe6990..8e5eb29 100644 --- a/flake.lock +++ b/flake.lock @@ -115,11 +115,11 @@ ] }, "locked": { - "lastModified": 1739845242, - "narHash": "sha256-rNMXpDubNWGLTs45MuoH9YHtXfXye/fn2u4YMSTPt9I=", + "lastModified": 1739877460, + "narHash": "sha256-0R74c61IDiLAi5xaAF4xUXHS5eQwYteJDGRIDU/L4sM=", "owner": "karaolidis", "repo": "home-manager", - "rev": "5cfbf5cc37a3bd1da07ae84eea1b828909c4456b", + "rev": "3cf2f577ce131fca013dd4d94dca3639561a72b4", "type": "github" }, "original": { diff --git a/hosts/common/configs/user/gui/obsidian/default.nix b/hosts/common/configs/user/gui/obsidian/default.nix index 6f1b27b..3078bea 100644 --- a/hosts/common/configs/user/gui/obsidian/default.nix +++ b/hosts/common/configs/user/gui/obsidian/default.nix @@ -15,8 +15,6 @@ in environment.persistence."/cache"."${home}/.config/obsidian" = { }; home-manager.users.${user} = { - imports = [ ./options.nix ]; - programs.obsidian = { enable = true; diff --git a/hosts/common/configs/user/gui/obsidian/options.nix b/hosts/common/configs/user/gui/obsidian/options.nix deleted file mode 100644 index 89a9ec3..0000000 --- a/hosts/common/configs/user/gui/obsidian/options.nix +++ /dev/null @@ -1,516 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -let - cfg = config.programs.obsidian; - - corePlugins = [ - "audio-recorder" - "backlink" - "bookmarks" - "canvas" - "command-palette" - "daily-notes" - "editor-status" - "file-explorer" - "file-recovery" - "global-search" - "graph" - "markdown-importer" - "note-composer" - "outgoing-link" - "outline" - "page-preview" - "properties" - "publish" - "random-note" - "slash-command" - "slides" - "switcher" - "sync" - "tag-pane" - "templates" - "word-count" - "workspaces" - "zk-prefixer" - ]; -in -{ - options.programs.obsidian = - with lib; - with types; - { - enable = mkEnableOption "obsidian"; - package = mkPackageOption pkgs "obsidian" { }; - - defaultSettings = { - app = mkOption { - description = "Settings to write to app.json."; - type = raw; - default = { }; - }; - - appearance = mkOption { - description = "Settings to write to appearance.json."; - type = raw; - default = { }; - }; - - corePlugins = mkOption { - description = "Core plugins to activate."; - type = raw; - default = [ - "backlink" - "bookmarks" - "canvas" - "command-palette" - "daily-notes" - "editor-status" - "file-explorer" - "file-recovery" - "global-search" - "graph" - "note-composer" - "outgoing-link" - "outline" - "page-preview" - "switcher" - "tag-pane" - "templates" - "word-count" - ]; - }; - - communityPlugins = mkOption { - description = "Community plugins to install and activate."; - type = raw; - default = [ ]; - }; - - cssSnippets = mkOption { - description = "CSS snippets to install."; - type = raw; - default = [ ]; - }; - - themes = mkOption { - description = "Themes to install."; - type = raw; - default = [ ]; - }; - - hotkeys = mkOption { - description = "Hotkeys to configure."; - type = raw; - default = { }; - }; - - extraFiles = mkOption { - description = "Extra files to link to the vault directory."; - type = raw; - default = { }; - }; - }; - - vaults = mkOption { - description = "List of vaults to create."; - type = attrsOf ( - submodule ( - { name, config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether this vault should be generated."; - }; - - target = mkOption { - type = str; - defaultText = literalExpression "name"; - description = "Path to target vault relative to the user's {env}`HOME`."; - }; - - settings = { - app = mkOption { - description = "Settings to write to app.json."; - type = attrsOf anything; - default = cfg.defaultSettings.app; - }; - - appearance = mkOption { - description = "Settings to write to appearance.json."; - type = attrsOf anything; - default = cfg.defaultSettings.appearance; - }; - - corePlugins = - let - corePluginsOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to enable the plugin."; - }; - - name = mkOption { - type = enum corePlugins; - description = "The plugin."; - }; - - options = mkOption { - type = attrsOf anything; - description = "Plugin options to include."; - default = { }; - }; - }; - }; - in - mkOption { - description = "Core plugins to activate."; - type = listOf (coercedTo (enum corePlugins) (p: { name = p; }) (submodule corePluginsOptions)); - default = cfg.defaultSettings.corePlugins; - }; - - communityPlugins = - let - communityPluginsOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to enable the plugin."; - }; - - pkg = mkOption { - type = package; - description = "The plugin package."; - }; - - options = mkOption { - type = attrsOf anything; - description = "Options to include in the plugin's `data.json`."; - default = { }; - }; - }; - }; - in - mkOption { - description = "Community plugins to install and activate."; - type = listOf (coercedTo package (p: { pkg = p; }) (submodule communityPluginsOptions)); - default = cfg.defaultSettings.communityPlugins; - }; - - cssSnippets = - let - checkCssPath = path: lib.filesystem.pathIsRegularFile path && lib.strings.hasSuffix ".css" path; - toCssName = path: lib.strings.removeSuffix ".css" (builtins.baseNameOf path); - cssSnippetsOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to enable the snippet."; - }; - - name = mkOption { - type = str; - defaultText = literalExpression "lib.strings.removeSuffix \".css\" (builtins.baseNameOf source)"; - description = "Name of the snippet."; - }; - - source = mkOption { - type = nullOr (addCheck path checkCssPath); - description = "Path of the source file."; - default = null; - }; - - text = mkOption { - type = nullOr str; - description = "Text of the file."; - default = null; - }; - }; - - config.name = mkDefault (toCssName config.source); - }; - in - mkOption { - description = "CSS snippets to install."; - type = listOf ( - coercedTo (addCheck path checkCssPath) (p: { source = p; }) (submodule cssSnippetsOptions) - ); - default = cfg.defaultSettings.cssSnippets; - }; - - themes = - let - themesOptions = - { config, ... }: - { - options = { - enable = mkOption { - type = bool; - default = true; - description = "Whether to set the theme as active."; - }; - - pkg = mkOption { - type = package; - description = "The theme package."; - }; - }; - }; - in - mkOption { - description = "Themes to install."; - type = listOf (coercedTo package (p: { pkg = p; }) (submodule themesOptions)); - default = cfg.defaultSettings.themes; - }; - - hotkeys = - let - hotkeysOptions = - { config, ... }: - { - options = { - modifiers = mkOption { - type = listOf str; - description = "The hotkey modifiers."; - default = [ ]; - }; - - key = mkOption { - type = str; - description = "The hotkey."; - }; - }; - }; - in - mkOption { - description = "Hotkeys to configure."; - type = attrsOf (listOf (submodule hotkeysOptions)); - default = cfg.defaultSettings.hotkeys; - }; - - extraFiles = - let - extraFilesOptions = - { name, config, ... }: - { - options = { - source = mkOption { - type = nullOr path; - description = "Path of the source file or directory."; - default = null; - }; - - text = mkOption { - type = nullOr str; - description = "Text of the file."; - default = null; - }; - - target = mkOption { - type = str; - defaultText = literalExpression "name"; - description = "Path to target relative to the vault's directory."; - }; - }; - - config.target = mkDefault name; - }; - in - mkOption { - description = "Extra files to link to the vault directory."; - type = attrsOf (submodule extraFilesOptions); - default = cfg.defaultSettings.extraFiles; - }; - }; - }; - - config.target = mkDefault name; - } - ) - ); - default = { }; - }; - }; - - config = - let - vaults = builtins.filter (vault: vault.enable == true) (builtins.attrValues cfg.vaults); - getManifest = - item: - let - manifest = builtins.fromJSON (builtins.readFile "${item.pkg}/manifest.json"); - in - manifest.id or manifest.name; - in - lib.mkIf cfg.enable { - home = { - packages = [ cfg.package ]; - - file = - let - mkApp = vault: { - name = "${vault.target}/.obsidian/app.json"; - value.source = (pkgs.formats.json { }).generate "app.json" vault.settings.app; - }; - - mkAppearance = vault: { - name = "${vault.target}/.obsidian/appearance.json"; - value = - let - enabledCssSnippets = builtins.filter (snippet: snippet.enable) vault.settings.cssSnippets; - activeTheme = lib.lists.findSingle ( - theme: theme.enable - ) null (throw "Only one theme can be enabled at a time.") vault.settings.themes; - in - { - source = (pkgs.formats.json { }).generate "appearance.json" ( - vault.settings.appearance - // { - enabledCssSnippets = builtins.map (snippet: snippet.name) enabledCssSnippets; - } - // lib.attrsets.optionalAttrs (activeTheme != null) { cssTheme = getManifest activeTheme; } - ); - }; - }; - - mkCorePlugins = - vault: - [ - { - name = "${vault.target}/.obsidian/core-plugins.json"; - value.source = (pkgs.formats.json { }).generate "core-plugins.json" ( - builtins.map (plugin: plugin.name) vault.settings.corePlugins - ); - } - { - name = "${vault.target}/.obsidian/core-plugins-migration.json"; - value.source = (pkgs.formats.json { }).generate "core-plugins-migration.json" ( - builtins.listToAttrs ( - builtins.map (name: { - inherit name; - value = builtins.any (plugin: name == plugin.name && plugin.enable) vault.settings.corePlugins; - }) corePlugins - ) - ); - } - ] - ++ builtins.map (plugin: { - name = "${vault.target}/.obsidian/${plugin.name}.json"; - value.source = (pkgs.formats.json { }).generate "${plugin.name}.json" plugin.options; - }) (builtins.filter (plugin: plugin.options != { }) vault.settings.corePlugins); - - mkCommunityPlugins = - vault: - [ - { - name = "${vault.target}/.obsidian/community-plugins.json"; - value.source = (pkgs.formats.json { }).generate "community-plugins.json" ( - builtins.map getManifest (builtins.filter (plugin: plugin.enable) vault.settings.communityPlugins) - ); - } - ] - ++ builtins.map (plugin: { - name = "${vault.target}/.obsidian/plugins/${getManifest plugin}"; - value = { - source = plugin.pkg; - recursive = true; - }; - }) vault.settings.communityPlugins - ++ builtins.map (plugin: { - name = "${vault.target}/.obsidian/plugins/${getManifest plugin}/data.json"; - value.source = (pkgs.formats.json { }).generate "data.json" plugin.options; - }) (builtins.filter (plugin: plugin.options != { }) vault.settings.communityPlugins); - - mkCssSnippets = - vault: - builtins.map (snippet: { - name = "${vault.target}/.obsidian/snippets/${snippet.name}.css"; - value = - if snippet.source != null then { inherit (snippet) source; } else { inherit (snippet) text; }; - }) vault.settings.cssSnippets; - - mkThemes = - vault: - builtins.map (theme: { - name = "${vault.target}/.obsidian/themes/${getManifest theme}"; - value.source = theme.pkg; - }) vault.settings.themes; - - mkHotkeys = vault: { - name = "${vault.target}/.obsidian/hotkeys.json"; - value.source = (pkgs.formats.json { }).generate "hotkeys.json" vault.settings.hotkeys; - }; - - mkExtraFiles = - vault: - builtins.map (file: { - name = "${vault.target}/.obsidian/${file.target}"; - value = if file.source != null then { inherit (file) source; } else { inherit (file) text; }; - }) (builtins.attrValues vault.settings.extraFiles); - in - builtins.listToAttrs ( - lib.lists.flatten ( - builtins.map (vault: [ - (mkApp vault) - (mkAppearance vault) - (mkCorePlugins vault) - (mkCommunityPlugins vault) - (mkCssSnippets vault) - (mkThemes vault) - (mkHotkeys vault) - (mkExtraFiles vault) - ]) vaults - ) - ); - }; - - xdg.configFile."obsidian/obsidian.json".source = (pkgs.formats.json { }).generate "obsidian.json" { - vaults = builtins.listToAttrs ( - builtins.map (vault: { - name = builtins.hashString "md5" vault.target; - value = { - path = "${config.home.homeDirectory}/${vault.target}"; - } // (lib.attrsets.optionalAttrs ((builtins.length vaults) == 1) { open = true; }); - }) vaults - ); - updateDisabled = true; - }; - - assertions = [ - { - assertion = builtins.all ( - vault: - builtins.all ( - snippet: - (snippet.source == null || snippet.text == null) && (snippet.source != null || snippet.text != null) - ) vault.settings.cssSnippets - ) (builtins.attrValues cfg.vaults); - message = "Each CSS snippet must have one of 'source' or 'text' set"; - } - { - assertion = builtins.all ( - vault: - builtins.all ( - file: (file.source == null || file.text == null) && (file.source != null || file.text != null) - ) (builtins.attrValues vault.settings.extraFiles) - ) (builtins.attrValues cfg.vaults); - message = "Each extra file must have one of 'source' or 'text' set"; - } - ]; - }; -} diff --git a/submodules/home-manager b/submodules/home-manager index 5cfbf5c..3cf2f57 160000 --- a/submodules/home-manager +++ b/submodules/home-manager @@ -1 +1 @@ -Subproject commit 5cfbf5cc37a3bd1da07ae84eea1b828909c4456b +Subproject commit 3cf2f577ce131fca013dd4d94dca3639561a72b4