nix-configs/modules/input/evremap.nix
2024-03-05 17:10:35 +01:00

110 lines
3.4 KiB
Nix

{
pkgs,
config,
lib,
utils,
...
}: let
cfg = config.jade.input.remapping;
evremap = pkgs.rustPlatform.buildRustPackage {
pname = "evremap";
version = "0.1.0";
src = pkgs.fetchFromGitHub {
owner = "wez";
repo = "evremap";
rev = "4480c4eda223b98899b0fbd926bc34f7bd0e1a18";
sha256 = "sha256-BxSrphgW1n465FX6bKVkq6O0XE2JqanfSYlsGwWUWkQ=";
};
cargoHash = "";
cargoLock.lockFile = ../../other/evremap.Cargo.lock;
postPatch = ''
cp ${../../other/evremap.Cargo.lock} Cargo.lock
'';
nativeBuildInputs = [pkgs.pkg-config];
buildInputs = [pkgs.libevdev];
};
toml = pkgs.formats.toml {};
in
with lib; {
options.jade.input.remapping = {
enable = mkEnableOption "Enable evremap";
devices = mkOption {
type = types.attrsOf (types.submodule ({name, ...}: {
options = {
device_name = mkOption {
type = types.str;
description = "The device name";
default = name;
};
remap = mkOption {
type = types.listOf (types.submodule ({...}: {
options.input = mkOption {type = types.listOf types.str;};
options.output = mkOption {type = types.listOf types.str;};
}));
default = [];
};
swapKeys = mkOption {
description = "Lists with two keys to be swapped on the keyboard layout.";
type = types.listOf (
# verify that each key swapping list contains two elements
types.addCheck (types.listOf types.str) (v: builtins.length v == 2)
);
default = [];
};
dual_role = mkOption {
type = types.listOf (types.submodule ({...}: {
options.input = mkOption {type = types.str;};
options.hold = mkOption {type = types.listOf types.str;};
options.tap = mkOption {type = types.listOf types.str;};
}));
default = [];
};
};
}));
};
};
config = mkIf cfg.enable (
with builtins; let
devs = map ({
device_name,
remap,
swapKeys,
dual_role,
}: {
inherit device_name dual_role;
# expand swapKeys to normal remaps
remap = concatLists [
remap
(lib.lists.flatten (map (keys: [
{
input = [(head keys)];
output = [(lib.lists.last keys)];
}
{
input = [(lib.lists.last keys)];
output = [(head keys)];
}
])
swapKeys))
];
}) (attrValues cfg.devices);
in {
# generate numbered systemd services for each device to be remapped
# https://github.com/wez/evremap/issues/17
systemd.services = listToAttrs (genList (i: {
name = "evremap${toString i}";
value = let
cfgFile = toml.generate "remaps-${toString i}.toml" (elemAt devs i);
in {
script = "${evremap}/bin/evremap remap ${cfgFile}";
wantedBy = ["multi-user.target"];
unitConfig = {
Restart = "on-failure";
};
};
}) (length devs));
environment.systemPackages = [evremap];
}
);
}