possible leader fix

This commit is contained in:
Kyle Brown
2020-11-09 10:08:07 -08:00
parent 1f0aa18a73
commit ab49e5edff
11 changed files with 10 additions and 309 deletions

View File

@@ -34,8 +34,6 @@ file](https://cdn.kmkfw.io/kmk-latest.unoptimized.zip) forms. These follow the
`KC.LWIN(KC.L)` to lock the screen on a Windows PC `KC.LWIN(KC.L)` to lock the screen on a Windows PC
- [Built-in unicode macros, including - [Built-in unicode macros, including
emojis](https://github.com/KMKfw/kmk_firmware/blob/master/docs/sequences.md) emojis](https://github.com/KMKfw/kmk_firmware/blob/master/docs/sequences.md)
- [Multiple vim-inspired leader key
modes](https://github.com/KMKfw/kmk_firmware/blob/master/docs/leader.md)
- [RGB underglow](https://github.com/KMKfw/kmk_firmware/blob/master/docs/rgb.md) - [RGB underglow](https://github.com/KMKfw/kmk_firmware/blob/master/docs/rgb.md)
and [LED and [LED
backlights](https://github.com/KMKfw/kmk_firmware/blob/master/docs/led.md) backlights](https://github.com/KMKfw/kmk_firmware/blob/master/docs/led.md)

View File

@@ -1,5 +1,5 @@
from kb import KMKKeyboard from kb import KMKKeyboard
from kmk.consts import LeaderMode, UnicodeMode from kmk.consts import UnicodeMode
from kmk.extensions.ble_split import BLE_Split from kmk.extensions.ble_split import BLE_Split
from kmk.extensions.layers import Layers from kmk.extensions.layers import Layers
from kmk.extensions.rgb import RGB from kmk.extensions.rgb import RGB
@@ -46,24 +46,6 @@ emoticons = cuss({
WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.') WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.')
keyboard.leader_mode = LeaderMode.ENTER
keyboard.leader_dictionary = {
'hello': send_string('hello world from kmk macros'),
'wpm': WPM,
'atf': emoticons.ANGRY_TABLE_FLIP,
'tf': emoticons.TABLE_FLIP,
'fca': emoticons.FLAG_CA,
'fus': emoticons.FLAG_US,
'cel': emoticons.CELEBRATORY_GLITTER,
'shr': emoticons.SHRUGGIE,
'shre': emoticons.SHRUG_EMOJI,
'poop': emoticons.POOP,
'joy': emoticons.FACE_JOY,
'ls': KC.LGUI(KC.HOME), # Lock screen
'cw': KC.LGUI(KC.END), # Close window
'dbg': KC.DBG,
}
_______ = KC.TRNS _______ = KC.TRNS
xxxxxxx = KC.NO xxxxxxx = KC.NO
HELLA_TD = KC.TD( HELLA_TD = KC.TD(
@@ -97,7 +79,7 @@ keyboard.keymap = [
_______, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F10, KC.F11, KC.F12, xxxxxxx, xxxxxxx, _______, _______, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F10, KC.F11, KC.F12, xxxxxxx, xxxxxxx, _______,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F7, KC.F8, KC.F9, xxxxxxx, xxxxxxx, KC.EQUAL, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F7, KC.F8, KC.F9, xxxxxxx, xxxxxxx, KC.EQUAL,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.INS, KC.F4, KC.F5, KC.F6, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.INS, KC.F4, KC.F5, KC.F6, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.LEAD, _______, KC.F1, KC.F2, KC.F3, xxxxxxx, xxxxxxx, _______, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.NO, _______, KC.F1, KC.F2, KC.F3, xxxxxxx, xxxxxxx, _______,
KC.HOME, KC.END, _______, xxxxxxx, KC.PGUP, KC.PGDN, KC.HOME, KC.END, _______, xxxxxxx, KC.PGUP, KC.PGDN,
], ],
[ [

View File

@@ -1,68 +0,0 @@
# Leader Key
The leader key acts as a prefix to a key sequence. These can be used to trigger macros quickly
without dedicated keys set to each function. For those of you who dislike key combos, such as
Ctrl+Shift+Esc, then this feature is for you. This is very much inspired from vim.
## Keycode
|Key |Description |
|-----------------------|---------------------------------------------------------------------|
|`KC.LEAD` |The [Leader key] |
# Enabling the extention
```python
from kmk.extensions.leader import Leader
from kmk.handlers.sequences import send_string
leader_ext = Leader(}
)
keyboard.extensions.append(leader_ext)
```
Leader key sequences can be as long or short as you like. The action be a keycode, or
can be things like unicode macros, or generic macros. The example below shows how you would
trigger task manager in Windows with a leader sequence.
1. Assign a key to KC.LEAD
2. Above your keymap, include a LEADER_DICTIONARY.
```python
from kmk.macros.simple import simple_key_sequence
# ...
leader_ext = Leader(
sequences={
'task': : simple_key_sequence([Modifiers.KC_LCTRL(Modifiers.KC_LSHIFT(Common.KC_ESC))])
}
)
keymap = [...KC.LEAD,...]
# ...
```
# Modes
1. LeaderMode.TIMEOUT (the default)
2. LeaderMode.ENTER
### Timeout Mode
Will expire after a timer and trigger the sequence that matches if any. The default timeout is 1000ms
### Enter Mode
Has no timeout. To end sequence press the enter key, or cancel and do nothing, press escape.
## Changing defaults
To change the mode or timeout, add them here
```python
from kmk.extensions.leader import Leader, LeaderMode
leader_ext = Leader(
mode=LeaderMode.ENTER,
timeout=1000
sequences={
'hello': send_string('hello world from kmk macros'),
}
)
```

View File

@@ -70,35 +70,6 @@ keymap = [...emoticons.BEER, emoticons.HAND_WAVE...]
> `kmk.types.AttrDict`, which you can think of as a read-only view over a > `kmk.types.AttrDict`, which you can think of as a read-only view over a
> dictionary adding attribute-based (dot-notation) access. > dictionary adding attribute-based (dot-notation) access.
Remember from the Leader Mode documentation that leader sequences simply bind to
keys, so extrapolating this example out a bit, you can bind emojis to leader
sequences matching some name or mnemonic representing the sequence you're
looking to send. If you ever wanted to type `<Leader>fire` and see a fire emoji
on your screen, welcome home.
```python
from kmk.handlers.sequences import compile_unicode_string_sequences as cuss
emoticons = cuss({
# Emojis
'BEER': r'🍺',
'BEER_TOAST': r'🍻',
'FACE_THINKING': r'🤔',
'FIRE': r'🔥',
'FLAG_CA': r'🇨🇦',
'FLAG_US': r'🇺🇸',
})
keyboard.leader_dictionary = {
'beer': emoticons.BEER,
'beers': emoticons.BEER_TOAST,
'fire': emoticons.FIRE,
'uhh': emoticons.FACE_THINKING,
'fca': emoticons.FLAG_CA,
'fus': emoticons.FLAG_US,
}
```
Finally, if you need to send arbitrary unicode codepoints in raw form, that's Finally, if you need to send arbitrary unicode codepoints in raw form, that's
supported too, through `unicode_codepoint_sequence`. supported too, through `unicode_codepoint_sequence`.

View File

@@ -32,10 +32,6 @@ are planned to be worked around "eventually", but for now are noteworthy:
we strongly recommend avoiding `KC.MO` (or any other layer switch keys that we strongly recommend avoiding `KC.MO` (or any other layer switch keys that
use momentary switch behavior - `KC.LM`, `KC.LT`, and `KC.TT`) use momentary switch behavior - `KC.LM`, `KC.LT`, and `KC.TT`)
- Super fancy stuff like sending a keypress only when the leader key is released
(perhaps based on how long the leader key was held) is **unsupported** - an
example use case might be "tap for Home, hold for Shift"
Here's an example of all this in action: Here's an example of all this in action:
```python ```python

View File

@@ -1,128 +0,0 @@
from kmk.extensions import Extension, InvalidExtensionEnvironment
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import KC, make_key
class LeaderMode:
TIMEOUT = 0
TIMEOUT_ACTIVE = 1
ENTER = 2
ENTER_ACTIVE = 3
class Leader(Extension):
def __init__(self, mode=LeaderMode.TIMEOUT, timeout=1000, sequences=None):
if sequences is None:
raise InvalidExtensionEnvironment(
'sequences must be a dictionary, not None'
)
self._mode = mode
self._timeout = timeout
self._sequences = self._compile_sequences(sequences)
self._leader_pending = None
self._assembly_last_len = 0
self._sequence_assembly = []
make_key(
names=('LEADER', 'LEAD'),
on_press=self._key_leader_pressed,
on_release=handler_passthrough,
)
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
return
def during_bootup(self, keyboard):
return
def before_matrix_scan(self, keyboard):
return
def after_matrix_scan(self, keyboard, matrix_update):
if self._mode % 2 == 1:
keys_pressed = keyboard.keys_pressed
if self._assembly_last_len and self._sequence_assembly:
history_set = set(self._sequence_assembly)
keys_pressed = keys_pressed - history_set
self._assembly_last_len = len(keyboard.keys_pressed)
for key in keys_pressed:
if self._mode == LeaderMode.ENTER_ACTIVE and key == KC.ENT:
self._handle_leader_sequence(keyboard)
elif key in (KC.ESC, KC.GESC):
# Clean self and turn leader mode off.
self._exit_leader_mode(keyboard)
break
elif key == KC.LEAD:
break
else:
# Add key if not needing to escape
# This needs replaced later with a proper debounce
self._sequence_assembly.append(key)
keyboard.hid_pending = False
def before_hid_send(self, keyboard):
return
def after_hid_send(self, keyboard):
return
def on_powersave_enable(self, keyboard):
return
def on_powersave_disable(self, keyboard):
return
@staticmethod
def _compile_sequences(sequences):
for k, v in sequences.items():
if not isinstance(k, tuple):
new_key = tuple(KC[c] for c in k)
sequences[new_key] = v
for k, v in sequences.items():
if not isinstance(k, tuple):
del sequences[k]
return sequences
def _handle_leader_sequence(self, keyboard):
lmh = tuple(self._sequence_assembly)
# Will get caught in infinite processing loops if we don't
# exit leader mode before processing the target key
self._exit_leader_mode(keyboard)
if lmh in self._sequences:
# Stack depth exceeded if try to use add_key here with a unicode sequence
keyboard.process_key(self._sequences[lmh], True)
keyboard.set_timeout(
False, lambda: keyboard.remove_key(self._sequences[lmh])
)
def _exit_leader_mode(self, keyboard):
self._sequence_assembly.clear()
self._mode -= 1
self._assembly_last_len = 0
keyboard.keys_pressed.clear()
def _key_leader_pressed(self, key, keyboard):
if self._mode % 2 == 0:
keyboard.keys_pressed.discard(key)
# All leader modes are one number higher when activating
self._mode += 1
if self._mode == LeaderMode.TIMEOUT_ACTIVE:
keyboard.set_timeout(
self._timeout, lambda: self._handle_leader_sequence(keyboard)
)

View File

@@ -97,9 +97,6 @@ def generate_codepoint_keysym_seq(codepoint, expected_length=4):
# Not sure how to send emojis on Mac/Windows like that, # Not sure how to send emojis on Mac/Windows like that,
# though, since (for example) the Canadian flag is assembled # though, since (for example) the Canadian flag is assembled
# from two five-character codepoints, 1f1e8 and 1f1e6 # from two five-character codepoints, 1f1e8 and 1f1e6
#
# As a bonus, this function can be pretty useful for
# leader dictionary keys as strings.
seq = [KC.N0 for _ in range(max(len(codepoint), expected_length))] seq = [KC.N0 for _ in range(max(len(codepoint), expected_length))]
for idx, codepoint_fragment in enumerate(reversed(codepoint)): for idx, codepoint_fragment in enumerate(reversed(codepoint)):
@@ -108,10 +105,6 @@ def generate_codepoint_keysym_seq(codepoint, expected_length=4):
return seq return seq
def generate_leader_dictionary_seq(string):
return tuple(generate_codepoint_keysym_seq(string, 1))
def unicode_codepoint_sequence(codepoints): def unicode_codepoint_sequence(codepoints):
kc_seqs = (generate_codepoint_keysym_seq(codepoint) for codepoint in codepoints) kc_seqs = (generate_codepoint_keysym_seq(codepoint) for codepoint in codepoints)

View File

@@ -5,7 +5,7 @@ def passthrough(key, state, *args, **kwargs):
return state return state
def default_pressed(key, state, KC, coord_int=None, coord_raw=None): def default_pressed(key, state, KC, coord_int=None, coord_raw=None, *args, **kwargs):
state.hid_pending = True state.hid_pending = True
if coord_int is not None: if coord_int is not None:
@@ -16,7 +16,7 @@ def default_pressed(key, state, KC, coord_int=None, coord_raw=None):
return state return state
def default_released(key, state, KC, coord_int=None, coord_raw=None): def default_released(key, state, KC, coord_int=None, coord_raw=None, *args, **kwargs):
state.hid_pending = True state.hid_pending = True
state.keys_pressed.discard(key) state.keys_pressed.discard(key)

View File

@@ -2,7 +2,6 @@ import board
from kb import KMKKeyboard from kb import KMKKeyboard
from kmk.extensions.layers import Layers from kmk.extensions.layers import Layers
from kmk.extensions.leader import Leader, LeaderMode
from kmk.extensions.modtap import ModTap from kmk.extensions.modtap import ModTap
from kmk.extensions.rgb import RGB from kmk.extensions.rgb import RGB
from kmk.handlers.sequences import send_string, simple_key_sequence from kmk.handlers.sequences import send_string, simple_key_sequence
@@ -13,17 +12,11 @@ keyboard = KMKKeyboard()
# ------------------User level config variables --------------------------------------- # ------------------User level config variables ---------------------------------------
keyboard.tap_time = 150 keyboard.tap_time = 150
leader_ext = Leader(mode=LeaderMode.ENTER, sequences={
'hello': send_string('hello world from kmk macros'),
'ls': KC.LGUI(KC.HOME),
'dbg': KC.DBG,
})
layers = Layers() layers = Layers()
modtap = ModTap() modtap = ModTap()
rgb_ext = RGB(pixel_pin=keyboard.rgb_pixel_pin, num_pixels=27, val_limit=100, hue_default=190, sat_default=100, val_default=5) rgb_ext = RGB(pixel_pin=keyboard.rgb_pixel_pin, num_pixels=27, val_limit=100, hue_default=190, sat_default=100, val_default=5)
keyboard.extensions = [leader_ext, modtap, layers, rgb_ext] keyboard.extensions = [modtap, layers, rgb_ext]
_______ = KC.TRNS _______ = KC.TRNS
XXXXXXX = KC.NO XXXXXXX = KC.NO
@@ -111,7 +104,7 @@ keyboard.keymap = [
# r1 # r1
KC.GESC, KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0, KC.DEL, KC.GESC, KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0, KC.DEL,
KC.TILD, KC.EXLM, KC.AT, KC.HASH, KC.DLR, KC.PERC, KC.CIRC, KC.AMPR, KC.ASTR, KC.LPRN, KC.RPRN, KC.DEL, KC.TILD, KC.EXLM, KC.AT, KC.HASH, KC.DLR, KC.PERC, KC.CIRC, KC.AMPR, KC.ASTR, KC.LPRN, KC.RPRN, KC.DEL,
KC.LEAD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.LBRC, KC.RBRC, KC.BSLS, KC.NO, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.LBRC, KC.RBRC, KC.BSLS,
_______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.INS, _______, _______, KC.MINS, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC.INS, _______, _______, KC.MINS,
KC.RESET, _______, _______, _______, _______, _______, _______, KC.EQL, KC.HOME, KC.PGDN, KC.PGUP, KC.END, KC.RESET, _______, _______, _______, _______, _______, _______, KC.EQL, KC.HOME, KC.PGDN, KC.PGUP, KC.END,
], ],

View File

@@ -1,7 +1,6 @@
from kb import KMKKeyboard from kb import KMKKeyboard
from kmk.consts import UnicodeMode from kmk.consts import UnicodeMode
from kmk.extensions.layers import Layers from kmk.extensions.layers import Layers
from kmk.extensions.leader import Leader, LeaderMode
from kmk.handlers.sequences import compile_unicode_string_sequences as cuss from kmk.handlers.sequences import compile_unicode_string_sequences as cuss
from kmk.handlers.sequences import send_string from kmk.handlers.sequences import send_string
from kmk.keys import KC from kmk.keys import KC
@@ -46,23 +45,6 @@ emoticons = cuss({
WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.') WPM = send_string('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.')
leader_dictionary = {
'hello': send_string('hello world from kmk macros'),
'wpm': WPM,
'atf': emoticons.ANGRY_TABLE_FLIP,
'tf': emoticons.TABLE_FLIP,
'fca': emoticons.FLAG_CA,
'fus': emoticons.FLAG_US,
'cel': emoticons.CELEBRATORY_GLITTER,
'shr': emoticons.SHRUGGIE,
'shre': emoticons.SHRUG_EMOJI,
'poop': emoticons.POOP,
'joy': emoticons.FACE_JOY,
'ls': KC.LGUI(KC.HOME), # Lock screen
'cw': KC.LGUI(KC.END), # Close window
'dbg': KC.DBG,
}
_______ = KC.TRNS _______ = KC.TRNS
xxxxxxx = KC.NO xxxxxxx = KC.NO
HELLA_TD = KC.TD( HELLA_TD = KC.TD(
@@ -72,8 +54,7 @@ HELLA_TD = KC.TD(
KC.TG(1), KC.TG(1),
) )
leader_ext = Leader(mode=LeaderMode.ENTER, sequences=leader_dictionary) keyboard.extentions = [layers_ext]
keyboard.extentions = [layers_ext, leader_ext]
keyboard.keymap = [ keyboard.keymap = [
[ [
@@ -87,7 +68,7 @@ keyboard.keymap = [
_______, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F10, KC.F11, KC.F12, xxxxxxx, xxxxxxx, _______, _______, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F10, KC.F11, KC.F12, xxxxxxx, xxxxxxx, _______,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F7, KC.F8, KC.F9, xxxxxxx, xxxxxxx, KC.EQUAL, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.F7, KC.F8, KC.F9, xxxxxxx, xxxxxxx, KC.EQUAL,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.INS, KC.F4, KC.F5, KC.F6, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.INS, KC.F4, KC.F5, KC.F6, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.LEAD, _______, KC.F1, KC.F2, KC.F3, xxxxxxx, xxxxxxx, _______, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.NO, _______, KC.F1, KC.F2, KC.F3, xxxxxxx, xxxxxxx, _______,
KC.HOME, KC.END, _______, xxxxxxx, KC.PGUP, KC.PGDN, KC.HOME, KC.END, _______, xxxxxxx, KC.PGUP, KC.PGDN,
], ],
[ [

View File

@@ -1,6 +1,5 @@
from kb import KMKKeyboard from kb import KMKKeyboard
from kmk.consts import UnicodeMode from kmk.consts import UnicodeMode
from kmk.extensions.leader import Leader, LeaderMode
from kmk.handlers.sequences import compile_unicode_string_sequences as cuss from kmk.handlers.sequences import compile_unicode_string_sequences as cuss
from kmk.handlers.sequences import send_string from kmk.handlers.sequences import send_string
from kmk.keys import KC, make_key from kmk.keys import KC, make_key
@@ -52,22 +51,6 @@ HELLA_TD = KC.TD(
KC.TG(1), KC.TG(1),
) )
leader_ext = Leader(mode=LeaderMode.ENTER, sequences={
'hello': send_string('hello world from kmk macros'),
'wpm': WPM,
'atf': emoticons.ANGRY_TABLE_FLIP,
'tf': emoticons.TABLE_FLIP,
'fca': emoticons.FLAG_CA,
'fus': emoticons.FLAG_US,
'cel': emoticons.CELEBRATORY_GLITTER,
'shr': emoticons.SHRUGGIE,
'poop': emoticons.POOP,
'ls': KC.LGUI(KC.HOME),
'dbg': KC.DBG,
})
keyboard.extensions = [leader_ext]
def shrek_is_life(*args, **kwargs): def shrek_is_life(*args, **kwargs):
''' '''
@@ -107,7 +90,7 @@ keyboard.keymap = [
KC.GESC, KC.QUOT, KC.COMM, KC.DOT, KC.P, KC.Y, KC.F, KC.G, KC.C, KC.R, KC.L, KC.BSPC, KC.GESC, KC.QUOT, KC.COMM, KC.DOT, KC.P, KC.Y, KC.F, KC.G, KC.C, KC.R, KC.L, KC.BSPC,
KC.TAB, KC.A, KC.O, KC.E, KC.U, KC.I, KC.D, KC.H, KC.T, KC.N, KC.S, KC.ENT, KC.TAB, KC.A, KC.O, KC.E, KC.U, KC.I, KC.D, KC.H, KC.T, KC.N, KC.S, KC.ENT,
KC.LGUI, KC.SCLN, KC.Q, KC.J, KC.K, KC.X, KC.B, KC.M, KC.W, KC.V, KC.Z, KC.LALT, KC.LGUI, KC.SCLN, KC.Q, KC.J, KC.K, KC.X, KC.B, KC.M, KC.W, KC.V, KC.Z, KC.LALT,
KC.LCTL, KC.LEAD, KC.LSHIFT(KC.LGUI), KC.MO(2), KC.MO(3), KC.LSFT, KC.SPC, KC.MO(1), KC.LEFT, KC.DOWN, KC.UP, KC.RGHT, KC.LCTL, KC.NO, KC.LSHIFT(KC.LGUI), KC.MO(2), KC.MO(3), KC.LSFT, KC.SPC, KC.MO(1), KC.LEFT, KC.DOWN, KC.UP, KC.RGHT,
], ],
[ [