diff --git a/hosts/common/user/configs/console/xdg/default.nix b/hosts/common/user/configs/console/xdg/default.nix index b4eb3a5..fe24a1b 100644 --- a/hosts/common/user/configs/console/xdg/default.nix +++ b/hosts/common/user/configs/console/xdg/default.nix @@ -2,6 +2,9 @@ user ? throw "user argument is required", }: { config, lib, ... }: +let + hmConfig = config.home-manager.users.${user.name}; +in { home-manager.users.${user.name} = { imports = [ ./options.nix ]; @@ -19,14 +22,14 @@ }; }; - home.persistence."/persist${user.home}".directories = [ - "Desktop" # userDirs.desktop - "Documents" # userDirs.documents - "Downloads" # userDirs.download - "Music" # userDirs.music - "Pictures" # userDirs.pictures - "Templates" # userDirs.templates - "Videos" # userDirs.videos + home.persistence."/persist${user.home}".directories = with hmConfig.xdg.userDirs; [ + relativeDesktop + relativeDocuments + relativeDownload + relativeMusic + relativePictures + relativeTemplates + relativeVideos "VMs" "git" ]; diff --git a/hosts/common/user/configs/console/xdg/options.nix b/hosts/common/user/configs/console/xdg/options.nix index a6170c2..394ce2a 100644 --- a/hosts/common/user/configs/console/xdg/options.nix +++ b/hosts/common/user/configs/console/xdg/options.nix @@ -13,30 +13,83 @@ in description = "Relative path to directory holding application caches."; }; - cacheHome = mkOption { default = "${config.home.homeDirectory}/${cfg.relativeCacheHome}"; }; - relativeConfigHome = mkOption { type = str; default = ".config"; description = "Relative path to directory holding application configurations."; }; - configHome = mkOption { default = "${config.home.homeDirectory}/${cfg.relativeConfigHome}"; }; - relativeDataHome = mkOption { type = str; default = ".local/share"; description = "Relative path to directory holding application data."; }; - dataHome = mkOption { default = "${config.home.homeDirectory}/${cfg.relativeDataHome}"; }; - relativeStateHome = mkOption { type = str; default = ".local/state"; description = "Relative path to directory holding application states."; }; - stateHome = mkOption { default = "${config.home.homeDirectory}/${cfg.relativeStateHome}"; }; + userDirs = { + relativeDesktop = mkOption { + type = str; + default = "Desktop"; + description = "Relative path to the Desktop directory."; + }; + + relativeDocuments = mkOption { + type = str; + default = "Documents"; + description = "Relative path to the Documents directory."; + }; + + relativeDownload = mkOption { + type = str; + default = "Downloads"; + description = "Relative path to the Downloads directory."; + }; + + relativeMusic = mkOption { + type = str; + default = "Music"; + description = "Relative path to the Music directory."; + }; + + relativePictures = mkOption { + type = str; + default = "Pictures"; + description = "Relative path to the Pictures directory."; + }; + + relativeTemplates = mkOption { + type = str; + default = "Templates"; + description = "Relative path to the Templates directory."; + }; + + relativeVideos = mkOption { + type = str; + default = "Videos"; + description = "Relative path to the Videos directory."; + }; + }; }; + + config.xdg = with lib; { + cacheHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeCacheHome}"; + configHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeConfigHome}"; + dataHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeDataHome}"; + stateHome = mkDefault "${config.home.homeDirectory}/${cfg.relativeStateHome}"; + + userDirs = { + desktop = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeDesktop}"; + documents = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeDocuments}"; + download = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeDownload}"; + music = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeMusic}"; + pictures = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativePictures}"; + templates = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeTemplates}"; + videos = mkDefault "${config.home.homeDirectory}/${cfg.userDirs.relativeVideos}"; + }; + }; } diff --git a/hosts/common/user/configs/gui/cliphist/default.nix b/hosts/common/user/configs/gui/cliphist/default.nix index 70abb98..6684363 100644 --- a/hosts/common/user/configs/gui/cliphist/default.nix +++ b/hosts/common/user/configs/gui/cliphist/default.nix @@ -28,11 +28,16 @@ in After = [ "graphical-session.target" ]; }; - Service.ExecStart = lib.meta.getExe (pkgs.writeShellApplication { - name = "init-cliphist"; - runtimeInputs = with pkgs; [ wl-clipboard cliphist ]; - text = "exec wl-paste --watch cliphist store"; - }); + Service.ExecStart = lib.meta.getExe ( + pkgs.writeShellApplication { + name = "init-cliphist"; + runtimeInputs = with pkgs; [ + wl-clipboard + cliphist + ]; + text = "exec wl-paste --watch cliphist store"; + } + ); Install.WantedBy = [ "graphical-session.target" ]; }; @@ -44,11 +49,16 @@ in After = [ "graphical-session.target" ]; }; - Service.ExecStart = lib.meta.getExe (pkgs.writeShellApplication { - name = "init-cliphist-image"; - runtimeInputs = with pkgs; [ wl-clipboard cliphist ]; - text = "exec wl-paste --type image --watch cliphist store"; - }); + Service.ExecStart = lib.meta.getExe ( + pkgs.writeShellApplication { + name = "init-cliphist-image"; + runtimeInputs = with pkgs; [ + wl-clipboard + cliphist + ]; + text = "exec wl-paste --type image --watch cliphist store"; + } + ); Install.WantedBy = [ "graphical-session.target" ]; }; diff --git a/hosts/common/user/configs/gui/obsidian/.stignore b/hosts/common/user/configs/gui/obsidian/.stignore new file mode 100644 index 0000000..d04bc72 --- /dev/null +++ b/hosts/common/user/configs/gui/obsidian/.stignore @@ -0,0 +1,12 @@ +// Declared +*/.obsidian/app.json +*/.obsidian/appearance.json +*/.obsidian/core-plugins*.json + +// Dynamic +*/.obsidian/graph.json +*/.obsidian/workspace.json +*/.obsidian/workspace-mobile.json + +// Android +.nomedia diff --git a/hosts/common/user/configs/gui/obsidian/default.nix b/hosts/common/user/configs/gui/obsidian/default.nix new file mode 100644 index 0000000..1dd9e7d --- /dev/null +++ b/hosts/common/user/configs/gui/obsidian/default.nix @@ -0,0 +1,39 @@ +{ + user ? throw "user argument is required", +}: +{ + config, + lib, + pkgs, + ... +}: +{ + home-manager.users.${user.name} = { + imports = [ ./options.nix ]; + + programs.obsidian = { + enable = true; + + sharedSettings = { + corePlugins = [ + "bookmarks" + "canvas" + "command-palette" + "editor-status" + "file-explorer" + "global-search" + "graph" + "note-composer" + "outgoing-link" + "outline" + "page-preview" + "slash-command" + "switcher" + "tag-pane" + ]; + }; + }; + + home.persistence."/cache${user.home}".directories = [ ".config/obsidian" ]; + }; +} diff --git a/hosts/common/user/configs/gui/obsidian/options.nix b/hosts/common/user/configs/gui/obsidian/options.nix new file mode 100644 index 0000000..1037e5e --- /dev/null +++ b/hosts/common/user/configs/gui/obsidian/options.nix @@ -0,0 +1,202 @@ +{ + 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" { }; + + sharedSettings = { + 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" + ]; + }; + }; + + 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.sharedSettings.app; + }; + + appearance = mkOption { + description = "Settings to write to appearance.json."; + type = attrsOf anything; + default = cfg.sharedSettings.appearance; + }; + + corePlugins = mkOption { + description = "Core plugins to activate."; + type = listOf (enum corePlugins); + default = cfg.sharedSettings.corePlugins; + }; + }; + }; + + config.target = mkDefault name; + } + ) + ); + default = { }; + }; + }; + + config = + let + vaults = builtins.filter (vault: vault.enable == true) (builtins.attrValues cfg.vaults); + 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 = { + source = (pkgs.formats.json { }).generate "appearance.json" vault.settings.appearance; + }; + }; + mkCorePlugins = vault: [ + { + name = "${vault.target}/.obsidian/core-plugins.json"; + value = { + source = (pkgs.formats.json { }).generate "core-plugins.json" 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 (plugin: { + name = plugin; + value = builtins.elem plugin vault.settings.corePlugins; + }) corePlugins + ) + ); + }; + } + ]; + in + builtins.listToAttrs ( + lib.lists.flatten ( + builtins.map (vault: [ + (mkApp vault) + (mkAppearance vault) + (mkCorePlugins 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 + ); + }; + }; +} diff --git a/hosts/eirene/nick.nix b/hosts/eirene/nick.nix index 26da1e3..18267e6 100644 --- a/hosts/eirene/nick.nix +++ b/hosts/eirene/nick.nix @@ -32,6 +32,7 @@ in (import ../common/user/configs/gui/kitty { inherit user; }) (import ../common/user/configs/gui/matugen { inherit user; }) (import ../common/user/configs/gui/networking { inherit user; }) + (import ../common/user/configs/gui/obsidian { inherit user; }) (import ../common/user/configs/gui/pipewire { inherit user; }) (import ../common/user/configs/gui/qalculate { inherit user; }) (import ../common/user/configs/gui/qt { inherit user; }) @@ -51,7 +52,6 @@ in users.users.nick = { isNormalUser = true; - home = "/home/nick"; email = "nick@karaolidis.com"; fullName = "Nikolaos Karaolidis"; description = user.fullName; @@ -72,13 +72,21 @@ in obsidian = { label = "Obsidian"; path = "${hmConfig.xdg.userDirs.documents}/Obsidian"; - devices = [ "amalthea" "ganymede" ]; + devices = [ + "amalthea" + "ganymede" + ]; }; official = { label = "Official"; path = "${hmConfig.xdg.userDirs.documents}/Official"; - devices = [ "amalthea" "ganymede" ]; + devices = [ + "amalthea" + "ganymede" + ]; }; }; + + home.file."${hmConfig.xdg.userDirs.documents}/Obsidian/.stignore".source = ../common/user/configs/gui/obsidian/.stignore; }; }