{ lib, pkgs, config, ... }: let inherit (lib) mkOption mkIf types; in { options = { type = mkOption { type = types.enum [ "qmk" ]; }; qmk = { qmk_firmware = mkOption { type = types.path; default = pkgs.qmk_firmware; description = '' qmk firmware path ''; }; keyboard = { name = mkOption { type = types.str; description = "keyboard path"; example = "4pplet/steezy60"; }; revision = mkOption { type = types.nullOr types.str; default = null; description = "keyboard revision"; example = "rev_a"; }; _path = mkOption { type = types.str; internal = true; default = lib.concatStringsSep "/" ([config.qmk.keyboard.name] ++ lib.optional (config.qmk.keyboard.revision != null) config.qmk.keyboard.revision); }; }; keymap = { name = mkOption { type = types.str; default = "default"; description = "keymap name"; }; src = mkOption { type = types.nullOr types.path; default = null; description = "qmk keymap files"; }; _path = mkOption { type = types.str; internal = true; default = "keyboards/${config.qmk.keyboard.name}/keymaps/${config.qmk.keymap.name}"; }; }; build = { bin = mkOption { type = types.path; internal = true; readOnly = true; default = let ksrc = config.qmk.keymap.src; in pkgs.stdenv.mkDerivation { name = "qmk:${config.qmk.keyboard._path}:${config.qmk.keymap.name}"; src = config.qmk.qmk_firmware; allowSubstitutes = false; # hardeningDisable = [ "pic" "pie" ]; nativeBuildInputs = [ pkgs.qmk ]; # dontFixup = true; postPatch = lib.optionalString (ksrc != null) /* bash */ '' mkdir -pv "${config.qmk.keymap._path}" cp -v "${ksrc}"/* "${config.qmk.keymap._path}" ''; buildPhase = /* bash */ '' runHook preBuild qmk compile \ --env SKIP_GIT=yes \ --env BUILD_DIR=build \ --env SKIP_VERSION=yes \ --env VERBOSE=true \ --keyboard "${config.qmk.keyboard._path}" \ --keymap "${config.qmk.keymap.name}" runHook postBuild ''; installPhase = '' mkdir -p $out cp -v build/*.{bin,hex,elf,dfu,uf2,eep} $out ''; }; }; flash = mkOption { type = types.functionTo <| types.either types.package types.str; default = hex: '' "${pkgs.dfu-util}/bin/dfu-util" --alt 0 --dfuse-address 0x08000000:leave -D "${hex}.hex" ''; }; }; }; }; config = mkIf (config.type == "qmk") { build.flash = let p = lib.replaceStrings [ "/" ":" ] [ "_" "_" ] "${config.qmk.keyboard._path}:${config.qmk.keymap.name}"; n = config.qmk.build.flash "${builtins.toString config.qmk.build.bin}/${p}"; in if builtins.isString n then pkgs.writeShellApplication { name = "flash"; text = n; } else n; }; }