Compare commits

..

No commits in common. "main" and "home-manager" have entirely different histories.

98 changed files with 560 additions and 1806 deletions

View File

@ -1,55 +1,28 @@
# Installing on a new machine # Installing on a new machine
1) Install [NixOS](https://nixos.org/) from an ISO via USB 1) Install [NixOS](https://nixos.org/) from an ISO via USB
2) Reboot machine 2) Reboot machine
3) Edit `/etc/nixos/configuration.nix` and add `git` to packages 3) Edit /etc/nixos/configuration and add `git` to packages
4) Clone this repo 4) Clone this repo
5) Create a new directory under `hosts/` for the new machine 5) Copy new `host/` configuration for the new machine
6) Copy `/etc/nixos/hardware-configuration.nix` to `hosts/<host>/hardware.nix` 6) Copy /etc/nixos/hardware-configuration to `host/<host>/hardware.nix`
7) Register the host in `flake.nix` via `mkHost`: 7) Edit `flake.nix` to point to the new `host`
```nix
nixosConfigurations.<host> = mkHost { host = "<host>"; };
```
8) `git add .` 8) `git add .`
9) Run `sudo nixos-rebuild switch --flake .#<host>` 9) Run `sudo nixos-rebuild switch --flake .#nixos`
# Building NixOS VM # Building NixOS VM
`nix build .#nixosConfigurations.vm.config.system.build.vm` `nix build .#nixosConfigurations.nixosvm.config.system.build.vm`
or run `./build-vm.sh` (removes `./vm.qcow2` first)
https://gist.github.com/FlakM/0535b8aa7efec56906c5ab5e32580adf https://gist.github.com/FlakM/0535b8aa7efec56906c5ab5e32580adf
# Building NixOS ISO # Building NixOS ISO
`nix build .#nixosConfigurations.live.config.system.build.isoImage` `nix build .#nixosConfigurations.live.config.system.build.isoImage`
or run `./build-iso.sh`
# Using Standalone Home Manager
1) Install [Nix](https://nixos.org/) via:
```
sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon
```
2) Create `~/.config/nix/nix.conf` file with the following contents to enable the use of flakes:
```
experimental-features = nix-command flakes
```
3) Install `git`
4) Clone this repo
5) Edit `flake.nix` variables as needed
6) `home-manager switch --flake .#josh`
# Misc # Misc
## Garbage collection ## Garbage collection
`nix-collect-garbage -d` `nix-collect-garbage -d`
## Fonts ## Fonts
### Checking installed fonts ### Checking installed fonts
`fc-list` `fc-list`
### Debugging kitty fonts ### Debugging kitty fonts
`kitty --debug-font-fallback` `kitty --debug-font-fallback`

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash #/usr/bin/env bash
echo "Building ISO ..." echo "Building ISO ..."
nix build .#nixosConfigurations.live.config.system.build.isoImage nix build .#nixosConfigurations.live.config.system.build.isoImage

View File

@ -38,11 +38,11 @@
"base16-helix": { "base16-helix": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1776754714, "lastModified": 1760703920,
"narHash": "sha256-E3OAK27smtATTmX45uoTSRsVD+Y+ZiVVfgM/tjpbtYg=", "narHash": "sha256-m82fGUYns4uHd+ZTdoLX2vlHikzwzdu2s2rYM2bNwzw=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "base16-helix", "repo": "base16-helix",
"rev": "4d508123037e7851ad36ebf7d9c48b0e9e1eb581", "rev": "d646af9b7d14bff08824538164af99d0c521b185",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -68,36 +68,14 @@
"type": "github" "type": "github"
} }
}, },
"elephant": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1781164160,
"narHash": "sha256-dxo3aPnfaQJt9K/3NhgKfu2Q9B42z4d4Or9Izoug+68=",
"owner": "abenz1267",
"repo": "elephant",
"rev": "3296842820d04d5ec774afc7528492fcbb3c01f2",
"type": "github"
},
"original": {
"owner": "abenz1267",
"ref": "master",
"repo": "elephant",
"type": "github"
}
},
"firefox-gnome-theme": { "firefox-gnome-theme": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1779670703, "lastModified": 1764873433,
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=", "narHash": "sha256-1XPewtGMi+9wN9Ispoluxunw/RwozuTRVuuQOmxzt+A=",
"owner": "rafaelmardojai", "owner": "rafaelmardojai",
"repo": "firefox-gnome-theme", "repo": "firefox-gnome-theme",
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9", "rev": "f7ffd917ac0d253dbd6a3bf3da06888f57c69f92",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -114,11 +92,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1778716662, "lastModified": 1767609335,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", "rev": "250481aafeb741edfe23d29195671c19b36b6dca",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -146,18 +124,20 @@
"gnome-shell": { "gnome-shell": {
"flake": false, "flake": false,
"locked": { "locked": {
"host": "gitlab.gnome.org",
"lastModified": 1767737596, "lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=", "narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"owner": "GNOME", "owner": "GNOME",
"repo": "gnome-shell", "repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49", "rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github" "type": "gitlab"
}, },
"original": { "original": {
"host": "gitlab.gnome.org",
"owner": "GNOME", "owner": "GNOME",
"ref": "gnome-49",
"repo": "gnome-shell", "repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49", "type": "gitlab"
"type": "github"
} }
}, },
"home-manager": { "home-manager": {
@ -167,11 +147,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1781989573, "lastModified": 1768836546,
"narHash": "sha256-npfH7Zv7t1akX/ArqCNro4zU4ViPlghLaPnbEfHbCxk=", "narHash": "sha256-nJZkTamcXXMW+SMYiGFB6lB8l0aJw0xjssfN8xYd/Fs=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "78e7d8b13ecd7f5256a5c11ce216876164099d9f", "rev": "b56c5ad14fcf8b5bc887463552483bf000ca562a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -204,11 +184,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1781928658, "lastModified": 1768789193,
"narHash": "sha256-E+NGWu/3TtblwLL0uYKHB7VQOcuu6nUYSHDsscTnG2s=", "narHash": "sha256-EWIj+tZSvbi3e43tBwc6xvNwEWEVwPQkuGim2tvxP/E=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-vscode-extensions", "repo": "nix-vscode-extensions",
"rev": "ff4a4123af3924ee8741902d0d0af6debdae36a9", "rev": "7e5664fa1e2051630b5e9e976cfd462f21a94abb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -219,11 +199,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1781577229, "lastModified": 1768564909,
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=", "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f", "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -245,11 +225,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1780281641, "lastModified": 1767810917,
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=", "narHash": "sha256-ZKqhk772+v/bujjhla9VABwcvz+hB2IaRyeLT6CFnT0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01", "rev": "dead29c804adc928d3a69dfe7f9f12d0eec1f1a4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -260,13 +240,11 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"elephant": "elephant",
"home-manager": "home-manager", "home-manager": "home-manager",
"install-system": "install-system", "install-system": "install-system",
"nix-vscode-extensions": "nix-vscode-extensions", "nix-vscode-extensions": "nix-vscode-extensions",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"stylix": "stylix", "stylix": "stylix"
"walker": "walker"
} }
}, },
"stylix": { "stylix": {
@ -282,18 +260,19 @@
"nixpkgs" "nixpkgs"
], ],
"nur": "nur", "nur": "nur",
"systems": "systems_2", "systems": "systems",
"tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty", "tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes", "tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux", "tinted-tmux": "tinted-tmux",
"tinted-zed": "tinted-zed" "tinted-zed": "tinted-zed"
}, },
"locked": { "locked": {
"lastModified": 1781997134, "lastModified": 1768744881,
"narHash": "sha256-muBZG4O/agq/ljgHr6c3AsobIWgODAS6vf50xIS7o+Q=", "narHash": "sha256-3+h7OxqfrPIB/tRsiZXWE9sCbTm7NQN5Ie428p+S6BA=",
"owner": "danth", "owner": "danth",
"repo": "stylix", "repo": "stylix",
"rev": "a6a493119e492e15874caf6f7f8c7e572e64c655", "rev": "06684f00cfbee14da96fd4307b966884de272d3a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -304,21 +283,6 @@
} }
}, },
"systems": { "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"
}
},
"systems_2": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
@ -333,18 +297,20 @@
"type": "github" "type": "github"
} }
}, },
"systems_3": { "tinted-foot": {
"flake": false,
"locked": { "locked": {
"lastModified": 1689347949, "lastModified": 1726913040,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", "narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=",
"owner": "nix-systems", "owner": "tinted-theming",
"repo": "default-linux", "repo": "tinted-foot",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-systems", "owner": "tinted-theming",
"repo": "default-linux", "repo": "tinted-foot",
"rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4",
"type": "github" "type": "github"
} }
}, },
@ -367,11 +333,11 @@
"tinted-schemes": { "tinted-schemes": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1777806186, "lastModified": 1767710407,
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=", "narHash": "sha256-+W1EB79Jl0/gm4JqmO0Nuc5C7hRdp4vfsV/VdzI+des=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "schemes", "repo": "schemes",
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795", "rev": "2800e2b8ac90f678d7e4acebe4fa253f602e05b2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -383,11 +349,11 @@
"tinted-tmux": { "tinted-tmux": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1778379944, "lastModified": 1767489635,
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=", "narHash": "sha256-e6nnFnWXKBCJjCv4QG4bbcouJ6y3yeT70V9MofL32lU=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "tinted-tmux", "repo": "tinted-tmux",
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d", "rev": "3c32729ccae99be44fe8a125d20be06f8d7d8184",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -399,11 +365,11 @@
"tinted-zed": { "tinted-zed": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1778378178, "lastModified": 1767488740,
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=", "narHash": "sha256-wVOj0qyil8m+ouSsVZcNjl5ZR+1GdOOAooAatQXHbuU=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "base16-zed", "repo": "base16-zed",
"rev": "9cd816033ff969415b190722cddf134e78a5665f", "rev": "11abb0b282ad3786a2aae088d3a01c60916f2e40",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -411,31 +377,6 @@
"repo": "base16-zed", "repo": "base16-zed",
"type": "github" "type": "github"
} }
},
"walker": {
"inputs": {
"elephant": [
"elephant"
],
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_3"
},
"locked": {
"lastModified": 1781164128,
"narHash": "sha256-xPcYrHdDXWykIi5/XXkLvliBArRnfzvs+atB9El1qhI=",
"owner": "abenz1267",
"repo": "walker",
"rev": "aa1e4b7d59237e8c43dde58636bae476f23d9bfb",
"type": "github"
},
"original": {
"owner": "abenz1267",
"ref": "master",
"repo": "walker",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

100
flake.nix
View File

@ -7,29 +7,15 @@
url = "github:nix-community/home-manager/master"; url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-vscode-extensions = { nix-vscode-extensions = {
url = "github:nix-community/nix-vscode-extensions"; url = "github:nix-community/nix-vscode-extensions";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
stylix = { stylix = {
url = "github:danth/stylix/master"; url = "github:danth/stylix/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
elephant = {
url = "github:abenz1267/elephant/master";
inputs.nixpkgs.follows = "nixpkgs";
};
walker = {
url = "github:abenz1267/walker/master";
inputs = {
elephant.follows = "elephant";
nixpkgs.follows = "nixpkgs";
};
};
install-system = { install-system = {
url = "path:scripts/install-system"; url = "path:scripts/install-system";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@ -41,86 +27,66 @@
nixpkgs, nixpkgs,
home-manager, home-manager,
install-system, install-system,
nix-vscode-extensions,
stylix, stylix,
... ...
}@inputs: }@inputs:
let let
system = "x86_64-linux"; system = "x86_64-linux";
host = "vm";
profile = "desktop";
username = "josh"; username = "josh";
homePath = ./. + "/users/${username}/home.nix";
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
overlays = [ nix-vscode-extensions.overlays.default ];
};
mkHost =
{
host,
profile,
extraModules ? [ ],
}:
nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit
homePath
host
inputs
profile
username
;
};
inherit pkgs;
modules = [ ./hosts/${host} ] ++ extraModules;
};
in in
{ {
nixosConfigurations = { nixosConfigurations = {
laptop = mkHost { nixos = nixpkgs.lib.nixosSystem {
host = "laptop"; inherit system;
profile = "gaming"; specialArgs = {
inherit inputs;
inherit host;
inherit profile;
inherit username;
};
modules = [
./hosts/${host}
];
}; };
vm = mkHost { live = nixpkgs.lib.nixosSystem {
host = "vm"; inherit system;
profile = "desktop"; specialArgs = {
}; inherit inputs;
inherit host;
live = mkHost { inherit profile;
host = "installation-iso"; inherit username;
profile = "desktop"; };
extraModules = [ modules = [
(nixpkgs + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix") (nixpkgs + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix")
{ environment.systemPackages = [ install-system.packages.${system}.default ]; } { environment.systemPackages = [ install-system.packages.${system}.default ]; }
./hosts/${host}
]; ];
}; };
}; };
homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration { homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
extraSpecialArgs = { extraSpecialArgs = {
inherit inputs username; inherit inputs;
profile = "desktop"; inherit profile;
}; inherit username;
inherit pkgs; };
pkgs = nixpkgs.legacyPackages.${system};
modules = [ modules = [
{ ./homes/${username}/home.nix
modules.gpg.signingKey = null;
}
homePath
stylix.homeModules.stylix stylix.homeModules.stylix
]; ];
}; };
devShell.${system} = pkgs.mkShell { devShell.${system} = nixpkgs.legacyPackages.${system}.pkgs.mkShell {
packages = with pkgs; [ packages = with nixpkgs.legacyPackages.${system}.pkgs; [
nil nil
nixd nixd
]; ];
}; };
formatter.${system} = pkgs.nixfmt-tree; formatter.${system} = nixpkgs.legacyPackages.${system}.nixfmt-tree;
}; };
} }

