Micron Document
a keyd service in Guix

It took a really long time to figure this out, but I can finally use keyd in Guix.

I started out with a manually created T383838keyd.conf file and I manually invoked keyd with T383838sudo so I could get my default bindings. This also helped to verify some of the pieces worked before I started.

about the keyd config

I tend to use small keyboards and so I've gotten used to what might sound like a peculiar mapping. I like the caps lock key to be a super if held down or a tab if pressed. I like the tab key to be an escape key or an alt key. And I like the left shift double as an escape key when tapped. Here's what the keyd.conf would look like for this:

[ids]
*

[main]
capslock=overload(meta, tab)
esc=tilde
leftshift=overload(shift, esc)
tab=overload(alt, esc)

I wanted to define a service to create the etc file for me instead of manually placing such a file.

the Guix config

It took weeks of trial and error and I can't even explain how I got here or even if it's really correct. I couldn't understand the documentation I was able to find and when I tried to use AI to generate something, nothing that it generated seemed to do anything. But this is the service that I ended up defining:

T282828
Tb4b4b4(Tff7b72define Te6edf3keyd-service-type
Tb4b4b4(Td2a8ffservice-type
Tb4b4b4(Td2a8ffname Ta5d6ff'keydTb4b4b4)
Tb4b4b4(Td2a8ffextensions
Tb4b4b4(Tffa657list Tb4b4b4(Td2a8ffservice-extension Te6edf3etc-service-type
Tb4b4b4(Tff7b72lambda Tb4b4b4(Td2a8ffconfigTb4b4b4)
Tff7b72`Tb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6ffkeyd/keyd.confTa5d6ff"
Tff7b72,Tb4b4b4(Td2a8ffplain-file Ta5d6ff"Ta5d6ffkeyd.confTa5d6ff" Te6edf3configTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffservice-extension Te6edf3shepherd-root-service-type
Tb4b4b4(Tff7b72lambda Tb4b4b4(Td2a8ffconfigTb4b4b4)
Tb4b4b4(Tffa657list Tb4b4b4(Td2a8ffshepherd-service
Tb4b4b4(Td2a8ffprovision Tff7b72'Tb4b4b4(Te6edf3keydTb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffdocumentation Ta5d6ff"Ta5d6ffkeyd keyboard remapping daemonTa5d6ff"Tb4b4b4)
Tb4b4b4(Td2a8ffrequirement Tff7b72'Tb4b4b4(Te6edf3user-processesTb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffauto-start? Tff7b72#tTb4b4b4)
Tb4b4b4(Td2a8ffstart Tff7b72#Te6edf3~Tb4b4b4(Td2a8ffmake-forkexec-constructor
Tb4b4b4(Tffa657list Tff7b72#Te6edf3$Tb4b4b4(Td2a8fffile-append Te6edf3keyd Ta5d6ff"Ta5d6ff/bin/keydTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72#:log-file Ta5d6ff"Ta5d6ff/var/log/keyd.logTa5d6ff"Tb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffstop Tff7b72#Te6edf3~Tb4b4b4(Td2a8ffmake-kill-destructorTb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffrespawn? Tff7b72#fTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffdefault-value Tb4b4b4(Tffa657apply Tffa657string-append Tb4b4b4(Tffa657list
Ta5d6ff"Ta5d6ff[ids]Ta5d6ff" Ta5d6ff"Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff*Ta5d6ff" Ta5d6ff"Tffea00\nTffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff[main]Ta5d6ff" Ta5d6ff"Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ffcapslock=overload(meta, tab)Ta5d6ff" Ta5d6ff"Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ffesc=tildeTa5d6ff" Ta5d6ff"Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ffleftshift=overload(shift, esc)Ta5d6ff" Ta5d6ff"Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6fftab=overload(alt, esc)Ta5d6ff" Ta5d6ff"Tffea00\nTa5d6ff"
Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4(Td2a8ffdescription Ta5d6ff"Ta5d6ffRun keyd keyboard remapping daemonTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4)


Working backwards, a default config is defined with my personalized settings. A service is defined to make use of the keyd Guix package and to use those default settings.

While reading through the keyd man page I learned there was a special key combo to kill keyd in case the config was so bad the system wasn't usable. With that in mind I decided the service should NOT respawn if the daemon were to exit.

That's a block near the top of my T383838config.scm file that defines the system. Additionally, I needed to add the following further up so some of the symbols would resolve properly:

T282828
Tb4b4b4(Td2a8ffuse-service-modules Te6edf3adminTb4b4b4)
Tb4b4b4(Td2a8ffuse-package-modules Te6edf3linuxTb4b4b4)


I can't remember what the errors were that came up without them.

To make use of this service, I needed to add it to the services list. Originally, this list looked like this:

T282828
Tb4b4b4(Td2a8ffservices Te6edf3%desktop-servicesTb4b4b4)


So I added the new one thusly:

T282828
Tb4b4b4(Td2a8ffservices
Tb4b4b4(Tffa657cons*
Tb4b4b4(Td2a8ffservice Te6edf3keyd-service-typeTb4b4b4)
Te6edf3%desktop-servicesTb4b4b4)Tb4b4b4)


what's the point

Of keyd? I think that's obvious, better mappings! Of Guix? I really like the GNU philosophy -- despite that I don't care too much for many of the tools -- and I really like determinant, reproducible systems. So I'm a step closer to understanding a new ecosystem. A painfully slow and meager step, but a step none-the-less.

Tags: index, guix

Tags
Navigation





created: 2026-05-09

(re)generated: 2026-07-17