pqrs-org / Karabiner-Elements

Karabiner-Elements is a powerful utility for keyboard customization on macOS Sierra (10.12) or later.
https://pqrs.org/osx/karabiner/
The Unlicense
18.58k stars 834 forks source link

how to simulate QMK home row mods in karabiner? #3559

Open jaroslaw-weber opened 1 year ago

jaroslaw-weber commented 1 year ago

https://precondition.github.io/home-row-mods

i want to use home row mods on my native keyboard. is there a way to do this with karabiner?

jluckyiv commented 1 year ago

I'm struggling with the same issue. I see a few common approaches, but there may be more.

to.if_alone

The first approach uses to and to.if_alone (example):

{
    "type": "basic",
    "from": {
        "key_code": "s",
        "modifiers": {
            "optional": ["any"]
        }
    },
    "to": [
        {
            "key_code": "left_alt",
            "lazy": true
        }
    ],
    "to_if_alone": [
        {
            "key_code": "s"
        }
    ]
}

from.simultaneous

The second approach uses the simultaneous modification (example). I'm reading up on this now, so I can't give a decent example on my own.

to.set_variable

I am just learning about this one. This setting (un)sets a variable on key down and key up. When other keys trigger, you can customize their behavior based on the variable being set.

Tooling

There are tools to ease configuration. A popular one is Goku, which generates a karabiner.json file from the .edn format.

John Lindquist has used Goku to make home-row mods. His dotfiles repo has his karabiner files. He has a couple of YouTube videos and an Egghead.io video.

I've been spelunking Lindquist's karabiner.edn and his karabiner-starter.edn.

Chords?

While I've been typing this post, I ran across a TypeScript configuration tool, karabiner.ts. The tool even has a playground.

The author, Evan Liu posted his config file as an example. He uses home-row key combos, e.g., f + d / j + k = . That would probably solve the fast/fa† problem, but means learning a bunch of chords for modifiers like ⌘+^.

Sorry for the long answer. I'm figuring it out too.

eytanhanig commented 1 year ago

@jluckyiv Fantastic summary! I've been playing with this and am increasingly disappointed at the complexity necessary to do this.

It is possible to improve the to_alone approach using these instructions. I'm still fiddling with the parameters and suspect that they will vary per person (it's easier to iterate if you just tweak them in the Karabiner UI). However based on the snappy behavior I've seen with a number of the complex modification rules that use simultaneous and/or variables I also believe that those approaches are necessary to achieve our goal.

Before turning to 3rd party tooling I recommend that you check out using ruby to generate rules, which is natively supported by the make command. This repo currently contains a whopping 41 examples of how to do so in src/json.

I've created this gist demonstrating how to use a .json.rb file to implement the improved if_alone approach.

jluckyiv commented 1 year ago

@eytanhanig Thanks for the tip! I have not used any generators myself. I've been hand-rolling the json.

The to_delayed_actions.to_if_canceled, to_if_alone, and to_if_held_down approach in the link you gave worked well. I looked at your gist, especially the timing parameters. I'm still fine-tuning, but around 100–120 ms seems to mitigate most of my unintentional triggers.

MartinBernstorff commented 1 year ago

Super happy to find this!

One challenge I'm struggling with is multi-key shortcuts. E.g. if I press S & D at the same time, only one of them trigger the hold command, the other is interrupted and triggers the to_if_canceled. Are you guys experiencing the same thing?

amiorin commented 1 year ago

I've replaced Karabiner with KMonad. My guide

willpuckett commented 11 months ago

Just switched to kmonad from Karabiner/ karabiner.ts. Everything actually works now. It's a relief, and far more responsive as well. Thanks 🪣s for the guide.

MShahzaib commented 11 months ago

I will try kMonad too

emadb commented 9 months ago

I used karabiner.ts to recreate a better configuration. My home row now works pretty well, and I add a chord modificator too a s to enable the arrows with the letters jkli

Here is my configuration: https://github.com/emadb/karabiner-config/blob/main/karabiner.json

In case some of you are interested here it is the typescript definition:

layer(['caps_lock', 'return_or_enter'], 'mod-layer').manipulators([
    map('a').to('left_shift'),
    map('s').to('left_control'),
    map('d').to('left_option'),
    map('f').to('left_command'),

    map('quote').to('right_shift'),
    map(';').to('right_control'),
    map('l').to('right_option'),
    map('k').to('right_command'),
  ]),

  duoLayer('a', 's').manipulators([
    map('i').to('up_arrow'), 
    map('j').to('left_arrow'), 
    map('k').to('down_arrow'), 
    map('l').to('right_arrow'),
  ])
rajasegar commented 5 months ago

I configured just now for MacOS Sonoma https://github.com/rajasegar/karabiner-config/blob/master/karabiner.json works fine for me now

argenkiwi commented 4 months ago

I am working on a keyboard layout and I would also like to know what the recommended implementation of home row modifiers is using Karabiner. I attempted to achieve this using Goku but I have not succeded so far. Kanata (and Kmonad) do seem to achieve this a lot more easily.