37
homes/josh/home.nix Normal file
View File

@ -0,0 +1,37 @@
{
lib,
pkgs,
profile,
...
}:
with lib;
{
imports = [
../../modules/homes
../../modules/options
../../profiles/${profile}
];
modules.zsh.enable = true;
modules.shell.defaultShell = "zsh";
home = {
username = "josh";
homeDirectory = "/home/josh";
stateVersion = "25.11";
};
# Let Home Manager install and manage itself
programs.home-manager.enable = true;
nix = {
package = mkDefault pkgs.nix;
settings = {
allowed-users = [ "josh" ];
experimental-features = [
"nix-command"
"flakes"
];
};
};
}

View File

@ -1,16 +0,0 @@
{
profile,
...
}:
{
imports = [
../../profiles/${profile}
../../modules/nixos
../../modules/drivers
../../modules/options
./hardware.nix
./host-packages.nix
];
}

View File

@ -1,3 +0,0 @@
{
}

View File

@ -1,10 +0,0 @@
{
pkgs,
...
}:
{
environment.systemPackages = with pkgs; [
parted
unixtools.fdisk
];
}

View File

@ -1,24 +0,0 @@
{
profile,
...
}:
{
imports = [
../../profiles/${profile}
../../modules/nixos
../../modules/drivers
../../modules/options
./hardware.nix
./host-packages.nix
];
modules.gpg.signingKey = "0x530DA0331EFE99F5";
modules.gnomeBoxes.enable = true;
modules.opencode.enable = true;
modules.display.scale = 2;
modules.steam.remotePlay.enable = true;
}

View File

@ -1,48 +0,0 @@
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"xhci_pci"
"thunderbolt"
"nvme"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/041a9bc5-aae2-44ec-bacf-7f6a08a696f9";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/79D1-97BE";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [
{ device = "/dev/disk/by-uuid/82b669f5-d624-4a29-bf18-dd8bc453f537"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -5,25 +5,26 @@
{ {
imports = [ imports = [
../../profiles/${profile} ../../profiles/${profile}
../../profiles/vm
../../modules/nixos ../../modules/core
../../modules/drivers
../../modules/options ../../modules/options
./hardware.nix ./hardware.nix
./host-packages.nix ./host-packages.nix
]; ];
virtualisation.vmVariant = { modules.hyprland = {
virtualisation = { enable = true;
memorySize = 8192; terminal = "kitty";
cores = 8; monitor = [
}; ",preferred,auto,1"
];
}; };
modules.plasma.enable = false;
modules.displayManager.displayManager = "gdm";
# drivers.amdgpu.enable = false; modules.zsh.enable = true;
# drivers.nvidia.enable = false; modules.shell.defaultShell = "zsh";
# drivers.nvidia-prime.enable = false;
# drivers.intel.enable = false; modules.pipewire.enable = true;
modules.vm.guestServices.enable = true;
} }

9
modules/core/boot.nix Normal file
View File

@ -0,0 +1,9 @@
{
...
}:
{
boot = {
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
};
}

View File

@ -3,26 +3,19 @@
}: }:
{ {
imports = [ imports = [
./battlenet.nix
./boot.nix ./boot.nix
./dev.nix ./firefox.nix
./fonts.nix ./fonts.nix
./gdm.nix ./gdm.nix
./gnomeBoxes.nix
./home-manager.nix
./hyprland.nix ./hyprland.nix
./localsend.nix
./network.nix ./network.nix
./packages.nix ./packages.nix
./pipewire.nix ./pipewire.nix
./plasma.nix ./plasma.nix
./sddm.nix ./sddm.nix
./services.nix ./services.nix
./steam.nix
./stylix.nix ./stylix.nix
./system.nix ./system.nix
./tailscale.nix
./user.nix ./user.nix
./zsh.nix
]; ];
} }

