about summary refs log tree commit diff
path: root/nixos/modules/services/hardware/kanata.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/hardware/kanata.nix')
-rw-r--r--nixos/modules/services/hardware/kanata.nix76
1 files changed, 45 insertions, 31 deletions
diff --git a/nixos/modules/services/hardware/kanata.nix b/nixos/modules/services/hardware/kanata.nix
index 333b2d2a88a55..60fb33881f256 100644
--- a/nixos/modules/services/hardware/kanata.nix
+++ b/nixos/modules/services/hardware/kanata.nix
@@ -5,7 +5,9 @@ with lib;
 let
   cfg = config.services.kanata;
 
-  keyboard = {
+  upstreamDoc = "See [the upstream documentation](https://github.com/jtroo/kanata/blob/main/docs/config.adoc) and [example config files](https://github.com/jtroo/kanata/tree/main/cfg_samples) for more information.";
+
+  keyboard = { name, config, ... }: {
     options = {
       devices = mkOption {
         type = types.listOf types.str;
@@ -22,28 +24,16 @@ let
         type = types.lines;
         example = ''
           (defsrc
-            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
-            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
-            caps a    s    d    f    g    h    j    k    l    ;    '    ret
-            lsft z    x    c    v    b    n    m    ,    .    /    rsft
-            lctl lmet lalt           spc            ralt rmet rctl)
-
-          (deflayer qwerty
-            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
-            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
-            @cap a    s    d    f    g    h    j    k    l    ;    '    ret
-            lsft z    x    c    v    b    n    m    ,    .    /    rsft
-            lctl lmet lalt           spc            ralt rmet rctl)
-
-          (defalias
-            ;; tap within 100ms for capslk, hold more than 100ms for lctl
-            cap (tap-hold 100 100 caps lctl))
+            caps)
+
+          (deflayermap (default-layer)
+            ;; tap caps lock as caps lock, hold caps lock as left control
+            caps (tap-hold 100 100 caps lctl))
         '';
         description = ''
           Configuration other than `defcfg`.
 
-          See [example config files](https://github.com/jtroo/kanata)
-          for more information.
+          ${upstreamDoc}
         '';
       };
       extraDefCfg = mkOption {
@@ -55,8 +45,22 @@ let
           from the devices option) and
           `linux-continue-if-no-devs-found` (hardcoded to be yes).
 
-          See [example config files](https://github.com/jtroo/kanata)
-          for more information.
+          ${upstreamDoc}
+        '';
+      };
+      configFile = mkOption {
+        type = types.path;
+        default = mkConfig name config;
+        defaultText =
+          "A config file generated by values from other kanata module options.";
+        description = ''
+          The config file.
+
+          By default, it is generated by values from other kanata
+          module options.
+
+          You can also set it to your own full config file which
+          overrides all other kanata module options.  ${upstreamDoc}
         '';
       };
       extraArgs = mkOption {
@@ -86,14 +90,24 @@ let
     in
     optionalString ((length devices) > 0) "linux-dev (${devicesString})";
 
-  mkConfig = name: keyboard: pkgs.writeText "${mkName name}-config.kdb" ''
-    (defcfg
-      ${keyboard.extraDefCfg}
-      ${mkDevices keyboard.devices}
-      linux-continue-if-no-devs-found yes)
-
-    ${keyboard.config}
-  '';
+  mkConfig = name: keyboard: pkgs.writeTextFile {
+    name = "${mkName name}-config.kdb";
+    text = ''
+      (defcfg
+        ${keyboard.extraDefCfg}
+        ${mkDevices keyboard.devices}
+        linux-continue-if-no-devs-found yes)
+
+      ${keyboard.config}
+    '';
+    # Only the config file generated by this module is checked.  A
+    # user-provided one is not checked because it may not be available
+    # at build time.  I think this is a good balance between module
+    # complexity and functionality.
+    checkPhase = ''
+      ${getExe cfg.package} --cfg "$target" --check --debug
+    '';
+  };
 
   mkService = name: keyboard: nameValuePair (mkName name) {
     wantedBy = [ "multi-user.target" ];
@@ -101,7 +115,7 @@ let
       Type = "notify";
       ExecStart = ''
         ${getExe cfg.package} \
-          --cfg ${mkConfig name keyboard} \
+          --cfg ${keyboard.configFile} \
           --symlink-path ''${RUNTIME_DIRECTORY}/${name} \
           ${optionalString (keyboard.port != null) "--port ${toString keyboard.port}"} \
           ${utils.escapeSystemdExecArgs keyboard.extraArgs}
@@ -153,7 +167,7 @@ in
   options.services.kanata = {
     enable = mkEnableOption "kanata, a tool to improve keyboard comfort and usability with advanced customization";
     package = mkPackageOption pkgs "kanata" {
-      example = "kanata-with-cmd";
+      example = [ "kanata-with-cmd" ];
       extraDescription = ''
         ::: {.note}
         If {option}`danger-enable-cmd` is enabled in any of the keyboards, the