├── .devcontainer.json ├── .envrc ├── .github └── workflows │ ├── binary-cache.yaml │ ├── sync.yaml │ ├── template-darwin-system.yaml │ └── update-inputs.yaml ├── .gitignore ├── README.markdown ├── config ├── 1password │ ├── darwin.nix │ └── home.nix ├── attic │ └── home.nix ├── atuin │ └── home.nix ├── bat │ └── home.nix ├── brew │ ├── darwin.nix │ ├── home.nix │ └── overlay.nix ├── certificate-authority │ └── nixos+darwin.nix ├── chromium │ ├── chromium-macos.nix │ ├── home.nix │ └── update.js ├── cloudflared │ └── home.nix ├── darwin-defaults │ └── darwin.nix ├── default.nix ├── direnv │ └── home.nix ├── editorconfig │ └── home.nix ├── eza │ └── home.nix ├── fish │ ├── darwin.nix │ ├── functions │ │ ├── gitco.fish │ │ ├── gzipsize.fish │ │ ├── krun.fish │ │ ├── mcat.fish │ │ ├── mkcd.fish │ │ └── mkpass.fish │ ├── home.nix │ └── nixos.nix ├── fonts │ └── home.nix ├── ghostty │ └── home.nix ├── git │ └── home.nix ├── helix │ ├── config.toml │ ├── home.nix │ └── nixos+darwin.nix ├── home-manager │ ├── darwin.nix │ ├── home.nix │ ├── nixos+darwin.nix │ └── nixos.nix ├── htop │ └── home.nix ├── nix │ ├── darwin.nix │ ├── home.nix │ ├── nixos+darwin.nix │ ├── nixos.nix │ └── substituters.nix ├── nixpkgs │ ├── config.nix │ ├── home.nix │ └── nixos+darwin.nix ├── nushell │ ├── config.nu │ ├── env.nu │ ├── home.nix │ └── login.nu ├── ssh │ └── home.nix ├── starship │ ├── config.toml │ └── home.nix ├── toolbox │ └── darwin.nix ├── vscode │ ├── extensions.nix │ ├── home.nix │ ├── keybindings.json │ ├── nixos+darwin.nix │ └── settings.json ├── wezterm │ ├── config.lua │ └── home.nix ├── zoxide │ └── home.nix └── zsh │ ├── darwin.nix │ └── nixos.nix ├── devenv.nix ├── flake.lock ├── flake.nix ├── modules ├── default.nix ├── flakeModules │ └── colmena.nix └── homeManager │ ├── default-packages.nix │ └── smallstep.nix ├── scripts ├── diff-flake-lock.pl └── update-flake-inputs.sh └── templates ├── darwin-system ├── .gitignore ├── configuration.nix ├── devenv.nix └── flake.nix ├── default.nix ├── dev-base ├── .envrc ├── .gitignore └── flake.nix ├── dev-fe-typescript ├── devenv.nix ├── index.ts ├── package.json └── tsconfig.json └── shell-nodejs ├── .envrc └── shell.nix /.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "customizations": { 3 | "vscode": { 4 | "extensions": [ 5 | "zhuangtongfa.material-theme", 6 | "mkhl.direnv", 7 | "editorconfig.editorconfig", 8 | "redhat.vscode-yaml", 9 | "redhat.vscode-xml", 10 | "streetsidesoftware.code-spell-checker", 11 | "eamodio.gitlens", 12 | "tamasfe.even-better-toml", 13 | "github.codespaces", 14 | "github.copilot", 15 | "jnoortheen.nix-ide", 16 | "1password.op-vscode", 17 | "jnoortheen.nix-ide", 18 | "thenuprojectcontributors.vscode-nushell-lang" 19 | ] 20 | } 21 | }, 22 | "image": "ghcr.io/cachix/devenv:latest", 23 | "overrideCommand": false, 24 | "updateContentCommand": "" 25 | } 26 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | watch_file flake.nix 4 | watch_file flake.lock 5 | watch_file devenv.nix 6 | 7 | # If 1Password CLI is installed and there are 1password secret references 8 | # then inject the secrets and source the resulting file. 9 | if [ -e .env ]; then 10 | COMPUTED_ENV="${TMPDIR}/$(pwd | sha1).env" 11 | 12 | if [ ! -e $COMPUTED_ENV ]; then 13 | op inject -i .env > $COMPUTED_ENV 14 | chmod g-rw,o-rw $COMPUTED_ENV 15 | fi 16 | 17 | source $COMPUTED_ENV 18 | fi 19 | 20 | DEVENV_ROOT_FILE="$(mktemp)" 21 | printf %s "$PWD" > "$DEVENV_ROOT_FILE" 22 | if ! use flake path:. --override-input devenv-root "file+file://$DEVENV_ROOT_FILE" 23 | then 24 | echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 25 | fi 26 | -------------------------------------------------------------------------------- /.github/workflows/binary-cache.yaml: -------------------------------------------------------------------------------- 1 | name: "Binary Cache" 2 | on: 3 | push: 4 | paths: 5 | - "config/*" 6 | - "*.nix" 7 | jobs: 8 | binary-cache: 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest, macos-latest] 12 | runs-on: ${{ matrix.os }} 13 | steps: 14 | - uses: "actions/checkout@v4" 15 | - uses: "DeterminateSystems/nix-installer-action@main" 16 | - uses: cachix/cachix-action@v14 17 | with: 18 | name: luke-channings 19 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 20 | - name: Build packages 21 | run: | 22 | export NIXPKGS_ALLOW_UNFREE=1 23 | nix run --accept-flake-config --impure .#home-manager -- build --impure --flake .#luke 24 | - name: Build dev shell 25 | run: | 26 | export NIXPKGS_ALLOW_UNFREE=1 27 | nix develop --impure --accept-flake-config --accept-flake-config --build 28 | -------------------------------------------------------------------------------- /.github/workflows/sync.yaml: -------------------------------------------------------------------------------- 1 | name: "Sync Home Manager dotfiles to home branch" 2 | on: 3 | push: 4 | branches: 5 | - main 6 | paths: 7 | - config/* 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | outputs: 12 | sha: ${{ steps.build.outputs.sha }} 13 | steps: 14 | - uses: "actions/checkout@v4" 15 | - uses: "DeterminateSystems/nix-installer-action@main" 16 | - uses: cachix/cachix-action@v14 17 | with: 18 | name: luke-channings 19 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 20 | - name: Build packages 21 | id: build 22 | run: | 23 | export NIXPKGS_ALLOW_UNFREE=1 24 | nix profile install nixpkgs#fd nixpkgs#sd 25 | 26 | nix run --accept-flake-config .#home-manager -- build --impure --flake .#luke 27 | 28 | mkdir home 29 | rsync -aL --chown="$(whoami):$(whoami)" --chmod=ug+rw result/home-files/.config/ home/ 30 | cp -L result/home-files/.editorconfig home/editorconfig 31 | cp -RL result/home-files/.ssh home/ssh 32 | sudo chown -R "$(whoami):$(whoami)" ./home 33 | chmod -R ug+rw ./home 34 | rm -rf home/environment.d 35 | 36 | fd --type=file . home --exec sd '/nix/store/.*/bin/' '' 37 | 38 | echo "sha=$GITHUB_SHA" >> "$GITHUB_OUTPUT" 39 | - uses: actions/upload-artifact@v4 40 | with: 41 | name: dotfiles 42 | path: home 43 | sync: 44 | needs: [build] 45 | permissions: 46 | contents: write 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v4 50 | with: 51 | ref: home 52 | - name: Download math result for job 1 53 | uses: actions/download-artifact@v4 54 | with: 55 | name: dotfiles 56 | - name: Push differences 57 | run: | 58 | git config --global user.name 'Luke Channings' 59 | git config --global user.email 'lukechannings@users.noreply.github.com' 60 | git add . 61 | git commit -am "Sync ${{needs.build.outputs.sha}}" 62 | git push 63 | -------------------------------------------------------------------------------- /.github/workflows/template-darwin-system.yaml: -------------------------------------------------------------------------------- 1 | name: "Template test: darwin-system" 2 | on: 3 | workflow_dispatch: 4 | jobs: 5 | template-test: 6 | runs-on: macos-latest 7 | steps: 8 | - uses: "actions/checkout@v4" 9 | - uses: "DeterminateSystems/nix-installer-action@main" 10 | - uses: cachix/cachix-action@v14 11 | with: 12 | name: luke-channings 13 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 14 | - name: Build packages 15 | run: | 16 | export NIXPKGS_ALLOW_UNFREE=1 17 | 18 | nix flake new -t ${{ github.workspace }}#darwin-system darwin-system 19 | cd darwin-system 20 | 21 | sudo nix run --override-input dotfiles path:${{ github.workspace }} .#activate --show-trace 22 | -------------------------------------------------------------------------------- /.github/workflows/update-inputs.yaml: -------------------------------------------------------------------------------- 1 | name: "Update Flake Input" 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | input_name: 6 | description: 'Flake input to update' 7 | required: true 8 | input_uri: 9 | description: 'URI to update to. (e.g. github:NixOS/nixpkgs/c128e44a249d)' 10 | required: true 11 | jobs: 12 | update-inputs: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | steps: 17 | - uses: "actions/checkout@v4" 18 | - uses: "DeterminateSystems/nix-installer-action@main" 19 | - uses: cachix/cachix-action@v14 20 | with: 21 | name: luke-channings 22 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 23 | - name: Update flake 24 | run: | 25 | export NIXPKGS_ALLOW_UNFREE=1 26 | export NIX_CONFIG="extra-substituters = true" 27 | nix flake update --option accept-flake-config true --override-input ${{ inputs.input_name }} ${{ inputs.input_uri }} 28 | 29 | git config --global user.name 'Luke Channings' 30 | git config --global user.email 'lukechannings@users.noreply.github.com' 31 | git commit flake.lock -m "Update flake" 32 | git push 33 | - name: Build packages 34 | run: | 35 | export NIXPKGS_ALLOW_UNFREE=1 36 | nix run --accept-flake-config --impure .#home-manager -- build --impure --flake .#luke 37 | - name: Build dev shell 38 | run: | 39 | export NIXPKGS_ALLOW_UNFREE=1 40 | nix develop --impure --accept-flake-config --accept-flake-config --build 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | fish_history 2 | fishd.* 3 | fish/fundle 4 | fish/functions/fzf_key_bindings.fish 5 | fish/functions/fish_user_key_bindings.fish 6 | fish/fish_variables 7 | 8 | .DS_Store 9 | .devenv 10 | .direnv 11 | .vscode 12 | .env 13 | result 14 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Luke's dotfiles 2 | 3 | ## Maintenance 4 | 5 | ### Keeping dependencies up-to-date 6 | 7 | - `./scripts/update-flake-inputs.sh` – update inputs, using the latest nixpkgs Hydra build. 8 | - `./scripts/diff-flake-lock.pl` – print updated inputs in the lockfile with github compare links 9 | 10 | ### Switching between a local clone and the git repo 11 | 12 | For flakes consuming this project it is useful to add a registry item for `dotfiles` 13 | 14 | ```sh 15 | nix registry add flake:dotfiles github:LukeChannings/dotfiles 16 | ``` 17 | 18 | This project can then be used as in input like so: 19 | 20 | ```nix 21 | { 22 | inputs.dotfiles.url = "dotfiles"; 23 | } 24 | ``` 25 | 26 | To switch to a local clone: 27 | 28 | ```bash 29 | nix registry add flake:dotfiles path:$LOCAL_DOTFILES_PATH 30 | 31 | cd $CONSUMING_REPO 32 | 33 | nix flake update dotfiles 34 | ``` 35 | -------------------------------------------------------------------------------- /config/1password/darwin.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | options = { 9 | programs._1password-gui = { 10 | enable = lib.mkEnableOption "1Password GUI"; 11 | }; 12 | }; 13 | 14 | config = lib.mkIf config.programs._1password-gui.enable { 15 | environment.systemPackages = [ pkgs._1password-gui ]; 16 | 17 | home-manager.sharedModules = [ 18 | ( 19 | { 20 | config, 21 | lib, 22 | pkgs, 23 | ... 24 | }: 25 | { 26 | options.programs._1password-cli = { 27 | enable = lib.mkEnableOption "1Password CLI"; 28 | }; 29 | 30 | config = lib.mkIf config.programs._1password-cli.enable { 31 | home.packages = [ pkgs._1password-cli ]; 32 | }; 33 | } 34 | ) 35 | ]; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /config/1password/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | config, 4 | pkgs, 5 | lib, 6 | ... 7 | }: 8 | { 9 | imports = [ inputs._1password-shell-plugins.hmModules.default ]; 10 | 11 | options = 12 | let 13 | inherit (lib) types mkOption; 14 | in 15 | with types; 16 | { 17 | programs._1password-cli = { 18 | enable = mkOption { 19 | type = bool; 20 | description = '' 21 | Enables 1Password shell integration 22 | ''; 23 | default = true; 24 | }; 25 | shellPluginPackages = mkOption { 26 | type = listOf package; 27 | description = '' 28 | Packages to be installed with 1Password shell integration 29 | ''; 30 | default = [ pkgs.gh ]; 31 | }; 32 | sshAgent = mkOption { 33 | description = '' 34 | Configuration for the 1Password SSH agent. 35 | See: https://developer.1password.com/docs/ssh/agent/config 36 | ''; 37 | type = nullOr (submodule { 38 | options.keys = mkOption { 39 | type = listOf (submodule { 40 | options = { 41 | item = mkOption { 42 | type = nullOr str; 43 | description = "The item name or ID"; 44 | default = null; 45 | }; 46 | 47 | vault = mkOption { 48 | type = nullOr str; 49 | description = "The vault name or ID"; 50 | default = null; 51 | }; 52 | 53 | account = mkOption { 54 | type = nullOr str; 55 | description = "The account name sign-in address or ID"; 56 | default = null; 57 | }; 58 | }; 59 | }); 60 | default = [ ]; 61 | }; 62 | }); 63 | default = null; 64 | }; 65 | }; 66 | }; 67 | 68 | config = { 69 | programs._1password-shell-plugins = { 70 | enable = true; 71 | plugins = config.programs._1password-cli.shellPluginPackages; 72 | }; 73 | 74 | xdg.configFile = lib.mkIf (config.programs._1password-cli.sshAgent != null) { 75 | "1Password/ssh/agent.toml".source = ( 76 | let 77 | tomlFormatter = pkgs.formats.toml { }; 78 | in 79 | tomlFormatter.generate "agent.toml" { 80 | "ssh-keys" = builtins.map (lib.filterAttrs ( 81 | _: v: v != null 82 | )) config.programs._1password-cli.sshAgent.keys; 83 | } 84 | ); 85 | }; 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /config/attic/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | lib, 5 | ... 6 | }: 7 | { 8 | options.dotfiles.attic = { 9 | watch-daemon = lib.mkOption { 10 | type = lib.types.submodule { 11 | options = { 12 | enable = lib.mkEnableOption "Enable the attic watch-store daemon"; 13 | cache = lib.mkOption { 14 | type = lib.types.str; 15 | description = "The cache to push to"; 16 | }; 17 | }; 18 | }; 19 | }; 20 | }; 21 | 22 | config = { 23 | home.packages = [ 24 | pkgs.attic-client 25 | ]; 26 | 27 | launchd.agents = lib.mkIf config.dotfiles.attic.watch-daemon.enable { 28 | attic = 29 | let 30 | inherit (config.home) homeDirectory; 31 | in 32 | { 33 | enable = true; 34 | config.ProgramArguments = [ 35 | (lib.getExe pkgs.attic-client) 36 | "watch-store" 37 | config.dotfiles.attic.watch-daemon.cache 38 | ]; 39 | config.RunAtLoad = true; 40 | config.KeepAlive = true; 41 | config.HardResourceLimits.NumberOfFiles = 6000; 42 | config.LowPriorityIO = true; 43 | config.ProcessType = "Background"; 44 | config.StandardErrorPath = "${homeDirectory}/Library/Logs/attic-watch-daemon.log"; 45 | config.StandardOutPath = "${homeDirectory}/Library/Logs/attic-watch-daemon.log"; 46 | config.EnvironmentVariables = { 47 | HOME = homeDirectory; 48 | XDG_CONFIG_HOME = "${homeDirectory}/.config"; 49 | }; 50 | }; 51 | }; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /config/atuin/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | # https://docs.atuin.sh/configuration/config/ 3 | programs.atuin = { 4 | enable = true; 5 | settings = { 6 | auto_sync = true; 7 | sync_address = "https://atuin.svc.channings.me"; 8 | workspaces = true; 9 | ctrl_n_shortcuts = true; 10 | dialect = "uk"; 11 | filter_mode = "host"; 12 | filter_mode_shell_up_key_binding = "session"; 13 | style = "compact"; 14 | inline_height = 5; 15 | show_help = false; 16 | enter_accept = true; 17 | 18 | sync.records = true; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /config/bat/home.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | programs.bat = { 4 | enable = true; 5 | 6 | config = { 7 | theme = "OneHalfDark"; 8 | style = "plain"; 9 | }; 10 | 11 | extraPackages = builtins.attrValues { inherit (pkgs.bat-extras) batman batgrep batwatch; }; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /config/brew/darwin.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.brew-nix.darwinModules.default 5 | ]; 6 | 7 | brew-nix.enable = true; 8 | 9 | nixpkgs.overlays = [ (import ./overlay.nix) ]; 10 | } 11 | -------------------------------------------------------------------------------- /config/brew/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | osConfig, 4 | lib, 5 | ... 6 | }: 7 | let 8 | useGlobalPkgs = if osConfig == null then false else osConfig.home-manager.useGlobalPkgs; 9 | in 10 | { 11 | config = lib.mkIf (!useGlobalPkgs) { 12 | nixpkgs = { 13 | overlays = [ 14 | inputs.brew-nix.overlays.default 15 | (import ./overlay.nix) 16 | ]; 17 | }; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /config/brew/overlay.nix: -------------------------------------------------------------------------------- 1 | (_self: super: { 2 | brewCasks = 3 | let 4 | overrideHash = ( 5 | name: hash: 6 | super.brewCasks.${name}.overrideAttrs (oldAttrs: { 7 | src = super.fetchurl { 8 | url = builtins.head oldAttrs.src.urls; 9 | inherit hash; 10 | }; 11 | }) 12 | ); 13 | in 14 | super.brewCasks 15 | // (builtins.mapAttrs overrideHash { 16 | apparency = "sha256-nktNbyJOXDydQPwb43Uq3nQv65XcwrqZTKu5OCcLyfU="; 17 | suspicious-package = "sha256-//iL7BRdox+KA1CJnGttUQiUfskuBeMGrf1YUNt/m90="; 18 | bonjour-browser = "sha256-+crlyoU0zPu+oilrTyLIOO61H7U9bkyDWe8EpWJfnOQ="; 19 | audio-hijack = "sha256-hzZbGfM0h7nrEqatRFMtTh3NQ0yFgGEyUVawvk3LpaQ="; 20 | logitech-options = "sha256-mqrGGSphCylYzkFl5iV/LTxofhy+4KoCxqG/WhkG0wM="; 21 | }); 22 | }) 23 | -------------------------------------------------------------------------------- /config/certificate-authority/nixos+darwin.nix: -------------------------------------------------------------------------------- 1 | { 2 | security.pki.certificates = [ 3 | # Channings Principal Certificate Authority Root 4 | '' 5 | -----BEGIN CERTIFICATE----- 6 | MIIByjCCAXGgAwIBAgIQQofn+rGxJXU/EI5Z1irlHzAKBggqhkjOPQQDAjBEMRww 7 | GgYDVQQKExNDaGFubmluZ3MgUHJpbmNpcGFsMSQwIgYDVQQDExtDaGFubmluZ3Mg 8 | UHJpbmNpcGFsIFJvb3QgQ0EwHhcNMjUwMTMxMTgyNjUwWhcNMzUwMTI5MTgyNjUw 9 | WjBEMRwwGgYDVQQKExNDaGFubmluZ3MgUHJpbmNpcGFsMSQwIgYDVQQDExtDaGFu 10 | bmluZ3MgUHJpbmNpcGFsIFJvb3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC 11 | AARji9/y0detw3pZlmoythdnAUgikjJrU3u1Ty/dXPtyfnfgd9RpRhtdIC5P34JF 12 | 5BXtXhO1ZRK6QcYO8epKkUWco0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/ 13 | BAgwBgEB/wIBATAdBgNVHQ4EFgQULNjZRx+vQr7P0uHOLnPBzQ+HmGwwCgYIKoZI 14 | zj0EAwIDRwAwRAIgSCosJwohwbcJkU5t7nQtg/Svrd6gM5Te7kZQaVsOGPkCIHEx 15 | 7v+ZhKQj+ApmSIxkASPYIkonlG4XlZwrfKCCZE1I 16 | -----END CERTIFICATE----- 17 | '' 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /config/chromium/chromium-macos.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | fetchurl, 4 | darwin, 5 | stdenv, 6 | undmg, 7 | unzip, 8 | gzip, 9 | _7zz, 10 | makeWrapper, 11 | xar, 12 | cpio, 13 | }: 14 | let 15 | version = "135.0.7049.52-1.1"; 16 | in 17 | assert lib.asserts.assertMsg ( 18 | stdenv.isAarch64 != "arm64" 19 | ) "ungoogled-chromium only supports aarch64"; 20 | stdenv.mkDerivation rec { 21 | name = "chromium"; 22 | pname = name; 23 | inherit version; 24 | 25 | src = fetchurl { 26 | url = "https://github.com/ungoogled-software/ungoogled-chromium-macos/releases/download/${version}/ungoogled-chromium_${version}_arm64-macos.dmg"; 27 | hash = "sha256-ePEeKAD2yNkY37ns4vdKJM78qsI6ik4kyL/4LL5WUpY="; 28 | }; 29 | 30 | nativeBuildInputs = [ 31 | undmg 32 | unzip 33 | gzip 34 | _7zz 35 | makeWrapper 36 | xar 37 | cpio 38 | darwin.xattr 39 | ]; 40 | 41 | unpackPhase = '' 42 | undmg $src || 7zz x -snld $src 43 | ''; 44 | 45 | sourceRoot = "Chromium.app"; 46 | 47 | dontPatchShebangs = true; 48 | 49 | installPhase = '' 50 | mkdir -p "$out/Applications/${sourceRoot}" 51 | cp -R . "$out/Applications/${sourceRoot}" 52 | 53 | makeWrapper "$out/Applications/${sourceRoot}/Contents/MacOS/${lib.removeSuffix ".app" sourceRoot}" $out/bin/chromium 54 | ''; 55 | 56 | meta = { 57 | homepage = "https://github.com/claudiodekker/ungoogled-chromium-macos"; 58 | description = "Codesigned builds of Chromium"; 59 | platforms = lib.platforms.darwin; 60 | mainProgram = "Chromium"; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /config/chromium/home.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | let 3 | inherit (pkgs._2lbx.lib) withInstallationMethod; 4 | in 5 | { 6 | config = { 7 | programs.chromium = { 8 | package = 9 | if pkgs.stdenv.isDarwin then 10 | (withInstallationMethod "copy" (pkgs.callPackage ./chromium-macos.nix { })) 11 | else 12 | pkgs.chromium; 13 | enable = true; 14 | extensions = [ 15 | { "id" = "fmkadmapgofadopljbjfkapdkoienihi"; } # React Developer Tools 16 | { "id" = "aeblfdkhhhdcdjpifhhbdiojplfjncoa"; } # 1Password 17 | ]; 18 | }; 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /config/chromium/update.js: -------------------------------------------------------------------------------- 1 | const repo = "ungoogled-software/ungoogled-chromium-macos"; 2 | 3 | const request = await fetch( 4 | `https://api.github.com/repos/${repo}/releases/latest`, 5 | { 6 | headers: { 7 | accept: " application/vnd.github+json", 8 | "X-GitHub-Api-Version": "2022-11-28", 9 | }, 10 | }, 11 | ); 12 | 13 | if (!request.ok) { 14 | console.error( 15 | `Failed to fetch the latest release metadata for github:${repo}`, 16 | ); 17 | Deno.exit(1); 18 | } 19 | 20 | const releaseMetadata = await request.json(); 21 | 22 | const version = releaseMetadata.name; 23 | 24 | console.log(`Latest release: ${version}`); 25 | 26 | for (const asset of releaseMetadata.assets) { 27 | console.log(`Asset: ${asset.name}`); 28 | 29 | const sha256Hash = await $("nix-prefetch-url", asset.browser_download_url); 30 | const sriHash = await $( 31 | "nix-hash", 32 | "--type", 33 | "sha256", 34 | "--to-sri", 35 | sha256Hash.trim(), 36 | ); 37 | 38 | console.log(` SRI: ${sriHash}`); 39 | console.log(` SHA256: ${sha256Hash}`); 40 | } 41 | 42 | async function $(name, ...args) { 43 | const command = new Deno.Command(name, { args }); 44 | 45 | const { code, stdout, stderr } = await command.output(); 46 | 47 | if (code !== 0) { 48 | console.log( 49 | `${name}: exited ${code} with ${new TextDecoder().decode(stderr)}`, 50 | ); 51 | } 52 | 53 | return new TextDecoder().decode(stdout); 54 | } 55 | -------------------------------------------------------------------------------- /config/cloudflared/home.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | home.packages = [ pkgs.cloudflared ]; 4 | } 5 | -------------------------------------------------------------------------------- /config/darwin-defaults/darwin.nix: -------------------------------------------------------------------------------- 1 | { 2 | security.pam.services.sudo_local.touchIdAuth = true; 3 | 4 | system.defaults = { 5 | ActivityMonitor = { 6 | ShowCategory = 101; 7 | }; 8 | menuExtraClock = { 9 | ShowDayOfMonth = true; 10 | ShowDayOfWeek = true; 11 | ShowDate = 0; 12 | }; 13 | dock = { 14 | autohide = false; 15 | show-process-indicators = false; 16 | static-only = true; 17 | tilesize = 32; 18 | }; 19 | finder = { 20 | AppleShowAllFiles = false; 21 | ShowStatusBar = false; 22 | ShowPathbar = true; 23 | FXDefaultSearchScope = "SCcf"; 24 | FXPreferredViewStyle = "clmv"; 25 | AppleShowAllExtensions = true; 26 | CreateDesktop = false; 27 | QuitMenuItem = false; 28 | _FXShowPosixPathInTitle = false; 29 | FXEnableExtensionChangeWarning = false; 30 | }; 31 | loginwindow = { 32 | SHOWFULLNAME = false; 33 | GuestEnabled = false; 34 | DisableConsoleAccess = true; 35 | }; 36 | spaces = { 37 | spans-displays = false; 38 | }; 39 | trackpad = { 40 | Clicking = true; 41 | Dragging = false; 42 | TrackpadRightClick = true; 43 | TrackpadThreeFingerDrag = true; 44 | ActuationStrength = 1; 45 | }; 46 | 47 | LaunchServices.LSQuarantine = false; 48 | 49 | CustomUserPreferences = { 50 | "com.apple.dock" = { 51 | "mru-spaces" = false; 52 | "show-recents" = false; 53 | }; 54 | "com.apple.WindowManager" = { 55 | GloballyEnabled = false; 56 | GloballyEnabledEver = true; 57 | }; 58 | }; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /config/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | self, 3 | inputs, 4 | lib, 5 | ... 6 | }: 7 | let 8 | inherit (lib) optional; 9 | inherit (lib.strings) toLower; 10 | inherit (lib.attrsets) genAttrs; 11 | 12 | filesCalled = 13 | with inputs.nixpkgs.lib.fileset; 14 | nameFilter: 15 | toList (fileFilter (file: (nameFilter file.name) || file.name == "home+nixos+darwin.nix") ./.); 16 | 17 | importAsAttrset = 18 | with builtins; 19 | pathList: 20 | listToAttrs ( 21 | map ( 22 | path: 23 | let 24 | type = (baseNameOf path); 25 | in 26 | { 27 | name = "${baseNameOf (dirOf path)}${ 28 | if type == "nixos+darwin.nix" then 29 | "-os-shared" 30 | else if type == "home+nixos+darwin.nix" then 31 | "-shared" 32 | else 33 | "" 34 | }"; 35 | value = import path; 36 | } 37 | ) pathList 38 | ); 39 | 40 | stateVersion = "25.05"; 41 | nixDarwinStateVersion = 5; 42 | 43 | # 44 | # To organise configurations I separate configurations into modules: 45 | # 46 | # - home.nix - home-manager modules 47 | # - darwin.nix - nix-darwin modules 48 | # - nixos.nix - nixos modules 49 | # 50 | # Available combinations: 51 | # 52 | # - home+nixos+darwin.nix 53 | # - nixos+darwin.nix 54 | # 55 | homeManagerModules = (importAsAttrset (filesCalled (_: _ == "home.nix"))) // { 56 | _setup.home.stateVersion = stateVersion; 57 | }; 58 | 59 | darwinModules = 60 | (importAsAttrset (filesCalled (_: _ == "darwin.nix" || _ == "nixos+darwin.nix"))) 61 | // { 62 | _setup.system.stateVersion = nixDarwinStateVersion; 63 | }; 64 | 65 | nixosModules = (importAsAttrset (filesCalled (_: _ == "nixos.nix" || _ == "nixos+darwin.nix"))) // { 66 | _setup.system.stateVersion = stateVersion; 67 | }; 68 | 69 | disableModules = 70 | allModules: disabledModules: (with builtins; attrValues (removeAttrs allModules disabledModules)); 71 | 72 | homeManagerModulesWithDisabled = disableModules self.modules.homeManager; 73 | darwinModulesWithDisabled = disableModules self.modules.darwin; 74 | nixosModulesWithDisabled = disableModules self.modules.nixos; 75 | 76 | configureOsModules = 77 | { osModules, homeManagerModules }: 78 | ( 79 | { 80 | config, 81 | inputs, 82 | ... 83 | }: 84 | { 85 | imports = osModules; 86 | 87 | config.home-manager.sharedModules = homeManagerModules; 88 | config.home-manager.extraSpecialArgs = { 89 | inherit inputs; 90 | } // inputs; 91 | } 92 | ); 93 | mkHomeManagerConfiguration = 94 | { 95 | pkgs, 96 | config ? {}, 97 | disabledModules ? [ ], 98 | user ? { }, 99 | }: 100 | ( 101 | assert user.name != null; 102 | 103 | inputs.home-manager.lib.homeManagerConfiguration { 104 | inherit pkgs; 105 | 106 | modules = [ 107 | { 108 | home.username = user.name; 109 | home.homeDirectory = "/home/${user.name}"; 110 | } 111 | config 112 | ] ++ (homeManagerModulesWithDisabled disabledModules); 113 | 114 | extraSpecialArgs = { 115 | inherit inputs user; 116 | } // inputs; 117 | } 118 | ); 119 | mkDarwinSystem = 120 | { 121 | hostName, 122 | user ? { }, 123 | system ? "aarch64-darwin", 124 | inputs ? inputs, 125 | osModules ? builtins.attrValues self.modules.darwin, 126 | sharedHomeManagerModules ? builtins.attrValues self.modules.homeManager, 127 | userHomeModule ? null, 128 | }: 129 | ( 130 | assert user.name != null; 131 | assert user.fullName != null; 132 | assert user.id != null; 133 | 134 | let 135 | inherit (inputs.darwin.lib) darwinSystem; 136 | systemCfg = darwinSystem { 137 | inherit system; 138 | 139 | modules = 140 | [ 141 | ( 142 | { lib, ... }: 143 | { 144 | networking.hostName = hostName; 145 | users.knownUsers = [ user.name ]; 146 | users.users.${user.name} = { 147 | description = user.fullName; 148 | home = "/Users/${user.name}"; 149 | uid = user.id; 150 | gid = user.id; 151 | }; 152 | 153 | home-manager.users.${user.name} = lib.mkIf (user ? gitEmail) { 154 | programs.git.userName = user.fullName; 155 | programs.git.userEmail = user.gitEmail; 156 | }; 157 | } 158 | ) 159 | (configureOsModules { 160 | inherit osModules; 161 | homeManagerModules = sharedHomeManagerModules; 162 | }) 163 | ] 164 | ++ (optional (userHomeModule != null) { 165 | home-manager.users.${user.name} = userHomeModule; 166 | }); 167 | 168 | specialArgs = { 169 | inherit inputs user; 170 | } // inputs; 171 | }; 172 | in 173 | genAttrs ([ hostName ] ++ (optional (hostName != (toLower hostName)) (toLower hostName))) ( 174 | _: systemCfg 175 | ) 176 | ); 177 | mkNixOsSystem = 178 | { 179 | hostName, 180 | deployment, 181 | user ? null, 182 | system ? "x86_64-linux", 183 | inputs ? inputs, 184 | osModules ? builtins.attrValues self.modules.nixos, 185 | sharedHomeManagerModules ? builtins.attrValues self.modules.homeManager, 186 | userHomeModule ? { }, 187 | }: 188 | ( 189 | let 190 | systemModules = [ 191 | (configureOsModules { 192 | inherit osModules; 193 | homeManagerModules = sharedHomeManagerModules; 194 | }) 195 | 196 | { 197 | networking.hostName = hostName; 198 | 199 | users.mutableUsers = false; 200 | } 201 | { 202 | config = 203 | if (user != null) then 204 | ( 205 | assert user ? name; 206 | { 207 | users.users.${user.name} = { }; 208 | home-manager.users.${user.name} = userHomeModule; 209 | } 210 | ) 211 | else 212 | { }; 213 | } 214 | ]; 215 | systemCfg = inputs.nixpkgs.lib.nixosSystem { 216 | inherit system; 217 | 218 | modules = systemModules; 219 | 220 | specialArgs = { 221 | inherit inputs user; 222 | } // inputs; 223 | }; 224 | normalizedHostName = (toLower hostName); 225 | hostNames = [ hostName ] ++ (optional (hostName != normalizedHostName) normalizedHostName); 226 | in 227 | { 228 | nixosConfigurations = genAttrs hostNames (_: systemCfg); 229 | colmena = { 230 | ${normalizedHostName} = { 231 | imports = systemModules; 232 | 233 | inherit deployment; 234 | }; 235 | meta.nodeSpecialArgs.${normalizedHostName} = { 236 | inherit inputs; 237 | } // inputs; 238 | }; 239 | } 240 | ); 241 | in 242 | { 243 | flake = { 244 | lib = { 245 | inherit 246 | configureOsModules 247 | homeManagerModulesWithDisabled 248 | darwinModulesWithDisabled 249 | nixosModulesWithDisabled 250 | mkHomeManagerConfiguration 251 | mkDarwinSystem 252 | mkNixOsSystem 253 | ; 254 | }; 255 | 256 | modules = { 257 | homeManager = homeManagerModules; 258 | nixos = nixosModules; 259 | darwin = darwinModules; 260 | }; 261 | }; 262 | } 263 | -------------------------------------------------------------------------------- /config/direnv/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | programs.direnv = { 3 | enable = true; 4 | nix-direnv.enable = true; 5 | 6 | config = { 7 | hide_env_diff = true; 8 | }; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /config/editorconfig/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | editorconfig = { 3 | enable = true; 4 | 5 | settings = { 6 | "*" = { 7 | end_of_line = "lf"; 8 | insert_final_newline = true; 9 | charset = "utf-8"; 10 | indent_style = "space"; 11 | indent_size = 2; 12 | }; 13 | }; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /config/eza/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | programs.eza = { 3 | enable = true; 4 | icons = "auto"; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /config/fish/darwin.nix: -------------------------------------------------------------------------------- 1 | { user, config, lib, ... }: 2 | let 3 | hmConfig = config.home-manager.users.${user.name}; 4 | in 5 | { 6 | config.programs.fish.enable = hmConfig.programs.fish.enable; 7 | config.home-manager.users.${user.name}.programs.fish = { 8 | loginShellInit = 9 | let 10 | # This naive quoting is good enough in this case. There shouldn't be any 11 | # double quotes in the input string, and it needs to be double quoted in case 12 | # it contains a space (which is unlikely!) 13 | dquote = str: "\"" + str + "\""; 14 | 15 | makeBinPathList = map (path: path + "/bin"); 16 | in 17 | '' 18 | fish_add_path --move --prepend --path ${ 19 | lib.concatMapStringsSep " " dquote (makeBinPathList config.environment.profiles) 20 | } 21 | set fish_user_paths $fish_user_paths 22 | ''; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /config/fish/functions/gitco.fish: -------------------------------------------------------------------------------- 1 | function gitco -d "Fuzzy-find and checkout a branch" 2 | if test $argv[1] = -- 3 | git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print $3 }' | awk ' !x[$0]++' | egrep -v '^[a-f0-9]{40}$' | fzf | xargs git checkout 4 | else if test $argv[1] 5 | git checkout $argv 6 | else 7 | git branch --all | grep -v '*' | string replace -r 'remotes/.*?/' '' | sort -u | fzf | xargs git checkout 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /config/fish/functions/gzipsize.fish: -------------------------------------------------------------------------------- 1 | function gzipsize 2 | gzip $argv[1] 3 | du -h $argv[1].gz 4 | rm $argv[1].gz 5 | end 6 | -------------------------------------------------------------------------------- /config/fish/functions/krun.fish: -------------------------------------------------------------------------------- 1 | function krun --description "Run an ephemeral container in a kubernetes cluster" 2 | argparse --name=krun 'H/hostname=' 'a/arch=' d/debug -- $argv 3 | or return 4 | 5 | set -x LC_ALL C 6 | set -l USAGE "krun [-H|--hostname=node-hostname] [-a|--arch=architecture]" 7 | 8 | set -l image $argv[1] 9 | set -l randomAffix (cat /dev/random | tr -dc '[:lower:]' | head -c 8) 10 | 11 | if ! test -n "$image" 12 | echo $USAGE 13 | return 14 | end 15 | 16 | set -l spec ' 17 | --- 18 | apiVersion: v1 19 | kind: Namespace 20 | metadata: 21 | name: krun 22 | --- 23 | kind: Pod 24 | apiVersion: v1 25 | metadata: 26 | name: krun-'$randomAffix' 27 | namespace: krun 28 | spec: 29 | containers: 30 | - name: shell 31 | image: '$image' 32 | tty: true 33 | stdin: true 34 | command: ["/bin/sh"] 35 | restartPolicy: Never' 36 | 37 | if test -n "$_flag_hostname" -o -n "$_flag_arch" 38 | set spec $spec(echo -e '\n nodeSelector:' | string collect) 39 | if test -n "$_flag_hostname" 40 | set spec $spec(echo -e '\n kubernetes.io/hostname: '$_flag_hostname | string collect) 41 | end 42 | if test -n "$_flag_arch" 43 | set spec $spec(echo -e '\n kubernetes.io/arch: '$_flag_arch | string collect) 44 | end 45 | end 46 | 47 | if test -n "$_flag_debug" 48 | echo $spec 49 | end 50 | 51 | echo $spec | kubectl apply -f - 52 | 53 | kubectl wait --for=condition=Ready -n krun pod krun-$randomAffix 54 | 55 | kubectl attach -n krun krun-$randomAffix -it --pod-running-timeout=2m0s 56 | 57 | kubectl delete -n krun pod krun-$randomAffix & 58 | end 59 | -------------------------------------------------------------------------------- /config/fish/functions/mcat.fish: -------------------------------------------------------------------------------- 1 | function mcat --description "display anything" 2 | if file --mime-type $argv | grep -qF image/ 3 | chafa -f iterm -s $FZF_PREVIEW_COLUMNS"x"$FZF_PREVIEW_LINES $argv 4 | else 5 | bat --color always --style numbers --theme TwoDark --line-range :200 $argv 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /config/fish/functions/mkcd.fish: -------------------------------------------------------------------------------- 1 | function mkcd 2 | mkdir -p $argv[1] 3 | cd $argv[1] 4 | end 5 | -------------------------------------------------------------------------------- /config/fish/functions/mkpass.fish: -------------------------------------------------------------------------------- 1 | function mkpass 2 | set -x LC_ALL C 3 | cat /dev/random | tr -dc '[:alnum:]' | head -c 40 4 | end 5 | -------------------------------------------------------------------------------- /config/fish/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | config, 5 | ... 6 | }: 7 | { 8 | programs.fish = { 9 | enable = true; 10 | 11 | shellInitLast = lib.mkIf config.programs.starship.enable '' 12 | status is-interactive; and begin 13 | enable_transience 14 | 15 | # Set QEMU=1 if we're in QEMU 16 | if command -q systemd-detect-virt; and [ $(systemd-detect-virt) = "qemu" ] 17 | set -x QEMU 1 18 | end 19 | end 20 | ''; 21 | 22 | functions = { 23 | fish_greeting = ""; 24 | 25 | fish_user_key_bindings = '' 26 | set -g fish_key_bindings fish_vi_key_bindings 27 | 28 | # Bind Ctrl+z to fg 29 | bind \cz -M insert 'fg 2>/dev/null; commandline -f repaint' 30 | bind \cz -M default 'fg 2>/dev/null; commandline -f repaint' 31 | ''; 32 | 33 | mcat = '' 34 | if file --mime-type $argv | grep -qF image/ 35 | ${lib.getExe pkgs.chafa} -f iterm -s $FZF_PREVIEW_COLUMNS"x"$FZF_PREVIEW_LINES $argv 36 | else 37 | ${lib.getExe pkgs.bat} --color always --style numbers --theme TwoDark --line-range :200 $argv 38 | end''; 39 | 40 | fdz = "${lib.getExe pkgs.fd} --type f --hidden --follow --exclude .git --color=always | ${lib.getExe pkgs.fzf} --ansi --multi --preview='mcat {}'"; 41 | }; 42 | }; 43 | 44 | # Copy over my fish functions that aren't managed by Nix 45 | xdg.configFile = 46 | with builtins; 47 | foldl' (acc: path: acc // { "fish/functions/${baseNameOf path}".text = (readFile path); }) { } ( 48 | with lib.fileset; toList (fileFilter (file: file.hasExt "fish") ./functions) 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /config/fish/nixos.nix: -------------------------------------------------------------------------------- 1 | { config.programs.fish.enable = true; } 2 | -------------------------------------------------------------------------------- /config/fonts/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | ... 4 | }: 5 | { 6 | config = { 7 | fonts.fontconfig = { 8 | enable = true; 9 | 10 | defaultFonts.monospace = [ 11 | "RecMonoLinear Nerd Font Mono" 12 | "Menlo" 13 | ]; 14 | }; 15 | 16 | home.packages = with pkgs.nerd-fonts; [ 17 | recursive-mono 18 | hasklug 19 | victor-mono 20 | fira-code 21 | iosevka-term 22 | ]; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /config/ghostty/home.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | programs.ghostty = { 4 | enable = true; 5 | package = if pkgs.stdenv.hostPlatform.isDarwin then pkgs.brewCasks.ghostty else pkgs.ghostty; 6 | enableFishIntegration = true; 7 | installBatSyntax = false; # The brew package doesn't have share/bat/syntaxes/ghostty.sublime-syntax. 8 | settings = { 9 | macos-option-as-alt = "right"; 10 | font-feature = "+calt, +liga, +dlig"; 11 | font-size = 14; 12 | font-family = "RecMonoLinear Nerd Font Mono"; 13 | macos-titlebar-proxy-icon = "hidden"; 14 | window-padding-x = 6; 15 | }; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /config/git/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | config, 4 | pkgs, 5 | ... 6 | }: 7 | with lib; 8 | { 9 | options.programs.git = with types; { 10 | signingInclude = mkOption { 11 | type = nullOr ( 12 | attrsOf (submodule { 13 | options = { 14 | enable = lib.mkEnableOption "Enable code signing for GitHub repos"; 15 | 16 | conditions = mkOption { 17 | type = nullOr (listOf str); 18 | default = null; 19 | }; 20 | 21 | signingKey = mkOption { 22 | type = str; 23 | description = "The key to use for signing commits"; 24 | }; 25 | 26 | signByDefault = mkOption { 27 | type = bool; 28 | default = true; 29 | description = "Whether commits and tags should be signed by default."; 30 | }; 31 | 32 | gpgPath = mkOption { 33 | type = str; 34 | default = "/Applications/1Password.app/Contents/MacOS/op-ssh-sign"; 35 | description = "Path to the commit signing binary"; 36 | }; 37 | 38 | allowedSigners = mkOption { 39 | type = listOf str; 40 | default = [ ]; 41 | }; 42 | }; 43 | }) 44 | ); 45 | default = null; 46 | }; 47 | }; 48 | 49 | # Check per-repo config with `git config -l` 50 | config = lib.mkMerge [ 51 | { 52 | programs.git = { 53 | enable = true; 54 | 55 | extraConfig = { 56 | pull.rebase = true; 57 | rebase.autostash = true; 58 | push.autosetupremote = true; 59 | init.defaultBranch = "main"; 60 | }; 61 | 62 | signing.format = "ssh"; 63 | 64 | lfs.enable = true; 65 | difftastic.enable = true; 66 | }; 67 | } 68 | { 69 | home.packages = [ pkgs.git-filter-repo ]; 70 | } 71 | (lib.mkIf (config.programs.git.signingInclude != null) { 72 | 73 | # Each signing configuration gets its own file in ~/.config/git. 74 | xdg.configFile = concatMapAttrs (name: cfg: { 75 | "git/${name}_signing.inc".text = generators.toGitINI { 76 | user.signingkey = cfg.signingKey; 77 | gpg.format = "ssh"; 78 | gpg.ssh.allowedSignersFile = pkgs.writeText "${name}_allowed_signers" ( 79 | concatLines ( 80 | [ "${config.programs.git.userEmail} namespaces=\"git\" ${cfg.signingKey}" ] ++ cfg.allowedSigners 81 | ) 82 | ); 83 | "gpg \"ssh\"".program = cfg.gpgPath; 84 | commit.gpgsign = cfg.signByDefault; 85 | }; 86 | }) config.programs.git.signingInclude; 87 | 88 | programs.git.includes = flatten ( 89 | mapAttrsToList ( 90 | name: cfg: 91 | let 92 | path = "${name}_signing.inc"; 93 | in 94 | ( 95 | if cfg.conditions == null then 96 | { inherit path; } 97 | else 98 | builtins.map (condition: { 99 | inherit condition; 100 | inherit path; 101 | }) cfg.conditions 102 | ) 103 | ) config.programs.git.signingInclude 104 | ); 105 | }) 106 | ]; 107 | } 108 | -------------------------------------------------------------------------------- /config/helix/config.toml: -------------------------------------------------------------------------------- 1 | theme = "onedark" 2 | 3 | [editor] 4 | line-number = "relative" 5 | 6 | [editor.cursor-shape] 7 | insert = "bar" 8 | normal = "block" 9 | select = "underline" 10 | 11 | [editor.file-picker] 12 | hidden = false 13 | 14 | [editor.whitespace.render] 15 | space = "all" 16 | tab = "all" 17 | nbsp = "all" 18 | nnbsp = "all" 19 | newline = "none" 20 | 21 | [keys.normal] 22 | A-down = ["extend_to_line_bounds", "delete_selection", "paste_after"] 23 | A-up = [ 24 | "extend_to_line_bounds", 25 | "delete_selection", 26 | "move_line_up", 27 | "paste_before", 28 | ] 29 | -------------------------------------------------------------------------------- /config/helix/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | pkgs, 4 | ... 5 | }: 6 | { 7 | programs.helix = { 8 | enable = true; 9 | defaultEditor = true; 10 | 11 | settings = (lib.importTOML ./config.toml); 12 | 13 | themes = { 14 | onedark = { 15 | inherits = "onedark"; 16 | 17 | "ui.background" = "#ff0000"; 18 | }; 19 | }; 20 | 21 | languages = { 22 | language-server = { 23 | nil = { 24 | command = lib.getExe pkgs.nil; 25 | config = { 26 | nix = { 27 | maxMemoryMB = 2560; 28 | flake = { 29 | autoArchive = false; 30 | autoEvalInputs = true; 31 | }; 32 | }; 33 | }; 34 | }; 35 | lua-language-server = { 36 | command = lib.getExe pkgs.lua-language-server; 37 | }; 38 | }; 39 | language = [ 40 | { 41 | name = "nix"; 42 | auto-format = true; 43 | formatter.command = lib.getExe pkgs.nixfmt-rfc-style; 44 | } 45 | { 46 | name = "lua"; 47 | auto-format = true; 48 | formatter.command = lib.getExe pkgs.stylua; 49 | } 50 | ]; 51 | }; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /config/helix/nixos+darwin.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | nixpkgs.overlays = [ 4 | inputs.helix.overlays.default 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /config/home-manager/darwin.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.home-manager.darwinModules.home-manager 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /config/home-manager/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | xdg.enable = true; 3 | } 4 | -------------------------------------------------------------------------------- /config/home-manager/nixos+darwin.nix: -------------------------------------------------------------------------------- 1 | { 2 | home-manager = { 3 | backupFileExtension = "backup"; 4 | 5 | # Use the system-level nixpkgs instead of Home Manager's 6 | useGlobalPkgs = true; 7 | 8 | # Install packages to /etc/profiles instead of ~/.nix-profile, useful when 9 | # using multiple profiles for one user 10 | useUserPackages = true; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /config/home-manager/nixos.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.home-manager.nixosModules.home-manager 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /config/htop/home.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | config.programs.htop = { 4 | enable = true; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /config/nix/darwin.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.nix-index-database.darwinModules.nix-index 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /config/nix/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | pkgs, 4 | lib, 5 | ... 6 | }: 7 | { 8 | 9 | imports = [ 10 | inputs.nix-index-database.hmModules.nix-index 11 | ]; 12 | 13 | nix.package = lib.mkDefault pkgs.lix; 14 | programs.nix-index-database.comma.enable = true; 15 | } 16 | -------------------------------------------------------------------------------- /config/nix/nixos+darwin.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | inputs, 4 | lib, 5 | ... 6 | }: 7 | with builtins; 8 | let 9 | substituters = import ./substituters.nix; 10 | in 11 | { 12 | imports = [ 13 | inputs.lix-module.nixosModules.default 14 | ]; 15 | 16 | nix.package = lib.mkDefault pkgs.lix; 17 | nix.channel.enable = false; 18 | nix.settings = { 19 | experimental-features = [ 20 | "nix-command" 21 | "flakes" 22 | ]; 23 | 24 | # It's tempting to enable this, but it's a massive security hole 25 | accept-flake-config = false; 26 | 27 | warn-dirty = false; 28 | trusted-users = [ 29 | "luke@idm.svc.channings.me" 30 | "luke" 31 | ]; 32 | 33 | substituters = [ 34 | "https://attic.svc.channings.me/nix" 35 | ] ++ (map (k: "https://${head (split "-1:" k)}") substituters); 36 | trusted-public-keys = [ "nix:CLpxkxK7MCT/RRXSU2EpfiQVoCLreSR6QiJGzHtcyYQ=" ] ++ substituters; 37 | 38 | max-substitution-jobs = 128; 39 | http-connections = 0; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /config/nix/nixos.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.nix-index-database.nixosModules.nix-index 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /config/nix/substituters.nix: -------------------------------------------------------------------------------- 1 | # I just put the public key in the list and derive the cache URL in the config. 2 | [ 3 | "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" 4 | "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" 5 | "luke-channings.cachix.org-1:ETsZ3R5ue9QOwO4spg8aGJMwMU6k5tQIaHWnTakGHjo=" 6 | "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" 7 | ] 8 | -------------------------------------------------------------------------------- /config/nixpkgs/config.nix: -------------------------------------------------------------------------------- 1 | { 2 | allowUnfree = true; 3 | allowUnfreePredicate = _pkg: true; 4 | } 5 | -------------------------------------------------------------------------------- /config/nixpkgs/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | osConfig, 3 | lib, 4 | ... 5 | }: 6 | let 7 | useGlobalPkgs = if osConfig == null then false else osConfig.home-manager.useGlobalPkgs; 8 | in 9 | { 10 | config = lib.mkIf (!useGlobalPkgs) { 11 | nixpkgs.config = import ./config.nix; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /config/nixpkgs/nixos+darwin.nix: -------------------------------------------------------------------------------- 1 | # These settings are inherited by home-manager when `useGlobalPkgs` is enabled. 2 | { 3 | nixpkgs.config = import ./config.nix; 4 | } 5 | -------------------------------------------------------------------------------- /config/nushell/config.nu: -------------------------------------------------------------------------------- 1 | # Nushell Config File 2 | # 3 | # version = "0.103.1" 4 | $env.config.color_config = { 5 | separator: white 6 | leading_trailing_space_bg: { attr: n } 7 | header: green_bold 8 | empty: blue 9 | bool: light_cyan 10 | int: white 11 | filesize: cyan 12 | duration: white 13 | datetime: purple 14 | range: white 15 | float: white 16 | string: white 17 | nothing: white 18 | binary: white 19 | cell-path: white 20 | row_index: green_bold 21 | record: white 22 | list: white 23 | closure: green_bold 24 | glob:cyan_bold 25 | block: white 26 | hints: dark_gray 27 | search_result: { bg: red fg: white } 28 | shape_binary: purple_bold 29 | shape_block: blue_bold 30 | shape_bool: light_cyan 31 | shape_closure: green_bold 32 | shape_custom: green 33 | shape_datetime: cyan_bold 34 | shape_directory: cyan 35 | shape_external: cyan 36 | shape_externalarg: green_bold 37 | shape_external_resolved: light_yellow_bold 38 | shape_filepath: cyan 39 | shape_flag: blue_bold 40 | shape_float: purple_bold 41 | shape_glob_interpolation: cyan_bold 42 | shape_globpattern: cyan_bold 43 | shape_int: purple_bold 44 | shape_internalcall: cyan_bold 45 | shape_keyword: cyan_bold 46 | shape_list: cyan_bold 47 | shape_literal: blue 48 | shape_match_pattern: green 49 | shape_matching_brackets: { attr: u } 50 | shape_nothing: light_cyan 51 | shape_operator: yellow 52 | shape_pipe: purple_bold 53 | shape_range: yellow_bold 54 | shape_record: cyan_bold 55 | shape_redirection: purple_bold 56 | shape_signature: green_bold 57 | shape_string: green 58 | shape_string_interpolation: cyan_bold 59 | shape_table: blue_bold 60 | shape_variable: purple 61 | shape_vardecl: purple 62 | shape_raw_string: light_purple 63 | shape_garbage: { 64 | fg: white 65 | bg: red 66 | attr: b 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /config/nushell/env.nu: -------------------------------------------------------------------------------- 1 | # Nushell Environment Config File 2 | # 3 | # version = "0.92.1" 4 | 5 | def create_left_prompt [] { 6 | starship prompt --cmd-duration $env.CMD_DURATION_MS $'--status=($env.LAST_EXIT_CODE)' 7 | } 8 | 9 | $env.STARSHIP_SHELL = "nu" 10 | 11 | # Use nushell functions to define your right and left prompt 12 | $env.PROMPT_COMMAND = { || create_left_prompt } 13 | $env.PROMPT_COMMAND_RIGHT = "" 14 | 15 | # The prompt indicators are environmental variables that represent 16 | # the state of the prompt 17 | $env.PROMPT_INDICATOR = "" 18 | $env.PROMPT_INDICATOR_VI_INSERT = ": " 19 | $env.PROMPT_INDICATOR_VI_NORMAL = "〉" 20 | $env.PROMPT_MULTILINE_INDICATOR = "::: " 21 | 22 | # If you want previously entered commands to have a different prompt from the usual one, 23 | # you can uncomment one or more of the following lines. 24 | # This can be useful if you have a 2-line prompt and it's taking up a lot of space 25 | # because every command entered takes up 2 lines instead of 1. You can then uncomment 26 | # the line below so that previously entered commands show with a single `🚀`. 27 | # $env.TRANSIENT_PROMPT_COMMAND = {|| "🚀 " } 28 | # $env.TRANSIENT_PROMPT_INDICATOR = {|| "" } 29 | # $env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = {|| "" } 30 | # $env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = {|| "" } 31 | # $env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = {|| "" } 32 | # $env.TRANSIENT_PROMPT_COMMAND_RIGHT = {|| "" } 33 | 34 | # Specifies how environment variables are: 35 | # - converted from a string to a value on Nushell startup (from_string) 36 | # - converted from a value back to a string when running external commands (to_string) 37 | # Note: The conversions happen *after* config.nu is loaded 38 | $env.ENV_CONVERSIONS = { 39 | "PATH": { 40 | from_string: { |s| $s | split row (char esep) | path expand --no-symlink } 41 | to_string: { |v| $v | path expand --no-symlink | str join (char esep) } 42 | } 43 | "Path": { 44 | from_string: { |s| $s | split row (char esep) | path expand --no-symlink } 45 | to_string: { |v| $v | path expand --no-symlink | str join (char esep) } 46 | } 47 | } 48 | 49 | # Directories to search for scripts when calling source or use 50 | # The default for this is $nu.default-config-dir/scripts 51 | $env.NU_LIB_DIRS = [ 52 | ($nu.default-config-dir | path join 'scripts') # add /scripts 53 | ($nu.data-dir | path join 'completions') # default home for nushell completions 54 | ] 55 | 56 | # Directories to search for plugin binaries when calling register 57 | # The default for this is $nu.default-config-dir/plugins 58 | $env.NU_PLUGIN_DIRS = [ 59 | ($nu.default-config-dir | path join 'plugins') # add /plugins 60 | ] 61 | 62 | # To add entries to PATH (on Windows you might use Path), you can use the following pattern: 63 | # $env.PATH = ($env.PATH | split row (char esep) | prepend '/some/path') 64 | # An alternate way to add entries to $env.PATH is to use the custom command `path add` 65 | # which is built into the nushell stdlib: 66 | # use std "path add" 67 | # $env.PATH = ($env.PATH | split row (char esep)) 68 | # path add /some/path 69 | # path add ($env.CARGO_HOME | path join "bin") 70 | # path add ($env.HOME | path join ".local" "bin") 71 | # $env.PATH = ($env.PATH | uniq) 72 | 73 | # To load from a custom file you can use: 74 | # source ($nu.default-config-dir | path join 'custom.nu') -------------------------------------------------------------------------------- /config/nushell/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | ... 4 | }: 5 | { 6 | config = { 7 | programs.nushell = { 8 | enable = true; 9 | 10 | envFile.text = (builtins.readFile ./env.nu); 11 | configFile.text = (builtins.readFile ./config.nu); 12 | loginFile.text = (builtins.readFile ./login.nu); 13 | }; 14 | 15 | home.packages = with pkgs.nushellPlugins; [ 16 | formats 17 | polars 18 | query 19 | ]; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /config/nushell/login.nu: -------------------------------------------------------------------------------- 1 | # Example Nushell Loginshell Config File 2 | # - has to be as login.nu in the default config directory 3 | # - will be sourced after config.nu and env.nu in case of nushell started as login shell 4 | 5 | # just as an example for overwriting of an environment variable of env.nu 6 | $env.PROMPT_INDICATOR = {|| "(LS)> " } 7 | 8 | # Similar to env-path and config-path there is a variable containing the path to login.nu 9 | echo $nu.loginshell-path -------------------------------------------------------------------------------- /config/ssh/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | pkgs, 4 | config, 5 | ... 6 | }: 7 | let 8 | cfg = config.programs.ssh; 9 | in 10 | { 11 | options.programs.ssh = with lib; { 12 | enableDefaultMacOSAgent = mkOption { 13 | type = types.bool; 14 | default = pkgs.stdenv.isDarwin; 15 | description = '' 16 | Sets the SSH_AUTH_SOCK env variable from the launchctl environment. 17 | ''; 18 | }; 19 | 20 | enableSmallstep = mkOption { 21 | type = types.bool; 22 | default = pkgs.stdenv.isDarwin; 23 | description = '' 24 | Enable step-cli and integrate with SSH. 25 | ''; 26 | }; 27 | 28 | enable1PasswordAgent = mkOption { 29 | type = types.bool; 30 | default = pkgs.stdenv.isDarwin; 31 | description = '' 32 | Enable 1Password SSH agent. 33 | ''; 34 | }; 35 | 36 | domainCanon = mkOption { 37 | type = types.nullOr (types.listOf types.str); 38 | default = [ 39 | "lon.channings.me" 40 | "ind.channings.me" 41 | ]; 42 | description = '' 43 | Transforms '' to '.lon.channings.me'. 44 | A host is valid if it has an A record. 45 | ''; 46 | }; 47 | }; 48 | 49 | config = lib.mkMerge [ 50 | { 51 | programs.ssh = { 52 | enable = lib.mkDefault true; 53 | 54 | # https://www.psc.edu/hpn-ssh-home/ 55 | # Enable HPN-SSH from PSC 56 | # Patches SSH with optimisations for long network paths. 57 | package = lib.mkDefault pkgs.openssh_hpn; 58 | }; 59 | } 60 | 61 | (lib.mkIf cfg.enableDefaultMacOSAgent { 62 | home.sessionVariables.SSH_AUTH_SOCK = "$(launchctl getenv SSH_AUTH_SOCK)"; 63 | }) 64 | 65 | (lib.mkIf (cfg.domainCanon != null) ({ 66 | programs.ssh.matchBlocks.canonical = { 67 | match = "all"; 68 | extraOptions = { 69 | CanonicalizeHostname = "yes"; 70 | CanonicalizeMaxDots = "0"; # Don't canonicalise "ssh foo.bar", but do for "ssh foo" 71 | CanonicalDomains = "${lib.concatStringsSep " " cfg.domainCanon}"; 72 | }; 73 | }; 74 | })) 75 | 76 | (lib.mkIf cfg.enableSmallstep { 77 | programs.ssh.matchBlocks.smallstep = lib.hm.dag.entryAfter [ "canonical" ] ( 78 | let 79 | step = lib.getExe pkgs.step-cli; 80 | in 81 | { 82 | match = "final exec \"${step} ssh check-host %h\""; 83 | proxyCommand = "${step} ssh proxycommand --issuer=oidc %r %h %p"; 84 | extraOptions = { 85 | IdentityAgent = "SSH_AUTH_SOCK"; 86 | }; 87 | } 88 | ); 89 | }) 90 | 91 | (lib.mkIf cfg.enable1PasswordAgent { 92 | programs.ssh.matchBlocks._1password = lib.hm.dag.entryAfter [ "smallstep" ] { 93 | match = "final all"; 94 | extraOptions = { 95 | IdentityAgent = 96 | if pkgs.stdenv.isDarwin then 97 | "\"~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock\"" 98 | else 99 | "~/.1password/agent.sock"; 100 | }; 101 | }; 102 | }) 103 | ]; 104 | } 105 | -------------------------------------------------------------------------------- /config/starship/config.toml: -------------------------------------------------------------------------------- 1 | add_newline = false 2 | format = "($username@)($hostname )$character$directory" 3 | right_format = "$git_branch$git_status$nix_shell" 4 | scan_timeout = 10 5 | 6 | [character] 7 | error_symbol = "[λ](bold red)" 8 | success_symbol = "[λ](bold green)" 9 | 10 | [cmd_duration] 11 | disabled = false 12 | 13 | [directory] 14 | fish_style_pwd_dir_length = 2 15 | 16 | [git_branch] 17 | format = "[$symbol$branch(:$remote_branch)]($style)" 18 | ignore_branches = ["master", "main"] 19 | 20 | [nix_shell] 21 | disabled = false 22 | format = "[$symbol](bold blue) " 23 | 24 | [hostname] 25 | ssh_only = false 26 | detect_env_vars = ['QEMU', 'SSH_CONNECTION'] 27 | disabled = false 28 | format = '[$hostname](bold bright-white)' 29 | 30 | [username] 31 | style_user = 'white bold' 32 | style_root = 'black bold' 33 | format = '[$user]($style)' 34 | detect_env_vars = ['QEMU', 'SSH_CONNECTION'] 35 | -------------------------------------------------------------------------------- /config/starship/home.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | { 3 | programs.starship = { 4 | enable = true; 5 | 6 | settings = (lib.importTOML ./config.toml); 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /config/toolbox/darwin.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.toolbox.modules.darwin.link-apps 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /config/vscode/extensions.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | (with pkgs.vscode-marketplace; [ 3 | zhuangtongfa.material-theme 4 | mkhl.direnv 5 | editorconfig.editorconfig 6 | redhat.vscode-yaml 7 | redhat.vscode-xml 8 | streetsidesoftware.code-spell-checker 9 | eamodio.gitlens 10 | tamasfe.even-better-toml 11 | github.codespaces 12 | github.copilot 13 | jnoortheen.nix-ide 14 | ]) 15 | ++ [ pkgs.vscode-marketplace."1password".op-vscode ] 16 | -------------------------------------------------------------------------------- /config/vscode/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | pkgs, 4 | config, 5 | ... 6 | }: 7 | { 8 | programs.vscode = { 9 | enable = true; 10 | 11 | package = pkgs.vscodium; 12 | 13 | profiles.default = { 14 | enableUpdateCheck = false; 15 | enableExtensionUpdateCheck = false; 16 | 17 | userSettings = (lib.importJSON ./settings.json) // { 18 | nix = { 19 | enableLanguageServer = true; 20 | serverPath = lib.getExe pkgs.nil; 21 | serverSettings.nil.formatting.command = [ (lib.getExe pkgs.nixfmt-rfc-style) ]; 22 | }; 23 | }; 24 | keybindings = (lib.importJSON ./keybindings.json); 25 | 26 | extensions = lib.mkIf (pkgs ? vscode-marketplace) (import ./extensions.nix { inherit pkgs; }); 27 | }; 28 | }; 29 | 30 | home.packages = [ 31 | (pkgs.writeShellScriptBin "code" '' 32 | ${config.programs.vscode.package}/Applications/VSCodium.app/Contents/MacOS/Electron $@ 33 | '') 34 | ]; 35 | } 36 | -------------------------------------------------------------------------------- /config/vscode/keybindings.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "command": "editor.action.joinLines", 4 | "key": "cmd+j" 5 | }, 6 | { 7 | "command": "editor.action.transformToLowercase", 8 | "key": "cmd+k cmd+l", 9 | "when": "editorTextFocus" 10 | }, 11 | { 12 | "command": "editor.action.transformToUppercase", 13 | "key": "cmd+k cmd+u", 14 | "when": "editorTextFocus" 15 | }, 16 | { 17 | "key": "shift+cmd+g", 18 | "command": "editor.action.selectHighlights", 19 | "when": "editorFocus" 20 | }, 21 | { 22 | "key": "shift+cmd+l", 23 | "command": "-editor.action.selectHighlights", 24 | "when": "editorFocus" 25 | }, 26 | { 27 | "key": "shift+cmd+g", 28 | "command": "-workbench.action.terminal.findPrevious", 29 | "when": "terminalFindFocused && terminalHasBeenCreated || terminalFindFocused && terminalProcessSupported || terminalFocusInAny && terminalHasBeenCreated || terminalFocusInAny && terminalProcessSupported" 30 | }, 31 | { 32 | "key": "shift+cmd+g", 33 | "command": "-workbench.action.terminal.openDetectedLink", 34 | "when": "accessibleViewIsShown && terminalHasBeenCreated && accessibleViewCurrentProviderId == 'terminal'" 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /config/vscode/nixos+darwin.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | { 5 | nixpkgs.overlays = [ 6 | inputs.vscode-extensions.overlays.default 7 | 8 | # (self: super: { 9 | # vscodium = super.vscodium.overrideAttrs ( 10 | # prev: 11 | # let 12 | # sha256 = 13 | # { 14 | # x86_64-linux = "095ilb9b8703lik5ssgs94b7z640pnmwwphnrilwzdj639ldjzf8"; 15 | # x86_64-darwin = "1a733b8c254fa63663101c52568b0528085baabe184aae3d34c64ee8ef0142d5"; 16 | # aarch64-linux = "0m9yf7ks4y6mw1qz5h1clw0s7vwn8yca830f98v69a3f2axb2x8i"; 17 | # aarch64-darwin = "c47c8e1df67fdbcbb8318cdccaf8fa4f7716cb2ed5e8359c09319d9a99a1a4b6"; 18 | # } 19 | # .${self.system} or (throw "Unsupported system: ${self.system}"); 20 | # plat = 21 | # { 22 | # x86_64-linux = "linux-x64"; 23 | # x86_64-darwin = "darwin-x64"; 24 | # aarch64-linux = "linux-arm64"; 25 | # aarch64-darwin = "darwin-arm64"; 26 | # armv7l-linux = "linux-armhf"; 27 | # } 28 | # .${self.system} or (throw "Unsupported system: ${self.system}"); 29 | 30 | # archive_fmt = if self.stdenv.hostPlatform.isDarwin then "zip" else "tar.gz"; 31 | # version = "1.97.2.25045"; 32 | # src = self.fetchurl { 33 | # url = "https://github.com/VSCodium/vscodium/releases/download/${version}/VSCodium-${plat}-${version}.${archive_fmt}"; 34 | # inherit sha256; 35 | # }; 36 | # in 37 | # { 38 | # inherit version src; 39 | # } 40 | # ); 41 | # }) 42 | ]; 43 | } 44 | ]; 45 | } 46 | -------------------------------------------------------------------------------- /config/vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "vscode://schemas/settings/user", 3 | "[markdown]": { 4 | "editor.wordWrap": "on" 5 | }, 6 | "cSpell.language": "en;en-GB", 7 | "cSpell.words": [ 8 | "harfbuzz", 9 | "Nixpkgs", 10 | "titlebar", 11 | "wezterm", 12 | "direnv", 13 | "dotenv", 14 | "devenv", 15 | "mktemp", 16 | "diffable", 17 | "lukechannings", 18 | "channings", 19 | "cachix", 20 | "nixpkgs" 21 | ], 22 | "editor.fontFamily": "RecMonoLinear Nerd Font", 23 | "editor.fontLigatures": true, 24 | "editor.fontSize": 16, 25 | "editor.inlineSuggest.enabled": true, 26 | "editor.multiCursorModifier": "ctrlCmd", 27 | "editor.renderWhitespace": "all", 28 | "editor.rulers": [120], 29 | "editor.snippetSuggestions": "bottom", 30 | "editor.suggestSelection": "first", 31 | "emmet.showSuggestionsAsSnippets": true, 32 | "explorer.confirmDelete": false, 33 | "extensions.autoCheckUpdates": false, 34 | "extensions.ignoreRecommendations": true, 35 | "git.openRepositoryInParentFolders": "never", 36 | "gitlens.plusFeatures.enabled": false, 37 | "gitlens.showWelcomeOnInstall": false, 38 | "gitlens.showWhatsNewAfterUpgrades": false, 39 | "gitlens.terminal.overrideGitEditor": false, 40 | "notebook.markup.fontSize": 14, 41 | "redhat.telemetry.enabled": false, 42 | "search.quickOpen.history.filterSortOrder": "recency", 43 | "terminal.integrated.fontSize": 14, 44 | "terminal.integrated.shellIntegration.enabled": false, 45 | "typescript.updateImportsOnFileMove.enabled": "always", 46 | "javascript.preferences.importModuleSpecifier": "relative", 47 | "typescript.preferences.importModuleSpecifier": "relative", 48 | "update.mode": "none", 49 | "window.commandCenter": false, 50 | "workbench.colorTheme": "One Dark Pro Flat", 51 | "workbench.editor.empty.hint": "hidden", 52 | "workbench.startupEditor": "none", 53 | "workbench.editorAssociations": { 54 | "git-rebase-todo": "default" 55 | }, 56 | "cypressHelper.enableCommandReferenceProvider": false, 57 | "workbench.remoteIndicator.showExtensionRecommendations": false, 58 | "extensions.autoUpdate": false, 59 | "direnv.restart.automatic": true 60 | } 61 | -------------------------------------------------------------------------------- /config/wezterm/config.lua: -------------------------------------------------------------------------------- 1 | local wezterm = require("wezterm") 2 | local mux = wezterm.mux 3 | 4 | local cache_dir = os.getenv("HOME") .. "/.cache/wezterm/" 5 | local window_size_cache_path = cache_dir .. "window_size_cache.txt" 6 | 7 | local multiplexing_unix_socket_name = "@multiplexingName@" 8 | 9 | local color_scheme_name = "Afterglow (Gogh)" 10 | local color_scheme = wezterm.color.get_builtin_schemes()[color_scheme_name] 11 | 12 | wezterm.on("gui-startup", function() 13 | os.execute("mkdir " .. cache_dir) 14 | 15 | local window_size_cache_file = io.open(window_size_cache_path, "r") 16 | if window_size_cache_file ~= nil then 17 | local _, _, width, height = string.find(window_size_cache_file:read(), "(%d+),(%d+)") 18 | mux.spawn_window({ width = tonumber(width), height = tonumber(height) }) 19 | window_size_cache_file:close() 20 | else 21 | local _, _, window = mux.spawn_window({}) 22 | window:gui_window():maximize() 23 | end 24 | end) 25 | 26 | wezterm.on("window-resized", function(_, pane) 27 | local window_size_cache_file = io.open(window_size_cache_path, "r") 28 | if window_size_cache_file == nil then 29 | local tab_size = pane:tab():get_size() 30 | local contents = string.format("%d,%d", tab_size["cols"], tab_size["rows"] + 2) 31 | window_size_cache_file = assert(io.open(window_size_cache_path, "w")) 32 | window_size_cache_file:write(contents) 33 | window_size_cache_file:close() 34 | end 35 | end) 36 | 37 | return { 38 | front_end = "WebGpu", 39 | enable_kitty_keyboard = true, 40 | quit_when_all_windows_are_closed = false, 41 | font = wezterm.font_with_fallback({ 42 | { 43 | family = "RecMonoLinear Nerd Font Mono", 44 | weight = "Regular", 45 | style = "Normal", 46 | harfbuzz_features = { "calt=1", "clig=0", "liga=0" }, 47 | }, 48 | "Menlo", 49 | }), 50 | font_size = 15, 51 | window_decorations = "INTEGRATED_BUTTONS|RESIZE", 52 | color_scheme = color_scheme_name, 53 | initial_cols = 100, 54 | initial_rows = 40, 55 | 56 | window_frame = { 57 | active_titlebar_bg = color_scheme.background, 58 | inactive_titlebar_bg = color_scheme.background, 59 | }, 60 | 61 | window_padding = { 62 | left = "1cell", 63 | right = "1cell", 64 | top = "1cell", 65 | bottom = "1cell", 66 | }, 67 | 68 | skip_close_confirmation_for_processes_named = { 69 | "bash", 70 | "sh", 71 | "zsh", 72 | "fish", 73 | "tmux", 74 | "nu", 75 | "cmd.exe", 76 | "pwsh.exe", 77 | "powershell.exe", 78 | }, 79 | 80 | unix_domains = { 81 | { 82 | name = multiplexing_unix_socket_name, 83 | }, 84 | }, 85 | default_gui_startup_args = { "connect", multiplexing_unix_socket_name }, 86 | keys = { 87 | { 88 | key = "w", 89 | mods = "CMD", 90 | action = wezterm.action.CloseCurrentPane({ confirm = false }), 91 | }, 92 | 93 | { 94 | key = "h", 95 | mods = "CTRL|SHIFT", 96 | action = wezterm.action.ActivatePaneDirection("Left"), 97 | }, 98 | { 99 | key = "j", 100 | mods = "CTRL|SHIFT", 101 | action = wezterm.action.ActivatePaneDirection("Down"), 102 | }, 103 | { 104 | key = "k", 105 | mods = "CTRL|SHIFT", 106 | action = wezterm.action.ActivatePaneDirection("Up"), 107 | }, 108 | { 109 | key = "l", 110 | mods = "CTRL|SHIFT", 111 | action = wezterm.action.ActivatePaneDirection("Right"), 112 | }, 113 | -- CTRL-SHIFT-l activates the debug overlay 114 | { key = "L", mods = "CMD", action = wezterm.action.ShowDebugOverlay }, 115 | }, 116 | colors = { 117 | tab_bar = { 118 | inactive_tab_edge = color_scheme.background, 119 | -- The active tab is the one that has focus in the window 120 | active_tab = { 121 | -- The color of the background area for the tab 122 | bg_color = color_scheme.background, 123 | -- The color of the text for the tab 124 | fg_color = color_scheme.brights[8], 125 | 126 | -- Specify whether you want "Half", "Normal" or "Bold" intensity for the 127 | -- label shown for this tab. 128 | -- The default is "Normal" 129 | intensity = "Bold", 130 | }, 131 | -- Inactive tabs are the tabs that do not have focus 132 | inactive_tab = { 133 | bg_color = color_scheme.background, 134 | fg_color = color_scheme.foreground, 135 | }, 136 | }, 137 | }, 138 | } 139 | -------------------------------------------------------------------------------- /config/wezterm/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | osConfig, 4 | config, 5 | ... 6 | }: 7 | { 8 | config.programs.wezterm = { 9 | enable = true; 10 | 11 | extraConfig = 12 | builtins.replaceStrings 13 | [ "@multiplexingName@" ] 14 | [ 15 | (lib.toLower ( 16 | "${ 17 | (if osConfig.networking.hostName != null then osConfig.networking.hostName else "wezterm") 18 | }_${config.home.username}" 19 | )) 20 | ] 21 | (builtins.readFile ./config.lua); 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /config/zoxide/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | programs.zoxide = { 3 | enable = true; 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /config/zsh/darwin.nix: -------------------------------------------------------------------------------- 1 | { user, config, lib, ... }: 2 | let 3 | hmConfig = config.home-manager.users.${user.name}; 4 | in 5 | { 6 | config = lib.mkIf hmConfig.programs.zsh.enable { 7 | programs.zsh = { 8 | enable = true; 9 | loginShellInit = ". /etc/zprofile\n"; 10 | }; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /config/zsh/nixos.nix: -------------------------------------------------------------------------------- 1 | { 2 | programs.zsh.enable = true; 3 | } 4 | -------------------------------------------------------------------------------- /devenv.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | perSystem = 4 | { 5 | pkgs, 6 | lib, 7 | system, 8 | ... 9 | }: 10 | { 11 | _module.args.pkgs = import inputs.nixpkgs { 12 | inherit system; 13 | config.allowUnfree = true; 14 | overlays = [ inputs.vscode-extensions.overlays.default ]; 15 | }; 16 | 17 | treefmt = { 18 | projectRoot = ./.; 19 | projectRootFile = "flake.nix"; 20 | programs.nixfmt.enable = true; 21 | programs.deadnix.enable = true; 22 | programs.fish_indent.enable = true; 23 | programs.stylua.enable = true; 24 | programs.shellcheck.enable = true; 25 | programs.yamlfmt.enable = true; 26 | programs.actionlint.enable = true; 27 | }; 28 | 29 | devenv.shells.default = { 30 | devenv.root = 31 | let 32 | devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath; 33 | in 34 | pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; 35 | 36 | imports = [ inputs.toolbox.modules.devenv.vscode-workspace ]; 37 | 38 | languages.shell.enable = true; 39 | 40 | devcontainer.settings.customizations.vscode.extensions = 41 | let 42 | globalExtensions = (import ./config/vscode/extensions.nix { inherit pkgs; }); 43 | inherit (builtins) foldl' attrNames readDir; 44 | in 45 | foldl' ( 46 | acc: extension: acc ++ (attrNames (readDir "${extension}/share/vscode/extensions")) 47 | ) [ ] globalExtensions; 48 | 49 | devcontainer.settings.updateContentCommand = ""; 50 | 51 | vscode-workspace = { 52 | extensions = with pkgs.vscode-marketplace; [ 53 | jnoortheen.nix-ide 54 | thenuprojectcontributors.vscode-nushell-lang 55 | ]; 56 | 57 | settings = { 58 | nix = { 59 | enableLanguageServer = true; 60 | serverPath = lib.getExe pkgs.nil; 61 | }; 62 | }; 63 | }; 64 | }; 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "_1password-shell-plugins": { 4 | "inputs": { 5 | "flake-utils": "flake-utils", 6 | "nixpkgs": [ 7 | "nixpkgs" 8 | ] 9 | }, 10 | "locked": { 11 | "lastModified": 1736185742, 12 | "narHash": "sha256-IRa9NAUK0vdoo2aMDKTZ86d4yDVyKWhpCfMgJOqcpwA=", 13 | "owner": "LukeChannings", 14 | "repo": "1password-shell-plugins", 15 | "rev": "5ef7244c6b8036dd2817ce821b95941980459536", 16 | "type": "github" 17 | }, 18 | "original": { 19 | "owner": "LukeChannings", 20 | "ref": "5ef7244", 21 | "repo": "1password-shell-plugins", 22 | "type": "github" 23 | } 24 | }, 25 | "brew-api": { 26 | "flake": false, 27 | "locked": { 28 | "lastModified": 1744114910, 29 | "narHash": "sha256-/t+eZrR4xWVjcIJiwrgTsyYFW5ceEFDlz2hSpdqzBZA=", 30 | "owner": "BatteredBunny", 31 | "repo": "brew-api", 32 | "rev": "c208afacc5161a405a40ac680599cc5deabd662c", 33 | "type": "github" 34 | }, 35 | "original": { 36 | "owner": "BatteredBunny", 37 | "repo": "brew-api", 38 | "type": "github" 39 | } 40 | }, 41 | "brew-nix": { 42 | "inputs": { 43 | "brew-api": [ 44 | "brew-api" 45 | ], 46 | "flake-utils": "flake-utils_2", 47 | "nix-darwin": [ 48 | "nixpkgs" 49 | ], 50 | "nixpkgs": [ 51 | "nixpkgs" 52 | ] 53 | }, 54 | "locked": { 55 | "lastModified": 1737913021, 56 | "narHash": "sha256-EZfEw6TTf1AjCGyVXPJO1hsc6hijMf5E91PP3kdn6ac=", 57 | "owner": "LukeChannings", 58 | "repo": "brew-nix", 59 | "rev": "c411faa4a74b2288f072f41738f9064e8cc3644d", 60 | "type": "github" 61 | }, 62 | "original": { 63 | "owner": "LukeChannings", 64 | "repo": "brew-nix", 65 | "type": "github" 66 | } 67 | }, 68 | "cachix": { 69 | "inputs": { 70 | "devenv": [ 71 | "devenv" 72 | ], 73 | "flake-compat": [ 74 | "devenv" 75 | ], 76 | "git-hooks": [ 77 | "devenv" 78 | ], 79 | "nixpkgs": "nixpkgs" 80 | }, 81 | "locked": { 82 | "lastModified": 1742042642, 83 | "narHash": "sha256-D0gP8srrX0qj+wNYNPdtVJsQuFzIng3q43thnHXQ/es=", 84 | "owner": "cachix", 85 | "repo": "cachix", 86 | "rev": "a624d3eaf4b1d225f918de8543ed739f2f574203", 87 | "type": "github" 88 | }, 89 | "original": { 90 | "owner": "cachix", 91 | "ref": "latest", 92 | "repo": "cachix", 93 | "type": "github" 94 | } 95 | }, 96 | "colmena": { 97 | "inputs": { 98 | "flake-compat": "flake-compat", 99 | "flake-utils": "flake-utils_3", 100 | "nix-github-actions": "nix-github-actions", 101 | "nixpkgs": [ 102 | "nixpkgs" 103 | ], 104 | "stable": [ 105 | "nixpkgs" 106 | ] 107 | }, 108 | "locked": { 109 | "lastModified": 1739900653, 110 | "narHash": "sha256-hPSLvw6AZQYrZyGI6Uq4XgST7benF/0zcCpugn/P0yM=", 111 | "owner": "zhaofengli", 112 | "repo": "colmena", 113 | "rev": "2370d4336eda2a9ef29fce10fa7076ae011983ab", 114 | "type": "github" 115 | }, 116 | "original": { 117 | "owner": "zhaofengli", 118 | "repo": "colmena", 119 | "type": "github" 120 | } 121 | }, 122 | "darwin": { 123 | "inputs": { 124 | "nixpkgs": [ 125 | "nixpkgs" 126 | ] 127 | }, 128 | "locked": { 129 | "lastModified": 1743496612, 130 | "narHash": "sha256-emPWa5lmKbnyuj8c1mSJUkzJNT+iJoU9GMcXwjp2oVM=", 131 | "owner": "LnL7", 132 | "repo": "nix-darwin", 133 | "rev": "73d59580d01e9b9f957ba749f336a272869c42dd", 134 | "type": "github" 135 | }, 136 | "original": { 137 | "owner": "LnL7", 138 | "repo": "nix-darwin", 139 | "type": "github" 140 | } 141 | }, 142 | "devenv": { 143 | "inputs": { 144 | "cachix": "cachix", 145 | "flake-compat": "flake-compat_2", 146 | "git-hooks": "git-hooks", 147 | "nix": "nix", 148 | "nixpkgs": "nixpkgs_3" 149 | }, 150 | "locked": { 151 | "lastModified": 1743783972, 152 | "narHash": "sha256-5wPsNCnWmeLpLxavsftA9L7tnYgtlexV7FwLegxtpy4=", 153 | "owner": "cachix", 154 | "repo": "devenv", 155 | "rev": "2f53e2f867e0c2ba18b880e66169366e5f8ca554", 156 | "type": "github" 157 | }, 158 | "original": { 159 | "owner": "cachix", 160 | "repo": "devenv", 161 | "type": "github" 162 | } 163 | }, 164 | "devenv-root": { 165 | "flake": false, 166 | "locked": { 167 | "narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=", 168 | "type": "file", 169 | "url": "file:///dev/null" 170 | }, 171 | "original": { 172 | "type": "file", 173 | "url": "file:///dev/null" 174 | } 175 | }, 176 | "devenv-root_2": { 177 | "flake": false, 178 | "locked": { 179 | "narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=", 180 | "type": "file", 181 | "url": "file:///dev/null" 182 | }, 183 | "original": { 184 | "type": "file", 185 | "url": "file:///dev/null" 186 | } 187 | }, 188 | "flake-compat": { 189 | "flake": false, 190 | "locked": { 191 | "lastModified": 1650374568, 192 | "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", 193 | "owner": "edolstra", 194 | "repo": "flake-compat", 195 | "rev": "b4a34015c698c7793d592d66adbab377907a2be8", 196 | "type": "github" 197 | }, 198 | "original": { 199 | "owner": "edolstra", 200 | "repo": "flake-compat", 201 | "type": "github" 202 | } 203 | }, 204 | "flake-compat_2": { 205 | "flake": false, 206 | "locked": { 207 | "lastModified": 1733328505, 208 | "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", 209 | "owner": "edolstra", 210 | "repo": "flake-compat", 211 | "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", 212 | "type": "github" 213 | }, 214 | "original": { 215 | "owner": "edolstra", 216 | "repo": "flake-compat", 217 | "type": "github" 218 | } 219 | }, 220 | "flake-compat_3": { 221 | "flake": false, 222 | "locked": { 223 | "lastModified": 1696426674, 224 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 225 | "owner": "edolstra", 226 | "repo": "flake-compat", 227 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 228 | "type": "github" 229 | }, 230 | "original": { 231 | "owner": "edolstra", 232 | "repo": "flake-compat", 233 | "type": "github" 234 | } 235 | }, 236 | "flake-parts": { 237 | "inputs": { 238 | "nixpkgs-lib": [ 239 | "devenv", 240 | "nix", 241 | "nixpkgs" 242 | ] 243 | }, 244 | "locked": { 245 | "lastModified": 1712014858, 246 | "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", 247 | "owner": "hercules-ci", 248 | "repo": "flake-parts", 249 | "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", 250 | "type": "github" 251 | }, 252 | "original": { 253 | "owner": "hercules-ci", 254 | "repo": "flake-parts", 255 | "type": "github" 256 | } 257 | }, 258 | "flake-parts_2": { 259 | "inputs": { 260 | "nixpkgs-lib": "nixpkgs-lib" 261 | }, 262 | "locked": { 263 | "lastModified": 1743550720, 264 | "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", 265 | "owner": "hercules-ci", 266 | "repo": "flake-parts", 267 | "rev": "c621e8422220273271f52058f618c94e405bb0f5", 268 | "type": "github" 269 | }, 270 | "original": { 271 | "owner": "hercules-ci", 272 | "repo": "flake-parts", 273 | "type": "github" 274 | } 275 | }, 276 | "flake-utils": { 277 | "inputs": { 278 | "systems": "systems" 279 | }, 280 | "locked": { 281 | "lastModified": 1710146030, 282 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 283 | "owner": "numtide", 284 | "repo": "flake-utils", 285 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 286 | "type": "github" 287 | }, 288 | "original": { 289 | "owner": "numtide", 290 | "repo": "flake-utils", 291 | "type": "github" 292 | } 293 | }, 294 | "flake-utils_2": { 295 | "inputs": { 296 | "systems": "systems_2" 297 | }, 298 | "locked": { 299 | "lastModified": 1731533236, 300 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 301 | "owner": "numtide", 302 | "repo": "flake-utils", 303 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 304 | "type": "github" 305 | }, 306 | "original": { 307 | "owner": "numtide", 308 | "repo": "flake-utils", 309 | "type": "github" 310 | } 311 | }, 312 | "flake-utils_3": { 313 | "locked": { 314 | "lastModified": 1659877975, 315 | "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", 316 | "owner": "numtide", 317 | "repo": "flake-utils", 318 | "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", 319 | "type": "github" 320 | }, 321 | "original": { 322 | "owner": "numtide", 323 | "repo": "flake-utils", 324 | "type": "github" 325 | } 326 | }, 327 | "flake-utils_4": { 328 | "inputs": { 329 | "systems": "systems_3" 330 | }, 331 | "locked": { 332 | "lastModified": 1731533236, 333 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 334 | "owner": "numtide", 335 | "repo": "flake-utils", 336 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 337 | "type": "github" 338 | }, 339 | "original": { 340 | "owner": "numtide", 341 | "repo": "flake-utils", 342 | "type": "github" 343 | } 344 | }, 345 | "flake-utils_5": { 346 | "inputs": { 347 | "systems": "systems_4" 348 | }, 349 | "locked": { 350 | "lastModified": 1731533236, 351 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 352 | "owner": "numtide", 353 | "repo": "flake-utils", 354 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 355 | "type": "github" 356 | }, 357 | "original": { 358 | "owner": "numtide", 359 | "repo": "flake-utils", 360 | "type": "github" 361 | } 362 | }, 363 | "flake-utils_6": { 364 | "inputs": { 365 | "systems": "systems_5" 366 | }, 367 | "locked": { 368 | "lastModified": 1710146030, 369 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 370 | "owner": "numtide", 371 | "repo": "flake-utils", 372 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 373 | "type": "github" 374 | }, 375 | "original": { 376 | "owner": "numtide", 377 | "repo": "flake-utils", 378 | "type": "github" 379 | } 380 | }, 381 | "flake-utils_7": { 382 | "inputs": { 383 | "systems": "systems_6" 384 | }, 385 | "locked": { 386 | "lastModified": 1710146030, 387 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 388 | "owner": "numtide", 389 | "repo": "flake-utils", 390 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 391 | "type": "github" 392 | }, 393 | "original": { 394 | "owner": "numtide", 395 | "repo": "flake-utils", 396 | "type": "github" 397 | } 398 | }, 399 | "flake-utils_8": { 400 | "inputs": { 401 | "systems": "systems_7" 402 | }, 403 | "locked": { 404 | "lastModified": 1731533236, 405 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 406 | "owner": "numtide", 407 | "repo": "flake-utils", 408 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 409 | "type": "github" 410 | }, 411 | "original": { 412 | "owner": "numtide", 413 | "repo": "flake-utils", 414 | "type": "github" 415 | } 416 | }, 417 | "flakey-profile": { 418 | "locked": { 419 | "lastModified": 1712898590, 420 | "narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=", 421 | "owner": "lf-", 422 | "repo": "flakey-profile", 423 | "rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d", 424 | "type": "github" 425 | }, 426 | "original": { 427 | "owner": "lf-", 428 | "repo": "flakey-profile", 429 | "type": "github" 430 | } 431 | }, 432 | "git-hooks": { 433 | "inputs": { 434 | "flake-compat": [ 435 | "devenv" 436 | ], 437 | "gitignore": "gitignore", 438 | "nixpkgs": [ 439 | "devenv", 440 | "nixpkgs" 441 | ] 442 | }, 443 | "locked": { 444 | "lastModified": 1742649964, 445 | "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", 446 | "owner": "cachix", 447 | "repo": "git-hooks.nix", 448 | "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", 449 | "type": "github" 450 | }, 451 | "original": { 452 | "owner": "cachix", 453 | "repo": "git-hooks.nix", 454 | "type": "github" 455 | } 456 | }, 457 | "gitignore": { 458 | "inputs": { 459 | "nixpkgs": [ 460 | "devenv", 461 | "git-hooks", 462 | "nixpkgs" 463 | ] 464 | }, 465 | "locked": { 466 | "lastModified": 1709087332, 467 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", 468 | "owner": "hercules-ci", 469 | "repo": "gitignore.nix", 470 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 471 | "type": "github" 472 | }, 473 | "original": { 474 | "owner": "hercules-ci", 475 | "repo": "gitignore.nix", 476 | "type": "github" 477 | } 478 | }, 479 | "helix": { 480 | "inputs": { 481 | "flake-utils": "flake-utils_4", 482 | "nixpkgs": [ 483 | "nixpkgs" 484 | ], 485 | "rust-overlay": "rust-overlay" 486 | }, 487 | "locked": { 488 | "lastModified": 1744079626, 489 | "narHash": "sha256-uh68j7OWp2KuSMKKO49C3fdQV1mQH6jbj5p6VBhCOMU=", 490 | "owner": "helix-editor", 491 | "repo": "helix", 492 | "rev": "5d16aae58e3ec4a960955bba0c7e35ea6c4cb582", 493 | "type": "github" 494 | }, 495 | "original": { 496 | "id": "helix", 497 | "type": "indirect" 498 | } 499 | }, 500 | "home-manager": { 501 | "inputs": { 502 | "nixpkgs": [ 503 | "nixpkgs" 504 | ] 505 | }, 506 | "locked": { 507 | "lastModified": 1744038920, 508 | "narHash": "sha256-9a4V1wQXS8hXZtc7mRtz0qINkGW+C99aDrmXY6oYBFg=", 509 | "owner": "nix-community", 510 | "repo": "home-manager", 511 | "rev": "a4d8020820a85b47f842eae76ad083b0ec2a886a", 512 | "type": "github" 513 | }, 514 | "original": { 515 | "owner": "nix-community", 516 | "repo": "home-manager", 517 | "type": "github" 518 | } 519 | }, 520 | "libgit2": { 521 | "flake": false, 522 | "locked": { 523 | "lastModified": 1697646580, 524 | "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", 525 | "owner": "libgit2", 526 | "repo": "libgit2", 527 | "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", 528 | "type": "github" 529 | }, 530 | "original": { 531 | "owner": "libgit2", 532 | "repo": "libgit2", 533 | "type": "github" 534 | } 535 | }, 536 | "lix": { 537 | "flake": false, 538 | "locked": { 539 | "lastModified": 1737234286, 540 | "narHash": "sha256-pgDJZjj4jpzkFxsqBTI/9Yb0n3gW+DvDtuv9SwQZZcs=", 541 | "rev": "079528098f5998ba13c88821a2eca1005c1695de", 542 | "type": "tarball", 543 | "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/079528098f5998ba13c88821a2eca1005c1695de.tar.gz?rev=079528098f5998ba13c88821a2eca1005c1695de" 544 | }, 545 | "original": { 546 | "type": "tarball", 547 | "url": "https://git.lix.systems/lix-project/lix/archive/release-2.92.tar.gz" 548 | } 549 | }, 550 | "lix-module": { 551 | "inputs": { 552 | "flake-utils": "flake-utils_5", 553 | "flakey-profile": "flakey-profile", 554 | "lix": "lix", 555 | "nixpkgs": [ 556 | "nixpkgs" 557 | ] 558 | }, 559 | "locked": { 560 | "lastModified": 1742943028, 561 | "narHash": "sha256-fprwZKE1uMzO9tiWWOrmLWBW3GPkMayQfb0xOvVFIno=", 562 | "rev": "868d97695bab9d21f6070b03957bcace249fbe3c", 563 | "type": "tarball", 564 | "url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/868d97695bab9d21f6070b03957bcace249fbe3c.tar.gz?rev=868d97695bab9d21f6070b03957bcace249fbe3c" 565 | }, 566 | "original": { 567 | "type": "tarball", 568 | "url": "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz" 569 | } 570 | }, 571 | "mk-shell-bin": { 572 | "locked": { 573 | "lastModified": 1677004959, 574 | "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", 575 | "owner": "rrbutani", 576 | "repo": "nix-mk-shell-bin", 577 | "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", 578 | "type": "github" 579 | }, 580 | "original": { 581 | "owner": "rrbutani", 582 | "repo": "nix-mk-shell-bin", 583 | "type": "github" 584 | } 585 | }, 586 | "nix": { 587 | "inputs": { 588 | "flake-compat": [ 589 | "devenv" 590 | ], 591 | "flake-parts": "flake-parts", 592 | "libgit2": "libgit2", 593 | "nixpkgs": "nixpkgs_2", 594 | "nixpkgs-23-11": [ 595 | "devenv" 596 | ], 597 | "nixpkgs-regression": [ 598 | "devenv" 599 | ], 600 | "pre-commit-hooks": [ 601 | "devenv" 602 | ] 603 | }, 604 | "locked": { 605 | "lastModified": 1741798497, 606 | "narHash": "sha256-E3j+3MoY8Y96mG1dUIiLFm2tZmNbRvSiyN7CrSKuAVg=", 607 | "owner": "domenkozar", 608 | "repo": "nix", 609 | "rev": "f3f44b2baaf6c4c6e179de8cbb1cc6db031083cd", 610 | "type": "github" 611 | }, 612 | "original": { 613 | "owner": "domenkozar", 614 | "ref": "devenv-2.24", 615 | "repo": "nix", 616 | "type": "github" 617 | } 618 | }, 619 | "nix-github-actions": { 620 | "inputs": { 621 | "nixpkgs": [ 622 | "colmena", 623 | "nixpkgs" 624 | ] 625 | }, 626 | "locked": { 627 | "lastModified": 1729742964, 628 | "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=", 629 | "owner": "nix-community", 630 | "repo": "nix-github-actions", 631 | "rev": "e04df33f62cdcf93d73e9a04142464753a16db67", 632 | "type": "github" 633 | }, 634 | "original": { 635 | "owner": "nix-community", 636 | "repo": "nix-github-actions", 637 | "type": "github" 638 | } 639 | }, 640 | "nix-index-database": { 641 | "inputs": { 642 | "nixpkgs": [ 643 | "nixpkgs" 644 | ] 645 | }, 646 | "locked": { 647 | "lastModified": 1743911143, 648 | "narHash": "sha256-4j4JPwr0TXHH4ZyorXN5yIcmqIQr0WYacsuPA4ktONo=", 649 | "owner": "nix-community", 650 | "repo": "nix-index-database", 651 | "rev": "a36f6a7148aec2c77d78e4466215cceb2f5f4bfb", 652 | "type": "github" 653 | }, 654 | "original": { 655 | "owner": "nix-community", 656 | "repo": "nix-index-database", 657 | "type": "github" 658 | } 659 | }, 660 | "nix2container": { 661 | "inputs": { 662 | "flake-utils": "flake-utils_6", 663 | "nixpkgs": [ 664 | "toolbox", 665 | "nixpkgs" 666 | ] 667 | }, 668 | "locked": { 669 | "lastModified": 1724996935, 670 | "narHash": "sha256-njRK9vvZ1JJsP8oV2OgkBrpJhgQezI03S7gzskCcHos=", 671 | "owner": "nlewo", 672 | "repo": "nix2container", 673 | "rev": "fa6bb0a1159f55d071ba99331355955ae30b3401", 674 | "type": "github" 675 | }, 676 | "original": { 677 | "owner": "nlewo", 678 | "repo": "nix2container", 679 | "type": "github" 680 | } 681 | }, 682 | "nixpkgs": { 683 | "locked": { 684 | "lastModified": 1733212471, 685 | "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=", 686 | "owner": "NixOS", 687 | "repo": "nixpkgs", 688 | "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776", 689 | "type": "github" 690 | }, 691 | "original": { 692 | "owner": "NixOS", 693 | "ref": "nixos-unstable", 694 | "repo": "nixpkgs", 695 | "type": "github" 696 | } 697 | }, 698 | "nixpkgs-lib": { 699 | "locked": { 700 | "lastModified": 1743296961, 701 | "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", 702 | "owner": "nix-community", 703 | "repo": "nixpkgs.lib", 704 | "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", 705 | "type": "github" 706 | }, 707 | "original": { 708 | "owner": "nix-community", 709 | "repo": "nixpkgs.lib", 710 | "type": "github" 711 | } 712 | }, 713 | "nixpkgs-nixos": { 714 | "locked": { 715 | "lastModified": 1743964447, 716 | "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", 717 | "owner": "NixOS", 718 | "repo": "nixpkgs", 719 | "rev": "063dece00c5a77e4a0ea24e5e5a5bd75232806f8", 720 | "type": "github" 721 | }, 722 | "original": { 723 | "owner": "NixOS", 724 | "ref": "nixos-unstable", 725 | "repo": "nixpkgs", 726 | "type": "github" 727 | } 728 | }, 729 | "nixpkgs-stable": { 730 | "locked": { 731 | "lastModified": 1743975612, 732 | "narHash": "sha256-o4FjFOUmjSRMK7dn0TFdAT0RRWUWD+WsspPHa+qEQT8=", 733 | "owner": "NixOS", 734 | "repo": "nixpkgs", 735 | "rev": "a880f49904d68b5e53338d1e8c7bf80f59903928", 736 | "type": "github" 737 | }, 738 | "original": { 739 | "owner": "NixOS", 740 | "ref": "nixos-24.11", 741 | "repo": "nixpkgs", 742 | "type": "github" 743 | } 744 | }, 745 | "nixpkgs_2": { 746 | "locked": { 747 | "lastModified": 1717432640, 748 | "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", 749 | "owner": "NixOS", 750 | "repo": "nixpkgs", 751 | "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", 752 | "type": "github" 753 | }, 754 | "original": { 755 | "owner": "NixOS", 756 | "ref": "release-24.05", 757 | "repo": "nixpkgs", 758 | "type": "github" 759 | } 760 | }, 761 | "nixpkgs_3": { 762 | "locked": { 763 | "lastModified": 1733477122, 764 | "narHash": "sha256-qamMCz5mNpQmgBwc8SB5tVMlD5sbwVIToVZtSxMph9s=", 765 | "owner": "cachix", 766 | "repo": "devenv-nixpkgs", 767 | "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", 768 | "type": "github" 769 | }, 770 | "original": { 771 | "owner": "cachix", 772 | "ref": "rolling", 773 | "repo": "devenv-nixpkgs", 774 | "type": "github" 775 | } 776 | }, 777 | "nixpkgs_4": { 778 | "locked": { 779 | "lastModified": 1744032190, 780 | "narHash": "sha256-KSlfrncSkcu1YE+uuJ/PTURsSlThoGkRqiGDVdbiE/k=", 781 | "owner": "NixOS", 782 | "repo": "nixpkgs", 783 | "rev": "b0b4b5f8f621bfe213b8b21694bab52ecfcbf30b", 784 | "type": "github" 785 | }, 786 | "original": { 787 | "owner": "NixOS", 788 | "ref": "nixpkgs-unstable", 789 | "repo": "nixpkgs", 790 | "type": "github" 791 | } 792 | }, 793 | "nixpkgs_5": { 794 | "locked": { 795 | "lastModified": 1725103162, 796 | "narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=", 797 | "owner": "nixos", 798 | "repo": "nixpkgs", 799 | "rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b", 800 | "type": "github" 801 | }, 802 | "original": { 803 | "owner": "nixos", 804 | "ref": "nixos-unstable", 805 | "repo": "nixpkgs", 806 | "type": "github" 807 | } 808 | }, 809 | "nixpkgs_6": { 810 | "locked": { 811 | "lastModified": 1713805509, 812 | "narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=", 813 | "owner": "NixOS", 814 | "repo": "nixpkgs", 815 | "rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4", 816 | "type": "github" 817 | }, 818 | "original": { 819 | "owner": "NixOS", 820 | "ref": "nixpkgs-unstable", 821 | "repo": "nixpkgs", 822 | "type": "github" 823 | } 824 | }, 825 | "nixpkgs_7": { 826 | "locked": { 827 | "lastModified": 1735554305, 828 | "narHash": "sha256-zExSA1i/b+1NMRhGGLtNfFGXgLtgo+dcuzHzaWA6w3Q=", 829 | "owner": "nixos", 830 | "repo": "nixpkgs", 831 | "rev": "0e82ab234249d8eee3e8c91437802b32c74bb3fd", 832 | "type": "github" 833 | }, 834 | "original": { 835 | "owner": "nixos", 836 | "ref": "nixpkgs-unstable", 837 | "repo": "nixpkgs", 838 | "type": "github" 839 | } 840 | }, 841 | "nixpkgs_8": { 842 | "locked": { 843 | "lastModified": 1740547748, 844 | "narHash": "sha256-Ly2fBL1LscV+KyCqPRufUBuiw+zmWrlJzpWOWbahplg=", 845 | "owner": "NixOS", 846 | "repo": "nixpkgs", 847 | "rev": "3a05eebede89661660945da1f151959900903b6a", 848 | "type": "github" 849 | }, 850 | "original": { 851 | "owner": "NixOS", 852 | "repo": "nixpkgs", 853 | "rev": "3a05eebede89661660945da1f151959900903b6a", 854 | "type": "github" 855 | } 856 | }, 857 | "root": { 858 | "inputs": { 859 | "_1password-shell-plugins": "_1password-shell-plugins", 860 | "brew-api": "brew-api", 861 | "brew-nix": "brew-nix", 862 | "colmena": "colmena", 863 | "darwin": "darwin", 864 | "devenv": "devenv", 865 | "devenv-root": "devenv-root", 866 | "flake-parts": "flake-parts_2", 867 | "helix": "helix", 868 | "home-manager": "home-manager", 869 | "lix-module": "lix-module", 870 | "nix-index-database": "nix-index-database", 871 | "nixpkgs": "nixpkgs_4", 872 | "nixpkgs-nixos": "nixpkgs-nixos", 873 | "nixpkgs-stable": "nixpkgs-stable", 874 | "sops-nix": "sops-nix", 875 | "toolbox": "toolbox", 876 | "treefmt-nix": "treefmt-nix_2", 877 | "vscode-extensions": "vscode-extensions_2" 878 | } 879 | }, 880 | "rust-overlay": { 881 | "inputs": { 882 | "nixpkgs": [ 883 | "helix", 884 | "nixpkgs" 885 | ] 886 | }, 887 | "locked": { 888 | "lastModified": 1740623427, 889 | "narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=", 890 | "owner": "oxalica", 891 | "repo": "rust-overlay", 892 | "rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab", 893 | "type": "github" 894 | }, 895 | "original": { 896 | "owner": "oxalica", 897 | "repo": "rust-overlay", 898 | "type": "github" 899 | } 900 | }, 901 | "sops-nix": { 902 | "inputs": { 903 | "nixpkgs": [ 904 | "nixpkgs" 905 | ] 906 | }, 907 | "locked": { 908 | "lastModified": 1744103455, 909 | "narHash": "sha256-SR6+qjkPjGQG+8eM4dCcVtss8r9bre/LAxFMPJpaZeU=", 910 | "owner": "Mic92", 911 | "repo": "sops-nix", 912 | "rev": "69d5a5a4635c27dae5a742f36108beccc506c1ba", 913 | "type": "github" 914 | }, 915 | "original": { 916 | "owner": "Mic92", 917 | "repo": "sops-nix", 918 | "type": "github" 919 | } 920 | }, 921 | "systems": { 922 | "locked": { 923 | "lastModified": 1681028828, 924 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 925 | "owner": "nix-systems", 926 | "repo": "default", 927 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 928 | "type": "github" 929 | }, 930 | "original": { 931 | "owner": "nix-systems", 932 | "repo": "default", 933 | "type": "github" 934 | } 935 | }, 936 | "systems_2": { 937 | "locked": { 938 | "lastModified": 1681028828, 939 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 940 | "owner": "nix-systems", 941 | "repo": "default", 942 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 943 | "type": "github" 944 | }, 945 | "original": { 946 | "owner": "nix-systems", 947 | "repo": "default", 948 | "type": "github" 949 | } 950 | }, 951 | "systems_3": { 952 | "locked": { 953 | "lastModified": 1681028828, 954 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 955 | "owner": "nix-systems", 956 | "repo": "default", 957 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 958 | "type": "github" 959 | }, 960 | "original": { 961 | "owner": "nix-systems", 962 | "repo": "default", 963 | "type": "github" 964 | } 965 | }, 966 | "systems_4": { 967 | "locked": { 968 | "lastModified": 1681028828, 969 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 970 | "owner": "nix-systems", 971 | "repo": "default", 972 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 973 | "type": "github" 974 | }, 975 | "original": { 976 | "owner": "nix-systems", 977 | "repo": "default", 978 | "type": "github" 979 | } 980 | }, 981 | "systems_5": { 982 | "locked": { 983 | "lastModified": 1681028828, 984 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 985 | "owner": "nix-systems", 986 | "repo": "default", 987 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 988 | "type": "github" 989 | }, 990 | "original": { 991 | "owner": "nix-systems", 992 | "repo": "default", 993 | "type": "github" 994 | } 995 | }, 996 | "systems_6": { 997 | "locked": { 998 | "lastModified": 1681028828, 999 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 1000 | "owner": "nix-systems", 1001 | "repo": "default", 1002 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 1003 | "type": "github" 1004 | }, 1005 | "original": { 1006 | "owner": "nix-systems", 1007 | "repo": "default", 1008 | "type": "github" 1009 | } 1010 | }, 1011 | "systems_7": { 1012 | "locked": { 1013 | "lastModified": 1681028828, 1014 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 1015 | "owner": "nix-systems", 1016 | "repo": "default", 1017 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 1018 | "type": "github" 1019 | }, 1020 | "original": { 1021 | "owner": "nix-systems", 1022 | "repo": "default", 1023 | "type": "github" 1024 | } 1025 | }, 1026 | "toolbox": { 1027 | "inputs": { 1028 | "devenv": [ 1029 | "devenv" 1030 | ], 1031 | "devenv-root": "devenv-root_2", 1032 | "flake-parts": [ 1033 | "flake-parts" 1034 | ], 1035 | "mk-shell-bin": "mk-shell-bin", 1036 | "nix2container": "nix2container", 1037 | "nixpkgs": [ 1038 | "nixpkgs" 1039 | ], 1040 | "treefmt-nix": "treefmt-nix", 1041 | "vscode-extensions": "vscode-extensions" 1042 | }, 1043 | "locked": { 1044 | "lastModified": 1732538261, 1045 | "narHash": "sha256-Zu7pPjIkUBQvCMFNK6Ry5H232GHbVhVfnjtry6ssEkY=", 1046 | "owner": "lukechannings", 1047 | "repo": "toolbox", 1048 | "rev": "ede1ba5de5d3f9af891ee77f6fa3524242d0c4ba", 1049 | "type": "github" 1050 | }, 1051 | "original": { 1052 | "owner": "lukechannings", 1053 | "repo": "toolbox", 1054 | "type": "github" 1055 | } 1056 | }, 1057 | "treefmt-nix": { 1058 | "inputs": { 1059 | "nixpkgs": "nixpkgs_5" 1060 | }, 1061 | "locked": { 1062 | "lastModified": 1725271838, 1063 | "narHash": "sha256-VcqxWT0O/gMaeWTTjf1r4MOyG49NaNxW4GHTO3xuThE=", 1064 | "owner": "numtide", 1065 | "repo": "treefmt-nix", 1066 | "rev": "9fb342d14b69aefdf46187f6bb80a4a0d97007cd", 1067 | "type": "github" 1068 | }, 1069 | "original": { 1070 | "owner": "numtide", 1071 | "repo": "treefmt-nix", 1072 | "type": "github" 1073 | } 1074 | }, 1075 | "treefmt-nix_2": { 1076 | "inputs": { 1077 | "nixpkgs": "nixpkgs_7" 1078 | }, 1079 | "locked": { 1080 | "lastModified": 1743748085, 1081 | "narHash": "sha256-uhjnlaVTWo5iD3LXics1rp9gaKgDRQj6660+gbUU3cE=", 1082 | "owner": "numtide", 1083 | "repo": "treefmt-nix", 1084 | "rev": "815e4121d6a5d504c0f96e5be2dd7f871e4fd99d", 1085 | "type": "github" 1086 | }, 1087 | "original": { 1088 | "owner": "numtide", 1089 | "repo": "treefmt-nix", 1090 | "type": "github" 1091 | } 1092 | }, 1093 | "vscode-extensions": { 1094 | "inputs": { 1095 | "flake-compat": "flake-compat_3", 1096 | "flake-utils": "flake-utils_7", 1097 | "nixpkgs": "nixpkgs_6" 1098 | }, 1099 | "locked": { 1100 | "lastModified": 1726451286, 1101 | "narHash": "sha256-hrNSd0rh8wZdNxzmFGAoQIQ7boY8OhRlzxb/lZ+5rW8=", 1102 | "owner": "nix-community", 1103 | "repo": "nix-vscode-extensions", 1104 | "rev": "156dc845e9e2193710b700aa92e4b5f1e7907cd8", 1105 | "type": "github" 1106 | }, 1107 | "original": { 1108 | "owner": "nix-community", 1109 | "repo": "nix-vscode-extensions", 1110 | "type": "github" 1111 | } 1112 | }, 1113 | "vscode-extensions_2": { 1114 | "inputs": { 1115 | "flake-utils": "flake-utils_8", 1116 | "nixpkgs": "nixpkgs_8" 1117 | }, 1118 | "locked": { 1119 | "lastModified": 1744077282, 1120 | "narHash": "sha256-iz+nxNBT3ddLIg2GFYSlukAfxCBcvot0EVHDvYPJ+uU=", 1121 | "owner": "nix-community", 1122 | "repo": "nix-vscode-extensions", 1123 | "rev": "dab6f44ebb63c5f556f61a6c2e540447e640a642", 1124 | "type": "github" 1125 | }, 1126 | "original": { 1127 | "owner": "nix-community", 1128 | "repo": "nix-vscode-extensions", 1129 | "type": "github" 1130 | } 1131 | } 1132 | }, 1133 | "root": "root", 1134 | "version": 7 1135 | } 1136 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Luke's dotfiles"; 3 | 4 | inputs = { 5 | 6 | # System 7 | 8 | ## Package repositories 9 | 10 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 11 | nixpkgs-nixos.url = "github:NixOS/nixpkgs/nixos-unstable"; 12 | nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; 13 | 14 | # See https://lix.systems/add-to-config/#flake-based-configurations for the latest version 15 | lix-module.url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz"; 16 | lix-module.inputs.nixpkgs.follows = "nixpkgs"; 17 | 18 | nix-index-database.url = "github:nix-community/nix-index-database"; 19 | nix-index-database.inputs.nixpkgs.follows = "nixpkgs"; 20 | 21 | brew-api.url = "github:BatteredBunny/brew-api"; 22 | brew-api.flake = false; 23 | brew-nix.url = "github:LukeChannings/brew-nix"; 24 | brew-nix.inputs.nixpkgs.follows = "nixpkgs"; 25 | brew-nix.inputs.nix-darwin.follows = "nixpkgs"; 26 | brew-nix.inputs.brew-api.follows = "brew-api"; 27 | 28 | ## Supporting configuration modules 29 | darwin.url = "github:LnL7/nix-darwin"; 30 | darwin.inputs.nixpkgs.follows = "nixpkgs"; 31 | 32 | home-manager.url = "github:nix-community/home-manager"; 33 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 34 | 35 | ## Secrets 36 | 37 | sops-nix.url = "github:Mic92/sops-nix"; 38 | sops-nix.inputs.nixpkgs.follows = "nixpkgs"; 39 | 40 | ### Temporarily using https://github.com/1Password/shell-plugins/pull/503 until merged 41 | ### _1password-shell-plugins.url = "github:1Password/shell-plugins"; 42 | _1password-shell-plugins.url = "github:LukeChannings/1password-shell-plugins/5ef7244"; 43 | _1password-shell-plugins.inputs.nixpkgs.follows = "nixpkgs"; 44 | 45 | ## Deployment 46 | colmena.url = "github:zhaofengli/colmena"; 47 | colmena.inputs.nixpkgs.follows = "nixpkgs"; 48 | colmena.inputs.stable.follows = "nixpkgs"; 49 | 50 | # Dev 51 | 52 | ## Nix 53 | 54 | devenv-root.url = "file+file:///dev/null"; 55 | devenv-root.flake = false; 56 | 57 | flake-parts.url = "github:hercules-ci/flake-parts"; 58 | 59 | devenv.url = "github:cachix/devenv"; 60 | 61 | treefmt-nix.url = "github:numtide/treefmt-nix"; 62 | 63 | ## Not Nix... 64 | 65 | vscode-extensions.url = "github:nix-community/nix-vscode-extensions"; 66 | 67 | helix.url = "helix"; 68 | helix.inputs.nixpkgs.follows = "nixpkgs"; 69 | 70 | toolbox.url = "github:lukechannings/toolbox"; 71 | toolbox.inputs.nixpkgs.follows = "nixpkgs"; 72 | toolbox.inputs.flake-parts.follows = "flake-parts"; 73 | toolbox.inputs.devenv.follows = "devenv"; 74 | }; 75 | 76 | outputs = 77 | inputs@{ 78 | self, 79 | flake-parts, 80 | nixpkgs, 81 | ... 82 | }: 83 | flake-parts.lib.mkFlake { inherit inputs; } { 84 | imports = [ 85 | flake-parts.flakeModules.modules 86 | inputs.devenv.flakeModule 87 | inputs.treefmt-nix.flakeModule 88 | ./devenv.nix 89 | ./config 90 | ./templates 91 | ./modules 92 | ]; 93 | 94 | systems = [ 95 | "aarch64-darwin" 96 | "x86_64-darwin" 97 | 98 | "x86_64-linux" 99 | "aarch64-linux" 100 | ]; 101 | 102 | flake.vscode.systemExtensions = 103 | (nixpkgs.lib.importJSON ./.devcontainer.json).customizations.vscode.extensions; 104 | 105 | flake.overlays = { 106 | vscode-extensions = inputs.vscode-extensions.overlays.default; 107 | lix = inputs.lix-module.overlays.default; 108 | helix = inputs.helix.overlays.default; 109 | }; 110 | 111 | perSystem = 112 | { 113 | pkgs, 114 | lib, 115 | system, 116 | ... 117 | }: 118 | { 119 | packages = { 120 | inherit (inputs.home-manager.packages.${system}) home-manager; 121 | }; 122 | 123 | legacyPackages.homeConfigurations.luke = self.lib.mkHomeManagerConfiguration { 124 | inherit pkgs; 125 | 126 | user.name = "luke"; 127 | 128 | disabledModules = [ 129 | "chromium" 130 | "wezterm" 131 | "vscode" 132 | "fonts" 133 | ]; 134 | 135 | config.dotfiles.defaultPackages.enableMacUtilities = false; 136 | }; 137 | }; 138 | }; 139 | } 140 | -------------------------------------------------------------------------------- /modules/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: { 2 | flake.modules.homeManager = { 3 | default-packages = import ./homeManager/default-packages.nix; 4 | smallstep = import ./homeManager/smallstep.nix; 5 | }; 6 | 7 | flake.flakeModules = { 8 | colmena = import ./flakeModules/colmena.nix; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /modules/flakeModules/colmena.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | lib, 4 | config, 5 | ... 6 | }: 7 | let 8 | inherit (lib) 9 | mkOption 10 | types 11 | ; 12 | inherit (inputs.colmena.lib) makeHive; 13 | inherit (inputs.colmena.nixosModules) metaOptions; 14 | in 15 | { 16 | options = { 17 | flake.colmena = mkOption { 18 | type = types.submodule { 19 | freeformType = types.lazyAttrsOf types.raw; 20 | 21 | options.meta = mkOption { 22 | type = types.submodule (metaOptions { 23 | inherit lib; 24 | }); 25 | default = { }; 26 | }; 27 | }; 28 | 29 | default = { }; 30 | }; 31 | }; 32 | 33 | config = { 34 | flake.colmenaHive = makeHive config.flake.colmena; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /modules/homeManager/default-packages.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | config, 5 | ... 6 | }: 7 | let 8 | macUtilities = { 9 | inherit (pkgs.brewCasks) 10 | apparency 11 | suspicious-package 12 | the-unarchiver 13 | 14 | raycast 15 | maccy 16 | swish 17 | contexts 18 | 19 | hot 20 | monitorcontrol 21 | ; 22 | }; 23 | 24 | cliTools = { 25 | inherit (pkgs) 26 | # File Management 27 | tree 28 | ncdu 29 | 30 | # Networking 31 | dig 32 | curl 33 | jq 34 | 35 | # Other 36 | ripgrep 37 | chafa 38 | 39 | # Nix 40 | nix-top 41 | ; 42 | }; 43 | 44 | cfg = config.dotfiles; 45 | in 46 | with lib; 47 | { 48 | options.dotfiles.defaultPackages = mkOption { 49 | type = types.submodule { 50 | options = { 51 | enable = mkOption { 52 | type = types.bool; 53 | default = true; 54 | description = "Whether to enable the default package set"; 55 | }; 56 | 57 | enableMacUtilities = mkOption { 58 | type = types.bool; 59 | default = pkgs.stdenv.isDarwin; 60 | }; 61 | 62 | enableCliTools = mkOption { 63 | type = types.bool; 64 | default = true; 65 | }; 66 | 67 | disabledPackageNames = mkOption { 68 | type = types.listOf types.str; 69 | default = [ ]; 70 | }; 71 | 72 | packages = mkOption { 73 | type = types.attrsOf types.package; 74 | internal = true; 75 | default = 76 | (if cfg.defaultPackages.enableMacUtilities then macUtilities else { }) 77 | // (if cfg.defaultPackages.enableCliTools then cliTools else { }); 78 | }; 79 | }; 80 | }; 81 | default = { }; 82 | }; 83 | 84 | options.dotfiles.loginItems = mkOption { 85 | type = types.attrsOf (types.either types.package types.str); 86 | default = { }; 87 | }; 88 | 89 | config = { 90 | home.packages = attrValues ( 91 | removeAttrs cfg.defaultPackages.packages cfg.defaultPackages.disabledPackageNames 92 | ); 93 | 94 | launchd.agents = lib.mkIf (cfg.loginItems != { }) ( 95 | builtins.mapAttrs (name: pkg: { 96 | enable = true; 97 | config.Program = "${pkg}/Contents/MacOS/${name}"; 98 | config.RunAtLoad = true; 99 | config.KeepAlive = true; 100 | }) cfg.loginItems 101 | ); 102 | }; 103 | } 104 | -------------------------------------------------------------------------------- /modules/homeManager/smallstep.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | config, 5 | ... 6 | }: 7 | with lib; 8 | with builtins; 9 | let 10 | authorityModule = types.submodule { 11 | options = { 12 | caUrl = mkOption { 13 | type = types.str; 14 | }; 15 | redirectUrl = mkOption { 16 | type = types.str; 17 | default = ""; 18 | }; 19 | fingerprint = mkOption { 20 | type = types.str; 21 | }; 22 | certFile = mkOption { 23 | type = types.path; 24 | }; 25 | defaults = mkOption { 26 | type = types.attrs; 27 | default = { }; 28 | }; 29 | }; 30 | }; 31 | cfg = config.programs.smallstep; 32 | in 33 | { 34 | options.programs.smallstep = { 35 | enable = mkEnableOption "Enable step-cli"; 36 | 37 | defaultAuthority = mkOption { 38 | type = types.nullOr types.str; 39 | default = null; 40 | }; 41 | 42 | authorities = mkOption { 43 | type = types.attrsOf authorityModule; 44 | default = { }; 45 | }; 46 | }; 47 | 48 | config = mkIf cfg.enable { 49 | home.packages = [ pkgs.step-cli ]; 50 | 51 | home.file = mkIf (cfg.authorities != { }) ( 52 | mkMerge ( 53 | (map ( 54 | { name, value }: 55 | { 56 | ".step/authorities/${name}/config/defaults.json".text = ( 57 | toJSON { 58 | "ca-url" = value.caUrl; 59 | "redirect-url" = value.redirectUrl; 60 | "fingerprint" = value.fingerprint; 61 | "root" = value.certFile; 62 | } 63 | ); 64 | ".step/authorities/${name}/certs/root_ca".source = value.certFile; 65 | ".step/profiles/${name}/config/defaults.json".text = (toJSON value.defaults); 66 | } 67 | ) (attrsToList cfg.authorities)) 68 | ++ [ 69 | { 70 | ".step/contexts.json".text = ( 71 | toJSON ( 72 | mapAttrs (name: value: { 73 | profile = name; 74 | authority = name; 75 | }) cfg.authorities 76 | ) 77 | ); 78 | ".step/default-context.json".text = mkIf (cfg.defaultAuthority != null) ( 79 | toJSON ({ 80 | context = cfg.defaultAuthority; 81 | }) 82 | ); 83 | } 84 | ] 85 | ) 86 | ); 87 | 88 | home.activation = mkIf (cfg.defaultAuthority != null) { 89 | smallstep = lib.hm.dag.entryAfter [ "writeBoundary" ] '' 90 | if [ ! -f "$HOME/.step/current-context.json" ]; then 91 | run cp -s $VERBOSE_ARG "$HOME/.step/default-context.json" "$HOME/.step/current-context.json" 92 | fi 93 | ''; 94 | }; 95 | }; 96 | } 97 | -------------------------------------------------------------------------------- /scripts/diff-flake-lock.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i perl --packages perlPackages.JSON 3 | 4 | use strict; 5 | use warnings; 6 | 7 | use JSON; 8 | 9 | use Term::ANSIColor; 10 | use File::Slurp; 11 | use Time::Piece; 12 | 13 | # Decode the lock files 14 | my $old_lock = decode_json `git show HEAD:flake.lock`; 15 | my $new_lock = decode_json( read_file('flake.lock') ); 16 | 17 | print "\n"; 18 | 19 | foreach my $key ( keys %{ $new_lock->{nodes} } ) { 20 | if ( exists $old_lock->{nodes}{$key} 21 | && exists $new_lock->{nodes}{$key}{locked} 22 | && defined $old_lock->{nodes}{$key}{locked}{type} 23 | && defined $old_lock->{nodes}{$key}{locked}{rev} 24 | && $new_lock->{nodes}{$key}{locked}{type} eq "github" ) 25 | { 26 | my $new = $new_lock->{nodes}{$key}{locked}; 27 | my $old = $old_lock->{nodes}{$key}{locked}; 28 | 29 | # Compare 'rev' values 30 | if ( $new->{rev} ne $old->{rev} ) { 31 | my $old_modified_date = localtime( $old->{lastModified} ); 32 | my $days_since_modified = 33 | int( ( $new->{lastModified} - $old->{lastModified} ) / 34 | ( 60 * 60 * 24 ) ); 35 | 36 | print color('bold'), "Updated input '$key':", color('reset'), "\n"; 37 | print "Last modified: " 38 | . $old_modified_date->strftime("%d-%m-%Y") 39 | . " ($days_since_modified days ago)" . "\n"; 40 | print "Compare: " 41 | . color('blue') 42 | . "https://github.com/$new->{owner}/$new->{repo}/compare/$old->{rev}...$new->{rev}?diff=unified&w=" 43 | . color("reset") . "\n\n"; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /scripts/update-flake-inputs.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash --packages curl jq 3 | 4 | set -x 5 | 6 | NIXPKGS_STATUS="$(curl -s "https://prometheus.nixos.org/api/v1/query?query=channel_revision")" 7 | 8 | NIXPKGS_REV="$(echo "$NIXPKGS_STATUS" | jq -r '.data.result[] | select(.metric.channel == "nixpkgs-unstable") | .metric.revision')" 9 | NIXOS_REV="$(echo "$NIXPKGS_STATUS" | jq -r '.data.result[] | select(.metric.channel == "nixos-unstable") | .metric.revision')" 10 | NIXPKGS_STABLE_REV="$(echo "$NIXPKGS_STATUS" | jq -r '.data.result[] | select(.metric.channel == "nixos-24.11") | .metric.revision')" 11 | 12 | nix flake update \ 13 | --override-input nixpkgs "github:NixOS/nixpkgs/${NIXPKGS_REV}" \ 14 | --override-input nixpkgs-stable "github:NixOS/nixpkgs/${NIXPKGS_STABLE_REV}" \ 15 | --override-input nixpkgs-nixos "github:NixOS/nixpkgs/${NIXOS_REV}" 16 | -------------------------------------------------------------------------------- /templates/darwin-system/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .devenv 3 | .direnv 4 | .vscode 5 | .env 6 | result 7 | -------------------------------------------------------------------------------- /templates/darwin-system/configuration.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | let 3 | inherit (builtins) attrValues; 4 | inherit (inputs) dotfiles darwin; 5 | in 6 | { 7 | flake.darwinConfigurations.default = darwin.lib.darwinSystem { 8 | system = "aarch64-darwin"; 9 | 10 | inherit inputs; 11 | 12 | modules = [ 13 | (dotfiles.lib.configureOsModules { 14 | osModules = attrValues dotfiles.modules.darwin; 15 | homeModules = attrValues dotfiles.modules.homeManager; 16 | }) 17 | ( 18 | let 19 | username = "runner"; 20 | in 21 | { ... }: 22 | { 23 | users = { 24 | knownUsers = [ username ]; 25 | 26 | users.${username} = { 27 | home = "/Users/${username}"; 28 | uid = 502; 29 | }; 30 | }; 31 | } 32 | ) 33 | ]; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /templates/darwin-system/devenv.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.devenv.flakeModule 5 | inputs.treefmt-nix.flakeModule 6 | ]; 7 | 8 | perSystem = 9 | { 10 | config, 11 | pkgs, 12 | lib, 13 | system, 14 | ... 15 | }: 16 | { 17 | treefmt = { 18 | projectRoot = ./.; 19 | projectRootFile = "flake.nix"; 20 | 21 | programs.nixfmt.enable = true; 22 | programs.deadnix.enable = true; 23 | programs.biome = { 24 | enable = true; 25 | settings.formatter.indentStyle = "space"; 26 | }; 27 | }; 28 | 29 | devenv.shells.default = { 30 | devenv.root = 31 | let 32 | devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath; 33 | in 34 | pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; 35 | 36 | imports = [ inputs.toolbox.modules.devenv.vscode-workspace ]; 37 | 38 | vscode-workspace = { 39 | extensions = with inputs.vscode-extensions.extensions.${system}.vscode-marketplace; [ 40 | jnoortheen.nix-ide 41 | ibecker.treefmt-vscode 42 | ]; 43 | 44 | settings = { 45 | nix = { 46 | enableLanguageServer = true; 47 | serverPath = lib.getExe pkgs.nil; 48 | }; 49 | 50 | treefmt = { 51 | command = lib.getExe config.treefmt.package; 52 | config = config.treefmt.build.configFile; 53 | }; 54 | 55 | editor.defaultFormatter = "ibecker.treefmt-vscode"; 56 | }; 57 | }; 58 | }; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /templates/darwin-system/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Configuration for Luke's Work MacBook Pro"; 3 | 4 | inputs = { 5 | devenv-root.url = "file+file:///dev/null"; 6 | devenv-root.flake = false; 7 | 8 | dotfiles.url = "dotfiles"; 9 | dotfiles.inputs.devenv-root.follows = "devenv-root"; 10 | }; 11 | 12 | outputs = 13 | inputs@{ dotfiles, self, ... }: 14 | let 15 | inputs' = dotfiles.inputs // inputs; 16 | in 17 | inputs'.flake-parts.lib.mkFlake { inputs = inputs'; } { 18 | imports = [ 19 | ./devenv.nix 20 | ./configuration.nix 21 | ]; 22 | 23 | systems = [ 24 | "aarch64-darwin" 25 | "x86_64-darwin" 26 | 27 | "x86_64-linux" 28 | "aarch64-linux" 29 | ]; 30 | 31 | perSystem = 32 | { system, ... }: 33 | let 34 | pkgs = inputs'.nixpkgs.legacyPackages.${system}; 35 | in 36 | { 37 | _module.args.pkgs = pkgs; 38 | 39 | packages = 40 | let 41 | inherit (inputs.dotfiles.inputs.nix-darwin.packages.${system}) darwin-rebuild; 42 | in 43 | { 44 | inherit darwin-rebuild; 45 | 46 | activate = pkgs.writeScriptBin "activate" '' 47 | #!${pkgs.bash}/bin/bash 48 | sudo rm -rf ~/.nix-defexpr 49 | sudo mv /etc/nix/nix.conf /etc/nix/nix.conf.before-nix-darwin 50 | export NIX_CONFIG="experimental-features = nix-command flakes" 51 | ${darwin-rebuild}/bin/darwin-rebuild switch --flake ${self}#default 52 | ''; 53 | }; 54 | }; 55 | }; 56 | 57 | nixConfig = { 58 | extra-substituters = [ 59 | "https://devenv.cachix.org" 60 | "https://luke-channings.cachix.org" 61 | ]; 62 | extra-trusted-public-keys = [ 63 | "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" 64 | "luke-channings.cachix.org-1:ETsZ3R5ue9QOwO4spg8aGJMwMU6k5tQIaHWnTakGHjo=" 65 | ]; 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /templates/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | flake.templates = { 4 | darwin-system = { 5 | description = "Create a nix-darwin system configuration"; 6 | path = ./darwin-system; 7 | }; 8 | 9 | dev-base = { 10 | description = "A barebones TypeScript frontend environment"; 11 | path = ./dev-base; 12 | }; 13 | 14 | dev-fe-ts = { 15 | description = "A barebones TypeScript frontend environment"; 16 | path = ./dev-fe-typescript; 17 | }; 18 | 19 | shell-nodejs = { 20 | description = "A NodeJS shell"; 21 | path = ./shell-nodejs; 22 | }; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /templates/dev-base/.envrc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Docs: https://direnv.net/man/direnv-stdlib.1.html 4 | 5 | watch_file flake.nix 6 | watch_file flake.lock 7 | watch_file devenv.nix 8 | 9 | DEVENV_ROOT_FILE="$(mktemp)" 10 | printf %s "$PWD" > "$DEVENV_ROOT_FILE" 11 | if ! use flake . --impure --override-input devenv-root "file+file://$DEVENV_ROOT_FILE" 12 | then 13 | echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 14 | fi 15 | -------------------------------------------------------------------------------- /templates/dev-base/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .devenv 3 | .direnv 4 | .vscode 5 | .env 6 | result 7 | -------------------------------------------------------------------------------- /templates/dev-base/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | devenv-root.url = "file+file:///dev/null"; 4 | devenv-root.flake = false; 5 | 6 | # nix registry add flake:dotfiles github:lukechannings/dotfiles 7 | dotfiles.url = "dotfiles"; 8 | dotfiles.inputs.devenv-root.follows = "devenv-root"; 9 | }; 10 | 11 | outputs = 12 | flakeInputs@{ 13 | dotfiles, 14 | self, 15 | ... 16 | }: 17 | let 18 | # I want to use the inputs from dotfiles in this flake 19 | # to avoid re-declaring those inputs and maintaining the 20 | # same versions. 21 | inputs = dotfiles.inputs // flakeInputs; 22 | 23 | inherit (inputs) 24 | nixpkgs 25 | treefmt-nix 26 | devenv 27 | ; 28 | in 29 | inputs.flake-parts.lib.mkFlake 30 | { 31 | inherit inputs; 32 | # I need to update `self.inputs` to be our merged inputs 33 | # otherwise `perSystem's inputs'` will be sourced from `flakeInputs` only. 34 | self = self // { 35 | inherit inputs; 36 | }; 37 | } 38 | { 39 | imports = [ 40 | treefmt-nix.flakeModule 41 | devenv.flakeModule 42 | 43 | ./devenv.nix 44 | ]; 45 | 46 | systems = [ 47 | "aarch64-darwin" 48 | "x86_64-darwin" 49 | 50 | "x86_64-linux" 51 | "aarch64-linux" 52 | ]; 53 | 54 | perSystem = 55 | { 56 | pkgs, 57 | system, 58 | ... 59 | }: 60 | { 61 | _module.args.pkgs = import nixpkgs { 62 | inherit system; 63 | overlays = [ dotfiles.overlays.vscode-extensions ]; 64 | }; 65 | }; 66 | }; 67 | 68 | nixConfig = { 69 | extra-substituters = [ "https://luke-channings.cachix.org" ]; 70 | extra-trusted-public-keys = [ 71 | "luke-channings.cachix.org-1:ETsZ3R5ue9QOwO4spg8aGJMwMU6k5tQIaHWnTakGHjo=" 72 | ]; 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /templates/dev-fe-typescript/devenv.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | perSystem = 4 | { 5 | pkgs, 6 | lib, 7 | ... 8 | }: 9 | { 10 | treefmt = { 11 | projectRootFile = "./flake.nix"; 12 | 13 | # TODO: Tailor these formatters for the current project 14 | programs.nixfmt.enable = true; 15 | programs.deadnix.enable = true; 16 | programs.biome = { 17 | enable = true; 18 | settings.formatter.indentStyle = "space"; 19 | }; 20 | programs.fish_indent.enable = true; 21 | programs.stylua.enable = true; 22 | programs.shellcheck.enable = true; 23 | }; 24 | 25 | devenv.shells.default = { 26 | devenv.root = 27 | let 28 | devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath; 29 | in 30 | pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; 31 | 32 | imports = [ inputs.toolbox.modules.devenv.vscode-workspace ]; 33 | 34 | dotenv.enable = true; 35 | 36 | devcontainer.enable = true; 37 | 38 | languages.shell.enable = true; 39 | languages.javascript.enable = true; 40 | languages.javascript.package = pkgs.nodejs_23; 41 | languages.javascript.corepack.enable = true; 42 | languages.javascript.npm.enable = true; 43 | languages.javascript.npm.install.enable = true; 44 | languages.typescript.enable = true; 45 | 46 | devcontainer.settings.customizations.vscode.extensions = [ "mkhl.direnv" ]; 47 | devcontainer.settings.updateContentCommand = ""; 48 | 49 | vscode-workspace = { 50 | extensions = with pkgs.vscode-marketplace; [ 51 | jnoortheen.nix-ide 52 | ]; 53 | 54 | settings = { 55 | nix = { 56 | enableLanguageServer = true; 57 | serverPath = lib.getExe pkgs.nil; 58 | }; 59 | 60 | editor.defaultFormatter = "ibecker.treefmt-vscode"; 61 | }; 62 | }; 63 | }; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /templates/dev-fe-typescript/index.ts: -------------------------------------------------------------------------------- 1 | console.log("Hello world"); 2 | -------------------------------------------------------------------------------- /templates/dev-fe-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev-fe-ts", 3 | "main": "index.ts", 4 | "scripts": { 5 | "start": "tsx ." 6 | }, 7 | "devDependencies": { 8 | "tsx": "^4.19.2" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /templates/dev-fe-typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "nodenext", 5 | "allowImportingTsExtensions": true, 6 | "rewriteRelativeImportExtensions": true, 7 | "verbatimModuleSyntax": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/shell-nodejs/.envrc: -------------------------------------------------------------------------------- 1 | use nix 2 | layout node -------------------------------------------------------------------------------- /templates/shell-nodejs/shell.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs ? import { }, 3 | }: 4 | with pkgs; 5 | mkShell { 6 | packages = [ nodejs_22 yarn ]; 7 | } 8 | --------------------------------------------------------------------------------