26
modules/core/firefox.nix Normal file
View File

@ -0,0 +1,26 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
pipewireCfg = config.modules.pipewire;
in
{
programs = {
firefox.enable = true;
};
# Add wayland screensharing support if PipeWire is enabled
environment.systemPackages =
with pkgs;
[ ]
++ (
if pipewireCfg.enable then
[ (wrapFirefox (firefox-unwrapped.override { pipewireSupport = true; }) { }) ]
else
[ firefox ]
);
}

View File

@ -5,12 +5,13 @@
}: }:
with lib; with lib;
let let
cfg = config.modules.display; cfg = config.modules.displayManager;
in in
{ {
config = mkIf (cfg.manager == "gdm") { config = mkIf (cfg.displayManager == "gdm") {
services.displayManager.gdm = { services.displayManager.gdm = {
enable = true; enable = true;
wayland = true;
}; };
}; };
} }

14
modules/core/network.nix Normal file
View File

@ -0,0 +1,14 @@
{
host,
pkgs,
...
}:
{
networking = {
hostName = "${host}";
networkmanager.enable = true;
wireless.enable = false;
};
environment.systemPackages = with pkgs; [ networkmanagerapplet ];
}

View File

@ -3,7 +3,14 @@
... ...
}: }:
{ {
environment.systemPackages = with pkgs; [ programs = {
};
environment.systemPackages = with pkgs; [
git
tldr
tmux
vim
]; ];
} }

25
modules/core/pipewire.nix Normal file
View File

@ -0,0 +1,25 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.modules.pipewire;
in
{
config = mkIf cfg.enable {
services.pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
pulse.enable = true;
jack.enable = true;
};
# Allows Pipewire to use the realtime scheduler for increased performance
security.rtkit.enable = true;
};
}

View File

