diff --git a/dotfiles/neovim/lua/my/plugins/mind.lua b/dotfiles/neovim/lua/my/plugins/mind.lua index f31e58d..8c4ff70 100644 --- a/dotfiles/neovim/lua/my/plugins/mind.lua +++ b/dotfiles/neovim/lua/my/plugins/mind.lua @@ -17,7 +17,7 @@ function M.config() mind.setup({ persistence = { - state_path = "~/Mind/mind.json", + state_path = "~/Projects/Mind/mind.json", data_dir = "~/Mind/data", }, ui = { diff --git a/home/features/README.md b/home/features/README.md index a2ab617..cc69d3f 100644 --- a/home/features/README.md +++ b/home/features/README.md @@ -4,11 +4,11 @@ Check out [tethys](../tethys.nix) for example imports ## File structure -| Directory | Description | -| -------------------- | --------------------------------------------- | -| [cli](./cli) | Configuration for terminal stuff | -| [desktop](./desktop) | Desktop apps usable on both wayland and xorg | -| [xorg](./xorg) | Xorg only stuff | -| [wayland](./wayland) | Wayland only stuff | -| [neovim](./neovim) | Neovim (to be expanded in the future ) | -| [games](./games) | Similar to [desktop](./desktop) but for games | +| Directory | Description | +| -------------------------------- | -------------------------------------------- | +| [cli](./cli) | Configuration for terminal stuff | +| [desktop](./desktop) | Desktop apps usable on both wayland and xorg | +| [xorg](./xorg) | Xorg only stuff | +| [wayland](./wayland) | Wayland only stuff | +| [neovim](./neovim) | Neovim (to be expanded in the future ) | +| [persistence](./persistence.nix) | For impermanence settings | diff --git a/home/features/desktop/firefox/default.nix b/home/features/desktop/firefox/default.nix index f3b6dcd..96c0d78 100644 --- a/home/features/desktop/firefox/default.nix +++ b/home/features/desktop/firefox/default.nix @@ -1,4 +1,4 @@ -{ pkgs, inputs, ... }: +{ config, pkgs, inputs, ... }: let # {{{ Global extensions extensions = with inputs.firefox-addons.packages.${pkgs.system}; [ @@ -227,12 +227,14 @@ in # Tell apps firefox is the default browser using an env var. home.sessionVariables.BROWSER = "firefox"; # }}} - # {{{ Persistence - home.persistence."/persist/home/adrielus".directories = [ - ".cache/mozilla/firefox" # Non important cache + satellite.persistence.at.state.apps.Firefox.directories = [ ".mozilla/firefox" # More important stuff ]; + + satellite.persistence.at.cache.apps.Firefox.directories = [ + "${config.xdg.cacheHome}/mozilla/firefox" # Non important cache + ]; # }}} } diff --git a/home/features/desktop/qbittorrent.nix b/home/features/desktop/qbittorrent.nix deleted file mode 100644 index bf38e3d..0000000 --- a/home/features/desktop/qbittorrent.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ pkgs, config, ... }: { - home.packages = [ - pkgs.qbittorrent - ]; - - satellite.persistence.at.state.apps.QBittorrent.directories = [ - "${config.xdg.configHome}/qBittorrent" # Config options - ]; - - satellite.persistence.at.cache.apps.QBittorrent.directories = [ - # TODO: investigate which subdirectories/files I actually want to keep - "${config.xdg.dataHome}/qBittorrent" # Torrent files, logs, etc - ]; -} diff --git a/home/features/desktop/signal.nix b/home/features/desktop/signal.nix deleted file mode 100644 index f60a50e..0000000 --- a/home/features/desktop/signal.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs, config, ... }: { - home.packages = [ - pkgs.signal-desktop # Signal client - ]; - - satellite.persistence.at.state.apps.Signal.directories = [ - "${config.xdg.configHome}/Signal" # Why tf does signal store it's state here 💀 - ]; -} diff --git a/home/features/games/default.nix b/home/features/games/default.nix deleted file mode 100644 index d66e834..0000000 --- a/home/features/games/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - imports = [ ./wine.nix ./lutris.nix ./steam.nix ]; -} diff --git a/home/features/games/lutris.nix b/home/features/games/lutris.nix deleted file mode 100644 index 97328f7..0000000 --- a/home/features/games/lutris.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ pkgs, config, ... }: -{ - home.packages = [ - pkgs.lutris - ]; - - home.persistence."/persist/home/adrielus".directories = [ - ("Lutris/.config/lutris") # General config data - ".cache/lutris/banners" # Game banners - ".cache/lutris/coverart" # Game cover art - - # Aparently IO intensive stuff like games prefer symlinks? - { directory = "Games/Lutris"; method = "symlink"; } # Lutris games - ]; -} diff --git a/home/features/games/steam.nix b/home/features/games/steam.nix deleted file mode 100644 index b7f9560..0000000 --- a/home/features/games/steam.nix +++ /dev/null @@ -1,20 +0,0 @@ -# Although steam is installed globally by nixos, -# there's some extra settings we make for a specific user! -{ - home.persistence."/persist/home/adrielus" = { - files = [ - ".steam/registry.vdf" # It seems like auto-login does not work without this - ]; - - directories = [ - # TODO: perhaps this should leave in it's own file? - ".factorio" - - # A couple of games don't play well with bindfs - { - directory = ".local/share/Steam"; - method = "symlink"; - } - ]; - }; -} diff --git a/home/features/games/wine.nix b/home/features/games/wine.nix deleted file mode 100644 index f47a7af..0000000 --- a/home/features/games/wine.nix +++ /dev/null @@ -1,6 +0,0 @@ -# TODO(imperanence): handle persistence -{ pkgs, ... }: { - home.packages = [ - pkgs.wine - ]; -} diff --git a/home/features/persistence.nix b/home/features/persistence.nix new file mode 100644 index 0000000..222885f --- /dev/null +++ b/home/features/persistence.nix @@ -0,0 +1,98 @@ +{ config, ... }: { + # {{{ XDG dirs + # The lack of "~/Desktop" and "~/Downloads" is intentional! + satellite.persistence.at.data.apps.main.directories = [ + config.xdg.userDirs.documents + config.xdg.userDirs.pictures + config.xdg.userDirs.music + config.xdg.userDirs.videos + "Projects" + ]; + # }}} + # {{{ OpenTabletDriver + satellite.persistence.at.state.apps.OpenTabletDriver.directories = [ + #"${config.xdg.configHome}/OpenTabletDriver" + ]; + # }}} + # {{{ Rust + satellite.persistence.at.cache.apps.Rust.directories = [ + #".cargo" + #".rustup" + ]; + # }}} + # {{{ Purescript + satellite.persistence.at.cache.apps.Purescript.directories = [ + #"${config.xdg.cacheHome}/spago" + ]; + # }}} + # {{{ Nodejs + satellite.persistence.at.cache.apps.Node.directories = [ + #"${config.xdg.cacheHome}/yarn" + #"${config.xdg.dataHome}/pnpm" + ]; + # }}} + # {{{ Shell stuff + satellite.persistence.at.cache.apps.Shell.directories = [ + #"${config.xdg.dataHome}/fish" + #"${config.xdg.dataHome}/z" # The z fish plugin + #"${config.xdg.dataHome}/direnv/allow" + #".tmux" + ]; + # }}} + # {{{ Neovim + satellite.persistence.at.cache.apps.Neovim.directories = [ + # "${config.xdg.dataHome}/nvim" + ]; + # }}} + # {{{ SSH + satellite.persistence.at.state.apps.Ssh.directories = [ + # ".ssh" + ]; + # }}} + # {{{ QBittorrent + satellite.persistence.at.state.apps.QBittorrent.directories = [ + "${config.xdg.configHome}/qBittorrent" # Config options + ]; + + satellite.persistence.at.cache.apps.QBittorrent.directories = [ + # TODO: investigate which subdirectories/files I actually want to keep + "${config.xdg.dataHome}/qBittorrent" # Torrent files, logs, etc + ]; + # }}} + # {{{ Signal + satellite.persistence.at.state.apps.Signal.directories = [ + "${config.xdg.configHome}/Signal" # Why tf does signal store it's state here 💀 + ]; + # }}} + # {{{ Steam + satellite.persistence.at.state.apps.Steam = { + files = [ + ".steam/registry.vdf" # It seems like auto-login does not work without this + ]; + + directories = [ + ".factorio" # TODO: perhaps this should leave in it's own file? + + # A couple of games don't play well with bindfs + { + directory = "${config.xdg.dataHome}/Steam"; + method = "symlink"; + } + ]; + }; + # }}} + # {{{ Lutris + # TODO: there might be more to cache in .cache/lutris + satellite.persistence.at.state.apps.Lutris.directories = [ + "${config.xdg.configHome}/lutris" # General config data + "${config.xdg.cacheHome}/lutris/banners" # Game banners + "${config.xdg.cacheHome}/lutris/coverart" # Game cover art + + # Aparently IO intensive stuff like games prefer symlinks? + { directory = "Games/Lutris"; method = "symlink"; } # Lutris games + ]; + # }}} + # {{{ Wine + satellite.persistence.at.state.apps.Wine.directories = [ ".wine" ]; + # }}} +} diff --git a/home/features/wayland/hyprland/default.nix b/home/features/wayland/hyprland/default.nix index 68bbf6d..ba5c75b 100644 --- a/home/features/wayland/hyprland/default.nix +++ b/home/features/wayland/hyprland/default.nix @@ -1,11 +1,34 @@ -{ pkgs, inputs, ... }: { +{ pkgs, lib, config, inputs, ... }: + +let + enabledMonitors = lib.filter (m: m.enabled) config.monitors; + hyprland-monitors = lib.concatStringsSep "\n" (lib.forEach enabledMonitors (m: '' + monitor=${m.name},${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},1 + ${lib.optionalString (m.workspace != null) "workspace=${m.name},${m.workspace}"} + '')); +in +{ imports = [ ../default.nix ]; - home.packages = [ inputs.hyprland-contrib.packages.${pkgs.system}.grimblast ]; + home.packages = [ inputs.hyprland-contrib.packages.${pkgs.system}.grimblast pkgs.hyprpaper ]; wayland.windowManager.hyprland = { enable = true; recommendedEnvironment = true; - extraConfig = builtins.readFile ./hyprland.conf; + extraConfig = '' + ${builtins.readFile ./hyprland.conf} + ${hyprland-monitors} + ''; + }; + + services.hyprpaper = { + enable = true; + preload = [ config.stylix.image ]; + wallpapers = [ + { image = config.stylix.image; } + ] ++ lib.forEach enabledMonitors ({ name, ... }: { + monitor = name; + image = config.stylix.image; + }); }; } diff --git a/home/features/wayland/hyprland/hyprland.conf b/home/features/wayland/hyprland/hyprland.conf index b1db2eb..d7355df 100644 --- a/home/features/wayland/hyprland/hyprland.conf +++ b/home/features/wayland/hyprland/hyprland.conf @@ -1,4 +1,5 @@ -# Monitors +# Fallback rule for monitors. +# More specific rules defined in the .nix file. # https://wiki.hyprland.org/Configuring/Monitors/ monitor=,preferred,auto,1 diff --git a/home/global/default.nix b/home/global/default.nix index df596a6..07ceee6 100644 --- a/home/global/default.nix +++ b/home/global/default.nix @@ -10,6 +10,7 @@ let ../features/cli ../features/neovim + ../features/persistence.nix ../../common ]; # }}} @@ -62,10 +63,10 @@ in # Set the xdg env vars xdg.enable = true; - # {{{ Create xdg user directories + # {{{ Xdg user directories xdg.userDirs = { enable = lib.mkDefault true; - createDirectories = lib.mkDefault true; + createDirectories = lib.mkDefault false; extraConfig.XDG_SCREENSHOTS_DIR = "${config.xdg.userDirs.pictures}/Screenshots"; }; # }}} diff --git a/home/tethys.nix b/home/tethys.nix index 03ac530..6e7b409 100644 --- a/home/tethys.nix +++ b/home/tethys.nix @@ -3,14 +3,11 @@ ./global ./features/desktop/discord.nix - ./features/desktop/signal.nix - ./features/desktop/qbittorrent.nix ./features/desktop/zathura.nix ./features/desktop/firefox ./features/xorg/xmonad.nix ./features/wayland/hyprland - ./features/games ]; # Arbitrary extra packages @@ -25,9 +22,13 @@ libreoffice # Free office suite lmms # Music software kicad # PCB editing + plover.dev # steno engine + qbittorrent # Torrent client + signal-desktop # Signal client + wine # Windows compat layer or whatever + lutris # Game launcher # google-chrome # Not my primary browser, but sometimes needed in webdev # obs-studio # video recorder - plover.dev # steno engine # Clis agenix # Secret encryption @@ -46,12 +47,19 @@ # Actual data/media (eg: projects, images, videos, etc) at.data.path = "/persist/data"; + at.data.prefixDirectories = false; # App state I want to keep at.state.path = "/persist/state"; # App state which I should be able to delete at any point - at.cache.path = "/persist/cache"; + at.cache.path = "/persist/local/cache"; }; }; + + monitors = [{ + name = "eDP-1"; + width = 1920; + height = 1080; + }]; } diff --git a/hosts/nixos/common/global/openssh.nix b/hosts/nixos/common/global/openssh.nix index ea4fc56..ea8889f 100644 --- a/hosts/nixos/common/global/openssh.nix +++ b/hosts/nixos/common/global/openssh.nix @@ -34,8 +34,8 @@ in let mkKey = type: path: extra: { inherit type path; } // extra; in [ - (mkKey "ed25519" "/persist/etc/ssh/ssh_host_ed25519_key" { }) - (mkKey "rsa" "/persist/etc/ssh/ssh_host_rsa_key" { bits = 4096; }) + (mkKey "ed25519" "/persist/state/etc/ssh/ssh_host_ed25519_key" { }) + (mkKey "rsa" "/persist/state/etc/ssh/ssh_host_rsa_key" { bits = 4096; }) ]; }; diff --git a/hosts/nixos/common/global/wireless/default.nix b/hosts/nixos/common/global/wireless/default.nix index cb86f89..e7e9140 100644 --- a/hosts/nixos/common/global/wireless/default.nix +++ b/hosts/nixos/common/global/wireless/default.nix @@ -33,19 +33,19 @@ }; # Imperative - allowAuxiliaryImperativeNetworks = true; - userControlled = { - enable = true; - group = "network"; - }; + # allowAuxiliaryImperativeNetworks = true; + # userControlled = { + # enable = true; + # group = "network"; + # }; }; # Ensure group exists users.groups.network = { }; - # TODO: figure out why this does not work! # Persist imperative config - # environment.persistence."/persist".files = [ - # "/etc/wpa_supplicant.conf" - # ]; + environment.persistence."/persist/state".files = [ + # TODO: investigate why this doesn't work + # "/etc/wpa_supplicant.conf" + ]; } diff --git a/hosts/nixos/tethys/default.nix b/hosts/nixos/tethys/default.nix index 6115559..e77e616 100644 --- a/hosts/nixos/tethys/default.nix +++ b/hosts/nixos/tethys/default.nix @@ -25,7 +25,6 @@ # {{{ A few ad-hoc hardware settings hardware.opengl.enable = true; - # TODO: persistence of config hardware.opentabletdriver.enable = true; # }}} # {{{ A few ad-hoc programs diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix index 19f5517..d5b79ce 100644 --- a/modules/home-manager/default.nix +++ b/modules/home-manager/default.nix @@ -2,9 +2,17 @@ { # example = import ./example.nix; - discord = import ./discord.nix; + + # Personal things firefox = import ./firefox; satellite-dev = import ./satellite-dev.nix; satellite-persistence = import ./persistence.nix; + monitors = import ./monitors.nix; + + # Should upstream + discord = import ./discord.nix; + hyprpaper = import ./hyprpaper.nix; + + # Temporary wofi = import ./wofi.nix; } diff --git a/modules/home-manager/hyprpaper.nix b/modules/home-manager/hyprpaper.nix new file mode 100644 index 0000000..55c89c9 --- /dev/null +++ b/modules/home-manager/hyprpaper.nix @@ -0,0 +1,106 @@ +# TODO: add maintainers and upstream into home-manager +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.hyprpaper; + mkWallpaper = { mode, image, monitor, ... }: + let + monitorString = lib.optionalString (monitor != null) monitor; + modeString = lib.optionalString (mode == "contain") "contain:"; + in + "wallpaper=${monitorString},${modeString}${image}"; +in +{ + options.services.hyprpaper = { + enable = mkEnableOption "hyprpaper"; + + package = mkOption { + type = types.package; + default = pkgs.hyprpaper; + defaultText = "pkgs.hyprpaper"; + description = '' + hyprpaper derivation to use. + ''; + }; + + systemdTarget = mkOption { + type = types.str; + default = "graphical-session.target"; + description = '' + Systemd target to bind to. + ''; + }; + + preload = mkOption { + type = types.listOf (types.oneOf [ types.str types.path ]); + default = [ ]; + example = [ "~/background.png" ]; + description = "List of images to preload"; + }; + + wallpapers = mkOption { + type = types.listOf (types.submodule (_: { + options = { + monitor = mkOption { + type = types.nullOr types.str; + default = null; + example = "eDP-1"; + description = '' + Monitor to use for the wallpaper. + Either leave empty as a wildcard, + type the name of the monitor, or + include the monitor's description + prefixed with `desc:`. + ''; + }; + + image = mkOption { + type = types.oneOf [ types.str types.path ]; + default = null; + example = "~/background.png"; + description = "Image to use as wallpaper"; + }; + + mode = mkOption { + type = lib.types.enum [ "cover" "contain" ]; + default = "cover"; + example = "contain"; + description = "The way to display the wallpaper"; + }; + }; + })); + + default = [ ]; + description = "List of wallpapers to set"; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.hyprpaper" pkgs + lib.platforms.linux) + ]; + + xdg.configFile."hypr/hyprpaper.conf".text = '' + ${lib.concatStringsSep "\n" (lib.forEach cfg.preload (image: "preload=${image}"))} + ${lib.concatStringsSep "\n" (lib.forEach cfg.wallpapers mkWallpaper)} + ''; + + systemd.user.services.hyprpaper = { + Unit = { + Description = "Wayland wallpaper service"; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = "${cfg.package}/bin/hyprpaper"; + }; + + Install = { + WantedBy = [ cfg.systemdTarget ]; + }; + }; + }; +} diff --git a/modules/home-manager/monitors.nix b/modules/home-manager/monitors.nix new file mode 100644 index 0000000..4954760 --- /dev/null +++ b/modules/home-manager/monitors.nix @@ -0,0 +1,50 @@ +# Taken from [misterio's config](https://github.com/Misterio77/nix-config/blob/main/modules/home-manager/monitors.nix) +# This is meant to provide a wm-independent way of specifying the monitor configuration of each machine. +{ lib, ... }: +{ + options.monitors = lib.mkOption { + type = lib.types.listOf (lib.types.submodule { + options = { + name = lib.mkOption { + type = lib.types.str; + example = "DP-1"; + }; + + width = lib.mkOption { + type = lib.types.int; + example = 1920; + }; + + height = lib.mkOption { + type = lib.types.int; + example = 1080; + }; + + refreshRate = lib.mkOption { + type = lib.types.int; + default = 60; + }; + + x = lib.mkOption { + type = lib.types.int; + default = 0; + }; + + y = lib.mkOption { + type = lib.types.int; + default = 0; + }; + + enabled = lib.mkOption { + type = lib.types.bool; + default = true; + }; + + workspace = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + }; + }; + }); + }; +} diff --git a/modules/home-manager/persistence.nix b/modules/home-manager/persistence.nix index a009909..3145f0c 100644 --- a/modules/home-manager/persistence.nix +++ b/modules/home-manager/persistence.nix @@ -18,11 +18,29 @@ in description = "The location to store the files described in this record"; }; + prefixDirectories = lib.mkOption { + type = lib.types.bool; + default = true; + example = false; + description = "Whether to enable gnu/stow type prefix directories"; + }; + apps = lib.mkOption { default = { }; description = "The apps to be stores in this persistent location"; type = lib.types.attrsOf (lib.types.submodule (_: { options = { + files = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + example = [ ".screenrc" ]; + description = '' + A list of files in your home directory you want to + link to persistent storage. Allows both absolute paths + and paths relative to the home directory. . + ''; + }; + directories = lib.mkOption { default = [ ]; description = "Modified version of home.persistence.*.directories which takes in absolute paths"; @@ -36,7 +54,7 @@ in method = lib.mkOption { type = lib.types.enum [ "bindfs" "symlink" ]; - default = "bindfs"; + default = "symlink"; description = '' The linking method that should be used for this directory. bindfs is the default and works for most use @@ -60,7 +78,12 @@ in makeLocation = location: let processPath = appName: value: - "${appName}/${lib.strings.removePrefix config.home.homeDirectory (builtins.toString value)}"; + let + suffix = "${lib.strings.removePrefix "${config.home.homeDirectory}/" (builtins.toString value)}"; + prefix = if location.prefixDirectories then "${appName}/" else ""; + in + # lib.debug.traceSeq "\nProcessing path at location ${location.path} and app ${appName} from original path ${value} to ${prefix + suffix}" + (prefix + suffix); mkDirectory = appName: directory: if builtins.isAttrs directory then { @@ -70,12 +93,16 @@ in else processPath appName directory; mkAppDirectory = appName: app: builtins.map (mkDirectory appName) app.directories; + mkAppFiles = appName: app: builtins.map (processPath appName) app.files; in lib.attrsets.nameValuePair (location.path + config.home.homeDirectory) { - removePrefixDirectory = true; + removePrefixDirectory = location.prefixDirectories; allowOther = true; directories = lib.lists.flatten (lib.attrsets.mapAttrsToList mkAppDirectory location.apps); + + files = lib.lists.flatten + (lib.attrsets.mapAttrsToList mkAppFiles location.apps); }; in lib.mkIf cfg.enable {