From 7754bc246f72e03c09de0e1ece58d5bb212adbb7 Mon Sep 17 00:00:00 2001 From: atagen Date: Wed, 21 May 2025 17:03:16 +1000 Subject: [PATCH] feat: init --- flake.lock | 43 ++++++++++++++++++++++++++++++++++ flake.nix | 41 ++++++++++++++++++++++++++++++++ module.nix | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ smooooth.sh | 39 +++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 module.nix create mode 100755 smooooth.sh diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..aa97b79 --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "nix-systems": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1747728033, + "narHash": "sha256-NnXFQu7g4LnvPIPfJmBuZF7LFy/fey2g2+LCzjQhTUk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2f9173bde1d3fbf1ad26ff6d52f952f9e9da52ea", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nix-systems": "nix-systems", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..3e07230 --- /dev/null +++ b/flake.nix @@ -0,0 +1,41 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nix-systems.url = "github:nix-systems/default-linux"; + }; + + outputs = + inputs: + with inputs; + let + forAllSystems = + function: + nixpkgs.lib.genAttrs (import nix-systems) ( + system: function system nixpkgs.legacyPackages.${system} + ); + in + { + packages = + preferredNix: + forAllSystems ( + _: pkgs: { + default = pkgs.writeShellApplication { + name = "smooooth"; + runtimeInputs = builtins.getAttrs { + inherit (pkgs) + polkit + gnugrep + coreutils + libnotify + ; + inherit preferredNix; + }; + text = builtins.readFile ./smooooth.sh; + }; + } + ); + nixosModules = forAllSystems ( + system: _: import ./module.nix { smooooth = self.packages.${system}.default; } + ); + }; +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..0199957 --- /dev/null +++ b/module.nix @@ -0,0 +1,67 @@ +{ + pkgs, + lib, + config, + smooooth, + ... +}: +let + inherit (lib.options) types mkEnable mkOption; + cfg = config.smooooth; +in +{ + options.smooooth = { + enable = mkEnable "the smooooth nixos hot reloader"; + blockers = mkOption { + description = "Names of processes that may block reloading when holding a flake (sub)path open."; + default = [ + "nano" + "nvim" + "vim" + "vi" + "hx" + ]; + example = '' + [ "hx" ] + ''; + type = types.listOf types.str; + }; + path = mkOption { + description = "Path to the root of your flake."; + type = types.str; + }; + pollingRate = mkOption { + description = "How frequently to poll for blockers when waiting on a reload."; + default = 10; + type = types.int; + }; + preferredNix = mkOption { + description = "Your preferred package that provides a nix-compatible executable."; + default = pkgs.nix; + type = types.package; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.user = { + services.smooooth = { + serviceConfig = { + Type = "oneshot"; + ExecStart = + let + blockers = builtins.concatStringsSep "|" cfg.blockers; + in + "smooooth ${cfg.path} ${blockers} ${toString cfg.pollingRate}"; + }; + }; + paths.smooooth = { + path = [ (smooooth cfg.preferredNix) ]; + pathConfig = { + PathChanged = cfg.path; + Unit = "smoooth.service"; + TriggerLimitIntervalSec = cfg.pollingRate * 2; + }; + }; + }; + }; +} diff --git a/smooooth.sh b/smooooth.sh new file mode 100755 index 0000000..c17ffb5 --- /dev/null +++ b/smooooth.sh @@ -0,0 +1,39 @@ +SACRED_SPACE="$1" +BLOCKERS="$2" +PERIOD="$3" + +scrapePids() { + for pid in $(ls /proc); do + if [[ "$pid" =~ ^[0-9]*$ ]]; then + if egrep -q $BLOCKERS /proc/$pid/comm; then + cat /proc/$pid/comm + readlink /proc/$pid/cwd + if [[ "$(readlink /proc/$pid/cwd)" == "$SACRED_SPACE"* ]]; then + return 0 + fi + fi + fi + done + return 1 +} + +notify-send "smooooth" "config change detected. waiting for blockers to resolve.." +while scrapePids; do + echo "found blocker in $SACRED_SPACE, waiting.." + sleep $PERIOD +done + +echo "building system" +notify-send "smooooth" "rebuilding your nixos config - please stand by" +temp="$(mktemp -d)" +build="$temp/system" +nix build --out-link $build $SACRED_SPACE#nixosConfigurations.$HOSTNAME.config.system.build.toplevel + +echo "built - attempting to activate system" +notify-send "smooooth" "activating your new config" +switch="$(readlink $build)/bin/switch-to-configuration" +pkexec $switch switch + +echo "cleaning up" +rm -r $temp +