@ -5,10 +5,10 @@
}: }:
with lib; with lib;
let let
cfg = config.modules.display; cfg = config.modules.displayManager;
in in
{ {
config = mkIf (cfg.manager == "sddm") { config = mkIf (cfg.displayManager == "sddm") {
services.displayManager.sddm = { services.displayManager.sddm = {
enable = true; enable = true;
wayland.enable = true; wayland.enable = true;

View File

@ -8,7 +8,7 @@
stylix = { stylix = {
enable = true; enable = true;
base16Scheme = ../../modules/stylix/blueish-custom.yaml; base16Scheme = "${pkgs.base16-schemes}/share/themes/blueish.yaml";
polarity = "dark"; polarity = "dark";
}; };

View File

@ -1,31 +1,17 @@
{ {
config, config,
username,
... ...
}: }:
let let
cfg = config.modules.system; cfg = config.system;
in in
{ {
nix = { nix = {
settings = { settings = {
allowed-users = [ username ];
trusted-users = [
"@wheel"
username
];
experimental-features = [ experimental-features = [
"nix-command" "nix-command"
"flakes" "flakes"
]; ];
extra-substituters = [
"https://walker.cachix.org"
"https://walker-git.cachix.org"
];
extra-trusted-public-keys = [
"walker.cachix.org-1:fG8q+uAaMqhsMxWjwvk0IMb4mFPFLqHjuvfwQxE4oJM="
"walker-git.cachix.org-1:vmC0ocfPWh0S/vRAQGtChuiZBTAe4wiKDeyyXM0/7pM="
];
}; };
}; };
@ -46,5 +32,5 @@ in
}; };
}; };
system.stateVersion = "26.05"; system.stateVersion = "25.05";
} }

55
modules/core/user.nix Normal file
View File

@ -0,0 +1,55 @@
{
config,
host,
inputs,
pkgs,
profile,
username,
...
}:
let
shellCfg = config.modules.shell;
zshCfg = config.modules.zsh;
in
{
imports = [ inputs.home-manager.nixosModules.home-manager ];
home-manager = {
useUserPackages = true;
useGlobalPkgs = false;
backupFileExtension = "backup";
extraSpecialArgs = {
inherit
host
inputs
profile
username
;
};
users.${username} = {
imports = [ ../../homes/${username}/home.nix ];
};
};
users.mutableUsers = true;
users.users.${username} = {
isNormalUser = true;
initialPassword = "changeme";
extraGroups = [
"networkmanager"
"wheel"
];
shell = pkgs.${shellCfg.defaultShell};
ignoreShellProgramCheck = true;
packages = with pkgs; [
];
};
# Set /etc/shells so GDM will show our user when ZSH is selected
environment.shells = [ pkgs.${shellCfg.defaultShell} ];
# Needed to get completion for system packages (e.g. systemd)
environment.pathsToLink =
[ ]
++ (if zshCfg.enable then [ "/share/zsh" ] else [ ]);
}

View File

@ -5,9 +5,13 @@
}: }:
with lib; with lib;
let let
cfg = config.modules.vm.guestServices; cfg = config.vm.guest-services;
in in
{ {
options.vm.guest-services = {
enable = mkEnableOption "Enable Virtual Machine Guest Services";
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.qemuGuest.enable = true; services.qemuGuest.enable = true;
services.spice-vdagentd.enable = true; services.spice-vdagentd.enable = true;

View File

@ -1,48 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.battlenet;
yq = "${pkgs.yq}/bin/yq";
jq = "${pkgs.jq}/bin/jq";
in
{
config = mkIf cfg.enable {
# Battle.net is installed manually through Lutris, which creates the game
# config and wine prefix outside of Home Manager's control. The Lutris
# installer script writes HardwareAcceleration "false" (software rendering,
# which breaks Battle.net's CEF UI repainting under XWayland), so patch it
# and the game env after every rebuild. Re-run the rebuild after installing
# Battle.net for these tweaks to land.
home.activation.battlenetClientTweaks = hm.dag.entryAfter [ "writeBoundary" ] ''
shopt -s nullglob
for game in "$HOME"/.local/share/lutris/games/battlenet*.yml; do
prefix=$(${yq} -r '.game.prefix // ""' "$game" 2>/dev/null) || continue
for configFile in "$prefix"/drive_c/users/*/AppData/Roaming/Battle.net/Battle.net.config; do
[ -e "$configFile" ] || continue
if [ "$(${jq} -r '.Client.HardwareAcceleration // ""' "$configFile" 2>/dev/null)" != "true" ]; then
${jq} '.Client.HardwareAcceleration = "true"' "$configFile" > "$configFile.tmp" && mv "$configFile.tmp" "$configFile"
fi
done
# GE-Proton's Wayland driver breaks Battle.net's CEF window sizing and
# painting, and Xalia misrenders the client, so pin both off.
if [ "$(${yq} -r '.system.env.PROTON_USE_XALIA // ""' "$game" 2>/dev/null)" != "0" ]; then
${yq} --in-place --yaml-output '.system.env.PROTON_USE_XALIA = "0"' "$game"
fi
if [ "$(${yq} -r '.system.env.WINE_SIMULATE_WRITECOPY // ""' "$game" 2>/dev/null)" != "1" ]; then
${yq} --in-place --yaml-output '.system.env.WINE_SIMULATE_WRITECOPY = "1"' "$game"
fi
if [ -n "$(${yq} -r '.system.env.PROTON_ENABLE_WAYLAND // ""' "$game" 2>/dev/null)" ]; then
${yq} --in-place --yaml-output 'del(.system.env.PROTON_ENABLE_WAYLAND)' "$game"
fi
done
shopt -u nullglob
'';
};
}

View File

@ -1,128 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.dictation;
hyprlandCfg = config.modules.hyprland;
models = {
"tiny.en" = pkgs.fetchurl {
url = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin";
hash = "sha256-kh5M+Ghv3Zk9zQgaXaW2w2W/3hFi5ysI11rHUomSCx8=";
};
"base.en" = pkgs.fetchurl {
url = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin";
hash = "sha256-oDd5yG3zMjB19eeWyyzlAp8A7Ihp7uP9+4l6/jbG0AI=";
};
"small.en" = pkgs.fetchurl {
url = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.en.bin";
hash = "sha256-xhONbVjsyDIgl+D5h8MvG+i7ChhTKj+I9zTRu/nEHl0=";
};
};
runtimeDeps = with pkgs; [
coreutils
gnused
libnotify
pipewire
whisper-cpp
wtype
];
dictation = pkgs.writeShellScriptBin "dictation" ''
PATH=${lib.makeBinPath runtimeDeps}:''${PATH:-}
set -euo pipefail
model="${models.${cfg.model}}"
dir="''${XDG_RUNTIME_DIR:-/tmp}/dictation"
mkdir -p "$dir"
pidfile="$dir/pid"
wav="$dir/clip.wav"
notify() {
notify-send -t 2500 "Dictation" "$1" 2>/dev/null || true
}
case "''${1:-}" in
start)
if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then
exit 0
fi
rm -f "$pidfile" "$wav"
notify "Listening..."
pw-record --rate 16000 --channels 1 --format s16 "$wav" >/dev/null 2>&1 &
pid=$!
echo "$pid" > "$pidfile"
disown
sleep 0.3
if ! kill -0 "$pid" 2>/dev/null; then
rm -f "$pidfile"
notify "Microphone unavailable"
fi
;;
stop)
[ -f "$pidfile" ] || exit 0
pid="$(cat "$pidfile")"
rm -f "$pidfile"
if kill -0 "$pid" 2>/dev/null; then
kill -INT "$pid" 2>/dev/null || true
for _ in $(seq 1 40); do
kill -0 "$pid" 2>/dev/null || break
sleep 0.05
done
kill -0 "$pid" 2>/dev/null && kill -KILL "$pid" 2>/dev/null || true
fi
sleep 0.1
if [ ! -f "$wav" ]; then
notify "Recording missing"
exit 0
fi
# Ignore clips shorter than 0.5s (16 kHz, s16, mono: 32000 B/s + 44 B header)
size="$(stat -c %s "$wav" 2>/dev/null || echo 0)"
if [ "$size" -lt 16044 ]; then
rm -f "$wav"
exit 0
fi
if ! text="$(whisper-cli -np -nt -t "$(nproc)" -m "$model" -f "$wav" 2>/dev/null \
| sed -e 's/([^)]*)//g' -e 's/\[[^]]*\]//g' \
| tr '\n' ' ' \
| sed -e 's/ */ /g' -e 's/^ *//' -e 's/ *$//')"; then
rm -f "$wav"
notify "Transcription failed"
exit 1
fi
rm -f "$wav"
if [ -z "$text" ]; then
notify "No speech detected"
exit 0
fi
wtype -- "$text" || notify "Could not type transcription"
;;
*)
echo "usage: dictation {start|stop}" >&2
exit 1
;;
esac
'';
in
{
config = mkIf cfg.enable {
home.packages = [ dictation ];
wayland.windowManager.hyprland = mkIf hyprlandCfg.enable {
settings = {
bind = [ "SUPER, T, exec, dictation start" ];
bindr = [ "SUPER, T, exec, dictation stop" ];
};
};
};
}

View File

@ -1,18 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.discord;
in
{
config = mkIf cfg.enable {
programs.discord = {
enable = true;
package = pkgs.discord;
};
};
}

View File

@ -1,101 +0,0 @@
{
config,
pkgs,
username,
...
}:
{
programs.firefox = {
enable = true;
package = pkgs.firefox;
configPath = "${config.xdg.configHome}/mozilla/firefox";
policies = {
# Updates & Background Services
AppAutoUpdate = false;
BackgroundAppUpdate = false;
# Quality of Life
OfferToSaveLogins = false;
# Extensions
ExtensionSettings =
let
moz = short: "https://addons.mozilla.org/firefox/downloads/latest/${short}/latest.xpi";
in
{
"*".installation_mode = "blocked";
# uBlock Origin
"uBlock0@raymondhill.net" = {
install_url = moz "ublock-origin";
installation_mode = "force_installed";
updates_disabled = true;
private_browsing = true;
default_area = "navbar";
};
# Bitwarden
"{446900e4-71c2-419f-a6a7-df9c091e268b}" = {
install_url = moz "bitwarden-password-manager";
installation_mode = "force_installed";
updates_disabled = true;
private_browsing = true;
default_area = "navbar";
};
# Dark Reader
"addon@darkreader.org" = {
install_url = moz "darkreader";
installation_mode = "force_installed";
updates_disabled = true;
private_browsing = true;
default_area = "navbar";
};
# SponsorBlock
"sponsorBlocker@ajay.app" = {
install_url = moz "sponsorblock";
installation_mode = "force_installed";
updates_disabled = true;
private_browsing = true;
default_area = "menupanel";
};
# Return YouTube Dislike
"{762f9885-5a13-4abd-9c77-433dcd38b8fd}" = {
install_url = moz "return-youtube-dislikes";
installation_mode = "force_installed";
updates_disabled = true;
private_browsing = true;
default_area = "menupanel";
};
# RES
"jid1-xUfzOsOFlzSOXg@jetpack" = {
install_url = moz "reddit-enhancement-suite";
installation_mode = "force_installed";
updates_disabled = true;
private_browsing = true;
default_area = "menupanel";
};
};
"3rdparty".Extensions = {
"{446900e4-71c2-419f-a6a7-df9c091e268b}" = {
environment = {
base = "https://bitwarden.joshuayuen.me";
};
};
};
profiles = {
${username} = {
id = 0;
isDefault = true;
name = "${username}";
};
};
};
};
}

View File

@ -1,36 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.gpg;
in
{
config = mkIf cfg.enable {
services = {
gpg-agent = {
enable = true;
enableSshSupport = true;
enableBashIntegration = true;
enableZshIntegration = true;
pinentry.package = pkgs.pinentry-qt;
};
};
home.packages = [ pkgs.gnupg ];
programs = {
gpg = {
enable = true;
settings = {
default-key = mkIf (cfg.signingKey != null) cfg.signingKey;
trusted-key = mkIf (cfg.signingKey != null) cfg.signingKey;
};
};
};
};
}

View File

@ -1,76 +0,0 @@
{
config,
...
}:
let
cfg = config.modules.hyprland;
in
{
wayland.windowManager.hyprland.settings = {
"$mod" = "SUPER";
bind = [
# Misc
"$mod, Return, exec, ${cfg.terminal}"
"$mod, D, exec, walker"
# Window management
"$mod, C, killactive"
"$mod, F, fullscreen, 1"
"$mod, Space, togglefloating"
# Focus
"$mod, H, movefocus, l"
"$mod, L, movefocus, r"
"$mod, K, movefocus, u"
"$mod, J, movefocus, d"
# Move windows
"$mod SHIFT, H, movewindow, l"
"$mod SHIFT, L, movewindow, r"
"$mod SHIFT, K, movewindow, u"
"$mod SHIFT, J, movewindow, d"
# Resize windows
"$mod CTRL, H, resizeactive, -20 0"
"$mod CTRL, L, resizeactive, 20 0"
"$mod CTRL, K, resizeactive, 0 -20"
"$mod CTRL, J, resizeactive, 0 20"
# Workspaces
"$mod, 1, workspace, 1"
"$mod, 2, workspace, 2"
"$mod, 3, workspace, 3"
"$mod, 4, workspace, 4"
"$mod, 5, workspace, 5"
# Move to workspace
"$mod SHIFT, 1, movetoworkspace, 1"
"$mod SHIFT, 2, movetoworkspace, 2"
"$mod SHIFT, 3, movetoworkspace, 3"
"$mod SHIFT, 4, movetoworkspace, 4"
"$mod SHIFT, 5, movetoworkspace, 5"
];
# Repeatable binds (hold key to keep changing)
bindel = [
# Volume
", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+"
", XF86AudioLowerVolume, exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%-"
# Brightness
", XF86MonBrightnessUp, exec, brightnessctl set +5%"
", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
];
# Binds that also work while screen is locked
bindl = [
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
];
bindm = [
"$mod, mouse:272, movewindow"
"$mod, mouse:273, resizewindow"
];
};
}

View File

@ -1,23 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.opencode;
in
{
config = mkIf cfg.enable {
programs.opencode.enable = true;
home.packages = mkIf cfg.notify [ pkgs.libnotify ];
xdg.configFile."opencode/plugin/notify.ts" = mkIf cfg.notify {
source = ./plugin/notify.ts;
};
home.file.".agents/skills/caveman/SKILL.md".source = ./skills/caveman/SKILL.md;
};
}

View File

@ -1,15 +0,0 @@
export default async ({ $ }) => {
const notify = (summary, body) => {
$`notify-send -a opencode ${summary} ${body}`.quiet().nothrow().catch(() => {})
}
return {
event: async ({ event }) => {
if (event.type === "permission.asked") {
notify("opencode needs input", event.properties.title ?? event.properties.type)
} else if (event.type === "session.idle") {
notify("opencode finished", "Agent is idle")
}
},
}
}

View File

@ -1,90 +0,0 @@
---
name: caveman
description: >
Ultra-compressed communication mode that cuts output tokens while keeping
technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for
/caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".
---
Respond terse like smart caveman. All technical substance stay. Only fluff die.
## Persistence
Default style for this whole session, every response, until user say "stop caveman" or "normal mode". Keep terse on long sessions no filler drift.
Default: **full**. Switch: `/caveman lite|full|ultra|wenyan-lite|wenyan-full|wenyan-ultra|off`.
## Rules
Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). No tool-call narration, no decorative tables/emoji, no dumping long raw error logs unless asked quote shortest decisive line. Standard well-known tech acronyms OK (DB/API/HTTP); never invent new abbreviations (cfg/impl/req/res/fn) tokenizer split them same as full word: zero token saved, reader still decode. Full word cheaper AND clearer. No causal arrows (→) either own token, save nothing. Technical terms exact. Code blocks unchanged. Errors quoted exact.
Never drop not/never/no/only/except flip meaning worse than any token saved. Numbers, units exact.
Never ADD word to sound caveman. Compression only style never grow output. No inserted pronoun or copula to fake broken grammar: "when it not" cost one token more than "when not" and say same thing. Keep correct verb form when correct form cost same "sees" one token, "see" one token, so mangle buy nothing and read worse. Same rule as abbreviations and arrows: if caveman phrasing not shorter than plain phrasing, use plain.
Clarity register: mix ASD-STE100 Simplified Technical English into caveman, always. One idea per sentence. Sentence short, target 20 words max. Active voice. Present tense where true. One word one meaning: same term for same thing every time, no synonym rotation. Instruction = imperative: "Run X", not "X should be run". Noun cluster 3 words max. Pronoun only with one clear referent, else repeat noun. Caveman cut filler; STE keep what make meaning unambiguous. Conflict between them → clarity win.
Tool calls: fire direct. No preamble, plan, or progress note before or between calls. After result: next call direct or final answer never announce next call. Text before call only to clarify, warn security/irreversible, or resolve ambiguity.
Preserve user's dominant language exactly reply in the language user writes, never switch regardless of example text or multilingual context elsewhere. Compress the style, not the language. Every emitted line in that language openings, pre-tool status lines, all not just final reply. ALWAYS keep technical terms, code, API names, CLI commands, commit-type keywords (feat/fix/...), and exact error strings verbatim unless user explicitly ask for translation.
'Drop articles' = article languages only. Where small markers carry case/role (particles, postpositions), keep them grammar, not filler; compress politeness/filler instead.
Answer directly in this style. Skip "caveman mode on", "me caveman think", "Caveman:" prefix or recap redundant with the reply itself. No normal answer plus caveman duplicate. User ask what mode is → say so plainly.
Pattern: `[thing] [action] [reason]. [next step].`
Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"
## Intensity
| Level | What change |
|-------|------------|
| **lite** | No filler/hedging. Keep articles + full sentences. Professional but tight |
| **full** | Drop articles, fragments OK, short synonyms. Classic caveman. No tool-call narration, no decorative tables/emoji, no long raw error-log dumps unless asked. Standard acronyms OK; no invented abbreviations |
| **ultra** | Strip conjunctions when cause-then-effect stay unambiguous. One word when one word enough. State each fact once. NO prose abbreviations (cfg/impl/req/res/fn/auth), NO arrows (X → Y) measured zero token saving under tokenizer, cost decode clarity. Code symbols, function names, API names, error strings: never touch |
| **wenyan-lite** | Semi-classical. Drop filler/hedging but keep grammar structure, classical register |
| **wenyan-full** | Maximum classical terseness. Fully 文言文. 80-90% character reduction chars, not tokens. Classical sentence patterns, verbs precede objects, subjects often omitted, classical particles (之/乃/為/其) |
| **wenyan-ultra** | Extreme abbreviation while keeping classical Chinese feel. Maximum compression, ultra terse |
Example "Why React component re-render?"
- lite: "Your component re-renders because you create a new object reference each render. Wrap it in `useMemo`."
- full: "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."
- ultra: "Inline obj prop, new ref, re-render. `useMemo`."
- wenyan-lite: "組件頻重繪,以每繪新生對象參照故。以 useMemo 包之。"
- wenyan-full: "每繪新生對象參照,故重繪;以 useMemo 包之則免。"
- wenyan-ultra: "新參照則重繪。useMemo 包之。"
Example "Explain database connection pooling."
- lite: "Connection pooling reuses open connections instead of creating new ones per request. Avoids repeated handshake overhead."
- full: "Pool reuse open DB connections. No new connection per request. Skip handshake overhead."
- ultra: "Pool reuse open DB connections. No per-request handshake."
- wenyan-full: "池蓄已開之連,不逐請而新開,省握手之費。"
- wenyan-ultra: "池蓄連,免逐請新開,省握手。"
Classical chars = wenyan modes only. Never swap a word to a classical char to shrink at non-wenyan levels.
## Auto-Clarity
Drop caveman when:
- Security warnings
- Irreversible action confirmations
- Multi-step sequences where fragment order or omitted conjunctions risk misread
- Compression itself creates technical ambiguity (e.g., `"migrate table drop column backup first"` order unclear without articles/conjunctions)
- User asks to clarify or repeats question
Resume caveman after clear part done.
Example shows FORMAT only write warning in session language, not example's.
Example destructive op:
> **Warning:** This will permanently delete all rows in the `users` table and cannot be undone.
> ```sql
> DROP TABLE users;
> ```
> Caveman resume. Verify backup exist first.
## Boundaries
Persisted outside chat: write normal prose code, comments, commits, docs, issue/PR/MR/defect/ticket/bug-report text, memory files, third-party messages (/caveman-compress exempt). "Open a defect" or "file a bug" mean the same as "open issue": body go to other humans, so body normal English. "stop caveman" or "normal mode": revert. Level persist until changed or session end.

View File

@ -1,58 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.screenshot;
hyprlandCfg = config.modules.hyprland;
runtimeDeps = with pkgs; [
coreutils
grim
libnotify
slurp
util-linux
wl-clipboard
];
screenshot = pkgs.writeShellScriptBin "screenshot" ''
PATH=${lib.makeBinPath runtimeDeps}:''${PATH:-}
set -euo pipefail
pictures_dir="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
mkdir -p "$pictures_dir"
file="$pictures_dir/screenshot_$(date +%Y-%m-%d_%H-%M-%S).png"
notify() {
notify-send -t 2500 -u low "Screenshot" "$1" 2>/dev/null || true
}
# Pick a region (Escape or a plain click cancels)
geometry="$(slurp 2>/dev/null)" || exit 0
if ! grim -g "$geometry" "$file"; then
rm -f "$file"
notify "Capture failed"
exit 1
fi
wl-copy < "$file" 2>/dev/null || true
notify "Saved to $file (also copied to clipboard)"
'';
in
{
config = mkIf cfg.enable {
home.packages = [ screenshot ];
wayland.windowManager.hyprland = mkIf hyprlandCfg.enable {
settings = {
bind = [ "SUPER SHIFT, S, exec, screenshot" ];
};
};
};
}

View File

@ -1,37 +0,0 @@
{
pkgs,
...
}:
{
programs.vscodium = {
enable = true;
package = pkgs.vscodium;
profiles.default = {
extensions =
with pkgs.vscode-extensions;
with pkgs.vscode-marketplace;
[
amazonwebservices.aws-toolkit-vscode
arrterian.nix-env-selector
christian-kohler.path-intellisense
eamodio.gitlens
esbenp.prettier-vscode
jnoortheen.nix-ide
leonardssh.vscord
mkhl.direnv
ms-python.debugpy
ms-python.python
opentofu.vscode-opentofu
redhat.ansible
redhat.vscode-yaml
rvest.vs-code-prettier-eslint
vscodevim.vim
];
userSettings = {
"editor.stickyScroll.maxLineCount" = 10;
"vim.smartRelativeLine" = true;
};
};
};
}

View File

@ -1,18 +0,0 @@
{
config,
inputs,
lib,
...
}:
with lib;
let
hyprlandCfg = config.modules.hyprland;
in
{
imports = [ inputs.walker.homeManagerModules.default ];
programs.walker = mkIf (hyprlandCfg.launcher == "walker") {
enable = true;
runAsService = true;
};
}

View File

@ -1,107 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.zsh;
xdgCfg = config.xdg;
in
{
imports = [
./completion.nix
./p10k.nix
];
programs.zsh = {
enable = cfg.enable;
dotDir = "${xdgCfg.configHome}/zsh";
autosuggestion.enable = false;
enableCompletion = false;
syntaxHighlighting = {
enable = true;
highlighters = [
"main"
"brackets"
"pattern"
"root"
];
};
historySubstringSearch.enable = true;
history = {
append = true;
ignoreDups = false;
ignoreSpace = true;
save = 100000;
share = true;
size = 100000;
extended = true;
};
initContent =
let
zshConfigInitEarly = mkOrder 500 ''
# p10k
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "''${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-''${(%):-%n}.zsh" ]]; then
source "''${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-''${(%):-%n}.zsh"
fi
source "${xdgCfg.configHome}/zsh/p10k.zsh";
'';
zshConfig = mkOrder 1000 ''
# Autocompletion and menu styling
zmodload zsh/complist
autoload -Uz compinit && compinit
source "${xdgCfg.configHome}/zsh/completion.zsh";
# vi keybindings for menu select
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -M menuselect 'l' vi-forward-char
# Tab to accept current selection
bindkey -M menuselect '^I' accept-and-infer-next-history
# Control arrow keys
bindkey '^[[1;5C' forward-word
bindkey '^[[1;5D' backward-word
# Control backspace
bindkey '^H' backward-kill-word
'';
in
mkMerge [
zshConfigInitEarly
zshConfig
];
shellAliases = {
".." = "cd ..";
"..." = "cd ../..";
ls = "ls --color=auto";
ll = "ls -al";
grep = "grep --color=auto";
back = "cd $OLDPWD";
gs = "git status";
ssha = "eval $(ssh-agent) && ssh-add";
};
plugins = [
{
name = "powerlevel10k";
src = "${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/";
file = "powerlevel10k.zsh-theme";
}
{
name = "zsh-autocomplete";
src = "${pkgs.zsh-autocomplete}/share/zsh-autocomplete/";
file = "zsh-autocomplete.zsh";
}
];
};
}

View File

@ -3,20 +3,13 @@
}: }:
{ {
imports = [ imports = [
./battlenet.nix
./direnv.nix ./direnv.nix
./discord.nix
./dictation.nix
./firefox.nix
./gpg.nix
./fzf.nix ./fzf.nix
./hyprland ./hyprland
./kitty.nix ./kitty.nix
./opencode ./overlays.nix
./screenshot.nix
./stylix.nix ./stylix.nix
./vscodium.nix ./vscodium.nix
./walker.nix
./xdg.nix ./xdg.nix
./zsh ./zsh
]; ];

View File

@ -0,0 +1,58 @@
{
config,
...
}:
let
cfg = config.modules.hyprland;
in
{
wayland.windowManager.hyprland.settings = {
"$mod" = "SUPER";
bind = [
# Misc
"$mod,Return,exec,${cfg.terminal}"
# Window management
"$mod,C,killactive"
"$mod,F,fullscreen, 1"
"$mod,Space,togglefloating"
# Focus
"$mod,H,movefocus,l"
"$mod,L,movefocus,r"
"$mod,K,movefocus,u"
"$mod,J,movefocus,d"
# Move windows
"$mod SHIFT,H,movewindow,l"
"$mod SHIFT,L,movewindow,r"
"$mod SHIFT,K,movewindow,u"
"$mod SHIFT,J,movewindow,d"
# Resize windows
"$mod CTRL,H,resizeactive,-20 0"
"$mod CTRL,L,resizeactive,20 0"
"$mod CTRL,K,resizeactive,0 -20"
"$mod CTRL,J,resizeactive,0 20"
# Workspaces
"$mod,1,workspace,1"
"$mod,2,workspace,2"
"$mod,3,workspace,3"
"$mod,4,workspace,4"
"$mod,5,workspace,5"
# Move to workspace
"$mod SHIFT,1,movetoworkspace,1"
"$mod SHIFT,2,movetoworkspace,2"
"$mod SHIFT,3,movetoworkspace,3"
"$mod SHIFT,4,movetoworkspace,4"
"$mod SHIFT,5,movetoworkspace,5"
];
bindm = [
"$mod,mouse:272,movewindow"
"$mod,mouse:273,resizewindow"
];
};
}

View File

@ -7,24 +7,22 @@
with lib; with lib;
let let
cfg = config.modules.hyprland; cfg = config.modules.hyprland;
displayCfg = config.modules.display;
in in
{ {
home.packages = with pkgs; [
brightnessctl
];
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = cfg.enable; enable = cfg.enable;
package = pkgs.hyprland; package = pkgs.hyprland;
systemd.enable = true; systemd.enable = false;
xwayland.enable = true;
settings = { settings = {
monitor = cfg.monitor; monitor = cfg.monitor;
general = { general = {
gaps_in = 3; gaps_in = 5;
gaps_out = 8; gaps_out = 20;
border_size = 2; border_size = 2;
"col.active_border" = mkForce "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = mkForce "rgba(595959aa)";
layout = "dwindle"; layout = "dwindle";
}; };
@ -44,27 +42,18 @@ in
enabled = true; enabled = true;
range = 4; range = 4;
render_power = 3; render_power = 3;
# Home manager hyprland module sets this for some reason
color = mkForce "rgba(1a1a1aee)";
}; };
}; };
misc = {
initial_workspace_tracking = 2;
};
env = [ env = [
"ELECTRON_OZONE_PLATFORM_HINT, wayland"
"NIXOS_OZONE_WL, 1" "NIXOS_OZONE_WL, 1"
"XDG_CURRENT_DESKTOP, Hyprland" "XDG_CURRENT_DESKTOP, Hyprland"
"XDG_SESSION_DESKTOP, Hyprland" "XDG_SESSION_DESKTOP, Hyprland"
"XDG_SESSION_TYPE, wayland" "XDG_SESSION_TYPE, wayland"
"GDK_SCALE, ${toString displayCfg.scale}"
]; ];
xwayland = {
enabled = true;
force_zero_scaling = true;
};
ecosystem = { ecosystem = {
no_update_news = true; no_update_news = true;
}; };

View File

@ -0,0 +1,11 @@
{
inputs,
...
}:
{
nixpkgs = {
overlays = [
inputs.nix-vscode-extensions.overlays.default
];
};
}

View File

@ -1,12 +1,11 @@
{ {
pkgs, pkgs,
username,
... ...
}: }:
{ {
stylix = { stylix = {
enable = true; enable = true;
base16Scheme = ../../modules/stylix/blueish-custom.yaml; base16Scheme = "${pkgs.base16-schemes}/share/themes/blueish.yaml";
polarity = "dark"; polarity = "dark";
@ -40,13 +39,5 @@
name = "Bibata-Modern-Classic"; name = "Bibata-Modern-Classic";
size = 24; size = 24;
}; };
targets = {
firefox = {
profileNames = [ "${username}" ];
firefoxGnomeTheme.enable = true;
};
hyprland.enable = true;
};
}; };
} }

