this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor!: multi platform support

Managing similar changes across 2 repos have become annoying enough that
I'm willing to take on the pain of managing multi-platform monorepo.
macOS-specific stuff are isolated in separate files, so when I don't
have any macOS machine anymore I can just cleanly remove them.

+1044 -349
+23 -10
.github/workflows/build.yaml
··· 12 12 id-token: write 13 13 14 14 jobs: 15 - build-nixos: 16 - name: Build NixOS hosts 15 + nixos: 16 + name: NixOS 17 17 runs-on: ubuntu-latest 18 18 steps: 19 - - name: Checkout 20 - uses: actions/checkout@v4 19 + - uses: actions/checkout@v4 20 + - uses: DeterminateSystems/nix-installer-action@main 21 + - uses: DeterminateSystems/magic-nix-cache-action@main 21 22 22 - - name: Install Nix 23 - uses: DeterminateSystems/nix-installer-action@main 23 + - name: Build hosts 24 + run: | 25 + for host in $(nix eval --json --apply builtins.attrNames .#nixosConfigurations | jq -r '.[]'); do 26 + nix build ".#nixosConfigurations.\"$host\".config.system.build.toplevel" 27 + done 24 28 25 - - name: Enable Magic Nix Cache 26 - uses: DeterminateSystems/magic-nix-cache-action@main 29 + darwin: 30 + name: Darwin 31 + runs-on: macos-latest 32 + steps: 33 + - uses: actions/checkout@v4 34 + - uses: DeterminateSystems/nix-installer-action@main 35 + - uses: DeterminateSystems/magic-nix-cache-action@main 27 36 28 37 - name: Build hosts 29 38 run: | 30 - for host in $(nix eval --json --apply builtins.attrNames .#nixosConfigurations | jq -r '.[]'); do 31 - make build host="$host" 39 + for host in $(nix eval --json --apply builtins.attrNames .#darwinConfigurations | jq -r '.[]'); do 40 + nix build ".#darwinConfigurations.\"$host\".system" 32 41 done 42 + 43 + - name: Apply test config 44 + run: | 45 + sudo make host=macos-test
+9 -17
Makefile
··· 1 1 .POSIX: 2 - .PHONY: default build test diff update install 2 + .PHONY: default build switch diff update install clean 3 3 4 - default: build 4 + default: diff switch 5 5 6 6 build: 7 - sudo nixos-rebuild \ 8 - --flake '.#${host}' \ 9 - switch 10 - 11 - test: 12 - nixos-rebuild \ 13 - --flake '.#${host}' \ 14 - build-vm 15 - ./result/bin/run-${host}-vm 7 + ./scripts/rebuild.py build --flake '.#$(host)' 16 8 17 - diff: 18 - nixos-rebuild \ 19 - --flake '.#${host}' \ 20 - build 9 + diff: build 21 10 nix store diff-closures \ 22 11 --allow-symlinked-store \ 23 12 /nix/var/nix/profiles/system ./result 24 13 14 + switch: 15 + sudo ./scripts/rebuild.py switch --flake '.#$(host)' 16 + 25 17 update: 26 18 nix flake update 27 19 ··· 31 23 # have a lot of RAM. 32 24 sudo disko-install \ 33 25 --write-efi-boot-entries \ 34 - --flake '.#${host}' \ 35 - --disk main '${disk}' 26 + --flake '.#$(host)' \ 27 + --disk main '$(disk)' 36 28 37 29 clean: 38 30 nix-collect-garbage --delete-old --log-format bar
+89 -34
README.md
··· 1 - # NixOS Setup 1 + # Nix Setup 2 2 3 - Automatically install and configure NixOS. 3 + Monorepo for my Nix-based machine setup across NixOS and macOS (for when I 4 + don't have a Linux machine). 4 5 5 - ## Usage 6 + ## Overview 6 7 7 - ### Customize the configuration 8 + Repository layout: 8 9 9 - Review all files and adjust the configurations to suit your needs. At a 10 - minimum, you’ll need to change the following: 10 + - `flake.nix`: entrypoint 11 + - `hosts/`: one per machine, each host sets hostname, username, and imports the 12 + modules it needs. 13 + - `base/`: shared baseline 14 + - `modules/` composable modules that hosts can mix and match: 15 + - `cli`: shared command-line tools and development packages 16 + - `gui`: graphical apps and desktop settings for non-headless machines 17 + - `dotfiles`: bootstraps my dotfiles repository separately from the base 18 + system (moved out of base in case you don't want it) 19 + - `personal`: personal-machine configuration 20 + - `work`: work-specific packages and configuration 21 + - Modules follow this pattern: 22 + - `default.nix`: entrypoint (Nix convention) 23 + - `darwin.nix`: Darwin override 24 + - `linux.nix`: Linux override 11 25 12 - - Users: 13 - - Replace `khuedoan` with your username. 14 - - Replace my SSH public keys with yours. 15 - - Replace `khuedoan/dotfiles` with your dotfiles repository, or use `home-manager` to manage all dotfiles. 16 - 17 - - Hosts: 18 - - Replace my hostnames with yours. 19 - - Adjust hardware configurations to match your system. 26 + ## Customize the configuration 27 + 28 + Fork this repo, then: 29 + 30 + - Add a new host to `hosts/${HOSTNAME}.nix` (or update an existing 31 + one) to match your machine and it to `flake.nix` 32 + - Customize the host's composable modules 33 + - Set your username and hostname 34 + - Replace the SSH public keys and dotfiles repository URLs (if you don't want to use my dotfiles) 35 + - Replace any host-specific hardware settings 36 + - Follow installation and usage instruction below 37 + - Customize the rest of the repo for your needs and clean up things that you 38 + don't use 39 + 40 + ## Installation 41 + 42 + Review the base, hosts, and modules directories and adjust the configuration to 43 + match your machines before installing. 20 44 21 - ### Install with the NixOS Live CD 45 + ### NixOS 22 46 23 - 1. Download the latest NixOS live CD from [here](https://nixos.org/download). 24 - 2. Create a bootable USB drive: 47 + Boot into the NixOS live ISO, then install the tools needed for the initial 48 + bootstrap: 25 49 26 50 ```sh 27 - sudo dd bs=4M if=/path/to/nixos.iso of=/dev/sda conv=fsync oflag=direct status=progress 51 + nix-shell -p git gnumake neovim disko 28 52 ``` 29 53 30 - 3. Boot from the USB drive. 31 - 4. Install NixOS from the live CD: 54 + Clone the repository and run the installer: 32 55 33 56 ```sh 34 - nix-shell -p git gnumake neovim disko 35 - git clone https://github.com/khuedoan/nixos-setup 36 - cd nixos-setup 37 - # Remember to replace the placeholders 57 + git clone https://github.com/khuedoan/nix-setup 58 + cd nix-setup 38 59 make install host=HOSTNAME disk=/dev/DISK 39 60 ``` 40 61 41 - ### Apply changes 62 + Replace `HOSTNAME` with the host module you want to install and `/dev/DISK` with 63 + the target disk device. 64 + 65 + ### macOS 66 + 67 + Before the first run: 68 + 69 + - Update the hostname and `primaryUser.username` values in `hosts/` 70 + - Go to `Settings > Privacy & Security > Full Disk Access` and allow Terminal 71 + 72 + Clone the repository and apply the configuration: 73 + 74 + ```sh 75 + git clone https://github.com/khuedoan/nix-setup 76 + cd nix-setup 77 + make switch host=HOSTNAME 78 + ``` 79 + 80 + Replace `HOSTNAME` with the matching entry in `flake.nix`. The rebuild script 81 + installs Nix and Homebrew automatically on a fresh macOS system if they are not 82 + already present. 83 + 84 + Then reboot. 85 + 86 + ## Usage 42 87 43 - After installation, clone your repository again and apply changes to the 44 - configuration by running: 88 + Diff the new configuration against the current system profile: 45 89 46 90 ```sh 47 - make 91 + make diff 48 92 ``` 49 93 50 - ### Update hardware configuration 94 + Apply changes on an installed machine: 51 95 52 - If hardware changes occur, update the hardware configuration using the command 53 - in the `install` target in `./Makefile`. 96 + ```sh 97 + make switch 98 + ``` 54 99 55 - ## Testing 100 + Update packages: 56 101 57 - To test updated configurations without applying them to a running machine, create a VM using: 102 + ```sh 103 + make update 104 + ``` 105 + 106 + Build a specific host without switching: 107 + 108 + ```sh 109 + make build host=HOSTNAME 110 + ``` 111 + 112 + Clean up Nix store: 58 113 59 114 ```sh 60 - make test 115 + make clean 61 116 ```
+62
base/darwin.nix
··· 1 + { config, lib, ... }: 2 + 3 + let 4 + username = config.primaryUser.username; 5 + in 6 + 7 + { 8 + system.primaryUser = username; 9 + 10 + # TODO https://github.com/LnL7/nix-darwin/issues/682 11 + users.users.${username}.home = "/Users/${username}"; 12 + 13 + homebrew = { 14 + enable = true; 15 + onActivation.cleanup = "zap"; 16 + }; 17 + 18 + services = { 19 + # TODO some machine have the driver blocked, needs to install from the web 20 + # And Karabiner on nix-darwin is currently broken https://github.com/LnL7/nix-darwin/issues/1041 21 + # karabiner-elements.enable = true; 22 + tailscale.enable = true; 23 + }; 24 + 25 + nix = { 26 + # configureBuildUsers = true; 27 + settings = { 28 + allowed-users = [ 29 + "@admin" 30 + ]; 31 + trusted-users = [ 32 + "@admin" 33 + ]; 34 + }; 35 + linux-builder = { 36 + enable = false; # TODO fix bootstrap 37 + ephemeral = true; 38 + systems = ["aarch64-linux" "x86_64-linux"]; 39 + config = { 40 + boot.binfmt.emulatedSystems = ["x86_64-linux"]; 41 + virtualisation = { 42 + cores = 4; 43 + darwin-builder = { 44 + diskSize = 64 * 1024; 45 + memorySize = 8 * 1024; 46 + }; 47 + }; 48 + }; 49 + }; 50 + }; 51 + 52 + security.pam.services.sudo_local.touchIdAuth = true; 53 + 54 + home-manager.users.${username} = { 55 + home.stateVersion = lib.mkDefault "25.05"; 56 + programs.home-manager.enable = lib.mkDefault true; 57 + }; 58 + 59 + # Used for backwards compatibility, please read the changelog before changing. 60 + # $ darwin-rebuild changelog 61 + system.stateVersion = 6; 62 + }
+55
base/default.nix
··· 1 + { lib, pkgs, platform, ... }: 2 + 3 + { 4 + imports = [ 5 + ./${platform.parsed.kernel.name}.nix 6 + ]; 7 + 8 + options.primaryUser = { 9 + username = lib.mkOption { 10 + type = lib.types.str; 11 + description = "Local account username for this host."; 12 + }; 13 + 14 + fullName = lib.mkOption { 15 + type = lib.types.str; 16 + default = "Khue Doan"; 17 + description = "Display name for the primary user."; 18 + }; 19 + 20 + }; 21 + 22 + config = { 23 + environment.systemPackages = with pkgs; [ 24 + curl 25 + git 26 + tmux 27 + tree 28 + unzip 29 + watch 30 + ]; 31 + 32 + programs = { 33 + zsh.enable = true; 34 + direnv = { 35 + enable = true; 36 + silent = true; 37 + }; 38 + }; 39 + 40 + nix = { 41 + settings = { 42 + experimental-features = [ 43 + "nix-command" 44 + "flakes" 45 + ]; 46 + }; 47 + optimise.automatic = true; 48 + }; 49 + 50 + home-manager = { 51 + useUserPackages = true; 52 + useGlobalPkgs = true; 53 + }; 54 + }; 55 + }
+24 -44
configuration.nix base/linux.nix
··· 1 1 { config, pkgs, ... }: 2 2 3 + let 4 + username = config.primaryUser.username; 5 + in 6 + 3 7 { 4 8 disko.devices = { 5 9 disk = { ··· 73 77 }; 74 78 75 79 nix = { 76 - settings = { 77 - experimental-features = [ 78 - "nix-command" 79 - "flakes" 80 - ]; 81 - }; 82 - optimise.automatic = true; 83 80 gc = { 84 81 automatic = true; 85 82 dates = "weekly"; ··· 87 84 }; 88 85 }; 89 86 90 - # List packages installed in system profile. 91 - environment = { 92 - systemPackages = with pkgs; [ 93 - curl 94 - file 95 - gcc 96 - git 97 - gnumake 98 - killall 99 - python3 100 - tmux 101 - tree 102 - unzip 103 - watch 104 - ]; 105 - }; 106 - 107 - programs = { 108 - zsh = { 109 - enable = true; 110 - loginShellInit = '' 111 - if [ -z "$WAYLAND_DISPLAY" ] && [ "$XDG_VTNR" -eq 1 ]; then 112 - exec sway 113 - fi 114 - ''; 115 - }; 116 - gnupg.agent = { 117 - enable = true; 118 - enableSSHSupport = true; 119 - }; 120 - direnv = { 121 - enable = true; 122 - silent = true; 123 - }; 124 - }; 125 - 126 87 services = { 127 88 openssh = { 128 89 enable = true; ··· 164 125 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 165 126 system.stateVersion = "23.05"; # Did you read the comment? 166 127 128 + users.users.${username} = { 129 + isNormalUser = true; 130 + description = config.primaryUser.fullName; 131 + extraGroups = [ 132 + "docker" 133 + "libvirtd" 134 + "networkmanager" 135 + "tss" 136 + "video" 137 + "wheel" 138 + ]; 139 + openssh.authorizedKeys.keys = [ 140 + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5ue4np7cF34f6dwqH1262fPjkowHQ8irfjVC156PCG" 141 + ]; 142 + shell = pkgs.zsh; 143 + }; 144 + 145 + home-manager.users.${username}.home.stateVersion = "23.05"; 146 + 167 147 virtualisation.vmVariant = { 168 148 virtualisation.qemu.options = [ 169 149 "-device virtio-vga-gl" 170 150 "-display gtk,gl=on" 171 151 ]; 172 - users.users.khuedoan.password = "testvm"; 152 + users.users.${username}.password = "testvm"; 173 153 }; 174 154 }
+34 -12
flake.lock
··· 1 1 { 2 2 "nodes": { 3 + "darwin": { 4 + "inputs": { 5 + "nixpkgs": [ 6 + "nixpkgs" 7 + ] 8 + }, 9 + "locked": { 10 + "lastModified": 1772129556, 11 + "narHash": "sha256-Utk0zd8STPsUJPyjabhzPc5BpPodLTXrwkpXBHYnpeg=", 12 + "owner": "lnl7", 13 + "repo": "nix-darwin", 14 + "rev": "ebec37af18215214173c98cf6356d0aca24a2585", 15 + "type": "github" 16 + }, 17 + "original": { 18 + "owner": "lnl7", 19 + "ref": "nix-darwin-25.11", 20 + "repo": "nix-darwin", 21 + "type": "github" 22 + } 23 + }, 3 24 "disko": { 4 25 "inputs": { 5 26 "nixpkgs": [ ··· 7 28 ] 8 29 }, 9 30 "locked": { 10 - "lastModified": 1773889306, 11 - "narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=", 31 + "lastModified": 1776613567, 32 + "narHash": "sha256-gC9Cp5ibBmGD5awCA9z7xy6MW6iJufhazTYJOiGlCUI=", 12 33 "owner": "nix-community", 13 34 "repo": "disko", 14 - "rev": "5ad85c82cc52264f4beddc934ba57f3789f28347", 35 + "rev": "32f4236bfc141ae930b5ba2fb604f561fed5219d", 15 36 "type": "github" 16 37 }, 17 38 "original": { ··· 43 64 }, 44 65 "nixos-hardware": { 45 66 "locked": { 46 - "lastModified": 1775490113, 47 - "narHash": "sha256-2ZBhDNZZwYkRmefK5XLOusCJHnoeKkoN95hoSGgMxWM=", 67 + "lastModified": 1776983936, 68 + "narHash": "sha256-ZOQyNqSvJ8UdrrqU1p7vaFcdL53idK+LOM8oRWEWh6o=", 48 69 "owner": "NixOS", 49 70 "repo": "nixos-hardware", 50 - "rev": "c775c2772ba56e906cbeb4e0b2db19079ef11ff7", 71 + "rev": "2096f3f411ce46e88a79ae4eafcfc9df8ed41c61", 51 72 "type": "github" 52 73 }, 53 74 "original": { ··· 59 80 }, 60 81 "nixpkgs": { 61 82 "locked": { 62 - "lastModified": 1776434932, 63 - "narHash": "sha256-gyqXNMgk3sh+ogY5svd2eNLJ6oEwzbAeaoBrrxD0lKk=", 83 + "lastModified": 1776734388, 84 + "narHash": "sha256-vl3dkhlE5gzsItuHoEMVe+DlonsK+0836LIRDnm6MXQ=", 64 85 "owner": "nixos", 65 86 "repo": "nixpkgs", 66 - "rev": "c7f47036d3df2add644c46d712d14262b7d86c0c", 87 + "rev": "10e7ad5bbcb421fe07e3a4ad53a634b0cd57ffac", 67 88 "type": "github" 68 89 }, 69 90 "original": { ··· 75 96 }, 76 97 "nixpkgs-unstable": { 77 98 "locked": { 78 - "lastModified": 1776329215, 79 - "narHash": "sha256-a8BYi3mzoJ/AcJP8UldOx8emoPRLeWqALZWu4ZvjPXw=", 99 + "lastModified": 1776949667, 100 + "narHash": "sha256-GMSVw35Q+294GlrTUKlx087E31z7KurReQ1YHSKp5iw=", 80 101 "owner": "nixos", 81 102 "repo": "nixpkgs", 82 - "rev": "b86751bc4085f48661017fa226dee99fab6c651b", 103 + "rev": "01fbdeef22b76df85ea168fbfe1bfd9e63681b30", 83 104 "type": "github" 84 105 }, 85 106 "original": { ··· 91 112 }, 92 113 "root": { 93 114 "inputs": { 115 + "darwin": "darwin", 94 116 "disko": "disko", 95 117 "home-manager": "home-manager", 96 118 "nixos-hardware": "nixos-hardware",
+62 -20
flake.nix
··· 1 1 { 2 - description = "NixOS"; 3 - 4 2 inputs = { 5 - nixpkgs = { 6 - url = "github:nixos/nixpkgs/nixos-25.11"; 7 - }; 8 - nixpkgs-unstable = { 9 - url = "github:nixos/nixpkgs/nixpkgs-unstable"; 3 + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; 4 + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable"; 5 + nixos-hardware.url = "github:NixOS/nixos-hardware/master"; 6 + darwin = { 7 + url = "github:lnl7/nix-darwin/nix-darwin-25.11"; 8 + inputs.nixpkgs.follows = "nixpkgs"; 10 9 }; 11 10 disko = { 12 11 url = "github:nix-community/disko"; 13 12 inputs.nixpkgs.follows = "nixpkgs"; 14 - }; 15 - nixos-hardware = { 16 - url = "github:NixOS/nixos-hardware/master"; 17 13 }; 18 14 home-manager = { 19 15 url = "github:nix-community/home-manager/release-25.11"; ··· 21 17 }; 22 18 }; 23 19 24 - outputs = { self, nixpkgs, nixpkgs-unstable, disko, nixos-hardware, home-manager }: 20 + outputs = { nixpkgs, nixpkgs-unstable, darwin, disko, nixos-hardware, home-manager, ... }: 25 21 let 26 22 baseModules = [ 27 - disko.nixosModules.disko 28 - ./configuration.nix 29 - home-manager.nixosModules.home-manager 30 - ./users/khuedoan 23 + ./base 31 24 { 32 25 nixpkgs.overlays = [ 33 26 (final: prev: { ··· 42 35 in { 43 36 nixosConfigurations = { 44 37 ryzentower = nixpkgs.lib.nixosSystem { 38 + system = "x86_64-linux"; 39 + specialArgs = { 40 + platform = nixpkgs.lib.systems.elaborate "x86_64-linux"; 41 + }; 45 42 modules = baseModules ++ [ 46 - ./graphical.nix 47 - ./hosts/ryzentower 43 + disko.nixosModules.disko 44 + home-manager.nixosModules.home-manager 45 + ./hosts/ryzentower.nix 48 46 ]; 49 47 }; 50 48 thinkpadz13 = nixpkgs.lib.nixosSystem { 49 + system = "x86_64-linux"; 50 + specialArgs = { 51 + platform = nixpkgs.lib.systems.elaborate "x86_64-linux"; 52 + }; 51 53 modules = baseModules ++ [ 54 + disko.nixosModules.disko 55 + home-manager.nixosModules.home-manager 52 56 nixos-hardware.nixosModules.lenovo-thinkpad-z13-gen1 53 - ./graphical.nix 54 - ./hosts/thinkpadz13 57 + ./hosts/thinkpadz13.nix 55 58 ]; 56 59 }; 57 60 codeserver = nixpkgs.lib.nixosSystem { 61 + system = "x86_64-linux"; 62 + specialArgs = { 63 + platform = nixpkgs.lib.systems.elaborate "x86_64-linux"; 64 + }; 58 65 modules = baseModules ++ [ 59 - ./hosts/codeserver 66 + disko.nixosModules.disko 67 + home-manager.nixosModules.home-manager 68 + ./hosts/codeserver.nix 69 + ]; 70 + }; 71 + }; 72 + 73 + darwinConfigurations = { 74 + "MacBookPro" = darwin.lib.darwinSystem { 75 + system = "aarch64-darwin"; 76 + specialArgs = { 77 + platform = nixpkgs.lib.systems.elaborate "aarch64-darwin"; 78 + }; 79 + modules = baseModules ++ [ 80 + home-manager.darwinModules.home-manager 81 + ./hosts/MacBookPro.nix 82 + ]; 83 + }; 84 + "AS-GXL19NXYYQ" = darwin.lib.darwinSystem { 85 + system = "aarch64-darwin"; 86 + specialArgs = { 87 + platform = nixpkgs.lib.systems.elaborate "aarch64-darwin"; 88 + }; 89 + modules = baseModules ++ [ 90 + home-manager.darwinModules.home-manager 91 + ./hosts/AS-GXL19NXYYQ.nix 92 + ]; 93 + }; 94 + macos-test = darwin.lib.darwinSystem { 95 + system = "aarch64-darwin"; 96 + specialArgs = { 97 + platform = nixpkgs.lib.systems.elaborate "aarch64-darwin"; 98 + }; 99 + modules = baseModules ++ [ 100 + home-manager.darwinModules.home-manager 101 + ./hosts/macos-test.nix 60 102 ]; 61 103 }; 62 104 };
+41 -4
graphical.nix modules/gui/linux.nix
··· 1 1 { config, pkgs, ... }: 2 2 3 3 { 4 + programs.zsh.loginShellInit = '' 5 + if [ -z "$WAYLAND_DISPLAY" ] && [ "$XDG_VTNR" -eq 1 ]; then 6 + exec sway 7 + fi 8 + ''; 9 + 4 10 i18n = { 5 11 inputMethod = { 6 12 enable = true; ··· 54 60 extraPackages = with pkgs; [ 55 61 autotiling 56 62 feh 63 + foot 57 64 grim 58 65 i3status-rust 59 66 libnotify ··· 79 86 gpu-screen-recorder.enable = true; 80 87 }; 81 88 82 - fonts.packages = with pkgs; [ 83 - nerd-fonts.fira-code 84 - ]; 85 - 86 89 xdg.portal = { 87 90 enable = true; 88 91 wlr.enable = true; ··· 102 105 virtualisation = { 103 106 libvirtd = { 104 107 enable = true; 108 + }; 109 + }; 110 + 111 + home-manager.users.${config.primaryUser.username} = { 112 + home = { 113 + packages = with pkgs.unstable; [ 114 + blender 115 + brave 116 + emacs-pgtk 117 + gnome-sound-recorder 118 + gpu-screen-recorder 119 + kdePackages.kdeconnect-kde 120 + onlyoffice-desktopeditors 121 + piper 122 + ]; 123 + 124 + pointerCursor = { 125 + name = "Adwaita"; 126 + package = pkgs.adwaita-icon-theme; 127 + }; 128 + }; 129 + 130 + services.easyeffects.enable = true; 131 + 132 + gtk = { 133 + enable = true; 134 + theme = { 135 + package = pkgs.arc-theme; 136 + name = "Arc-Dark"; 137 + }; 138 + iconTheme = { 139 + package = pkgs.arc-icon-theme; 140 + name = "Arc"; 141 + }; 105 142 }; 106 143 }; 107 144 }
+12
hosts/AS-GXL19NXYYQ.nix
··· 1 + { 2 + imports = [ 3 + ../modules/cli 4 + ../modules/dotfiles 5 + ../modules/gui 6 + ../modules/work 7 + ]; 8 + 9 + primaryUser.username = "kdoan"; 10 + 11 + networking.hostName = "AS-GXL19NXYYQ"; 12 + }
+12
hosts/MacBookPro.nix
··· 1 + { 2 + imports = [ 3 + ../modules/cli 4 + ../modules/dotfiles 5 + ../modules/gui 6 + ../modules/personal 7 + ]; 8 + 9 + primaryUser.username = "khuedoan"; 10 + 11 + networking.hostName = "MacBookPro"; 12 + }
+19
hosts/codeserver.nix
··· 1 + { ... }: 2 + 3 + { 4 + imports = [ 5 + ../modules/cli 6 + ../modules/dotfiles 7 + ../modules/personal 8 + ]; 9 + 10 + primaryUser.username = "khuedoan"; 11 + 12 + nixpkgs = { 13 + hostPlatform = "x86_64-linux"; 14 + }; 15 + 16 + networking = { 17 + hostName = "codeserver"; 18 + }; 19 + }
-11
hosts/codeserver/default.nix
··· 1 - { pkgs, ... }: 2 - 3 - { 4 - nixpkgs = { 5 - hostPlatform = "x86_64-linux"; 6 - }; 7 - 8 - networking = { 9 - hostName = "codeserver"; 10 - }; 11 - }
+17
hosts/macos-test.nix
··· 1 + { config, lib, ... }: 2 + 3 + { 4 + primaryUser.username = "runner"; 5 + 6 + networking.hostName = "macos-test"; 7 + 8 + # Linux builder is disabled in CI until bootstrap issues are fixed. 9 + nix.linux-builder.enable = lib.mkForce false; 10 + 11 + home-manager = { 12 + users.${config.primaryUser.username} = { 13 + home.stateVersion = "25.11"; 14 + programs.home-manager.enable = true; 15 + }; 16 + }; 17 + }
+15 -14
hosts/ryzentower/default.nix hosts/ryzentower.nix
··· 1 - { lib, ... }: 1 + { config, lib, ... }: 2 2 3 3 { 4 + imports = [ 5 + ../modules/cli 6 + ../modules/dotfiles 7 + ../modules/gui 8 + ../modules/personal 9 + ]; 10 + 11 + primaryUser.username = "khuedoan"; 12 + 4 13 networking = { 5 14 hostName = "ryzentower"; 6 15 }; ··· 87 96 }; 88 97 }; 89 98 90 - home-manager = { 91 - users.khuedoan = { 92 - home = { 93 - file = { 94 - ".config/sway/config.d/hardware".text = '' 95 - output "DP-3" { 96 - mode 2560x1440@180Hz 97 - } 98 - ''; 99 - }; 100 - }; 101 - }; 102 - }; 99 + home-manager.users.${config.primaryUser.username}.home.file.".config/sway/config.d/hardware".text = '' 100 + output "DP-3" { 101 + mode 2560x1440@180Hz 102 + } 103 + ''; 103 104 }
+17 -16
hosts/thinkpadz13/default.nix hosts/thinkpadz13.nix
··· 1 - { pkgs, ... }: 1 + { config, ... }: 2 2 3 3 { 4 + imports = [ 5 + ../modules/cli 6 + ../modules/dotfiles 7 + ../modules/gui 8 + ../modules/personal 9 + ]; 10 + 11 + primaryUser.username = "khuedoan"; 12 + 4 13 hardware = { 5 14 graphics = { 6 15 enable32Bit = true; ··· 82 91 }; 83 92 }; 84 93 85 - home-manager = { 86 - users.khuedoan = { 87 - home = { 88 - file = { 89 - ".config/sway/config.d/hardware".text = '' 90 - output "eDP-1" { 91 - scale 1.333 92 - } 94 + home-manager.users.${config.primaryUser.username}.home.file.".config/sway/config.d/hardware".text = '' 95 + output "eDP-1" { 96 + scale 1.333 97 + } 93 98 94 - bindswitch --reload --locked lid:on output eDP-1 disable 95 - bindswitch --reload --locked lid:off output eDP-1 enable 96 - ''; 97 - }; 98 - }; 99 - }; 100 - }; 99 + bindswitch --reload --locked lid:on output eDP-1 disable 100 + bindswitch --reload --locked lid:off output eDP-1 enable 101 + ''; 101 102 }
+35
modules/cli/darwin.nix
··· 1 + { config, pkgs, ... }: 2 + 3 + { 4 + environment.systemPackages = with pkgs; [ 5 + coreutils 6 + docker 7 + gnupg 8 + pinentry-tty 9 + ]; 10 + 11 + homebrew.casks = [ 12 + "claude-code" 13 + ]; 14 + 15 + environment.systemPath = [ 16 + config.homebrew.brewPrefix # TODO https://github.com/LnL7/nix-darwin/issues/596 17 + ]; 18 + 19 + # Create /etc/zshrc that loads the nix-darwin environment. 20 + programs = { 21 + zsh = { 22 + enable = true; 23 + enableBashCompletion = false; 24 + enableCompletion = false; 25 + promptInit = ""; 26 + }; 27 + direnv = { 28 + # TODO remove this workaround https://github.com/NixOS/nixpkgs/issues/507531 29 + package = pkgs.direnv.overrideAttrs (_: { 30 + doCheck = false; 31 + }); 32 + silent = true; 33 + }; 34 + }; 35 + }
+68
modules/cli/default.nix
··· 1 + { config, pkgs, platform, ... }: 2 + 3 + { 4 + imports = [ 5 + ./${platform.parsed.kernel.name}.nix 6 + ]; 7 + 8 + home-manager.users.${config.primaryUser.username}.home.packages = with pkgs.unstable; [ 9 + aria2 10 + backblaze-b2 11 + bat 12 + btop 13 + cargo 14 + colima 15 + dyff 16 + fd 17 + ffmpeg 18 + fzf 19 + gh 20 + ghstack 21 + go 22 + imagemagick 23 + inetutils 24 + jq 25 + k9s 26 + kubectl 27 + kubectl-tree 28 + kubectx 29 + kubernetes-helm 30 + kustomize 31 + markdown-oxide 32 + mosh 33 + neovim 34 + nnn 35 + nodejs 36 + poppler-utils 37 + python314 38 + rbw 39 + ripgrep 40 + sapling 41 + uv 42 + yt-dlp 43 + zk 44 + zoxide 45 + 46 + (pass.withExtensions (ext: with ext; [ 47 + # pass-import # TODO fix build on darwin 48 + pass-otp 49 + ])) 50 + 51 + # Language servers 52 + gopls 53 + lua-language-server 54 + nil 55 + pyright 56 + rust-analyzer 57 + terraform-ls 58 + typescript-language-server 59 + 60 + # AI 61 + agent-browser 62 + codex 63 + mcp-grafana 64 + opencode 65 + pi-coding-agent 66 + playwright-mcp 67 + ]; 68 + }
+18
modules/cli/linux.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + environment.systemPackages = with pkgs; [ 5 + file 6 + gcc 7 + gnumake 8 + killall 9 + python3 10 + ]; 11 + 12 + programs = { 13 + gnupg.agent = { 14 + enable = true; 15 + enableSSHSupport = true; 16 + }; 17 + }; 18 + }
+27
modules/dotfiles/default.nix
··· 1 + { config, pkgs, ... }: 2 + 3 + { 4 + config.home-manager.users.${config.primaryUser.username} = { 5 + home.file."Pictures/Wallpapers/astronaut-jellyfish.jpg".source = builtins.fetchurl { 6 + url = "https://github.com/user-attachments/assets/b63195d0-7fe3-4ab5-95c7-20127123836c"; 7 + sha256 = "1g120j4z6665j4wh2g84m4rb24gvzdxyhx9lqym68cwn8ny2j7fz"; 8 + }; 9 + 10 + home.activation.dotfiles = '' 11 + set -eu 12 + 13 + if [ ! -d "$HOME/.git" ]; then 14 + ${pkgs.git}/bin/git init 15 + ${pkgs.git}/bin/git config status.showUntrackedFiles no 16 + ${pkgs.git}/bin/git remote add origin https://github.com/khuedoan/dotfiles 17 + 18 + until ${pkgs.curl}/bin/curl --fail --silent --head --output /dev/null https://github.com; do 19 + sleep 1 20 + done 21 + 22 + ${pkgs.git}/bin/git pull origin master 23 + ${pkgs.git}/bin/git branch --set-upstream-to=origin/master master 24 + fi 25 + ''; 26 + }; 27 + }
+51
modules/gui/darwin.nix
··· 1 + { config, ... }: 2 + 3 + { 4 + homebrew.casks = [ 5 + "brave-browser" 6 + "handy" 7 + "helium-browser" 8 + "kitty" 9 + "linearmouse" 10 + "obsidian" 11 + "secretive" 12 + "utm" 13 + ]; 14 + 15 + system.defaults = { 16 + dock = { 17 + autohide = true; 18 + expose-group-apps = true; 19 + minimize-to-application = true; 20 + mru-spaces = false; 21 + showhidden = true; 22 + }; 23 + NSGlobalDomain = { 24 + AppleInterfaceStyle = "Dark"; 25 + AppleKeyboardUIMode = 3; 26 + ApplePressAndHoldEnabled = false; 27 + NSAutomaticCapitalizationEnabled = false; 28 + NSAutomaticDashSubstitutionEnabled = false; 29 + NSAutomaticPeriodSubstitutionEnabled = false; 30 + NSAutomaticQuoteSubstitutionEnabled = false; 31 + NSAutomaticSpellingCorrectionEnabled = false; 32 + }; 33 + CustomUserPreferences = { 34 + "com.apple.Safari" = { 35 + AlwaysRestoreSessionAtLaunch = true; 36 + AutoOpenSafeDownloads = false; 37 + EnableNarrowTabs = false; 38 + IncludeDevelopMenu = true; 39 + NeverUseBackgroundColorInToolbar = true; 40 + ShowFullURLInSmartSearchField = true; 41 + ShowOverlayStatusBar = true; 42 + ShowStandaloneTabBar = false; 43 + }; 44 + }; 45 + }; 46 + 47 + home-manager.users.${config.primaryUser.username}.home.file = { 48 + ".config/karabiner/karabiner.json".source = ./files/karabiner.json; 49 + ".config/kitty/kitty.d/macos.conf".source = ./files/kitty.conf; 50 + }; 51 + }
+11
modules/gui/default.nix
··· 1 + { pkgs, platform, ... }: 2 + 3 + { 4 + imports = [ 5 + ./${platform.parsed.kernel.name}.nix 6 + ]; 7 + 8 + fonts.packages = with pkgs; [ 9 + nerd-fonts.fira-code 10 + ]; 11 + }
+137
modules/gui/files/karabiner.json
··· 1 + { 2 + "profiles": [ 3 + { 4 + "complex_modifications": { 5 + "rules": [ 6 + { 7 + "description": "Post Esc if Capslock is tapped, Control if held", 8 + "manipulators": [ 9 + { 10 + "from": { 11 + "key_code": "caps_lock", 12 + "modifiers": { "optional": ["any"] } 13 + }, 14 + "to": [ 15 + { 16 + "key_code": "left_control", 17 + "lazy": true 18 + } 19 + ], 20 + "to_if_alone": [{ "key_code": "escape" }], 21 + "type": "basic" 22 + } 23 + ] 24 + }, 25 + { 26 + "description": "Linux-style keymap for word motions", 27 + "manipulators": [ 28 + { 29 + "from": { 30 + "key_code": "delete_or_backspace", 31 + "modifiers": { "mandatory": ["left_control"] } 32 + }, 33 + "to": [ 34 + { 35 + "key_code": "delete_or_backspace", 36 + "modifiers": ["left_option"] 37 + } 38 + ], 39 + "type": "basic" 40 + }, 41 + { 42 + "from": { 43 + "key_code": "left_arrow", 44 + "modifiers": { "mandatory": ["left_control"] } 45 + }, 46 + "to": [ 47 + { 48 + "key_code": "left_arrow", 49 + "modifiers": ["left_option"] 50 + } 51 + ], 52 + "type": "basic" 53 + }, 54 + { 55 + "from": { 56 + "key_code": "down_arrow", 57 + "modifiers": { "mandatory": ["left_control"] } 58 + }, 59 + "to": [ 60 + { 61 + "key_code": "down_arrow", 62 + "modifiers": ["left_option"] 63 + } 64 + ], 65 + "type": "basic" 66 + }, 67 + { 68 + "from": { 69 + "key_code": "up_arrow", 70 + "modifiers": { "mandatory": ["left_control"] } 71 + }, 72 + "to": [ 73 + { 74 + "key_code": "up_arrow", 75 + "modifiers": ["left_option"] 76 + } 77 + ], 78 + "type": "basic" 79 + }, 80 + { 81 + "from": { 82 + "key_code": "right_arrow", 83 + "modifiers": { "mandatory": ["left_control"] } 84 + }, 85 + "to": [ 86 + { 87 + "key_code": "right_arrow", 88 + "modifiers": ["left_option"] 89 + } 90 + ], 91 + "type": "basic" 92 + } 93 + ] 94 + }, 95 + { 96 + "description": "Right Command as custom layer", 97 + "manipulators": [ 98 + { 99 + "from": { 100 + "key_code": "h", 101 + "modifiers": { "mandatory": ["right_command"] } 102 + }, 103 + "to": [{ "key_code": "left_arrow" }], 104 + "type": "basic" 105 + }, 106 + { 107 + "from": { 108 + "key_code": "j", 109 + "modifiers": { "mandatory": ["right_command"] } 110 + }, 111 + "to": [{ "key_code": "down_arrow" }], 112 + "type": "basic" 113 + }, 114 + { 115 + "from": { 116 + "key_code": "k", 117 + "modifiers": { "mandatory": ["right_command"] } 118 + }, 119 + "to": [{ "key_code": "up_arrow" }], 120 + "type": "basic" 121 + }, 122 + { 123 + "from": { 124 + "key_code": "l", 125 + "modifiers": { "mandatory": ["right_command"] } 126 + }, 127 + "to": [{ "key_code": "right_arrow" }], 128 + "type": "basic" 129 + } 130 + ] 131 + } 132 + ] 133 + }, 134 + "virtual_hid_keyboard": { "keyboard_type_v2": "ansi" } 135 + } 136 + ] 137 + }
+20
modules/gui/files/kitty.conf
··· 1 + # Fonts 2 + 3 + font_size 12 4 + 5 + # Keymaps 6 + 7 + kitty_mod cmd 8 + 9 + map cmd+c copy_to_clipboard 10 + map cmd+v paste_from_clipboard 11 + 12 + map cmd+equal change_font_size all +1.0 13 + map cmd+minus change_font_size all -1.0 14 + map cmd+0 change_font_size all 0 15 + 16 + # macOS specific tweaks 17 + 18 + hide_window_decorations titlebar-only 19 + macos_option_as_alt yes 20 + macos_quit_when_last_window_closed yes
+17
modules/personal/darwin.nix
··· 1 + { ... }: 2 + 3 + { 4 + homebrew = { 5 + casks = [ 6 + "discord" 7 + "iina" 8 + "signal" 9 + "zen" 10 + ]; 11 + masApps = { 12 + # Need to be signed into the Mac App Store 13 + "Bitwarden" = 1352778147; 14 + "WireGuard" = 1451685025; 15 + }; 16 + }; 17 + }
+7
modules/personal/default.nix
··· 1 + { platform, ... }: 2 + 3 + { 4 + imports = [ 5 + ./${platform.parsed.kernel.name}.nix 6 + ]; 7 + }
+52
modules/personal/linux.nix
··· 1 + { config, pkgs, ... }: 2 + 3 + let 4 + username = config.primaryUser.username; 5 + in 6 + 7 + { 8 + home-manager.users.${username} = { 9 + home.packages = with pkgs.unstable; [ 10 + signal-desktop 11 + ]; 12 + 13 + systemd.user = { 14 + services.sync-notes = { 15 + Unit.Description = "Sync notes"; 16 + Service = { 17 + Type = "oneshot"; 18 + WorkingDirectory = "%h/Documents/notes"; 19 + Environment = [ 20 + "HOSTNAME=%H" 21 + "GIT_SSH_COMMAND=/run/current-system/sw/bin/ssh" 22 + ]; 23 + ExecStart = "${pkgs.writeTextFile { 24 + name = "sync-notes"; 25 + executable = true; 26 + text = '' 27 + #!${pkgs.bash}/bin/sh 28 + set -eu 29 + 30 + if [ -n "$(${pkgs.git}/bin/git status --porcelain)" ]; then 31 + ${pkgs.git}/bin/git add --all 32 + if ! ${pkgs.git}/bin/git diff --cached --quiet; then 33 + ${pkgs.git}/bin/git commit -m "Update notes from $HOSTNAME" 34 + fi 35 + fi 36 + ${pkgs.git}/bin/git pull --rebase --strategy-option theirs 37 + ${pkgs.git}/bin/git push 38 + ''; 39 + }}"; 40 + }; 41 + }; 42 + timers.sync-notes = { 43 + Unit.Description = "Sync notes every 5 minutes"; 44 + Timer = { 45 + OnUnitActiveSec = "5min"; 46 + Persistent = true; 47 + }; 48 + Install.WantedBy = [ "timers.target" ]; 49 + }; 50 + }; 51 + }; 52 + }
+17
modules/work/darwin.nix
··· 1 + { ... }: 2 + 3 + { 4 + homebrew = { 5 + taps = [ 6 + { name = "atlassian/homebrew-acli"; } 7 + ]; 8 + brews = [ 9 + "acli" 10 + ]; 11 + casks = [ 12 + "aws-vpn-client" 13 + "cursor-cli" 14 + "royal-tsx" 15 + ]; 16 + }; 17 + }
+25
modules/work/default.nix
··· 1 + { config, pkgs, platform, ... }: 2 + 3 + { 4 + imports = [ 5 + ./${platform.parsed.kernel.name}.nix 6 + ]; 7 + 8 + home-manager.users.${config.primaryUser.username}.home.packages = with pkgs.unstable; [ 9 + # acr-cli 10 + argocd 11 + awscli2 12 + azure-cli 13 + cmctl 14 + granted 15 + istioctl 16 + jira-cli-go 17 + kubelogin 18 + prometheus.cli 19 + sops 20 + ssm-session-manager-plugin 21 + tenv 22 + tflint 23 + yq-go 24 + ]; 25 + }
+3
modules/work/linux.nix
··· 1 + { ... }: 2 + 3 + { }
+65
scripts/rebuild.py
··· 1 + #!/usr/bin/env python3 2 + 3 + import os 4 + import shutil 5 + import subprocess 6 + import sys 7 + import tempfile 8 + import urllib.request 9 + 10 + 11 + def run_installer(url: str, shell: str, env: dict[str, str] | None = None) -> None: 12 + with tempfile.NamedTemporaryFile(delete=False) as script: 13 + path = script.name 14 + 15 + try: 16 + with urllib.request.urlopen(url) as response: 17 + with open(path, "wb") as file: 18 + file.write(response.read()) 19 + 20 + subprocess.run( 21 + [shell, path], 22 + check=True, 23 + env={**os.environ, **(env or {})}, 24 + ) 25 + finally: 26 + os.unlink(path) 27 + 28 + 29 + def ensure_homebrew() -> None: 30 + if shutil.which("brew") is None: 31 + run_installer( 32 + "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh", 33 + "bash", 34 + {"NONINTERACTIVE": "1"}, 35 + ) 36 + 37 + 38 + def ensure_nix() -> None: 39 + binary = shutil.which("nix") 40 + if binary is None: 41 + run_installer("https://nixos.org/nix/install", "sh") 42 + 43 + 44 + def main() -> None: 45 + match os.uname().sysname.lower(): 46 + case "linux": 47 + command = ["nixos-rebuild", *sys.argv[1:]] 48 + case "darwin": 49 + ensure_homebrew() 50 + ensure_nix() 51 + command = [ 52 + "/nix/var/nix/profiles/default/bin/nix", 53 + "run", 54 + "nix-darwin/nix-darwin-25.11#darwin-rebuild", 55 + "--", 56 + *sys.argv[1:], 57 + ] 58 + case platform: 59 + raise SystemExit(f"unsupported platform: {platform}") 60 + 61 + os.execvp(command[0], command) 62 + 63 + 64 + if __name__ == "__main__": 65 + main()
-167
users/khuedoan/default.nix
··· 1 - { pkgs, ... }: 2 - 3 - { 4 - users.users.khuedoan = { 5 - isNormalUser = true; 6 - description = "Khue Doan"; 7 - extraGroups = [ 8 - "docker" 9 - "libvirtd" 10 - "networkmanager" 11 - "tss" 12 - "video" 13 - "wheel" 14 - ]; 15 - openssh.authorizedKeys.keys = [ 16 - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5ue4np7cF34f6dwqH1262fPjkowHQ8irfjVC156PCG" 17 - ]; 18 - shell = pkgs.zsh; 19 - # Use newer packages from the unstable channel for user-level programs (system packages still use the stable channel). 20 - packages = with pkgs.unstable; [ 21 - aria2 22 - bat 23 - btop 24 - cargo 25 - fd 26 - ffmpeg 27 - foot 28 - fzf 29 - gemini-cli 30 - gh 31 - go 32 - jq 33 - k9s 34 - kubectl 35 - kubernetes-helm 36 - kustomize 37 - neovim 38 - nodejs 39 - radicle-node 40 - ripgrep 41 - yt-dlp 42 - zk 43 - zoxide 44 - 45 - (pass-nodmenu.withExtensions (ext: with ext; [ 46 - pass-import 47 - pass-otp 48 - ])) 49 - 50 - # Language servers 51 - gopls 52 - lua-language-server 53 - markdown-oxide 54 - nil 55 - pyright 56 - rust-analyzer 57 - terraform-ls 58 - typescript-language-server 59 - 60 - # AI 61 - codex 62 - opencode 63 - playwright-mcp 64 - 65 - # GUI 66 - blender 67 - brave 68 - emacs-pgtk 69 - gnome-sound-recorder 70 - gpu-screen-recorder 71 - kdePackages.kdeconnect-kde 72 - onlyoffice-desktopeditors 73 - piper 74 - signal-desktop 75 - ]; 76 - }; 77 - 78 - home-manager = { 79 - useGlobalPkgs = true; 80 - useUserPackages = true; 81 - users.khuedoan = { 82 - home = { 83 - stateVersion = "23.05"; 84 - activation = { 85 - dotfiles = '' 86 - set -eu 87 - [ -d ~/.git ] \ 88 - || ${pkgs.git}/bin/git init \ 89 - && ${pkgs.git}/bin/git config status.showUntrackedFiles no \ 90 - && ${pkgs.git}/bin/git remote add origin https://github.com/khuedoan/dotfiles \ 91 - && (until ${pkgs.iputils}/bin/ping -c 1 github.com; do sleep 1; done) \ 92 - && ${pkgs.git}/bin/git pull origin master \ 93 - && ${pkgs.git}/bin/git branch --set-upstream-to=origin/master master 94 - ''; 95 - }; 96 - file = { 97 - "Pictures/Wallpapers/astronaut-jellyfish.jpg".source = builtins.fetchurl { 98 - url = "https://github.com/user-attachments/assets/b63195d0-7fe3-4ab5-95c7-20127123836c"; 99 - sha256 = "1g120j4z6665j4wh2g84m4rb24gvzdxyhx9lqym68cwn8ny2j7fz"; # nix-prefetch-url 100 - }; 101 - }; 102 - }; 103 - services = { 104 - easyeffects.enable = true; 105 - }; 106 - systemd.user = { 107 - services.sync-notes = { 108 - Unit = { 109 - Description = "Sync notes"; 110 - }; 111 - Service = { 112 - Type = "oneshot"; 113 - WorkingDirectory = "%h/Documents/notes"; 114 - Environment = [ 115 - "HOSTNAME=%H" 116 - "GIT_SSH_COMMAND=/run/current-system/sw/bin/ssh" 117 - ]; 118 - ExecStart = "${pkgs.writeTextFile { 119 - name = "sync-notes"; 120 - executable = true; 121 - text = '' 122 - #!${pkgs.bash}/bin/sh 123 - set -eu 124 - 125 - if [ -n "$(${pkgs.git}/bin/git status --porcelain)" ]; then 126 - ${pkgs.git}/bin/git add --all 127 - if ! ${pkgs.git}/bin/git diff --cached --quiet; then 128 - ${pkgs.git}/bin/git commit -m "Update notes from $HOSTNAME" 129 - fi 130 - fi 131 - ${pkgs.git}/bin/git pull --rebase --strategy-option theirs 132 - ${pkgs.git}/bin/git push 133 - ''; 134 - }}"; 135 - }; 136 - }; 137 - timers.sync-notes = { 138 - Unit = { 139 - Description = "Sync notes every 5 minutes"; 140 - }; 141 - Timer = { 142 - OnUnitActiveSec = "5min"; 143 - Persistent = true; 144 - }; 145 - Install = { 146 - WantedBy = [ "timers.target" ]; 147 - }; 148 - }; 149 - }; 150 - home.pointerCursor = { 151 - name = "Adwaita"; 152 - package = pkgs.adwaita-icon-theme; 153 - }; 154 - gtk = { 155 - enable = true; 156 - theme = { 157 - package = pkgs.arc-theme; 158 - name = "Arc-Dark"; 159 - }; 160 - iconTheme = { 161 - package = pkgs.arc-icon-theme; 162 - name = "Arc"; 163 - }; 164 - }; 165 - }; 166 - }; 167 - }