From fea7171ae5e645e3debca1fb5060058896944251 Mon Sep 17 00:00:00 2001 From: Peder Bergebakken Sundt <pbsds@hotmail.com> Date: Tue, 1 Apr 2025 01:41:21 +0200 Subject: [PATCH] lkjsalkjdsalkjdsalkj --- flake.nix | 2 +- justfile | 198 +++++++++++++++--- profiles/known-hosts/hosts.toml | 4 +- .../pbsds/home/profiles/bashrc.d/nix-shell.sh | 1 + .../home/profiles/bashrc.d/zeditor-remote.sh | 29 ++- .../home/profiles/desktop/zed/remote.nix | 8 +- users/pbsds/home/profiles/git.nix | 32 +-- users/pbsds/home/profiles/nix.nix | 10 + 8 files changed, 230 insertions(+), 54 deletions(-) diff --git a/flake.nix b/flake.nix index 7c708ca..592d559 100644 --- a/flake.nix +++ b/flake.nix @@ -369,7 +369,7 @@ in lib.pipe files [ (lib.filterAttrs (k: v: lib.hasPrefix (toString self) (toString v.source))) (lib.mapAttrs' (k: v: lib.nameValuePair - (lib.removePrefix "/home/pbsds" k) + (lib.removePrefix "/home/pbsds/" k) ("." + lib.removePrefix (toString self) (toString v.source)) )) ]; diff --git a/justfile b/justfile index 44e54b5..e5ac869 100644 --- a/justfile +++ b/justfile @@ -2,6 +2,7 @@ set positional-arguments # makes variables accesible as $1 $2 $@ export invokedir := invocation_directory() export GUM_CHOOSE_HEIGHT := "15" export GUM_FILTER_HEIGHT := "15" +export FZF_DEFAULT_OPTS := "--height 15 --cycle --bind 'ctrl-a:toggle-all' " + env('FZF_DEFAULT_OPTS', "") #export hosts_nixos := `2>/dev/null nix eval .\#nixosConfigurations --apply builtins.attrNames --json` #export hosts_fhs := `2>/dev/null nix eval .\#systemConfigs --apply builtins.attrNames --json` @@ -10,9 +11,9 @@ export GUM_FILTER_HEIGHT := "15" just "$(gum filter --placeholder "Pick a recipie..." $(just --summary --unsorted))" eval hostname=`just _a_host`: - nix eval .#nixosConfigurations."{{hostname}}".config.system.build.toplevel.outPath --show-trace + nix eval ".#nixosConfigurations.\"{{hostname}}\".config.system.build.toplevel.outPath" --show-trace eval-vm hostname=`just _a_host`: - nix eval .#nixosConfigurations."{{hostname}}".config.system.build.vm.outPath --show-trace + nix eval ".#nixosConfigurations.\"{{hostname}}\".config.system.build.vm.outPath" --show-trace repl $hostname=`just _a_host`: NIX_NO_NOM=1 nixos-rebuild --flake .#"$hostname" repl @@ -73,46 +74,187 @@ boot-and-reboot: push hostname=`just _a_host` cmd=`gum choose test switch boot --header "Select mode..."`: nixos-rebuild build --flake .#{{hostname}} @printf "%s\n" pushing... - NIX_NO_NOM=1 nixos-rebuild {{cmd}} --flake .#{{hostname}} --target-host root@$(nix eval .#nixosConfigurations."{{hostname}}".config.networking.fqdn --json | jq . -r) --use-substitutes + NIX_NO_NOM=1 nixos-rebuild {{cmd}} --flake .#{{hostname}} --target-host root@$(nix eval ".#nixosConfigurations.\"{{hostname}}\".config.networking.fqdn" --json | jq . -r) --use-substitutes #NIX_NO_NOM=1 NIX_SSHOPTS="-tt" nixos-rebuild {{cmd}} --flake .#"{{hostname}}" --use-remote-sudo --target-host $(nix eval .#nixosReports."{{hostname}}".fqdn --json | jq . -r) --use-substitutes +test-files $hostname=`just _a_host` *filenames: + #!/usr/bin/env -S bash -euo pipefail + # TODO: remember previous choices + [[ -n "$hostname" ]] || { printf >&2 "%s\n" "ERROR: no hostname"; false; } + declare -a filenames=("${@:2}") + if [[ "${#filenames[@]}" -eq 0 ]]; then + etcfiles=$( + nix eval ".#nixosConfigurations.\"$hostname\".config.environment.etc" --json \ + --apply 'builtins.mapAttrs (k: v: { inherit (v) enable target mode; })' + ) + homekeys=$( + nix eval ".#nixosConfigurations.\"$hostname\".config.home-manager.users" --json \ + --apply 'builtins.mapAttrs (user: config: { inherit (config.home) homeDirectory; files = builtins.mapAttrs (k: v: { inherit (v) enable target recursive; }) config.home.file; } )' + # | jq 'to_entries[]| .key as $user | .value.homeDirectory as $homeDirectory | .value.files | to_entries[] | select(.value) | [ "config.home-manager.users.\"\($user)\".home.file.\"\(.key)\"", $homeDirectory + "/" + .value.target, .value.target, .key, $user, $homeDirectory] | @tsv' -r + ) + filepathindex=$( + jq --null-input -c \ + --arg hostname "$hostname" \ + --argjson etcfiles "$etcfiles" \ + --argjson homekeys "$homekeys" \ + '{ + "nixosConfigurations.\"\($hostname)\".config.environment.etc": ( + $etcfiles | with_entries( select(.value.enable) | { key, value: (.value + { target : ("/etc/" + .value.target) }) } ) + ) + } + ( + $homekeys | with_entries( + .key as $user | + .value.homeDirectory as $homeDirectory | + { + key: ("nixosConfigurations.\"\($hostname)\".config.home-manager.users.\"\($user)\".home.file"), + value: ( + .value.files | with_entries( + select(.value.enable) | { + key, + value: (.value + { + target: ($homeDirectory + "/" + .value.target), + }), + } + ) + ), + } + ) + )' + ) + + # cache + if [[ "$UID" -ne 0 ]]; then + mkdir -p .direnv/ + cat <<<"$filepathindex" >.direnv/just-cache-test-files-"$hostname".json + fi + else + [[ -s .direnv/just-cache-test-files-"$hostname".json ]] || { printf >&2 "%s\n" "ERROR: no cache found"; false; } + filepathindex=$(cat .direnv/just-cache-test-files-"$hostname".json) + fi + + if [[ "${#filenames[@]}" -eq 0 ]]; then + filenames=$( + set +e + jq <<<"$filepathindex" 'to_entries[] | .value | to_entries[] | .value' -r \ + | fzf --height=50% --reverse --multi -d$'\t' --with-nth 2 + ) + [[ -n "$selection" ]] + fi + + # jq <<<"$filepathindex" . ; false + + filepathindex_inverse=$( + jq <<<"$filepathindex" 'with_entries( .key as $attr | .value | to_entries[] | {key: .value.target, value: (.value + {attr: $attr, key})} )' -c + ) + # jq <<<"$filepathindex_inverse" . ; false + + # jq <<<"$filepathindex" 'to_entries[] | .key as $attr | .value | to_entries[] | @sh "\(.value) \($attr).\("\""+.key+"\"")"' -r + + nix_expr=$( + printf "%s\n" 'pkgs.writeScript "do" (' + printf '"%s\\n" +\n' '#!${pkgs.runtimeShell}' + printf '"%s\\n" +\n' 'set -euo pipefail' + printf '"%s\\n" +\n' 'sudo : && SUDO=sudo || SUDO=:' + printf "%s\n" "${filenames[@]}" | + jq -sR --argjson index "$filepathindex_inverse" ' + split("\n") | map(select(.==""|not) | $index[.] ) | group_by(.attr) | map( + " (let cfg = \(.[0].attr); in '"''"'" + (map( + if .target | startswith("/etc/") then + if .mode == "symlink" and false then " + $SUDO ln -sfn ${cfg.\"\(.key)\".source} \(.target | @sh ) + " else " + $SUDO rm -rf \(.target | @sh ) + $SUDO cp -a ${cfg.\"\(.key)\".source} \(.target | @sh ) + $SUDO chown -R ${toString cfg.\"\(.key)\".uid}:${toString cfg.\"\(.key)\".gid} \(.target | @sh ) + $SUDO chmod -R ${toString cfg.\"\(.key)\".uid}:${toString cfg.\"\(.key)\".gid} \(.target | @sh ) + # TODO: cfg.\"\(.key)\".user + # TODO: cfg.\"\(.key)\".group + " end + else + if .recursive then + "${lib.getExe pkgs.xorg.lndir} -silent ${cfg.\"\(.key)\".source} \(.target | @sh )\n" + else + "ln -sfn ${cfg.\"\(.key)\".source} \(.target | @sh )\n" + end + end + ) | join("")) + "'"''"')" + ) | join(" + \n") + ' -r + printf "%s\n" ')' + ) + # printf "%s\n" "$nix_expr" ; false + + flake=$(nix flake archive . --json | jq .path -r) + nix build --impure --expr "with (builtins.getFlake ''$flake''); let inherit (nixosConfigurations.\"$hostname\") pkgs; in $nix_expr" --show-trace + false + + # TODO: run the result + + inspect: nix run -- nixpkgs#nix-inspect -p . inspect-config host=`just _a_host` prefix="": nix run -- nixpkgs#nix-inspect -e '(builtins.getFlake "'"$PWD"'").nixosConfigurations."{{host}}".config{{ if prefix == "" { "" } else { "." + prefix } }}' -_a_host: +_nixos_attrnames: #!/usr/bin/env -S bash -euo pipefail - hostnames="$(nix eval .#nixosConfigurations --apply builtins.attrNames --json 2>/dev/null | jq '.[]' -r)" - if test "$(grep <<<"$hostnames" "^$(just remote-current)$" | wc -l)" -eq 1; then hostnames="$(just remote-current; grep <<<"$hostnames" -v "^$(just remote-current)$")"; fi - if test "$(grep <<<"$hostnames" "^$(hostname)$" | wc -l)" -eq 1; then hostnames="$(hostname; grep <<<"$hostnames" -v "^$(hostname)$")"; fi - gum <<<"$hostnames" filter --placeholder "Pick a host..." + hostname=$(hostname) + cachefile=.direnv/just-cache-nixos-attrnames.txt + if [[ flake.nix -nt "$cachefile" ]]; then + hostnames=$(nix eval .#nixosConfigurations --apply builtins.attrNames --json 2>/dev/null | jq '.[]' -r) + if [[ "$(grep <<<"$hostnames" -Fx "$hostname" | wc -l)" -eq 1 ]]; then + hostnames="$(printf "%s\n" "$hostname"; grep <<<"$hostnames" -v "^$hostname$")" + fi + if [[ "$UID" -ne 0 ]]; then + mkdir -p .direnv/ + cat <<<"$hostnames" >"$cachefile" + fi + else + hostnames="$(cat $cachefile)" + fi + current_remote=$(just remote-current) + if [[ -n "$current_remote" && "$current_remote" != "$hostname" && "$(grep <<<"$hostnames" -Fx "$current_remote" | wc -l)" -eq 1 ]]; then + head -n1 <<<"$hostnames" + printf "%s\n" "$current_remote" + tail -n+2 <<<"$hostnames" | grep -vFx "$current_remote" + else + printf "%s\n" "$hostnames" + fi -# ctrl-c is counted as a timeout... -_a_host_timeout: - #!/usr/bin/env -S bash -euo pipefail - hostnames="$(nix eval .#nixosConfigurations --apply builtins.attrNames --json 2>/dev/null | jq '.[]' -r)" - if test "$(grep <<<"$hostnames" "^$(hostname)$" | wc -l)" -eq 1; then hostnames="$(hostname; grep <<<"$hostnames" -v "^$(hostname)$")"; fi - gum <<<"$hostnames" filter --placeholder "Pick a host..." --timeout 5s || hostname +@_a_host: + # just _nixos_attrnames | gum filter --placeholder "Pick a host..." + # just _nixos_attrnames | fzf --reverse + just _nixos_attrnames | fzf -_some_hosts: - #!/usr/bin/env -S bash -euo pipefail - hostnames="$(nix eval .#nixosConfigurations --apply builtins.attrNames --json 2>/dev/null | jq '.[]' -r)" - if test "$(grep <<<"$hostnames" "^$(hostname)$" | wc -l)" -eq 1; then hostnames="$(hostname; grep <<<"$hostnames" -v "^$(hostname)$")"; fi - gum <<<"$hostnames" filter --placeholder "Pick a host..." --no-limit +@_some_hosts: + # just _nixos_attrnames | gum filter --placeholder "Pick a host..." --no-limit + # just _nixos_attrnames | fzf --reverse --multi + just _nixos_attrnames | fzf --multi -_a_fqdn: +_nixos_fqdns: #!/usr/bin/env -S bash -euo pipefail - hostnames="$(nix eval .#nixosConfigurations --apply 'c: builtins.attrValues (builtins.mapAttrs (_: x: x.config.networking.fqdn) c)' --json 2>/dev/null | jq '.[]' -r)" - if test "$(grep <<<"$hostnames" "^$(hostname --fqdn)$" | wc -l)" -eq 1; then hostnames="$(hostname --fqdn; grep <<<"$hostnames" -v "^$(hostname --fqdn)$")"; fi - gum <<<"$hostnames" filter --placeholder "Pick a host..." + cachefile=.direnv/just-cache-nixos-fqdns.json + if [[ flake.nix -nt "$cachefile" ]]; then + mkdir -p .direnv/ + fqdns=$(nix eval .#nixosConfigurations --apply 'builtins.mapAttrs (_: x: x.config.networking.fqdn)' --json 2>/dev/null) + if [[ "$UID" -ne 0 ]]; then + cat <<<"$fqdns" >"$cachefile" + fi + else + fqdns=$( cat "$cachefile" ) + fi + just _nixos_attrnames | jq -R --argjson fqdns "$fqdns" '$fqdns[.]' -r -_some_fqdns: - #!/usr/bin/env -S bash -euo pipefail - hostnames="$(nix eval .#nixosConfigurations --apply 'c: builtins.attrValues (builtins.mapAttrs (_: x: x.config.networking.fqdn) c)' --json 2>/dev/null | jq '.[]' -r)" - if test "$(grep <<<"$hostnames" "^$(hostname --fqdn)$" | wc -l)" -eq 1; then hostnames="$(hostname --fqdn; grep <<<"$hostnames" -v "^$(hostname --fqdn)$")"; fi - gum <<<"$hostnames" filter --placeholder "Pick a host..." --no-limit +@_a_fqdn: + # just _nixos_fqdns | gum filter --placeholder "Pick a host..." + # just _nixos_fqdns | fzf --reverse + just _nixos_fqdns | fzf + +@_some_fqdns: + # just _nixos_fqdns | gum filter --placeholder "Pick a host..." --no-limit + # just _nixos_fqdns | fzf --reverse --multi + just _nixos_fqdns | fzf --multi @remote-current: # remote-host # slow diff --git a/profiles/known-hosts/hosts.toml b/profiles/known-hosts/hosts.toml index 94c5400..ca511dd 100644 --- a/profiles/known-hosts/hosts.toml +++ b/profiles/known-hosts/hosts.toml @@ -131,8 +131,8 @@ buildMachine.maxJobs = 2 # 8 threads 16GB ssh.userPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF4v1+FbiEa6Mohpf3/Una5ahKeKSG9yZ9iU5TC7ddL5 root@bjarte" # wakeonlan f8:75:a4:58:f1:35 -["FuriPhoneFLX1"] -aliases = [ "FuriPhoneFLX1.tail9aac63.ts.net" ] # "FuriPhoneFLX1.pbsds.net", +["furiphoneflx1"] +aliases = [ "furiphoneflx1.tail9aac63.ts.net" ] # "FuriPhoneFLX1.pbsds.net", ssh.userPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAsBuczprbq2seyfZ4UCoX8DeRmyCg+LfBzrY4tfUhjK root@FuriPhoneFLX1" # wakeonlan 1c:9f:4e:57:85:58 wireless diff --git a/users/pbsds/home/profiles/bashrc.d/nix-shell.sh b/users/pbsds/home/profiles/bashrc.d/nix-shell.sh index ba7697a..b9e9fc4 100644 --- a/users/pbsds/home/profiles/bashrc.d/nix-shell.sh +++ b/users/pbsds/home/profiles/bashrc.d/nix-shell.sh @@ -95,6 +95,7 @@ _ns_ohk2aaDu() { seen["$storepath"]=1 # TODO: $dev/lib/cmake + # TODO: source completions from /share/bash-completion/completions/* if [[ -d "$storepath/bin" ]]; then export PATH="$storepath/bin${PATH:+":$PATH"}" fi diff --git a/users/pbsds/home/profiles/bashrc.d/zeditor-remote.sh b/users/pbsds/home/profiles/bashrc.d/zeditor-remote.sh index 9e8ce71..a2f5df1 100644 --- a/users/pbsds/home/profiles/bashrc.d/zeditor-remote.sh +++ b/users/pbsds/home/profiles/bashrc.d/zeditor-remote.sh @@ -1,5 +1,4 @@ zeditor-remote() { - local prefix="${1:-repos}" local statedir="${XDG_STATE_HOME:-"$HOME/.local/state/"}/zeditor-remote-sh" local -a missing=() @@ -17,15 +16,6 @@ zeditor-remote() { return 1 fi - # make $prefix relative to $HOME - if [[ "$prefix" =~ ^/ ]]; then - prefix=${prefix//"$HOME/"/} - fi - if [[ "$prefix" =~ ^/ ]]; then - printf >&2 "%s\n" "ERROR: prefix not in \$HOME ($prefix)" - return 1 - fi - uniq-stable() ( command cat -n | sort -b --key=2.1 -u | sort -n | cut -f2- ) @@ -69,6 +59,25 @@ zeditor-remote() { return 1 fi + local prefix="${gum input }" + # make $prefix relative to $HOME + if [[ "$prefix" =~ ^/ ]]; then + prefix="${prefix//"$HOME/"/}" + fi + if [[ "$prefix" =~ ^/ ]]; then + printf >&2 "%s\n" "ERROR: prefix not in \$HOME ($prefix)" + return 1 + fi + # remove trialing slash + while [[ "$prefix" =~ /$ ]]; do + prefix="${prefix/%"/"/}" + done + if [[ -z "$prefix" ]]; then + printf >&2 "%s\n" "ERROR: prefix chosen" + return 1 + fi + + # local spin=(gum spin --show-output --show-error --) local spin=(gum spin --show-output --) local repos=$( diff --git a/users/pbsds/home/profiles/desktop/zed/remote.nix b/users/pbsds/home/profiles/desktop/zed/remote.nix index 2deaa57..447a8eb 100644 --- a/users/pbsds/home/profiles/desktop/zed/remote.nix +++ b/users/pbsds/home/profiles/desktop/zed/remote.nix @@ -25,11 +25,17 @@ nil # nix unstable.nixfmt-rfc-style # nix harper # harper - vale-ls # vale + vale-ls vale # vale typos-lsp # typos tinymist # typst # I prefer these in shell.nix / virtual environments # python3Packages.python-lsp-server # pylsp ]; + + home.file.".config/vale/.vale.init".text = '' + MinAlertLevel = suggestion + [*] + BasedOnStyles = Vale + ''; } diff --git a/users/pbsds/home/profiles/git.nix b/users/pbsds/home/profiles/git.nix index 7e125b3..79bec39 100644 --- a/users/pbsds/home/profiles/git.nix +++ b/users/pbsds/home/profiles/git.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ pkgs, lib, ... }: { home.packages = with pkgs; [ #git @@ -55,10 +55,10 @@ programs.git.extraConfig.log.date = "iso"; /* programs.git.extraConfig.interactive.singleKey = true; */ - programs.git.iniContent.init.defaultBranch = "main"; programs.git.ignores = [ #".envrc" + ".direnv" ".remote.toml" ".remoteenv" ".zed" @@ -73,25 +73,33 @@ home.shellAliases = { # git gud gs = "git status"; - gl = "git log --oneline --color | head -n 30"; - glg = "git log --all --decorate --oneline --graph"; + gl = "git --no-pager log --oneline --color -n30"; + glg = "git log --color --all --decorate --oneline --graph"; gpra = "git pull --rebase --autostash"; gprau = ''git pull --rebase --autostash upstream "$(git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"''; gd = "git diff"; - gdwd = "git diff --word-diff"; - gdwdr = "git diff --word-diff --word-diff-regex=."; gds = "git diff --staged"; - gdswd = "git diff --staged --word-diff"; - gdswdr = "git diff --staged --word-diff --word-diff-regex=."; - gcp = "git cherry-pick"; + gdwd = "git -c core.pager=\"$PAGER\" diff --word-diff"; # delta does not support --word-diff + gdwdr = "git -c core.pager=\"$PAGER\" diff --word-diff --word-diff-regex=."; + gdwds = "git -c core.pager=\"$PAGER\" diff --staged --word-diff"; + gdswd = "git -c core.pager=\"$PAGER\" diff --staged --word-diff"; + gdwdrs = "git -c core.pager=\"$PAGER\" diff --staged --word-diff --word-diff-regex=."; + gdswdr = "git -c core.pager=\"$PAGER\" diff --staged --word-diff --word-diff-regex=."; + #gcp = "git cherry-pick"; gca = "git commit --amend"; gcara = "git commit --amend --reset-author"; - gfr = "git pull --rebase"; - gc = "git branch | cut -c2- | gum choose | xargs git checkout"; - gbrm = "git fetch origin; git branch --merged | cut -c3- | grep -vE '^(main|master)$' | gum choose --no-limit --header 'Which branches to delete:' | xargs git branch -D"; + gc = "git branch | cut -c2- | gum choose | xargs -n'\n' --no-run-if-empty git checkout"; + gbrm = "git fetch origin; git branch --merged | cut -c3- | grep -vE '^(main|master)$' | gum choose --no-limit --header 'Which branches to delete:' | xargs -n'\n' --no-run-if-empty git branch -D"; #gb = "git blame"; #gpo = "git push origin"; #gpf = "git push --force-with-lease --force-if-includes"; + gcm = ''git commit --message "$(printf '%s\n' ${lib.concatStringsSep " " [ + ''"$(curl -sL https://whatthecommit.com/index.txt)"'' + ''""'' + ''"$(curl -s 'https://printerfacts.cetacean.club/fact')"'' + ''""'' + ''"(made with https://whatthecommit.com/index.txt and https://printerfacts.cetacean.club/fact)"'' + ]})"; git show --name-status; ''; }; } diff --git a/users/pbsds/home/profiles/nix.nix b/users/pbsds/home/profiles/nix.nix index a09df49..6b8ced9 100644 --- a/users/pbsds/home/profiles/nix.nix +++ b/users/pbsds/home/profiles/nix.nix @@ -46,6 +46,10 @@ in rnix = mkArgsAlias ''nix "$@" --system riscv64-linux -j0''; fnom = mkArgsAlias ''nom "$@" --system x86_64-freebsd -j0''; fnix = mkArgsAlias ''nix "$@" --system x86_64-freebsd -j0''; + fanom = mkArgsAlias ''nom "$@" --system aarch64-freebsd -j0''; + fanix = mkArgsAlias ''nix "$@" --system aarch64-freebsd -j0''; + xnom = mkArgsAlias ''nom "$@" --system x86_64-linux -j0''; + xnix = mkArgsAlias ''nix "$@" --system x86_64-linux -j0''; anom = mkArgsAlias ''nom "$@" --system aarch64-linux -j0''; anix = mkArgsAlias ''nix "$@" --system aarch64-linux -j0''; dnom = mkArgsAlias ''nom "$@" --system x86_64-darwin -j0''; @@ -59,6 +63,10 @@ in rnix-build = "nix-build --system riscv64-linux -j0"; fnom-build = "nom-build --system x86_64-freebsd -j0"; fnix-build = "nix-build --system x86_64-freebsd -j0"; + fanom-build = "nom-build --system aarch64-freebsd -j0"; + fanix-build = "nix-build --system aarch64-freebsd -j0"; + xnom-build = "nom-build --system x86_64-linux -j0"; + xnix-build = "nix-build --system x86_64-linux -j0"; anom-build = "nom-build --system aarch64-linux -j0"; anix-build = "nix-build --system aarch64-linux -j0"; dnom-build = "nom-build --system x86_64-darwin -j0"; @@ -66,6 +74,8 @@ in danom-build = "nom-build --system aarch64-darwin -j0"; danix-build = "nix-build --system aarch64-darwin -j0"; + nix-eval = "nix eval --impure --expr"; + nix-eval-nixpkgs = mkArgsAlias ''nix eval --impure --expr "with import (builtins.getFlake "nixpkgs") {}; $1" "''${@:2}"''; }; programs.bash.initExtra = ''