View File

@ -0,0 +1,29 @@
{
pkgs,
...
}:
{
programs.vscode = {
enable = true;
package = pkgs.vscodium;
profiles.default.extensions =
with pkgs.vscode-extensions;
with pkgs.vscode-marketplace;
[
amazonwebservices.aws-toolkit-vscode
arrterian.nix-env-selector
christian-kohler.path-intellisense
eamodio.gitlens
esbenp.prettier-vscode
jnoortheen.nix-ide
leonardssh.vscord
mkhl.direnv
ms-python.debugpy
ms-python.python
opentofu.vscode-opentofu
redhat.ansible
redhat.vscode-yaml
rvest.vs-code-prettier-eslint
];
};
}

View File

@ -0,0 +1,100 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.zsh;
xdgCfg = config.xdg;
in
{
imports = [
./completion.nix
./p10k.nix
];
programs.zsh = {
enable = cfg.enable;
dotDir = "${xdgCfg.configHome}/zsh";
autosuggestion.enable = false;
enableCompletion = false;
syntaxHighlighting = {
enable = true;
highlighters = [
"main"
"brackets"
"pattern"
"root"
];
};
historySubstringSearch.enable = true;
history = {
append = true;
ignoreDups = false;
ignoreSpace = true;
save = 100000;
share = true;
size = 100000;
extended = true;
};
initContent =
let
zshConfigInitEarly = mkOrder 500 ''
# p10k
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "''${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-''${(%):-%n}.zsh" ]]; then
source "''${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-''${(%):-%n}.zsh"
fi
source "${xdgCfg.configHome}/zsh/p10k.zsh";
'';
zshConfig = mkOrder 1000 ''
# Autocompletion and menu styling
zmodload zsh/complist
autoload -Uz compinit && compinit
source "${xdgCfg.configHome}/zsh/completion.zsh";
# vi keybindings for menu select
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -M menuselect 'l' vi-forward-char
# Tab to accept current selection
bindkey -M menuselect '^I' accept-and-infer-next-history
# Control arrow keys
bindkey '^[[1;5C' forward-word
bindkey '^[[1;5D' backward-word
'';
in mkMerge [ zshConfigInitEarly zshConfig ];
shellAliases = {
".." = "cd ..";
"..." = "cd ../..";
ls = "ls --color=auto";
ll = "ls -al";
grep = "grep --color=auto";
back = "cd $OLDPWD";
gs = "git status";
ssha = "eval $(ssh-agent) && ssh-add";
};
plugins = [
{
name = "powerlevel10k";
src = "${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/";
file = "powerlevel10k.zsh-theme";
}
{
name = "zsh-autocomplete";
src = "${pkgs.zsh-autocomplete}/share/zsh-autocomplete/";
file = "zsh-autocomplete.zsh";
}
];
};
}

