Skip to main content

layer()

Layer is a group of manipulators which are only active when a key is pressed and held.

layer('a', 'a-mode').manipulators([
map(1).to(2), // Only when key 'a' is pressed and held
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Layer - a-mode",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "a" },
"to": [ {"set_variable": {"name": "a-mode", "value": 1}} ],
"to_after_key_up": [ {"set_variable": {"name": "a-mode", "value": 0}} ],
"to_if_alone": [ {"key_code": "a"} ]
},
{
"type": "basic",
"from": {"key_code": "1"},
"to": [{"key_code": "2"}],
"conditions": [ { "type": "variable_if", "name": "a-mode", "value": 1 } ]
}
]
}

How layer works

layer() add a variable_if condition to all manipulators in the group

{ "type": "variable_if", "name": "a-mode", "value": 1 }

And set the variable to 1 when the layer key is pressed

"from": { "key_code": "a" },
"to": [ { "set_variable": {"name": "a-mode", "value": 1} } ],

The variable is set back to 0 on to_after_key_up, so once the layer key is released the layer manipulators are disabled.

"to_after_key_up": [ {"set_variable": {"name": "a-mode", "value": 0}} ]

The layer key is still functional if it is tapped alone

"to_if_alone": [ {"key_code": "a"} ]

Layer modifiers

Layers can have modifiers, so that the layer is only active when the key and the modifiers are all pressed and held.

layer('a', 'a-mode')
.modifiers('⌘')
.manipulators([
map(1).to(2),
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Layer - a-mode",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "a",
"modifiers": {"mandatory": ["command"]}
},
"to": [
{"set_variable": {"name": "a-mode", "value": 1}}
],
"to_after_key_up": [
{"set_variable": {"name": "a-mode", "value": 0}}
],
"to_if_alone": [
{"key_code": "a"}
]
},
{
"type": "basic",
"from": {
"key_code": "1",
"modifiers": {"mandatory": ["any"]}
},
"to": [
{"key_code": "2"}
],
"conditions": [
{"type": "variable_if", "name": "a-mode", "value": 1}
]
}
]
}

from.modifiers is set to {"mandatory": ["any"]} for all manipulators on the layer, so that the layer modifiers are not sent to manipulators to events. So the manipulators on the layer cannot have other modifiers.

modifiers('??')

layer().modifiers('optionalAny') (or '??') passes modifiers to the layer.
with layer(';').modifiers('??').manipulators({ l: toKey('→') })
⌘ ; + l triggers ⌘ →

Config the layer key

The layer key can also be mapped to something else by layer().configKey()

layer('a', 'a-mode')
.configKey((v) => v.toIfAlone('b', '⌘'), true)
.manipulators([
map(1).to(2),
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Layer - a-mode",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "a" },
"to": [ { "set_variable": {"name": "a-mode", "value": 1} } ],
"to_after_key_up": [ { "set_variable": {"name": "a-mode", "value": 0} } ],
"to_if_alone": [ { "key_code": "b", "modifiers": ["command"] } ]
},
{
"type": "basic",
"from": {"key_code": "1"},
"to": [ {"key_code": "2"} ],
"conditions": [ { "type": "variable_if", "name": "a-mode", "value": 1 } ]
}
]
}
warning

The second parameter replaceToIfAlone, of configKey(, true), makes sure only the new toIfAlone() is used. The layer key will otherwise still be triggered, sending [a, b⌘] instead of only b⌘.

Multiple layer keys

layer() can have multiple trigger keys

layer(['a', ';'], 'a-mode').manipulators([
map(1).to(2), // When either 'a' or ';' is pressed and held
])
Generated JSON in profiles.complex_modifications.rules
{
"description": "Layer - a-mode",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "semicolon" },
"to": [ { "set_variable": { "name": "a-mode", "value": 1 } } ],
"to_after_key_up": [ { "set_variable": { "name": "a-mode", "value": 0 } } ],
"to_if_alone": [ { "key_code": "semicolon" } ]
},
{
"type": "basic",
"from": { "key_code": "a" },
"to": [ { "set_variable": { "name": "a-mode", "value": 1 } } ],
"to_after_key_up": [ { "set_variable": { "name": "a-mode", "value": 0 } } ],
"to_if_alone": [ { "key_code": "a" } ]
},
{
"type": "basic",
"from": { "key_code": "1" },
"to": [ { "key_code": "2" } ],
"conditions": [ { "type": "variable_if", "name": "a-mode", "value": 1 } ]
}
]
}

The same key can also trigger multiple layers

layer('a', 'a-mode').manipulators([
map(1).to(2),
])
layer('a', 'b-mode').manipulators([
map(3).to(4),
])
Generated JSON in profiles.complex_modifications.rules
[
{
"description": "Layer - a-mode",
"manipulators": [
{
"type": "basic",
"from": {"key_code": "a"},
"to": [
{"set_variable": {"name": "a-mode", "value": 1}},
{"set_variable": {"name": "b-mode", "value": 1}}
],
"to_after_key_up": [
{"set_variable": {"name": "a-mode", "value": 0}},
{"set_variable": {"name": "b-mode", "value": 0}}
],
"to_if_alone": [{"key_code": "a"}]
},
{
"type": "basic",
"from": {"key_code": "1"},
"to": [{"key_code": "2"}],
"conditions": [{"type": "variable_if", "name": "a-mode", "value": 1}]
}
]
},
{
"description": "Layer - b-mode",
"manipulators": [
{
"type": "basic",
"from": {"key_code": "3"},
"to": [{"key_code": "4"}],
"conditions": [{"type": "variable_if", "name": "b-mode", "value": 1}]
}
]
]
info

Both variables are set by one manipulator as

if there are multiple manipulators which change the same key, the manipulator placed at the top is applied and other manipulators are ignored - Karabiner-Elements

Problems in layer

There're two problems in old layer. When we type "w1" really fast, we trigger the "1" in w layer rather than insert "w1". When we keep press w key down, the w key won't repeat. There won't be a "wwwwwwwwwwwwwwwwwwww". - Goku