Using a standard key as a modifier when held?

477 views
Skip to first unread message

Josh Ritz

unread,
Dec 10, 2020, 3:40:35 PM12/10/20
to Karabiner
I am trying to create a layout where combining 'semicolon' and i/j/k/l will modify to the arrow keys. I'm halfway there, I have it set up to work with simultaneous keypresses,  but i'd like to be able to hold semicolon down to create the result, the way you can with a modifier key.

Specifically, I want 'semicolon' to not trigger a semicolon character if its held down, for my modification of i/j/k/l to trigger when combined with the held down 'semicolon' key, and to still be able to use the 'semicolon' key as originally intended with a normal keypress/release.

For example, tapping the 'semicolon' key, holding 'semicolon' down, tapping 'J' twice, then releasing and tapping 'semicolon' again would type a semicolon character, move the cursor two characters over, then type another semicolon character.

I'm sure there's an obvious way to achieve this but im struggling with the documentation. I suspect I would need to modify the semicolon key so that keyup and keydown behaviors are modified separately. Does anyone have suggestions?

Sean Mackesey

unread,
Dec 20, 2020, 12:46:26 PM12/20/20
to Karabiner
I have something very similar configured using `f` as the layer toggle (your semicolon) and j-k-l-semicolon as the arrow keys (along with some other keys). I highly recommend configuring this with goku rather than in the karabiner json, it is much more readable (goku is a tool that allows you to write your config in condensed syntax and emits the corresponding json). Goku has decent docs on setting this up (one name for this functionality is "layers"). Here is my goku config for this feature:

  {
   :des "layer 2 (nav)"
   :rules [
           [:f ["layer-2" 1] nil {:afterup ["layer-2" 0] :alone :f}]
           [:j :left_arrow ["layer-2" 1]]
           [:k :down_arrow ["layer-2" 1]]
           [:l :up_arrow ["layer-2" 1]]
           [:semicolon :right_arrow ["layer-2" 1]]
           [:d :delete_forward ["layer-2" 1]]
           [:s :delete_or_backspace ["layer-2" 1]]
           [:h :escape ["layer-2" 1]]
           [:m :return_or_enter ["layer-2" 1]]
           [:quote :!QOSf13 ["layer-2" 1]]
           ]
   }

In broad strokes, the first line of "rules" means:

- when f is pressed, set a a variable layer-2 to 1
- when f is released (afterup), set the variable layer-2 to 0
- when f is pressed alone, insert f

The second line means that when j is pressed and layer-2 is set to 1, send a left_arrow. The remaining lines can be interpreted similarly.

In case you want to skip goku, I'm including the generated json below:

                    {
                        "description": "layer 2 (nav)",
                        "manipulators": [
                            {
                                "from": {
                                    "key_code": "f"
                                },
                                "to": [
                                    {
                                        "set_variable": {
                                            "name": "layer-2",
                                            "value": 1
                                        }
                                    }
                                ],
                                "to_after_key_up": [
                                    {
                                        "set_variable": {
                                            "name": "layer-2",
                                            "value": 0
                                        }
                                    }
                                ],
                                "to_if_alone": [
                                    {
                                        "key_code": "f"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "j"
                                },
                                "to": [
                                    {
                                        "key_code": "left_arrow"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "k"
                                },
                                "to": [
                                    {
                                        "key_code": "down_arrow"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "l"
                                },
                                "to": [
                                    {
                                        "key_code": "up_arrow"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "semicolon"
                                },
                                "to": [
                                    {
                                        "key_code": "right_arrow"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "d"
                                },
                                "to": [
                                    {
                                        "key_code": "delete_forward"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "s"
                                },
                                "to": [
                                    {
                                        "key_code": "delete_or_backspace"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "h"
                                },
                                "to": [
                                    {
                                        "key_code": "escape"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "m"
                                },
                                "to": [
                                    {
                                        "key_code": "return_or_enter"
                                    }
                                ],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "layer-2",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "quote"
                                },
                                "to": [
                                    {
                                        "key_code": "f13",
                                        "modifiers": [
                                            "left_option",
                                            "left_shift",
                                            "right_command"
                                        ]
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    }
Reply all
Reply to author
Forward
0 new messages