View File

@ -1,23 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.battlenet;
in
{
config = mkIf cfg.enable {
# Battle.net games rely on 32-bit graphics libraries; Steam would
# normally force this on, but enable it independently as a fallback.
hardware.graphics.enable32Bit = mkDefault true;
environment.systemPackages = with pkgs; [
lutris
wineWow64Packages.staging
winetricks
];
};
}

View File

@ -1,14 +0,0 @@
{
config,
...
}:
{
boot = {
loader.systemd-boot = {
enable = true;
configurationLimit = 10;
consoleMode = config.modules.system.systemdBootConsoleMode;
};
loader.efi.canTouchEfiVariables = true;
};
}

View File

@ -1,39 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.modules.dev;
in
{
config = mkIf cfg.enable {
# Runs dynamically linked executables intended for generic Linux (e.g. Python
# binaries downloaded by uv) by providing the standard loaders in /lib/*
programs.nix-ld = {
enable = true;
libraries = with pkgs; [
zlib
zstd
stdenv.cc.cc
curl
openssl
attr
libssh
bzip2
libxml2
acl
libsodium
util-linux
xz
systemd
glib
libelf
];
};
environment.systemPackages = with pkgs; [ uv ];
};
}

View File

@ -1,41 +0,0 @@
{
config,
lib,
pkgs,
username,
...
}:
with lib;
let
cfg = config.modules.gnomeBoxes;
in
{
config = mkIf cfg.enable {
virtualisation = {
libvirtd = {
enable = true;
# Enable TPM emulation (for Windows 11)
qemu = {
package = pkgs.qemu_kvm;
swtpm.enable = true;
};
};
# Enable USD redirection
spiceUSBRedirection.enable = true;
};
# Allow VM management
users.groups.libvirtd.members = [ username ];
users.groups.kvm.members = [ username ];
# Enable VM networking and file sharing
environment.systemPackages = with pkgs; [
gnome-boxes
swtpm
dnsmasq
phodav
];
};
}

