Below are the smart key features implemented for smart keymap:
Automation keys implement macro key behaviour.
For common use cases, it’s simpler to use higher-level wrappers
around the key, such as K.string_macro
(documented below),
or otherwise use Nickel’s expressive language to build abstractions
above it.
For examples of this key in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
let MY_MACRO = {
automation_instructions.on_press = [
{ Press = { key_code = { Keyboard = 0x04 } } },
{ Release = { key_code = { Keyboard = 0x04 } } },
{ Press = { key_code = { Keyboard = 0x05 } } },
{ Release = { key_code = { Keyboard = 0x05 } } },
{ Press = { key_code = { Keyboard = 0x06 } } },
{ Release = { key_code = { Keyboard = 0x06 } } },
],
} in
{
keys = [
MY_MACRO,
],
}
When the keymap registers the following input
[
tap_keymap_index 0,
]
Then the output should be equivalent to output from
[
tap K.A,
tap K.B,
tap K.C,
]
The automation key’s key instructions support on_press
,
while_pressed
, on_release
instructions:
Given a keymap.ncl:
let K = import "keys.ncl" in
let { string_to_instructions, .. } = import "smart_keys/automation/lib.ncl" in
let MY_MACRO = {
automation_instructions = {
on_press = "ab" |> string_to_instructions,
while_pressed = [
{ Tap = { key_code = { Keyboard = 0x06 } } },
{ Wait = 1000 },
],
on_release = "de" |> string_to_instructions,
},
} in
{
keys = [
MY_MACRO,
],
}
Automation keys implement macro key behaviour.
For examples of this key in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
let MY_MACRO = K.string_macro "hello world" in
{
keys = [
MY_MACRO,
],
}
When the keymap registers the following input
let K = import "keys.ncl" in
let MY_MACRO = K.string_macro "hello world" in
[
tap MY_MACRO,
]
Then the output should be equivalent to output from
[
tap K.H,
tap K.E,
tap K.L,
tap K.L,
tap K.O,
tap K.Space,
tap K.W,
tap K.O,
tap K.R,
tap K.L,
tap K.D,
]
Callback keys invoke keymap callbacks, allowing the implementing firmware to execute arbitrary behaviour when the key is pressed.
Callbacks for resetting the keyboard and entering the bootloader have been defined.
Firmware should register the callback with
void keymap_register_callback(uint8_t callback_id, void (*callback_fn)(void));
using KEYMAP_CALLBACK_RESET
(for
libsmart_keymap
), or
keymap::Keymap::set_callback
(when using the
smart_keymap
crate).
Given a keymap.ncl:
let K = import "keys.ncl" in
{ keys = [ K.reset ] }
Firmware should register the callback with
void keymap_register_callback(uint8_t callback_id, void (*callback_fn)(void));
using KEYMAP_CALLBACK_BOOTLOADER
(for
libsmart_keymap
), or
keymap::Keymap::set_callback
(when using the
smart_keymap
crate).
Given a keymap.ncl:
let K = import "keys.ncl" in
{ keys = [ K.reset_to_bootloader ] }
Arbitrary callbacks to the keyboard firmware are indicated as a pair of numbers 0-255.
Firmware should register the callback with
void keymap_register_custom_callback(uint8_t custom_0, uint8_t custom_1, void (*callback_fn)(void))
(for libsmart_keymap
), or
keymap::Keymap::set_callback
(when using the
smart_keymap
crate).
Given a keymap.ncl:
let K = import "keys.ncl" in
let my_callback = K.callback 0 255 in
{ keys = [ my_callback ] }
The “Caps Word” key can be thought of as “Caps Lock, for a single word”.
Where Caps Lock shifts all keys until it is disabled, Caps Word shifts while alphabetical keys (and underscore) are typed.
A motivating use case is typing out CONSTANTS_LIKE_THIS
,
automatically leaving the caps word mode when space is hit.
For examples of this key in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
K.caps_word.toggle,
K.A,
K.B,
K.Space,
]
}
When the keymap registers the following input
[
tap K.caps_word.toggle,
tap K.A,
tap K.Space,
tap K.A,
]
Then the output should be equivalent to output from
[
press (K.LeftShift),
tap K.A,
release (K.LeftShift),
tap K.Space,
tap K.A,
]
HID Consumer usage codes.
Media keys (play/pause, volume up, volume down, etc.) have been defined.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
K.PlayPause,
K.ScanNext,
K.ScanPrevious,
K.Stop,
K.VolumeDown,
K.VolumeUp,
],
}
Custom keys are reported as arbitrary codes 0-255
in the
keymap output.
Their functionality is arbitrary, defined by the keyboard firmware implementation.
The pressed custom codes are available through the
KeymapHidReport.custom
(for libsmart_keymap
),
or keymap::KeymapOutput::pressed_custom_codes
(for the
smart_keymap
crate).
Given a keymap.ncl:
let K = import "keys.ncl" in
let my_custom_key = K.custom 255 in
{ keys = [ my_custom_key ] }
HID Keyboard usage codes.
Given a keymap.ncl:
let K = import "keys.ncl" in
{ keys = [ K.A ] }
When the keymap registers the following input
[
press K.A,
]
Then the HID keyboard report should equal
{ key_codes = [K.A] }
In keymap.ncl, modifiers can be merged with keys to form a modified key.
Given a keymap.ncl:
let K = import "keys.ncl" in
{ keys = [ K.A & K.LeftCtrl ] }
When the keymap registers the following input
[
press (K.A & K.LeftCtrl),
]
Then the HID keyboard report should equal
{ modifiers = { left_ctrl = true }, key_codes = [K.A] }
“Layered Keys” are a lower-level key which implements layering functionality.
See Layers for a friendlier way to declare layers in a keymap.ncl file.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
K.layer_mod.hold 1,
K.A & { layered = [ K.B ] },
],
}
If no layers are active, the key will be the key on the base layer.
When the keymap registers the following input
[
press (K.A & { layered = [ K.B ] }),
]
Then the HID keyboard report should equal
{ key_codes = [K.A] }
When the keymap registers the following input
[
press (K.layer_mod.hold 1),
press (K.A & { layered = [ K.B ] }),
]
Then the HID keyboard report should equal
{ key_codes = [K.B] }
The K.layer_mod.set_default
key allows setting the
Default layer.
For examples of this feature in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
layers = [
[
K.layer_mod.set_default 0,
K.layer_mod.set_default 1,
K.A,
],
[
K.TTTT,
K.TTTT,
K.B,
],
],
}
When the keymap registers the following input
[
tap (K.layer_mod.set_default 1),
press_keymap_index 2
]
Then the HID keyboard report should equal
{ key_codes = [K.B] }
The K.layer_mod.hold
key activates a layer when it is
held.
For examples of this feature in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
layers = [
[
K.layer_mod.hold 1,
K.A,
],
[
K.TTTT,
K.B,
],
],
}
If no layers are active, the key will be the key on the base layer.
When the keymap registers the following input
[
press (K.A),
]
Then the HID keyboard report should equal
{ key_codes = [K.A] }
When the keymap registers the following input
[
press (K.layer_mod.hold 1),
press (K.B),
]
Then the HID keyboard report should equal
{ key_codes = [K.B] }
The K.layer_mod.set_active_layers_to
key allows setting
the active layers.
For examples of this feature in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
layers = [
[
K.layer_mod.set_active_layers_to [1],
K.A,
],
[
K.layer_mod.set_active_layers_to [0],
K.B,
],
],
}
When the keymap registers the following input
[
press (K.layer_mod.set_active_layers_to [1]),
press_keymap_index 1,
]
Then the output should be equivalent to output from
[
press (K.B),
]
The K.layer_mod.sticky
key activates a layer in a
similar manner to sticky key modifiers:
K.layer_mod.hold
.For examples of this feature in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
layers = [
[K.layer_mod.sticky 1, K.A, K.B],
[K.TTTT, K.X, K.Y],
],
}
When the keymap registers the following input
[
tap (K.layer_mod.sticky 1),
tap_keymap_index 1,
tap_keymap_index 2,
]
Then the output should be equivalent to output from
[
tap (K.X),
tap (K.B),
]
When the keymap registers the following input
[
tap (K.layer_mod.sticky 1),
press_keymap_index 1,
press_keymap_index 2,
]
Then the output should be equivalent to output from
[
press (K.X),
press (K.B),
]
When the keymap registers the following input
[
press (K.layer_mod.sticky 1),
tap_keymap_index 1,
tap_keymap_index 2,
]
Then the output should be equivalent to output from
[
tap (K.X),
tap (K.Y),
]
The K.layer_mod.toggle
key toggles whether a layer is
active when it is pressed.
For examples of this feature in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
layers = [
[
K.layer_mod.toggle 1,
K.A,
],
[
K.TTTT,
K.B,
],
],
}
When the keymap registers the following input
[
press (K.layer_mod.toggle 1),
press (K.B),
]
Then the HID keyboard report should equal
{ key_codes = [K.B] }
When the keymap registers the following input
[
tap (K.layer_mod.toggle 1),
press (K.layer_mod.toggle 1),
press (K.A),
]
Then the HID keyboard report should equal
{ key_codes = [K.A] }
HID Mouse usage codes.
The pressed mouse codes are available through the
KeymapHidReport.mouse
(for libsmart_keymap
),
or keymap::KeymapOutput::pressed_mouse_output
(for the
smart_keymap
crate).
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
K.MouseButton1,
K.MouseButton2,
K.MouseButton3,
K.MouseLeft,
K.MouseDown,
K.MouseUp,
K.MouseRight,
K.MouseWheelDown,
K.MouseWheelUp,
],
}
The “Sticky Modifiers” key is keymap implementation of the “sticky key” accessibility feature that many desktop environments have.
If the sticky modifier key is tapped (without interruption), it modifies the next key press.
If the sticky modifier key is interrupted by another key press, then it behaves as a regular modifier key.
For examples of this key in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
(K.sticky K.LeftShift),
(K.sticky K.LeftCtrl),
K.A,
K.B,
]
}
When the keymap registers the following input
[
tap (K.sticky K.LeftShift),
press K.A,
]
Then the output should be equivalent to output from
[
press (K.LeftShift),
press K.A,
]
When the keymap registers the following input
[
tap (K.sticky K.LeftShift),
tap (K.sticky K.LeftCtrl),
press K.A,
]
Then the output should be equivalent to output from
[
press K.LeftShift,
press K.LeftCtrl,
press K.A,
]
When the keymap registers the following input
[
tap (K.sticky K.LeftShift),
tap K.A,
]
Then the output should be equivalent to output from
[
press (K.LeftShift),
tap K.A,
release (K.LeftShift),
]
When the keymap registers the following input
[
press (K.sticky K.LeftShift),
tap K.A,
release (K.sticky K.LeftShift),
tap K.B,
]
Then the output should be equivalent to output from
[
press (K.LeftShift),
tap K.A,
release (K.LeftShift),
tap K.B,
]
The config.sticky.release
can be set to
"OnNextKeyPress"
so that the sticky key releases when the
next key is pressed after the modified key.
This helps with rolling key presses.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.sticky.release = "OnNextKeyPress",
keys = [
(K.sticky K.LeftShift),
(K.sticky K.LeftCtrl),
K.A,
K.B,
]
}
When the keymap registers the following input
[
tap (K.sticky K.LeftShift),
press K.A,
press K.B,
]
Then the output should be equivalent to output from
[
press (K.LeftShift),
press K.A,
release (K.LeftShift),
press K.B,
]
The TapDance key can behave differently depending on how many times it is tapped.
For examples of this key in other smart keyboard firmware, see e.g.:
Let’s use a keymap with a tap-hold key, and a keyboard key.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
K.A & { tap_dances = [K.B, K.C] },
]
}
When the keymap registers the following input
[
press (K.A & { tap_dances = [K.B, K.C] }),
release (K.A & { tap_dances = [K.B, K.C] }),
]
And the keymap ticks 250 times
Then the output should be equivalent to output from
[
press K.A,
release K.A,
]
When the keymap registers the following input
[
press (K.A & { tap_dances = [K.B, K.C] })
]
And the keymap ticks 250 times
Then the output should be equivalent to output from
[
press K.A,
]
When the keymap registers the following input
[
tap (K.A & { tap_dances = [K.B, K.C] }),
tap (K.A & { tap_dances = [K.B, K.C] }),
tap (K.A & { tap_dances = [K.B, K.C] }),
]
Then the output should be equivalent to output from
[
tap K.C,
]
The TapHold key can behave differently depending on whether the key has been tapped or held.
e.g.
Quickly pressing and releasing a TapHold key results in a the ‘tap’ behaviour.
Pressing the TapHold key for a long enough period results in the ‘hold’ behaviour.
Pressing another key while the TapHold key is pressed “interrupts” the TapHold key, resulting in the ‘hold’ behaviour.
For examples of this key in other smart keyboard firmware, see e.g.:
Let’s use a keymap with a tap-hold key, and a keyboard key.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
keys = [
K.A & K.hold K.LeftCtrl,
K.B
]
}
When the keymap registers the following input
[
tap (K.A & K.hold K.LeftCtrl),
]
Then the HID keyboard report should equal
{ key_codes = [K.A] }
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
]
And the keymap ticks 500 times
Then the HID keyboard report should equal
{ modifiers = { left_ctrl = true } }
The tap hold key’s response to interruptions can be configured.
“Interrupts ignored” can be configured by setting
config.tap_hold.interrupt_response
to "Ignore"
in keymap.ncl
.
“Ignore interrupts” just means the key only acts as hold by holding the key for longer than the tap-hold timeout duration.
Let’s demonstrate tap-hold “ignore interrupt” behaviour using a keymap with a tap-hold key, and a keyboard key:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.tap_hold.interrupt_response = "Ignore",
keys = [
K.A & K.hold K.LeftCtrl,
K.B
]
}
Rolling the tap-hold key with another key (i.e. interrupting the
tap-hold key with another key press), releasing the tap-hold key with
interrupt_response = "Ignore"
resolves the key as tap.
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
press (K.B),
release (K.A & K.hold K.LeftCtrl),
release (K.B),
]
Then the output should be equivalent to output from
[
press (K.A),
press (K.B),
release (K.A),
release (K.B),
]
After interrupting the tap-hold key with another key tap (press &
release), releasing the tap-hold key with
interrupt_response = "Ignore"
resolves the key as tap.
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
tap (K.B),
release (K.A & K.hold K.LeftCtrl),
]
Then the output should be equivalent to output from
[
press (K.A),
tap (K.B),
release (K.A),
]
The tap hold key’s response to interruptions can be configured.
“Resolves as ‘Hold’ when interrupted by key press” can be configured
by setting config.tap_hold.interrupt_response
to
"HoldOnKeyPress"
in keymap.ncl
.
Let’s demonstrate tap-hold “hold on interrupting key press” behaviour using a keymap with a tap-hold key, and a keyboard key:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.tap_hold.interrupt_response = "HoldOnKeyPress",
keys = [
K.A & K.hold K.LeftCtrl,
K.B
]
}
Rolling the tap-hold key with another key (i.e. interrupting the
tap-hold key with another key press), for a tap-hold key configured with
interrupt_response = "HoldOnKeyPress"
resolves the tap-hold
key as ‘hold’.
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
press (K.B),
release (K.A & K.hold K.LeftCtrl),
release (K.B),
]
Then the output should be equivalent to output from
[
press (K.LeftCtrl),
press (K.B),
release (K.LeftCtrl),
release (K.B),
]
Interrupting the tap-hold key with another key tap (press &
release), for a tap-hold key configured with
interrupt_response = "HoldOnKeyPress"
resolves the key as
“hold”.
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
tap (K.B),
]
Then the output should be equivalent to output from
[
press (K.LeftCtrl),
tap (K.B),
]
The tap hold key’s response to interruptions can be configured.
“Resolves as ‘Hold’ when interrupted by key tap” can be configured by
setting config.tap_hold.interrupt_response
to
"HoldOnKeyTap"
in keymap.ncl
.
Let’s demonstrate tap-hold “hold on interrupting key tap” behaviour using a keymap with a tap-hold key, and a keyboard key:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.tap_hold.interrupt_response = "HoldOnKeyTap",
keys = [
K.A & K.hold K.LeftCtrl,
K.B
]
}
Rolling the tap-hold key with another key (i.e. interrupting the
tap-hold key with another key press), for a tap-hold key configured with
interrupt_response = "HoldOnKeyTap"
resolves the tap-hold
key as ‘tap’.
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
press (K.B),
release (K.A & K.hold K.LeftCtrl),
release (K.B),
]
Then the output should be equivalent to output from
[
press (K.A),
press (K.B),
release (K.A),
release (K.B),
]
Interrupting the tap-hold key with another key tap (press &
release), for a tap-hold key configured with
interrupt_response = "HoldOnKeyTap"
resolves the key as
“hold”.
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
tap (K.B),
]
Then the output should be equivalent to output from
[
press (K.LeftCtrl),
tap (K.B),
]
The required_idle_time
config for tap hold keys means
that tap hold keys act as ‘tap’ if they are pressed before the required
idle time has passed since the previous keymap input event
(press/release).
This helps prevent accidental ‘resolved-as-hold’ tap-hold key presses when typing quickly.
For examples of this key in other smart keyboard firmware, see e.g.:
Let’s demonstrate tap-hold “required_idle_time” behaviour using a keymap with a keyboard key, and a tap-hold key:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.tap_hold.required_idle_time = 100,
keys = [
K.A,
K.B & K.hold K.LeftCtrl,
]
}
Pressing a tap-hold key immediately resolves it as ‘tap’ when it’s pressed after another key, within the required idle time.
When the keymap registers the following input
[
tap (K.A),
wait 50,
press (K.B & K.hold K.LeftCtrl),
]
Then the output should be equivalent to output from
[
tap (K.A),
press (K.B),
]
Whereas, the tap-hold key behaves as usual if the keymap is idle for the required time.
When the keymap registers the following input
[
tap (K.A),
wait 110,
tap (K.B & K.hold K.LeftCtrl),
]
Then the output should be equivalent to output from
[
tap (K.A),
tap (K.B),
]
When the keymap registers the following input
[
tap (K.A),
wait 110,
press (K.B & K.hold K.LeftCtrl),
wait 250,
]
Then the output should be equivalent to output from
[
tap (K.A),
press (K.LeftCtrl),
]
The “timeout” before a tap-hold is considered as held can be
configured by the field config.tap_hold.timeout
in
keymap.ncl
.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.tap_hold.timeout = 50,
keys = [ K.A & K.hold K.LeftCtrl ],
}
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
wait 60,
]
Then the HID keyboard report should equal
{ modifiers = { left_ctrl = true } }
e.g. by setting the timeout to a very high value, the key still won’t resolve as “held” until that the timeout has been reached.
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.tap_hold.timeout = 30000,
keys = [ K.A & K.hold K.LeftCtrl ],
}
When the keymap registers the following input
[
press (K.A & K.hold K.LeftCtrl),
]
And the keymap ticks 10000 times
Then the HID keyboard report should equal
{ modifiers = {}, key_codes = [] }
The Nickel code in ncl/
has some functions which help
when writing keymap.ncl
files.
“Chords” (also sometimes called “combos”) allow pressing multiple keys together at the same time to behave as another key.
For examples of this feature in other smart keyboard firmware, see e.g.:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
chords = [
{ indices = [0, 1], key = K.C, },
],
keys = [
K.A, K.B,
],
}
When the keymap registers the following input
[
press K.A,
]
Then the output should be equivalent to output from
[
press (K.A),
]
When the keymap registers the following input
[
press K.A,
press K.B,
]
Then the output should be equivalent to output from
[
press (K.C),
]
When the keymap registers the following input
[
press K.A,
wait 250,
press K.B,
]
Then the output should be equivalent to output from
[
press (K.A),
press (K.B),
]
The required_idle_time
config for chords means that
chords can only be activated after the required idle time has passed
since the previous keymap input event (press/release).
This helps prevent accidental chord activation when typing quickly.
For examples of this key in other smart keyboard firmware, see e.g.:
Let’s demonstrate tap-hold “required_idle_time” behaviour using a keymap with a keyboard key, and a tap-hold key:
Given a keymap.ncl:
let K = import "keys.ncl" in
{
config.chorded.required_idle_time = 100,
chords = [
{ indices = [0, 1], key = K.C, },
],
keys = [
K.A, K.B, K.D,
],
}
When the keymap registers the following input
[
tap (K.D),
wait 50,
press_keymap_index 0,
press_keymap_index 1,
]
Then the output should be equivalent to output from
[
tap (K.D),
press (K.A),
press (K.B),
]
When the keymap registers the following input
[
tap (K.D),
wait 150,
press_keymap_index 0,
press_keymap_index 1,
]
Then the output should be equivalent to output from
[
tap (K.D),
press (K.C),
]
Layers in keymap.ncl
can be defined using strings.
keymap.ncl
supports defining each layer in the keymap
with a string.
This is simpler than the equivalent nickel array using keys such as
K.A
, K.B
, etc.
Each whitespace-delimited substring is then used as a field to lookup
the key from keys.ncl
.
For example:
{
layers = [
m%"
Q W E R T Y
"%,
],
}
Often you’ll want to be able to use custom keys, even in layer strings.
This can be achieved by providing a custom_keys
function, which is a keys extension. i.e. returns a record of keys,
extending a given K
keys record.
For example:
{
custom_keys = fun K =>
{
MY_Q = K.Q & K.LeftShift
},
layers = [
m%"
MY_Q W E R T Y
"%,
],
}
Layers are a basic part of smart keyboard firmware.
Layers are like the Fn key on laptop keyboards, where holding the Fn key allows alternate functionality for other keys on the keyboard.
For examples of this key in other smart keyboard firmware, see e.g.:
Layers can be used by setting using the layers
field of
a keymap.ncl.
Here, a keymap.ncl file with 2 keys, and 2 layers (base layer + 1 layer).
Given a keymap.ncl:
let K = import "keys.ncl" in
{
layers = [
[
K.layer_mod.hold 1,
K.A,
],
[
K.TTTT,
K.B,
],
],
}
If no layers are active, the key will be the key on the base layer.
When the keymap registers the following input
[
press (K.A),
]
Then the HID keyboard report should equal
{ key_codes = [K.A] }
When the keymap registers the following input
[
press (K.layer_mod.hold 1),
press (K.B),
]
Then the HID keyboard report should equal
{ key_codes = [K.B] }
keys.ncl
Fieldskeys.ncl
provides the values for key definitions used in
keymap.ncl
.
See the documentation for keymap.ncl for
examples of using keys.ncl
.
The fields available in keys.ncl
:
AMP
APPN
ASTR
AT
BOOT
BSLS
BSPC
CAPS
CARE
CIRC
COLN
COMM
CWTG
DEL
DLR
DOT
DOWN
DQUO
END
ENT
EQLS
ESC
EXCL
GRV
HASH
HOME
INS
LABR
LALT
LBRC
LBRK
LCBR
LCTL
LEFT
LGUI
LPRN
LSFT
MINS
NPDT
NPEN
NPMN
NPNL
NPPL
NPSL
NPST
NUSB
NUSH
PAUS
PCT
PERC
PGDN
PGUP
PIPE
PLUS
PSCR
QUES
QUOT
RABR
RALT
RBRC
RBRK
RCBR
RCTL
RET
RGHT
RGUI
RPRN
RSFT
RST
SCLN
SCRL
SLCK
SLSH
SPC
TAB
TILD
UNDS
UP
XXXX
Circumflex
Enter
LeftBrace
MouseBtn1
MouseBtn2
MouseBtn3
MouseBtn4
MouseBtn5
MouseBtn6
MouseBtn7
MouseBtn8
MouseScrollDown
MouseScrollLeft
MouseScrollRight
MouseScrollUp
RightBrace
VolDown
VolUp
string_macro
callback
reset
reset_to_bootloader
caps_word
Eject
FastForward
Mute
PlayPause
Rewind
ScanNext
ScanPrevious
Stop
VolumeDown
VolumeUp
custom
A
Application
B
Backslash
Backspace
C
CapsLock
Comma
D
Delete
Dot
Down
E
End
Equals
Escape
F
F1
F10
F11
F12
F2
F3
F4
F5
F6
F7
F8
F9
G
Grave
H
Home
I
Insert
J
K
L
Left
LeftAlt
LeftBracket
LeftCtrl
LeftGUI
LeftShift
M
Minus
N
N0
N1
N2
N3
N4
N5
N6
N7
N8
N9
NO
NP0
NP1
NP2
NP3
NP4
NP5
NP6
NP7
NP8
NP9
NPDot
NPEnter
NPMinus
NPPlus
NPSlash
NPStar
NonUSBackslash
NonUSHash
NumLock
O
P
PageDown
PageUp
Pause
PrintScreen
Q
Quote
R
Return
Right
RightAlt
RightBracket
RightCtrl
RightGUI
RightShift
S
ScrollLock
Semicolon
Slash
Space
T
Tab
U
Up
V
W
X
Y
Z
TTTT
layer_mod
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
[
\
]
^
_
`
{
|
}
~
MouseButton1
MouseButton2
MouseButton3
MouseButton4
MouseButton5
MouseButton6
MouseButton7
MouseButton8
MouseDown
MouseLeft
MouseRight
MouseUp
MouseWheelDown
MouseWheelLeft
MouseWheelRight
MouseWheelUp
Ampersand
Asterisk
At
Caret
Colon
Dollar
DoubleQuote
Exclaim
Hash
LeftAngleBracket
LeftCurlyBracket
LeftParen
Percent
Pipe
Plus
Question
RightAngleBracket
RightCurlyBracket
RightParen
Tilde
Underscore
sticky
H_LAlt
H_LCtrl
H_LGUI
H_LShift
H_RAlt
H_RCtrl
H_RGUI
H_RShift
hold