nix-configs/modules/input/evremap.nix

133 lines
3.8 KiB
Nix

{
pkgs,
config,
lib,
...
}:
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=";
};
useFetchCargoVendor = true;
cargoHash = "sha256-O1rJ48m8Q7kZABw/UNpmUT7FFBWQedo6CuV+NX9kDt8=";
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
{
wantedBy = [ "multi-user.target" ];
serviceConfig.ExecStart = "-${evremap}/bin/evremap remap ${cfgFile}";
unitConfig = {
Restart = "on-failure";
};
};
}) (length devs)
);
environment.systemPackages = [ evremap ];
}
);
}