View File

@ -1,44 +0,0 @@
{
config,
host,
inputs,
homePath,
profile,
username,
...
}:
let
zshCfg = config.modules.zsh;
in
{
imports = [ inputs.home-manager.nixosModules.home-manager ];
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
backupFileExtension = "backup";
extraSpecialArgs = {
inherit
host
inputs
profile
username
;
};
users.${username} = {
imports = [ homePath ];
modules.gpg.signingKey = config.modules.gpg.signingKey;
modules.display.scale = config.modules.display.scale;
modules.opencode = config.modules.opencode;
};
};
environment.pathsToLink =
# Since Home Manager is installed via its NixOS module, we need to add this so that
# the portal definitions and DE provided configurations get linked
[
"/share/applications"
"/share/xdg-desktop-portal"
]
# Needed to get completion for system packages (e.g. systemd)
++ (if zshCfg.enable then [ "/share/zsh" ] else [ ]);
}

View File

@ -1,16 +0,0 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.modules.localsend;
in
{
config = mkIf cfg.enable {
programs.localsend = {
enable = true;
};
};
}

View File

@ -1,21 +0,0 @@
{
host,
config,
lib,
pkgs,
...
}:
{
networking = {
hostName = "${host}";
networkmanager = {
enable = true;
# resolved is only enabled when tailscale is; pointing NM at a
# systemd-resolved that isn't running would break DNS entirely
dns = lib.mkIf config.services.resolved.enable "systemd-resolved";
};
wireless.enable = true;
};
environment.systemPackages = with pkgs; [ networkmanagerapplet ];
}

View File

@ -1,5 +0,0 @@
{
...
}:
{
}

View File

@ -1,46 +0,0 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.modules.pipewire;
in
{
config = mkIf cfg.enable {
services.pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
pulse.enable = true;
jack.enable = true;
};
# Re-enable PulseAudio-style auto profile switching (ACP), since
# WirePlumber 0.5 disables it and never reacts to HDMI hotplug events,
# leaving audio stuck on analog when a dock/TV is connected.
services.pipewire.wireplumber.extraConfig."99-acp-auto-profile" = {
"monitor.alsa.rules" = [
{
matches = [
{
"device.name" = "~alsa_card.*";
}
];
actions = {
update-props = {
"api.acp.auto-profile" = true;
"api.acp.auto-port" = true;
};
};
}
];
};
# Allows Pipewire to use the realtime scheduler for increased performance
security.rtkit.enable = true;
};
}

View File

@ -1,20 +0,0 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.modules.steam;
in
{
config = mkIf cfg.enable {
programs.steam = {
enable = true;
remotePlay.openFirewall = cfg.remotePlay.enable;
dedicatedServer.openFirewall = cfg.remotePlay.enable;
};
hardware.steam-hardware.enable = true;
};
}

View File

@ -1,21 +0,0 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.modules.tailscale;
in
{
config = mkIf cfg.enable {
services.tailscale.enable = true;
# systemd-resolved is needed for tailscale's MagicDNS to work properly
services.resolved.enable = true;
# tailscaled applies its DNS config (split DNS, MagicDNS) to
# systemd-resolved over D-Bus, which is polkit-guarded
security.polkit.enable = true;
};
}

View File

@ -1,29 +0,0 @@
{
config,
pkgs,
username,
...
}:
let
shellCfg = config.modules.shell;
in
{
users.mutableUsers = true;
users.users.${username} = {
isNormalUser = true;
initialPassword = "changeme";
extraGroups = [
"networkmanager"
"video"
"wheel"
];
shell = pkgs.${shellCfg.defaultShell};
ignoreShellProgramCheck = true;
packages = with pkgs; [
];
};
# Set /etc/shells so GDM will show our user when ZSH is selected
environment.shells = [ pkgs.${shellCfg.defaultShell} ];
}

View File

@ -1,14 +0,0 @@
{
config,
lib,
...
}:
with lib;
let
zshCfg = config.modules.zsh;
in
{
config = mkIf zshCfg.enable {
programs.zsh.enable = true;
};
}

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.battlenet = {
enable = mkEnableOption "Battle.net via Lutris/Wine";
};
}

View File

@ -3,24 +3,12 @@
}: }:
{ {
imports = [ imports = [
./battlenet.nix ./displayManager.nix
./discord.nix
./dictation.nix
./dev.nix
./display.nix
./gnomeBoxes.nix
./gpg.nix
./hyprland.nix ./hyprland.nix
./localsend.nix
./opencode.nix
./pipewire.nix ./pipewire.nix
./plasma.nix ./plasma.nix
./screenshot.nix
./shell.nix ./shell.nix
./steam.nix
./system.nix ./system.nix
./tailscale.nix
./vm.nix
./zsh.nix ./zsh.nix
]; ];
} }

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.dev = {
enable = mkEnableOption "Python development with uv and nix-ld";
};
}

View File

@ -1,21 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.dictation = {
enable = mkEnableOption "hold-to-talk voice dictation (hold SUPER+T)";
model = mkOption {
type = types.enum [
"tiny.en"
"base.en"
"small.en"
];
default = "base.en";
description = ''
The local Whisper model to use for transcription.
'';
};
};
}

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.discord = {
enable = mkEnableOption "Discord";
};
}

View File

@ -4,8 +4,8 @@
}: }:
with lib; with lib;
{ {
options.modules.display = { options.modules.displayManager = {
manager = mkOption { displayManager = mkOption {
type = types.enum [ type = types.enum [
"gdm" "gdm"
"sddm" "sddm"
@ -15,11 +15,5 @@ with lib;
The display manager to use. The display manager to use.
''; '';
}; };
scale = mkOption {
type = types.int;
default = 1;
description = "Display Scaling";
};
}; };
} }

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.gnomeBoxes = {
enable = mkEnableOption "GNOME Boxes";
};
}

View File

@ -1,16 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.gpg = {
enable = mkEnableOption "gpg-agent";
signingKey = mkOption {
type = types.nullOr types.str;
default = null;
description = "The key ID to sign with for git";
};
};
}

View File

