diff --git a/hosts/common/home/default.nix b/hosts/common/home/default.nix index dcc6cd0b..8f077993 100644 --- a/hosts/common/home/default.nix +++ b/hosts/common/home/default.nix @@ -3,8 +3,8 @@ imports = [ ./aerc.nix ./firefox.nix - ./gfeeds.nix ./git.nix + ./gnome-feeds.nix ./gpodder.nix ./keyring.nix ./kitty diff --git a/hosts/common/home/git.nix b/hosts/common/home/git.nix index 1ac6ae52..51e76d28 100644 --- a/hosts/common/home/git.nix +++ b/hosts/common/home/git.nix @@ -4,7 +4,7 @@ let mkCfg = lib.generators.toINI { }; in { - sane.user.fs.".config/git/config" = sane-lib.fs.wantedText (mkCfg { + sane.programs.git.fs.".config/git/config" = sane-lib.fs.wantedText (mkCfg { user.name = "Colin"; user.email = "colin@uninsane.org"; alias.co = "checkout"; diff --git a/hosts/common/home/gfeeds.nix b/hosts/common/home/gnome-feeds.nix similarity index 92% rename from hosts/common/home/gfeeds.nix rename to hosts/common/home/gnome-feeds.nix index c38294b3..eb66dae3 100644 --- a/hosts/common/home/gfeeds.nix +++ b/hosts/common/home/gnome-feeds.nix @@ -6,7 +6,7 @@ let all-feeds = config.sane.feeds; wanted-feeds = feeds.filterByFormat ["text" "image"] all-feeds; in { - sane.user.fs.".config/org.gabmus.gfeeds.json" = sane-lib.fs.wantedText ( + sane.programs.gnome-feeds.fs.".config/org.gabmus.gfeeds.json" = sane-lib.fs.wantedText ( builtins.toJSON { # feed format is a map from URL to a dict, # with dict["tags"] a list of string tags. diff --git a/hosts/common/home/gpodder.nix b/hosts/common/home/gpodder.nix index 41bdecfb..eafc3e80 100644 --- a/hosts/common/home/gpodder.nix +++ b/hosts/common/home/gpodder.nix @@ -6,7 +6,7 @@ let all-feeds = config.sane.feeds; wanted-feeds = feeds.filterByFormat ["podcast"] all-feeds; in { - sane.user.fs.".config/gpodderFeeds.opml" = sane-lib.fs.wantedText ( + sane.programs.gpodder.fs.".config/gpodderFeeds.opml" = sane-lib.fs.wantedText ( feeds.feedsToOpml wanted-feeds ); } diff --git a/hosts/common/home/kitty/default.nix b/hosts/common/home/kitty/default.nix index 14c54c3a..e81cbe35 100644 --- a/hosts/common/home/kitty/default.nix +++ b/hosts/common/home/kitty/default.nix @@ -1,7 +1,7 @@ { pkgs, sane-lib, ... }: { - sane.user.fs.".config/kitty/kitty.conf" = sane-lib.fs.wantedText '' + sane.programs.kitty.fs.".config/kitty/kitty.conf" = sane-lib.fs.wantedText '' # docs: https://sw.kovidgoyal.net/kitty/conf/ # disable terminal bell (when e.g. you backspace too many times) enable_audio_bell no diff --git a/hosts/common/home/libreoffice.nix b/hosts/common/home/libreoffice.nix index 60fb5ff5..69379d56 100644 --- a/hosts/common/home/libreoffice.nix +++ b/hosts/common/home/libreoffice.nix @@ -2,7 +2,7 @@ { # libreoffice: disable first-run stuff - sane.user.fs.".config/libreoffice/4/user/registrymodifications.xcu" = sane-lib.fs.wantedText '' + sane.programs.libreoffice-fresh.fs.".config/libreoffice/4/user/registrymodifications.xcu" = sane-lib.fs.wantedText '' false diff --git a/hosts/common/home/mpv.nix b/hosts/common/home/mpv.nix index 27194c02..7ee62611 100644 --- a/hosts/common/home/mpv.nix +++ b/hosts/common/home/mpv.nix @@ -1,10 +1,13 @@ { sane-lib, ... }: { - # format is =%% - sane.user.fs.".config/mpv/mpv.conf" = sane-lib.fs.wantedText '' - save-position-on-quit=%3%yes - keep-open=%3%yes - ''; + sane.programs.mpv = { + persist.plaintext = [ ".config/mpv/watch_later" ]; + # format is =%% + fs.".config/mpv/mpv.conf" = sane-lib.fs.wantedText '' + save-position-on-quit=%3%yes + keep-open=%3%yes + ''; + }; } diff --git a/hosts/common/home/neovim.nix b/hosts/common/home/neovim.nix index 61f349dc..2743a56e 100644 --- a/hosts/common/home/neovim.nix +++ b/hosts/common/home/neovim.nix @@ -1,8 +1,8 @@ -{ lib, pkgs, ... }: +{ config, lib, pkgs, ... }: let inherit (builtins) map; - inherit (lib) concatMapStrings optionalString; + inherit (lib) concatMapStrings mkIf optionalString; # this structure roughly mirrors home-manager's `programs.neovim.plugins` option plugins = with pkgs.vimPlugins; [ # docs: surround-nvim: https://github.com/ur4ltz/surround.nvim/ @@ -72,9 +72,9 @@ let in { # private because there could be sensitive things in the swap - sane.user.persist.private = [ ".cache/vim-swap" ]; + sane.programs.neovim.persist.private = [ ".cache/vim-swap" ]; - programs.neovim = { + programs.neovim = mkIf config.sane.programs.neovim.enabled { # neovim: https://github.com/neovim/neovim enable = true; viAlias = true; diff --git a/hosts/common/home/newsflash.nix b/hosts/common/home/newsflash.nix index 8dff84de..ff36d8cd 100644 --- a/hosts/common/home/newsflash.nix +++ b/hosts/common/home/newsflash.nix @@ -6,7 +6,10 @@ let all-feeds = config.sane.feeds; wanted-feeds = feeds.filterByFormat ["text" "image"] all-feeds; in { - sane.user.fs.".config/newsflashFeeds.opml" = sane-lib.fs.wantedText ( - feeds.feedsToOpml wanted-feeds - ); + sane.programs.newsflash = { + persist.plaintext = [ ".local/share/news-flash" ]; + fs.".config/newsflashFeeds.opml" = sane-lib.fs.wantedText ( + feeds.feedsToOpml wanted-feeds + ); + }; } diff --git a/hosts/common/home/offlineimap.nix b/hosts/common/home/offlineimap.nix index e9001fba..9081e457 100644 --- a/hosts/common/home/offlineimap.nix +++ b/hosts/common/home/offlineimap.nix @@ -12,6 +12,6 @@ sopsFile = ../../../secrets/universal/offlineimaprc.bin; format = "binary"; }; - sane.user.fs.".config/offlineimap/config" = sane-lib.fs.wantedSymlinkTo config.sops.secrets.offlineimaprc.path; + sane.programs.offlineimap.fs.".config/offlineimap/config" = sane-lib.fs.wantedSymlinkTo config.sops.secrets.offlineimaprc.path; } diff --git a/hosts/common/home/ripgrep.nix b/hosts/common/home/ripgrep.nix index ab46f2c3..e7e7c1b1 100644 --- a/hosts/common/home/ripgrep.nix +++ b/hosts/common/home/ripgrep.nix @@ -3,7 +3,7 @@ # .ignore file is read by ripgrep (rg), silver searcher (ag), maybe others. # ignore translation files by default when searching, as they tend to have # a LOT of duplicate text. - sane.user.fs.".ignore" = sane-lib.fs.wantedText '' + sane.programs.ripgrep.fs.".ignore" = sane-lib.fs.wantedText '' po/ ''; } diff --git a/hosts/common/home/splatmoji.nix b/hosts/common/home/splatmoji.nix index ed7928e4..6cadf68c 100644 --- a/hosts/common/home/splatmoji.nix +++ b/hosts/common/home/splatmoji.nix @@ -4,17 +4,19 @@ { pkgs, sane-lib, ... }: { - sane.user.persist.plaintext = [ ".local/state/splatmoji" ]; - sane.user.fs.".config/splatmoji/splatmoji.config" = sane-lib.fs.wantedText '' - # XXX doesn't seem to understand ~ as shorthand for `$HOME` - history_file=/home/colin/.local/state/splatmoji/history - history_length=5 - # TODO: wayland equiv - paste_command=xdotool key ctrl+v - # rofi_command=${pkgs.wofi}/bin/wofi --dmenu --insensitive --cache-file /dev/null - rofi_command=${pkgs.fuzzel}/bin/fuzzel -d -i -w 60 - xdotool_command=${pkgs.wtype}/bin/wtype - # TODO: wayland equiv - xsel_command=xsel -b -i - ''; + sane.programs.splatmoji = { + persist.plaintext = [ ".local/state/splatmoji" ]; + fs.".config/splatmoji/splatmoji.config" = sane-lib.fs.wantedText '' + # XXX doesn't seem to understand ~ as shorthand for `$HOME` + history_file=/home/colin/.local/state/splatmoji/history + history_length=5 + # TODO: wayland equiv + paste_command=xdotool key ctrl+v + # rofi_command=${pkgs.wofi}/bin/wofi --dmenu --insensitive --cache-file /dev/null + rofi_command=${pkgs.fuzzel}/bin/fuzzel -d -i -w 60 + xdotool_command=${pkgs.wtype}/bin/wtype + # TODO: wayland equiv + xsel_command=xsel -b -i + ''; + }; } diff --git a/hosts/common/home/sublime-music.nix b/hosts/common/home/sublime-music.nix index 1a1301c8..28649507 100644 --- a/hosts/common/home/sublime-music.nix +++ b/hosts/common/home/sublime-music.nix @@ -1,11 +1,20 @@ -{ config, sane-lib, ... }: +{ config, pkgs, sane-lib, ... }: { - # TODO: this should only be shipped on gui platforms sops.secrets."sublime_music_config" = { owner = config.users.users.colin.name; sopsFile = ../../../secrets/universal/sublime_music_config.json.bin; format = "binary"; }; - sane.user.fs.".config/sublime-music/config.json" = sane-lib.fs.wantedSymlinkTo config.sops.secrets.sublime_music_config.path; + sane.programs.sublime-music = { + package = pkgs.sublime-music-mobile; + # sublime music persists any downloaded albums here. + # it doesn't obey a conventional ~/Music/{Artist}/{Album}/{Track} notation, so no symlinking + # config (e.g. server connection details) is persisted in ~/.config/sublime-music/config.json + # possible to pass config as a CLI arg (sublime-music -c config.json) + persist.plaintext = [ ".local/share/sublime-music" ]; + + fs.".config/sublime-music/config.json" = sane-lib.fs.wantedSymlinkTo + config.sops.secrets.sublime_music_config.path; + }; } diff --git a/hosts/common/home/vlc.nix b/hosts/common/home/vlc.nix index 7f19403e..a0774a00 100644 --- a/hosts/common/home/vlc.nix +++ b/hosts/common/home/vlc.nix @@ -9,12 +9,16 @@ let ); in { - sane.user.fs.".config/vlc/vlcrc" = sane-lib.fs.wantedText '' - [podcast] - podcast-urls=${podcast-urls} - [core] - metadata-network-access=0 - [qt] - qt-privacy-ask=0 - ''; + sane.programs.vlc = { + # vlc remembers play position in ~/.config/vlc/vlc-qt-interface.conf + persist.plaintext = [ ".config/vlc" ]; + fs.".config/vlc/vlcrc" = sane-lib.fs.wantedText '' + [podcast] + podcast-urls=${podcast-urls} + [core] + metadata-network-access=0 + [qt] + qt-privacy-ask=0 + ''; + }; } diff --git a/hosts/common/programs.nix b/hosts/common/programs.nix index c9dfbb23..8bc968c1 100644 --- a/hosts/common/programs.nix +++ b/hosts/common/programs.nix @@ -111,6 +111,7 @@ let lshw ffmpeg memtester + neovim # nettools # networkmanager nixpkgs-review @@ -148,15 +149,15 @@ let emote evince # works on phosh - # { pkg = fluffychat-moby; dir = [ ".local/share/chat.fluffy.fluffychat" ]; } # TODO: ship normal fluffychat on non-moby? + # { pkg = fluffychat-moby; persist.plaintext = [ ".local/share/chat.fluffy.fluffychat" ]; } # TODO: ship normal fluffychat on non-moby? # foliate # e-book reader # XXX by default fractal stores its state in ~/.local/share/. # after logging in, manually change ~/.local/share/keyrings/... to point it to some predictable subdir. # then reboot (so that libsecret daemon re-loads the keyring...?) - # { pkg = fractal-latest; private = [ ".local/share/fractal" ]; } - # { pkg = fractal-next; private = [ ".local/share/fractal" ]; } + # { pkg = fractal-latest; persist.private = [ ".local/share/fractal" ]; } + # { pkg = fractal-next; persist.private = [ ".local/share/fractal" ]; } # "gnome.cheese" "gnome.dconf-editor" @@ -181,12 +182,7 @@ let playerctl # "libsForQt5.plasmatube" # Youtube player soundconverter - # sublime music persists any downloaded albums here. - # it doesn't obey a conventional ~/Music/{Artist}/{Album}/{Track} notation, so no symlinking - # config (e.g. server connection details) is persisted in ~/.config/sublime-music/config.json - # possible to pass config as a CLI arg (sublime-music -c config.json) - # { pkg = sublime-music; dir = [ ".local/share/sublime-music" ]; } - sublime-music-mobile + sublime-music # tdesktop # broken on phosh # tokodon vlc @@ -308,75 +304,65 @@ in ghostscriptSupport = true; }; - dino.private = [ ".local/share/dino" ]; + dino.persist.private = [ ".local/share/dino" ]; # creds, but also 200 MB of node modules, etc - discord.private = [ ".config/discord" ]; + discord.persist.private = [ ".config/discord" ]; # creds/session keys, etc - element-desktop.private = [ ".config/Element" ]; + element-desktop.persist.private = [ ".config/Element" ]; # `emote` will show a first-run dialog based on what's in this directory. # mostly, it just keeps a LRU of previously-used emotes to optimize display order. # TODO: package [smile](https://github.com/mijorus/smile) for probably a better mobile experience. - emote.dir = [ ".local/share/Emote" ]; + emote.persist.plaintext = [ ".local/share/Emote" ]; # MS GitHub stores auth token in .config # TODO: we can populate gh's stuff statically; it even lets us use the same oauth across machines - gh.private = [ ".config/gh" ]; + gh.persist.private = [ ".config/gh" ]; # XXX: we preserve the whole thing because if we only preserve gPodder/Downloads # then startup is SLOW during feed import, and we might end up with zombie eps in the dl dir. - gpodder-configured.dir = [ "gPodder" ]; + gpodder-configured.persist.plaintext = [ "gPodder" ]; # jellyfin stores things in a bunch of directories: this one persists auth info. # it *might* be possible to populate this externally (it's Qt stuff), but likely to # be fragile and take an hour+ to figure out. - jellyfin-media-player.dir = [ ".local/share/Jellyfin Media Player" ]; + jellyfin-media-player.persist.plaintext = [ ".local/share/Jellyfin Media Player" ]; # actual monero blockchain (not wallet/etc; safe to delete, just slow to regenerate) # XXX: is it really safe to persist this? it doesn't have info that could de-anonymize if captured? - monero-gui.dir = [ ".bitmonero" ]; + monero-gui.persist.plaintext = [ ".bitmonero" ]; - mpv.dir = [ ".config/mpv/watch_later" ]; - - mumble.private = [ ".local/share/Mumble" ]; + mumble.persist.private = [ ".local/share/Mumble" ]; # not strictly necessary, but allows caching articles; offline use, etc. - newsflash.dir = [ ".local/share/news-flash" ]; - nheko.private = [ + nheko.persist.private = [ ".config/nheko" # config file (including client token) ".cache/nheko" # media cache ".local/share/nheko" # per-account state database ]; # settings (electron app) - obsidian.dir = [ ".config/obsidian" ]; + obsidian.persist.plaintext = [ ".config/obsidian" ]; # creds, media - signal-desktop.private = [ ".config/Signal" ]; + signal-desktop.persist.private = [ ".config/Signal" ]; # printer/filament settings - slic3r.dir = [ ".Slic3r" ]; + slic3r.persist.plaintext = [ ".Slic3r" ]; # creds, widevine .so download. TODO: could easily manage these statically. - spotify.dir = [ ".config/spotify" ]; + spotify.persist.plaintext = [ ".config/spotify" ]; - steam.dir = [ + steam.persist.plaintext = [ ".steam" ".local/share/Steam" ]; - # sublime music persists any downloaded albums here. - # it doesn't obey a conventional ~/Music/{Artist}/{Album}/{Track} notation, so no symlinking - # config (e.g. server connection details) is persisted in ~/.config/sublime-music/config.json - # possible to pass config as a CLI arg (sublime-music -c config.json) - # { pkg = sublime-music; dir = [ ".local/share/sublime-music" ]; } - sublime-music-mobile.dir = [ ".local/share/sublime-music" ]; + tdesktop.persist.private = [ ".local/share/TelegramDesktop" ]; - tdesktop.private = [ ".local/share/TelegramDesktop" ]; - - tokodon.private = [ ".cache/KDE/tokodon" ]; + tokodon.persist.private = [ ".cache/KDE/tokodon" ]; # hardenedMalloc solves a crash at startup # TODO 2023/02/02: is this safe to remove yet? @@ -384,15 +370,12 @@ in useHardenedMalloc = false; }; - # vlc remembers play position in ~/.config/vlc/vlc-qt-interface.conf - vlc.dir = [ ".config/vlc" ]; + whalebird.persist.private = [ ".config/Whalebird" ]; - whalebird.private = [ ".config/Whalebird" ]; - - yarn.dir = [ ".cache/yarn" ]; + yarn.persist.plaintext = [ ".cache/yarn" ]; # zcash coins. safe to delete, just slow to regenerate (10-60 minutes) - zecwallet-lite.private = [ ".zcash" ]; + zecwallet-lite.persist.private = [ ".zcash" ]; } ]; diff --git a/hosts/modules/gui/sway.nix b/hosts/modules/gui/sway.nix index 7dc1343c..b3d21157 100644 --- a/hosts/modules/gui/sway.nix +++ b/hosts/modules/gui/sway.nix @@ -126,6 +126,7 @@ in package = null; suggestedPrograms = [ "guiApps" + "splatmoji" # used by us, but 'enabling' it gets us persistence & cfg "swaylock" "swayidle" "wl-clipboard" diff --git a/modules/programs.nix b/modules/programs.nix index a0f37190..90acf5f7 100644 --- a/modules/programs.nix +++ b/modules/programs.nix @@ -77,15 +77,17 @@ let type = types.bool; default = true; }; - dir = mkOption { - type = types.listOf types.str; - default = []; - description = "list of home-relative paths to persist for this package"; - }; - private = mkOption { - type = types.listOf types.str; - default = []; - description = "list of home-relative paths to persist (in encrypted format) for this package"; + persist = { + plaintext = mkOption { + type = types.listOf types.str; + default = []; + description = "list of home-relative paths to persist for this package"; + }; + private = mkOption { + type = types.listOf types.str; + default = []; + description = "list of home-relative paths to persist (in encrypted format) for this package"; + }; }; fs = mkOption { type = types.attrs; @@ -118,9 +120,7 @@ let # conditionally persist relevant user dirs and create files sane.users = mapAttrs (user: en: optionalAttrs en { - persist.plaintext = p.dir; - persist.private = p.private; - fs = p.fs; + inherit (p) fs persist; }) p.enableFor.user; }) cfg; in