This commit is contained in:
Madeleine Sydney
2025-04-12 19:54:00 -06:00
16 changed files with 139 additions and 281 deletions

35
flake.lock generated Executable file → Normal file
View File

@@ -679,6 +679,22 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_12": {
"locked": {
"lastModified": 1743568003,
"narHash": "sha256-ZID5T65E8ruHqWRcdvZLsczWDOAWIE7om+vQOREwiX0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b7ba7f9f45c5cd0d8625e9e217c28f8eb6a19a76",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1742669843, "lastModified": 1742669843,
@@ -867,6 +883,7 @@
"sops-nix": "sops-nix", "sops-nix": "sops-nix",
"stylix": "stylix", "stylix": "stylix",
"sydnix-cli": "sydnix-cli", "sydnix-cli": "sydnix-cli",
"tf2-nix": "tf2-nix",
"vpn-confinement": "vpn-confinement" "vpn-confinement": "vpn-confinement"
} }
}, },
@@ -984,6 +1001,24 @@
"type": "github" "type": "github"
} }
}, },
"tf2-nix": {
"inputs": {
"nixpkgs": "nixpkgs_12"
},
"locked": {
"lastModified": 1744277918,
"narHash": "sha256-8C+wwrjYvatRDXE8HLeN0rUnfOW/ehqpBKhOkx4/mm0=",
"owner": "msyds",
"repo": "tf2-nix",
"rev": "e40d15248908d22041dbea7e3f693972a5913c2f",
"type": "gitlab"
},
"original": {
"owner": "msyds",
"repo": "tf2-nix",
"type": "gitlab"
}
},
"tinted-foot": { "tinted-foot": {
"flake": false, "flake": false,
"locked": { "locked": {

View File

@@ -28,6 +28,7 @@
url = "github:nix-community/NUR"; url = "github:nix-community/NUR";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
tf2-nix.url = "gitlab:msyds/tf2-nix";
}; };
outputs = { self, nixpkgs, ... }@inputs: outputs = { self, nixpkgs, ... }@inputs:

View File

@@ -13,7 +13,11 @@
sydnix = { sydnix = {
filesystemType = "btrfs"; filesystemType = "btrfs";
steam.enable = true; steam = {
enable = true;
impermanenceUsers = ["crumb"];
};
niri.enable = true; niri.enable = true;
stylix.enable = true; stylix.enable = true;
qemu.enable = true; qemu.enable = true;

View File

@@ -19,7 +19,7 @@ in {
# #
# https://github.com/ValveSoftware/steam-for-linux/issues/10552 # https://github.com/ValveSoftware/steam-for-linux/issues/10552
# https://github.com/nix-community/impermanence/issues/165 # https://github.com/nix-community/impermanence/issues/165
{ directory = ".local/share/Steam"; method = "symlink"; } # { directory = ".local/share/Steam"; method = "symlink"; }
{ directory = ".steam"; method = "symlink"; } { directory = ".steam"; method = "symlink"; }
]; ];

View File

@@ -1,24 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.tf2;
in {
options.tf2 = {
enable = lib.mkEnableOption "Team Fortress 2 configuration";
packages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
};
};
config = lib.mkIf cfg.enable
(let gameDir = ".local/share/Steam/steamapps/common/Team Fortress 2";
in {
home.file."tf" = {
recursive = true;
source = pkgs.symlinkJoin {
name = "tf2-files";
paths = cfg.packages;
};
};
});
}

View File

@@ -1,99 +0,0 @@
{ lib
, runCommand
, fetchFromGitHub
, fetchurl
, fetchzip
, ... }:
let
mkTf2Package =
{ pname
, version ? null
, cfg ? []
, custom ? []
, env ? {}
}@args:
let name = "${pname}${lib.optionalString (version != null) "-${version}"}";
in runCommand name env ''
${lib.toShellVar "cfgs" cfg}
${lib.toShellVar "customs" custom}
set -xe
mkdir -p $out/cfg $out/custom
for i in "''${cfgs[@]}"; do
ln -s "$i" "$out/cfg/$(basename "$i")"
done
for i in "''${customs[@]}"; do
ln -s "$i" "$out/custom/$(basename "$i")"
done
'';
mkCfg = name: body:
runCommand name {} ''
${lib.toShellVar "name" name}
mkdir -p $out/cfg "$(dirname "$out/cfg/$name")"
tee "$out/cfg/$name.cfg" << SUPER_UNIQUE_EOF
// Generated by tf2.nix
${body}
SUPER_UNIQUE_EOF
'';
mkTf2PackageFromDir = path:
runCommand "tf2-dir" {} ''
cp -r "${path}" $out
'';
fetchFromGameBanana =
{ id
, hash
}:
fetchzip {
url = "https://gamebanana.com/dl/${id}";
extension = "zip";
inherit hash;
};
mastercomfig = import ./packages/mastercomfig.nix {
inherit mkTf2Package;
inherit fetchurl;
};
in {
inherit mkTf2Package mastercomfig mkCfg mkTf2PackageFromDir;
huds.deerhud = mkTf2Package {
pname = "deerhud";
version = "78a24ef";
custom = [
(fetchFromGitHub {
name = "deerhud";
owner = "DeerUwU";
repo = "deerhud-tf2";
rev = "78a24effbc66bc78b4bb557228eaa0195db3270c";
hash = "sha256-uwKRilkEPHk1snjH/n9u32dMXr3cXjYN06cfthpZe7g=";
})
];
};
loadouts-script = mkTf2Package rec {
pname = "tf2-loadouts-script";
version = "3.1";
custom = [
(fetchurl {
url = "https://github.com/jooonior/tf2-loadouts-script/releases/download/v${version}/loadouts.vpk";
hash = "sha256-qMDQe/lLZz5YdH6kvG7vNKHUxPvId4AMqu/hFqr/Sd8=";
})
];
};
improved-crosshairs = mkTf2Package {
pname = "improved-crosshairs";
custom = [
(fetchFromGameBanana {
id = "1047153";
hash = "sha256-ULcSfxuiGY1YCE1zQ693183F7ZRC11tYhvDMJKyzL1A=";
})
];
};
}

View File

@@ -1,116 +0,0 @@
{ fetchurl
, mkTf2Package
}:
let
mastercomfigVersion = "9.10.3";
releasesUrl = version:
"https://github.com/mastercomfig/mastercomfig/releases/download/${version}";
fetchMastercomfig = { version, file, hash ? "" }:
fetchurl {
url = "${releasesUrl version}/${file}";
inherit hash;
};
mkMastercomfig =
type:
{ name
, hash
, file ? "mastercomfig-${name}-${type}.vpk"
, version ? mastercomfigVersion
}:
mkTf2Package {
pname = "mastercomfig-${name}-${type}";
inherit version;
custom = [
(fetchMastercomfig {
inherit version file hash;
})
];
};
mkMastercomfigAddon = mkMastercomfig "addon";
mkMastercomfigPreset = mkMastercomfig "preset";
in {
addons.disable-pyroland = mkMastercomfigAddon {
name = "disable-pyroland";
hash = "sha256-cEFaXSXwlHwm7BnkSLmG4vAPYhL1O0XwNG0UpTnDFY8=";
};
addons.flat-mouse = mkMastercomfigAddon {
name = "flat-mouse";
hash = "sha256-v2Url+m8dzXIrs8mz5VZWRqwqSSaxyH7t2vDvT10cdg=";
};
presets.high = mkMastercomfigPreset {
name = "high";
hash = "sha256-704aEg1Gyl5vI6Y6VTmlUEiP70PjrF6/VlxsrkkepWs=";
};
presets.low = mkMastercomfigPreset {
name = "low";
hash = "sha256-CpIbjy1dzNCEa583DthygkIQ5aq7Wp2QOJGANC2IGNs=";
};
addons.lowmem = mkMastercomfigAddon {
name = "lowmem";
hash = "sha256-21iyJ4Zg+p5qES05FP2fMO7/p3YrrIkNp2GM2oEjT4E=";
};
presets.medium-high = mkMastercomfigPreset {
name = "medium-high";
hash = "sha256-pS1KcFxxB/oT9DcopZyu77nr4td6x2mDrEFVNOPmtws=";
};
presets.medium-low = mkMastercomfigPreset {
name = "medium-low";
hash = "sha256-P9Zk9IZVpX1hkAcdpNvKfzP2P+TDPNRwwv4I8uM+WU4=";
};
presets.medium = mkMastercomfigPreset {
name = "medium";
hash = "sha256-yEcxPkU/0vJn7vy3n2ViYdTCBV3O9gX57fMQQZYlm3I=";
};
addons.no-footsteps = mkMastercomfigAddon {
name = "no-footsteps";
hash = "sha256-7WIWwV2PnwRM79I7vOdfRggQi/NUS+6GHkAAyo8ap2I=";
};
addons.no-soundscapes = mkMastercomfigAddon {
name = "no-soundscapes";
hash = "sha256-Qp7QW9zZXpX7zrK+Fmpf428lU7Mc86sMn6+5Syhnxz0=";
};
addons.no-tutorial = mkMastercomfigAddon {
name = "no-tutorial";
hash = "sha256-sA3kN2iNe5bwh+954ef+sV0hjMdMZLs6IPgsHDi5oXE=";
};
presets.none = mkMastercomfigPreset {
name = "none";
hash = "sha256-FQ8o4fxUkIAqlFPZPULScwDBaQjc88NiO579IaFTikA=";
};
addons.null-canceling-movement = mkMastercomfigAddon {
name = "null-canceling-movement";
hash = "sha256-B3pHn80lMRN4q5hF/JSAdzDLTnyh7MNbYzMURrYmXxU=";
};
addons.transparent-viewmodels = mkMastercomfigAddon {
name = "transparent-viewmodels";
hash = "sha256-nsUBSsGHXM+xwecixZvhisbifLqkqSyF7kIkJFmq6ow=";
};
presets.ultra = mkMastercomfigPreset {
name = "ultra";
hash = "sha256-VfSFxRuZtYLuNrtX6X7BEMtL6wMbFyela7zbmZurlCw=";
};
presets.very-low = mkMastercomfigPreset {
name = "very-low";
hash = "sha256-faGnju5aPovl++kAh2HNkkroUoMz9/Fx6kSgb3IBRfg=";
};
}

View File

@@ -29,6 +29,7 @@ alias jsp jj split $*
alias l ls -alh $* alias l ls -alh $*
alias ll ls -l $* alias ll ls -l $*
alias ls ls --color=tty $* alias ls ls --color=tty $*
alias ff find-file $*
alias pass /nix/store/hqhi6dgl7p16v49ymg2hwkgl844092fb-passage-1.7.4a2/bin/passage $* alias pass /nix/store/hqhi6dgl7p16v49ymg2hwkgl844092fb-passage-1.7.4a2/bin/passage $*

View File

@@ -24,6 +24,11 @@
(evil-append-line nil) (evil-append-line nil)
(haskell-indentation-newline-and-indent)) (haskell-indentation-newline-and-indent))
(defun syd-haskell-hoogle-start-server ()
(interactive)
(haskell-hoogle-start-server)
(message "Hoogle started on localhost:%d" haskell-hoogle-port-number))
(use-package haskell-mode (use-package haskell-mode
:mode (("\\.l?hs'" . haskell-literate-mode) :mode (("\\.l?hs'" . haskell-literate-mode)
("\\.hs'" . haskell-mode)) ("\\.hs'" . haskell-mode))
@@ -39,7 +44,7 @@
:prefix syd-localleader-key :prefix syd-localleader-key
:non-normal-prefix syd-alt-localleader-key :non-normal-prefix syd-alt-localleader-key
"c" #'haskell-cabal-visit-file "c" #'haskell-cabal-visit-file
"h s" #'haskell-hoogle-start-server "h s" #'syd-haskell-hoogle-start-server
"h q" #'haskell-hoogle-kill-server) "h q" #'haskell-hoogle-kill-server)
(:keymaps 'interactive-haskell-mode-map (:keymaps 'interactive-haskell-mode-map
:states '(normal insert) :states '(normal insert)
@@ -62,7 +67,9 @@
(syd-add-hook 'haskell-mode-local-vars-hook (syd-add-hook 'haskell-mode-local-vars-hook
;; Folding of Haskell sections. ;; Folding of Haskell sections.
#'haskell-collapse-mode #'haskell-collapse-mode
#'interactive-haskell-mode)) #'interactive-haskell-mode)
(dolist (c '(?' ?_))
(modify-syntax-entry c "w" haskell-mode-syntax-table)))
(use-package lsp-haskell (use-package lsp-haskell
:defer t :defer t

View File

@@ -78,14 +78,19 @@ directory."
(dirvish-directory-view-mode . diredfl-mode))) (dirvish-directory-view-mode . diredfl-mode)))
(use-package dirvish (use-package dirvish
:after dired
:custom ((dirvish-cache-dir (file-name-concat syd-cache-dir "dirvish/")) :custom ((dirvish-cache-dir (file-name-concat syd-cache-dir "dirvish/"))
(dirvish-reuse-session 'open) (dirvish-reuse-session 'open)
(dirvish-default-layout '(0 0.4 0.6)) (dirvish-default-layout '(0 0.4 0.6))
(dirvish-hide-details '(dirvish dirvish-fd dirvish-side))) (dirvish-hide-details '(dirvish dirvish-fd dirvish-side)))
:general
(:keymaps 'dired-mode-map
"<tab>" #'dirvish-subtree-toggle
"TAB" #'dirvish-subtree-toggle)
:init
;; Ugh… I'm fairly certain this leads to eager loading of the entire package.
(dirvish-override-dired-mode 1)
:config :config
;; Fix random void-variable errors. ;; Fix random void-variable errors.
(require 'autorevert) (require 'autorevert))
(dirvish-override-dired-mode 1))
(provide 'syd-dired) (provide 'syd-dired)

View File

@@ -25,6 +25,17 @@
(add-to-list 'project-switch-commands (add-to-list 'project-switch-commands
(funcall switch-cmd #'syd-project-root-find-file "Browse")))) (funcall switch-cmd #'syd-project-root-find-file "Browse"))))
(defun syd-project-checkout (repo-uri)
(interactive (list (read-string "Repo: ")))
(let* ((repo-name
(when (string-match (rx "/" (group-n 1 (+ (any alphanumeric "-_")))
(? ".git") eol)
repo-uri)
(match-string 1 repo-uri)))
(dest (file-name-concat (expand-file-name "~/git") repo-name)))
(shell-command (format "git clone %s %s" repo-uri dest))
(find-file dest)))
;; Projection provides a Projectile-like project management library atop ;; Projection provides a Projectile-like project management library atop
;; Emacs built-in project.el. It's more lightweight, while still featureful. ;; Emacs built-in project.el. It's more lightweight, while still featureful.
(use-package projection (use-package projection

View File

@@ -92,7 +92,9 @@
;; Disable the menu bar, scroll bar, and tool bar. ;; Disable the menu bar, scroll bar, and tool bar.
(menu-bar-mode -1) (menu-bar-mode -1)
(scroll-bar-mode -1) (scroll-bar-mode -1)
(tool-bar-mode -1)) (tool-bar-mode -1)
;; Remember allowed risky variabled.
(advice-add 'risky-local-variable-p :override #'ignore))
(defun syd-init-kill-process-buffer-on-exit () (defun syd-init-kill-process-buffer-on-exit ()
(defun syd-comint--kill-buffer-sentinel (process _output) (defun syd-comint--kill-buffer-sentinel (process _output)

View File

@@ -7,15 +7,13 @@
# -- # --
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib;
let cfg = config.${1:`this-current-file-name`}; let cfg = config.${1:`this-current-file-name`};
in { in {
options.$1 = { options.$1 = {
enable = mkEnableOption "$2"; enable = lib.mkEnableOption "$2";
}; };
config = mkIf cfg.enable { config = lib.mkIf cfg.enable {
$3 $3
}; };
} }

View File

@@ -11,36 +11,45 @@ in {
programs.bash.profileExtra = '' programs.bash.profileExtra = ''
# Start a GHCi REPL with the given packages made available. # Start a GHCi REPL with the given packages made available.
ghci-with-packages () { ghci-with-packages () {
nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [ $@ ])" \ packages=""
--run ghci while getopts 'p:h' opt; do
} case "$opt" in
p)
# Run GHC with the given packages made available. packages="''${OPTARG}"
ghc-with-packages () {
getopt -o "p" -- "$@"
while true; do
case "$1" in
-p)
packages="$1"
shift 2
;; ;;
--) ?|h)
shift echo >&2 "Usage: $(basename $0) [-p packages] [-- ghci-options]"
break exit 1
;; ;;
esac esac
done done
shift "$(($OPTIND -1))"
if [ $? -ne 0 ]; then nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [ $packages ])" \
echo "Invalid options provided" --run "ghci $@"
}
export -f ghci-with-packages
# Run GHC with the given packages made available.
ghc-with-packages () {
packages=""
while getopts 'p:h' opt; do
case "$opt" in
p)
packages="''${OPTARG}"
;;
?|h)
echo >&2 "Usage: $(basename $0) [-p packages] [-- ghc-options]"
exit 1 exit 1
fi ;;
esac
eval set -- "$options" done
shift "$(($OPTIND -1))"
nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [ $packages ])" \ nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [ $packages ])" \
--run "ghc $@" --run "ghc $@"
} }
export -f ghc-with-packages
''; '';
sydnix.impermanence.cache.directories = sydnix.impermanence.cache.directories =