@ -5,7 +5,10 @@
with lib; with lib;
{ {
options.modules.hyprland = { options.modules.hyprland = {
enable = mkEnableOption "Hyprland"; enable = mkEnableOption {
default = false;
description = "Enable Hyprland";
};
terminal = mkOption { terminal = mkOption {
type = types.enum [ type = types.enum [
"kitty" "kitty"
@ -16,18 +19,9 @@ with lib;
The terminal to use for Hyprland. The terminal to use for Hyprland.
''; '';
}; };
launcher = mkOption {
type = types.enum [
"walker"
];
default = "walker";
description = ''
The application launcher to use for Hyprland.
'';
};
monitor = mkOption { monitor = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = [ ",preferred,auto,auto" ]; default = [ ",preferred,auto,1" ];
description = '' description = ''
Monitors to use for Hyprland. Monitors to use for Hyprland.
''; '';

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.localsend = {
enable = mkEnableOption "LocalSend";
};
}

View File

@ -1,15 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.opencode = {
enable = mkEnableOption "opencode";
notify = mkOption {
type = types.bool;
default = true;
description = "Desktop notifications when opencode needs input or finishes";
};
};
}

View File

@ -5,8 +5,7 @@
with lib; with lib;
{ {
options.modules.pipewire = { options.modules.pipewire = {
enable = mkOption { enable = mkEnableOption {
type = types.bool;
default = true; default = true;
description = "Enable PipeWire"; description = "Enable PipeWire";
}; };

View File

@ -5,6 +5,9 @@
with lib; with lib;
{ {
options.modules.plasma = { options.modules.plasma = {
enable = mkEnableOption "Plasma"; enable = mkEnableOption {
default = false;
description = "Enable Plasma";
};
}; };
} }

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.screenshot = {
enable = mkEnableOption "screenshot capture tool (SUPER+SHIFT+S)";
};
}

View File

@ -1,13 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.steam = {
enable = mkEnableOption "Steam";
remotePlay = {
enable = mkEnableOption "Steam Remote Play firewall rules";
};
};
}

View File

@ -4,7 +4,7 @@
}: }:
with lib; with lib;
{ {
options.modules.system = { options.system = {
locale = mkOption { locale = mkOption {
type = types.str; type = types.str;
default = "en_US.UTF-8"; default = "en_US.UTF-8";
@ -19,11 +19,5 @@ with lib;
type = types.str; type = types.str;
default = "US/Eastern"; default = "US/Eastern";
}; };
systemdBootConsoleMode = mkOption {
type = types.str;
default = "auto";
description = "The console mode when booting";
};
}; };
} }

View File

@ -1,10 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.tailscale = {
enable = mkEnableOption "Tailscale";
};
}

View File

@ -1,12 +0,0 @@
{
lib,
...
}:
with lib;
{
options.modules.vm = {
guestServices = {
enable = mkEnableOption "Virtual Machine guest services";
};
};
}

View File

@ -5,10 +5,9 @@
with lib; with lib;
{ {
options.modules.zsh = { options.modules.zsh = {
enable = mkOption { enable = mkEnableOption {
type = types.bool;
default = true;
description = "Install Zsh"; description = "Install Zsh";
default = true;
}; };
}; };
} }

View File

@ -1,21 +0,0 @@
system: "base16"
name: "Blueish (custom)"
author: "Ben Mayoras (modified by Joshua Yuen)"
variant: "dark"
palette:
base00: "#182430"
base01: "#243C54"
base02: "#2E4460"
base03: "#616D78"
base04: "#74AFE7"
base05: "#C8E1F8"
base06: "#DDEAF6"
base07: "#8F98A0"
base08: "#4CE587"
base09: "#F6A85C"
base0A: "#F6CD5C"
base0B: "#C3E88D"
base0C: "#5FD1FF"
base0D: "#82AAFF"
base0E: "#FF84DD"
base0F: "#BBD2E8"

View File

@ -2,31 +2,9 @@
... ...
}: }:
{ {
imports = [ ../../modules/options ];
modules.hyprland = { modules.hyprland = {
enable = true; enable = true;
terminal = "kitty";
launcher = "walker";
monitor = [
",preferred,auto,auto"
];
}; };
modules.plasma.enable = false;
modules.display.manager = "gdm";
modules.localsend.enable = true;
modules.dev.enable = true;
modules.zsh.enable = true;
modules.shell.defaultShell = "zsh";
modules.pipewire.enable = true;
modules.discord.enable = true;
modules.dictation.enable = true;
modules.screenshot.enable = true;
modules.tailscale.enable = true;
} }

View File

@ -1,12 +0,0 @@
{
...
}:
{
imports = [
../desktop
];
modules.steam.enable = true;
modules.battlenet.enable = true;
}

21
profiles/vm/default.nix Normal file
View File

@ -0,0 +1,21 @@
{
...
}:
{
imports = [
../../modules/drivers
];
virtualisation.vmVariant = {
virtualisation = {
memorySize = 8192;
cores = 8;
};
};
# drivers.amdgpu.enable = false;
# drivers.nvidia.enable = false;
# drivers.nvidia-prime.enable = false;
# drivers.intel.enable = false;
vm.guest-services.enable = true;
}

View File

@ -1,10 +1,10 @@
#!/usr/bin/env bash #/usr/bin/env bash
echo "Removing old qcow2 disk ..." echo "Removing old qcow2 disk ..."
rm -f ./vm.qcow2 rm -f ./vm.qcow2
echo "Building new VM ..." echo "Building new VM ..."
nix build .#nixosConfigurations.vm.config.system.build.vm nix build .#nixosConfigurations.nixos.config.system.build.vm
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Failed to build VM" echo "Failed to build VM"

View File

@ -2,16 +2,16 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1769089682, "lastModified": 1767313136,
"narHash": "sha256-9yA/LIuAVQq0lXelrZPjLuLVuZdm03p8tfmHhnDIkms=", "narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "078d69f03934859a181e81ba987c2bb033eebfc5", "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nixos",
"ref": "nixos-25.11", "ref": "nixos-25.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

View File

@ -2,7 +2,7 @@
description = "_template package and shell environment"; description = "_template package and shell environment";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
}; };
outputs = outputs =
@ -10,7 +10,7 @@
let let
system = "x86_64-linux"; system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system}.pkgs; pkgs = nixpkgs.legacyPackages.${system}.pkgs;
name = baseNameOf (toString ./.); name = builtins.baseNameOf (builtins.toString ./.);
shellApplication = pkgs.writeShellApplication { shellApplication = pkgs.writeShellApplication {
inherit name; inherit name;

View File

@ -2,16 +2,16 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1769089682, "lastModified": 1767313136,
"narHash": "sha256-9yA/LIuAVQq0lXelrZPjLuLVuZdm03p8tfmHhnDIkms=", "narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "078d69f03934859a181e81ba987c2bb033eebfc5", "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nixos",
"ref": "nixos-25.11", "ref": "nixos-25.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

View File

@ -2,20 +2,23 @@
description = "install-system package and shell environment"; description = "install-system package and shell environment";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
}; };
outputs = outputs =
{ nixpkgs, ... }: { nixpkgs, ... }:
let let
pkgs = nixpkgs.legacyPackages.x86_64-linux.pkgs; pkgs = nixpkgs.legacyPackages.x86_64-linux.pkgs;
name = baseNameOf (toString ./.); name = builtins.baseNameOf (builtins.toString ./.);
shellApplication = pkgs.writeShellApplication { shellApplication = pkgs.writeShellApplication {
inherit name; inherit name;
text = builtins.readFile ./${name}.sh; text = builtins.readFile ./${name}.sh;
runtimeInputs = with pkgs; [ runtimeInputs = with pkgs; [
coreutils
gnused
unixtools.column
]; ];
}; };
in in

View File

@ -1,59 +0,0 @@
{
config,
lib,
pkgs,
profile,
username,
...
}:
with lib;
let
gpgCfg = config.modules.gpg;
in
{
imports = [
../../modules/home
../../modules/options
../../profiles/${profile}
];
modules.zsh.enable = true;
modules.shell.defaultShell = "zsh";
home = {
inherit username;
homeDirectory = "/home/${username}";
stateVersion = "25.11";
sessionVariables = {
EDITOR = "vim";
VISUAL = "vim";
};
packages = with pkgs; [
git
tldr
tmux
vim-full
wl-clipboard
];
};
programs.git = {
enable = true;
settings = {
user = {
name = "Joshua Yuen";
email = "joshuayuen99@gmail.com";
signingkey = mkIf (gpgCfg.signingKey != null) gpgCfg.signingKey;
};
commit.gpgsign = true;
init.defaultBranch = "main";
};
};
# Enable GPG-agent for git signing
modules.gpg.enable = true;
# Let Home Manager install and manage itself
programs.home-manager.enable = true;
}