Thicket data repository for the EEG
1{
2 "id": "https://mort.io/blog/keymapping-reprise/",
3 "title": "Re-key-remapping",
4 "link": "https://mort.io/blog/keymapping-reprise/",
5 "updated": "2025-07-26T00:00:00",
6 "published": "2025-07-26T00:00:00",
7 "summary": "<p>As all right-minded people must, I remap the historic, redundant, absurd\n<code>CAPSLOCK</code> key<a href=\"https://mort.io/blog/keymapping-reprise/#1\">1</a> to be a more conveniently accessible current, useful, sleek\n<code>CTRL</code> (control) key on any given keyboard. I also do some other minor mods to\nassist retention of the little sanity I still have – as I get older and more\ndecrepit, it gets harder for me to handle change. Deal with it.</p>\n<p>I <a href=\"https://mort.io/blog/elcapitan-maps/\">used</a> <a href=\"https://mort.io/blog/mess-with-my-keyboard/\">to do this</a> <a href=\"https://mort.io/blog/setup-new-laptop/\">on\nmy Macbook</a> using a tool called <a href=\"https://karabiner-elements.pqrs.org/\">Karabiner\nElements</a>. But now I’m on Linux, that’s\nnot a thing. So I use the excellent <a href=\"https://github.com/rvaiya/keyd\"><code>keyd</code></a> instead. The UK Thinkpad keyboard\nbeing a lot less daft in design than the UK Macbook keyboard, the modifications\nare also much smaller, which is nice.</p>\n<p>However the canonical First Modification, <code>CAPSLOCK</code> to <code>CONTROL</code> remains the\nkey one. For added convenience, given I rarely need to “tap” <code>CTRL</code> I also make a\ntap on the <code>CAPSLOCK</code> key into an <code>ESC</code> (escape). And there the fun starts.</p>\n<p>It turns out the <a href=\"https://github.com/rvaiya/keyd\"><code>keyd</code></a> recommended way to achieve this is with the\nconfiguration stanza</p>\n<pre><code><span><span>[main]\n</span></span><span><span><span>capslock</span> <span>=</span></span> <span><span>overload</span>(</span>capslock<span>,</span> esc)\n</span></code></pre>\n<p>…which is mostly fine and has worked well for me for some time. But I realised\nI was getting increasingly irritated that I seemed to get spurious <code>ESC</code> key\npresses when using <code>CAPSLOCK</code> as <code>CTRL</code>. <code>sudo keyd monitor</code> and it became clear\nthat the semantics of the <code>overload()</code> function weren’t quite as I thought. From\n<code>man keyd</code>,</p>\n<pre><code><span>overload(<layer>, <action>)\n</span><span> Activates the given layer while held and executes <action> on tap.\n</span></code></pre>\n<p>I had assumed this meant that <code><action></code> did not execute if the assigned key was\nheld, but it doesn’t quite: it seems that a tap is deemed to have occurred if\nthe key is not <em>chorded</em>. So sometimes, being a bit slow, when I hold <code>CAPSLOCK</code>\nthinking I want to chord and thus have it treated as <code>CTRL</code> but then realise I\ndon’t and I just let go, I still get an <code>ESC</code> generated – even if it was a\nsecond or two that I was holding it down for.<a href=\"https://mort.io/blog/keymapping-reprise/#2\">2</a></p>\n<p>So I read a bit more of the manpage can came across the <code>timeout</code> function</p>\n<pre><code><span>timeout(<action 1>, <timeout>, <action 2>)\n</span><span> If the key is held in isolation for more than <timeout> ms, activate the\n</span><span> second action, if the key is held for less than <timeout> ms or another key\n</span><span> is struck before <timeout> ms expires, execute the first action.\n</span><span>\n</span><span> E.g.\n</span><span>\n</span><span> timeout(a, 500, layer(control))\n</span><span>\n</span><span> Will cause the assigned key to behave as control if it is held for more than\n</span><span> 500 ms.\n</span></code></pre>\n<p>…used as <code>capslock = timeout(esc, 250, layer(control))</code> but that turns out\nalso not to be quite right. In the end, it looks like the right answer is\n<code>overloadt2</code>:</p>\n<pre><code><span>overloadt(<layer>, <action>, <timeout>)\n</span><span> Identical to overload, but only activates the layer if the bound key is held\n</span><span> for <timeout> milliseconds. This is mainly useful for overloading keys which\n</span><span> are commonly struck in sequence (e.g letter keys).\n</span><span>\n</span><span> Note that this will add a visual delay when typing, since overlapping keys\n</span><span> will be queued until the timeout expires or the bound key is released.\n</span><span>\n</span><span>overloadt2(<layer>, <action>, <timeout>)\n</span><span> \n</span><span> Identical to overloadt, but additionally resolves as a hold in the event of\n</span><span> an intervening key tap.\n</span></code></pre>\n<p>The end result is the following stanza in my <a href=\"https://nixos.org/\">NixOS</a>\nconfiguration:</p>\n<pre><code><span><span>keyd</span> <span>=</span> <span>{</span>\n</span><span> <span>enable</span> <span>=</span> <span>true</span><span>;</span>\n</span><span> <span>keyboards</span>.<span>default</span> <span>=</span> <span>{</span>\n</span><span> <span>ids</span> <span>=</span> <span>[</span> <span><span>"</span>*<span>"</span></span> <span>]</span><span>;</span>\n</span><span> <span>settings</span> <span>=</span> <span>{</span>\n</span><span> <span>main</span> <span>=</span> <span>{</span>\n</span><span> <span># capslock -> (held) ctrl, (tap) ESC</span>\n</span><span> <span>capslock</span> <span>=</span> <span><span>"</span>overloadt2(control, esc, 150)<span>"</span></span><span>;</span>\n</span><span> <span>rightalt</span> <span>=</span> <span><span>"</span>leftalt<span>"</span></span><span>;</span>\n</span><span> <span>}</span><span>;</span>\n</span><span> <span>shift</span> <span>=</span> <span>{</span>\n</span><span> <span>grave</span> <span>=</span> <span><span>"</span>G-4<span>"</span></span><span>;</span> <span># S-` -> €</span>\n</span><span> <span>}</span><span>;</span>\n</span><span> <span>}</span><span>;</span>\n</span><span> <span>}</span><span>;</span>\n</span><span><span>}</span><span>;</span>\n</span></code></pre>\n<p>The <code>timeout</code> of 150ms feels “about right” at this point – 100ms was borderline\nnot enough, and 200ms was definitely annoyingly long.</p>\n<div>1\n<p>Not to be confused with the elegant, historic, radical <code>RUN/STOP</code> key of course. C64 FTW!</p>\n</div>\n<div>2\n<p>Honestly, sometimes I really am that slow. I’m old see?</p>\n</div>",
8 "content": "<p>As all right-minded people must, I remap the historic, redundant, absurd\n<code>CAPSLOCK</code> key<a href=\"https://mort.io/blog/keymapping-reprise/#1\">1</a> to be a more conveniently accessible current, useful, sleek\n<code>CTRL</code> (control) key on any given keyboard. I also do some other minor mods to\nassist retention of the little sanity I still have – as I get older and more\ndecrepit, it gets harder for me to handle change. Deal with it.</p>\n<p>I <a href=\"https://mort.io/blog/elcapitan-maps/\">used</a> <a href=\"https://mort.io/blog/mess-with-my-keyboard/\">to do this</a> <a href=\"https://mort.io/blog/setup-new-laptop/\">on\nmy Macbook</a> using a tool called <a href=\"https://karabiner-elements.pqrs.org/\">Karabiner\nElements</a>. But now I’m on Linux, that’s\nnot a thing. So I use the excellent <a href=\"https://github.com/rvaiya/keyd\"><code>keyd</code></a> instead. The UK Thinkpad keyboard\nbeing a lot less daft in design than the UK Macbook keyboard, the modifications\nare also much smaller, which is nice.</p>\n<p>However the canonical First Modification, <code>CAPSLOCK</code> to <code>CONTROL</code> remains the\nkey one. For added convenience, given I rarely need to “tap” <code>CTRL</code> I also make a\ntap on the <code>CAPSLOCK</code> key into an <code>ESC</code> (escape). And there the fun starts.</p>\n<p>It turns out the <a href=\"https://github.com/rvaiya/keyd\"><code>keyd</code></a> recommended way to achieve this is with the\nconfiguration stanza</p>\n<pre><code><span><span>[main]\n</span></span><span><span><span>capslock</span> <span>=</span></span> <span><span>overload</span>(</span>capslock<span>,</span> esc)\n</span></code></pre>\n<p>…which is mostly fine and has worked well for me for some time. But I realised\nI was getting increasingly irritated that I seemed to get spurious <code>ESC</code> key\npresses when using <code>CAPSLOCK</code> as <code>CTRL</code>. <code>sudo keyd monitor</code> and it became clear\nthat the semantics of the <code>overload()</code> function weren’t quite as I thought. From\n<code>man keyd</code>,</p>\n<pre><code><span>overload(<layer>, <action>)\n</span><span> Activates the given layer while held and executes <action> on tap.\n</span></code></pre>\n<p>I had assumed this meant that <code><action></code> did not execute if the assigned key was\nheld, but it doesn’t quite: it seems that a tap is deemed to have occurred if\nthe key is not <em>chorded</em>. So sometimes, being a bit slow, when I hold <code>CAPSLOCK</code>\nthinking I want to chord and thus have it treated as <code>CTRL</code> but then realise I\ndon’t and I just let go, I still get an <code>ESC</code> generated – even if it was a\nsecond or two that I was holding it down for.<a href=\"https://mort.io/blog/keymapping-reprise/#2\">2</a></p>\n<p>So I read a bit more of the manpage can came across the <code>timeout</code> function</p>\n<pre><code><span>timeout(<action 1>, <timeout>, <action 2>)\n</span><span> If the key is held in isolation for more than <timeout> ms, activate the\n</span><span> second action, if the key is held for less than <timeout> ms or another key\n</span><span> is struck before <timeout> ms expires, execute the first action.\n</span><span>\n</span><span> E.g.\n</span><span>\n</span><span> timeout(a, 500, layer(control))\n</span><span>\n</span><span> Will cause the assigned key to behave as control if it is held for more than\n</span><span> 500 ms.\n</span></code></pre>\n<p>…used as <code>capslock = timeout(esc, 250, layer(control))</code> but that turns out\nalso not to be quite right. In the end, it looks like the right answer is\n<code>overloadt2</code>:</p>\n<pre><code><span>overloadt(<layer>, <action>, <timeout>)\n</span><span> Identical to overload, but only activates the layer if the bound key is held\n</span><span> for <timeout> milliseconds. This is mainly useful for overloading keys which\n</span><span> are commonly struck in sequence (e.g letter keys).\n</span><span>\n</span><span> Note that this will add a visual delay when typing, since overlapping keys\n</span><span> will be queued until the timeout expires or the bound key is released.\n</span><span>\n</span><span>overloadt2(<layer>, <action>, <timeout>)\n</span><span> \n</span><span> Identical to overloadt, but additionally resolves as a hold in the event of\n</span><span> an intervening key tap.\n</span></code></pre>\n<p>The end result is the following stanza in my <a href=\"https://nixos.org/\">NixOS</a>\nconfiguration:</p>\n<pre><code><span><span>keyd</span> <span>=</span> <span>{</span>\n</span><span> <span>enable</span> <span>=</span> <span>true</span><span>;</span>\n</span><span> <span>keyboards</span>.<span>default</span> <span>=</span> <span>{</span>\n</span><span> <span>ids</span> <span>=</span> <span>[</span> <span><span>"</span>*<span>"</span></span> <span>]</span><span>;</span>\n</span><span> <span>settings</span> <span>=</span> <span>{</span>\n</span><span> <span>main</span> <span>=</span> <span>{</span>\n</span><span> <span># capslock -> (held) ctrl, (tap) ESC</span>\n</span><span> <span>capslock</span> <span>=</span> <span><span>"</span>overloadt2(control, esc, 150)<span>"</span></span><span>;</span>\n</span><span> <span>rightalt</span> <span>=</span> <span><span>"</span>leftalt<span>"</span></span><span>;</span>\n</span><span> <span>}</span><span>;</span>\n</span><span> <span>shift</span> <span>=</span> <span>{</span>\n</span><span> <span>grave</span> <span>=</span> <span><span>"</span>G-4<span>"</span></span><span>;</span> <span># S-` -> €</span>\n</span><span> <span>}</span><span>;</span>\n</span><span> <span>}</span><span>;</span>\n</span><span> <span>}</span><span>;</span>\n</span><span><span>}</span><span>;</span>\n</span></code></pre>\n<p>The <code>timeout</code> of 150ms feels “about right” at this point – 100ms was borderline\nnot enough, and 200ms was definitely annoyingly long.</p>\n<div>1\n<p>Not to be confused with the elegant, historic, radical <code>RUN/STOP</code> key of course. C64 FTW!</p>\n</div>\n<div>2\n<p>Honestly, sometimes I really am that slow. I’m old see?</p>\n</div>",
9 "content_type": "html",
10 "author": {
11 "name": "Unknown",
12 "email": null,
13 "uri": null
14 },
15 "categories": [],
16 "source": "https://mort.io/atom.xml"
17}