From ab49e5edff9a30bcf80fe55a811c34ecf873a3e9 Mon Sep 17 00:00:00 2001 From: Kyle Brown Date: Mon, 9 Nov 2020 10:08:07 -0800 Subject: [PATCH] possible leader fix --- README.md | 2 - boards/keebio/iris/main.py | 22 +--- docs/leader.md | 68 ----------- docs/sequences.md | 29 ----- docs/tapdance.md | 6 +- kmk/extensions/leader.py | 128 -------------------- kmk/handlers/sequences.py | 7 -- kmk/handlers/stock.py | 4 +- user_keymaps/kdb424/nyquist_r2.py | 11 +- user_keymaps/klardotsh/iris_r2.py | 23 +--- user_keymaps/klardotsh/klarank_featherm4.py | 19 +-- 11 files changed, 10 insertions(+), 309 deletions(-) delete mode 100644 docs/leader.md delete mode 100644 kmk/extensions/leader.py diff --git a/README.md b/README.md index 7933418..21b9802 100644 --- a/README.md +++ b/README.md @@ -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 - [Built-in unicode macros, including 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) and [LED backlights](https://github.com/KMKfw/kmk_firmware/blob/master/docs/led.md) diff --git a/boards/keebio/iris/main.py b/boards/keebio/iris/main.py index 6294f05..5fcec27 100644 --- a/boards/keebio/iris/main.py +++ b/boards/keebio/iris/main.py @@ -1,5 +1,5 @@ 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.layers import Layers 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.') -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 xxxxxxx = KC.NO 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, 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, 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, ], [ diff --git a/docs/leader.md b/docs/leader.md deleted file mode 100644 index efefbd0..0000000 --- a/docs/leader.md +++ /dev/null @@ -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'), - } -) -``` diff --git a/docs/sequences.md b/docs/sequences.md index 8c4b08c..f021c87 100644 --- a/docs/sequences.md +++ b/docs/sequences.md @@ -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 > 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 `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 supported too, through `unicode_codepoint_sequence`. diff --git a/docs/tapdance.md b/docs/tapdance.md index 0140bcc..73ccd21 100644 --- a/docs/tapdance.md +++ b/docs/tapdance.md @@ -15,7 +15,7 @@ quickly, then tapped and held (both actions within the timeout window), the letter "b" will be held down until the tap dance key is released. To use this, you may want to define a `tap_time` value in your keyboard -configuration. This is an integer in milliseconds, and defaults to `300`. +configuration. This is an integer in milliseconds, and defaults to `300`. You'll then want to create a sequence of keys using `KC.TD(KC.SOMETHING, KC.SOMETHING_ELSE, MAYBE_THIS_IS_A_MACRO, WHATEVER_YO)`, and place it in your @@ -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 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: ```python diff --git a/kmk/extensions/leader.py b/kmk/extensions/leader.py deleted file mode 100644 index d9a8c6e..0000000 --- a/kmk/extensions/leader.py +++ /dev/null @@ -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) - ) diff --git a/kmk/handlers/sequences.py b/kmk/handlers/sequences.py index a72c7bf..d7f61ac 100644 --- a/kmk/handlers/sequences.py +++ b/kmk/handlers/sequences.py @@ -97,9 +97,6 @@ def generate_codepoint_keysym_seq(codepoint, expected_length=4): # Not sure how to send emojis on Mac/Windows like that, # though, since (for example) the Canadian flag is assembled # 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))] for idx, codepoint_fragment in enumerate(reversed(codepoint)): @@ -108,10 +105,6 @@ def generate_codepoint_keysym_seq(codepoint, expected_length=4): return seq -def generate_leader_dictionary_seq(string): - return tuple(generate_codepoint_keysym_seq(string, 1)) - - def unicode_codepoint_sequence(codepoints): kc_seqs = (generate_codepoint_keysym_seq(codepoint) for codepoint in codepoints) diff --git a/kmk/handlers/stock.py b/kmk/handlers/stock.py index 3f9b69d..c85b063 100644 --- a/kmk/handlers/stock.py +++ b/kmk/handlers/stock.py @@ -5,7 +5,7 @@ def passthrough(key, state, *args, **kwargs): 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 if coord_int is not None: @@ -16,7 +16,7 @@ def default_pressed(key, state, KC, coord_int=None, coord_raw=None): 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.keys_pressed.discard(key) diff --git a/user_keymaps/kdb424/nyquist_r2.py b/user_keymaps/kdb424/nyquist_r2.py index ac89e1f..06200fe 100644 --- a/user_keymaps/kdb424/nyquist_r2.py +++ b/user_keymaps/kdb424/nyquist_r2.py @@ -2,7 +2,6 @@ import board from kb import KMKKeyboard from kmk.extensions.layers import Layers -from kmk.extensions.leader import Leader, LeaderMode from kmk.extensions.modtap import ModTap from kmk.extensions.rgb import RGB from kmk.handlers.sequences import send_string, simple_key_sequence @@ -13,17 +12,11 @@ keyboard = KMKKeyboard() # ------------------User level config variables --------------------------------------- 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() 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) -keyboard.extensions = [leader_ext, modtap, layers, rgb_ext] +keyboard.extensions = [modtap, layers, rgb_ext] _______ = KC.TRNS XXXXXXX = KC.NO @@ -111,7 +104,7 @@ keyboard.keymap = [ # 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.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, KC.RESET, _______, _______, _______, _______, _______, _______, KC.EQL, KC.HOME, KC.PGDN, KC.PGUP, KC.END, ], diff --git a/user_keymaps/klardotsh/iris_r2.py b/user_keymaps/klardotsh/iris_r2.py index e1eacac..de905eb 100644 --- a/user_keymaps/klardotsh/iris_r2.py +++ b/user_keymaps/klardotsh/iris_r2.py @@ -1,7 +1,6 @@ from kb import KMKKeyboard from kmk.consts import UnicodeMode 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 send_string 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.') -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 xxxxxxx = KC.NO HELLA_TD = KC.TD( @@ -72,8 +54,7 @@ HELLA_TD = KC.TD( KC.TG(1), ) -leader_ext = Leader(mode=LeaderMode.ENTER, sequences=leader_dictionary) -keyboard.extentions = [layers_ext, leader_ext] +keyboard.extentions = [layers_ext] 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, 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, 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, ], [ diff --git a/user_keymaps/klardotsh/klarank_featherm4.py b/user_keymaps/klardotsh/klarank_featherm4.py index 2f53fa4..a371ce4 100644 --- a/user_keymaps/klardotsh/klarank_featherm4.py +++ b/user_keymaps/klardotsh/klarank_featherm4.py @@ -1,6 +1,5 @@ from kb import KMKKeyboard 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 send_string from kmk.keys import KC, make_key @@ -52,22 +51,6 @@ HELLA_TD = KC.TD( 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): ''' @@ -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.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.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, ], [