View File

@@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, inputs, ... }:
# Launch options: -novid -nojoy -nosteamcontroller -nohltv -particles 1 -precachefontchars -noquicktime -console -windowed -noborder # Launch options: -novid -nojoy -nosteamcontroller -nohltv -particles 1 -precachefontchars -noquicktime -console -windowed -noborder
@@ -10,21 +10,26 @@ in {
config = lib.mkIf cfg.enable config = lib.mkIf cfg.enable
(let (let
tf2pkgs = pkgs.callPackage ../../tf2/packages.nix {}; tf2pkgs = inputs.tf2-nix.packages.x86_64-linux;
in { my-config = pkgs.symlinkJoin {
tf2 = { name = "tf2-files";
enable = true; paths = with tf2pkgs; [
packages = with tf2pkgs; [
mastercomfig.presets.medium-low mastercomfig.presets.medium-low
mastercomfig.addons.flat-mouse mastercomfig.addons.flat-mouse
mastercomfig.addons.no-tutorial mastercomfig.addons.no-tutorial
mastercomfig.addons.null-canceling-movement mastercomfig.addons.null-canceling-movement
improved-crosshairs improved-crosshairs
loadouts-script loadouts-script
huds.deerhud deerhud
(tf2pkgs.mkTf2PackageFromDir ./tf2/my-config) ./tf2/my-config
(tf2pkgs.mkTf2PackageFromDir ./tf2/quake-hitsounds) ./tf2/quake-hitsounds
]; ];
}; };
game-dir = ".local/share/Steam/steamapps/common/Team Fortress 2/tf";
in {
home.file.${game-dir} = {
recursive = true;
source = my-config;
};
}); });
} }

View File

@@ -4,6 +4,16 @@ let cfg = config.sydnix.steam;
in { in {
options.sydnix.steam = { options.sydnix.steam = {
enable = lib.mkEnableOption "Steam"; enable = lib.mkEnableOption "Steam";
impermanenceUsers = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
description = ''
A list of users for which ~/.local/share/Steam shall be persisted. This
is a disgusting hack to get around an issue with Impermanence's
home-manager module.
https://github.com/nix-community/impermanence/issues/165#issuecomment-2537723929
'';
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@@ -28,5 +38,14 @@ in {
enable = true; enable = true;
enable32Bit = true; enable32Bit = true;
}; };
environment.persistence.${config.sydnix.impermanence.persistDirectory}.users =
builtins.listToAttrs
(builtins.map
(user: {
name = user;
value.directories = [".local/share/Steam"];
})
cfg.impermanenceUsers);
}; };
} }