diff --git a/kmk/handlers/sequences.py b/kmk/handlers/sequences.py index 2eaa371..933b7a2 100644 --- a/kmk/handlers/sequences.py +++ b/kmk/handlers/sequences.py @@ -1,5 +1,7 @@ +from kmk.consts import UnicodeMode from kmk.keycodes import KC, make_key -from kmk.types import KeySequenceMeta +from kmk.types import AttrDict, KeySequenceMeta +from kmk.util import get_wide_ordinal def sequence_press_handler(key, state, KC, *args, **kwargs): @@ -38,3 +40,111 @@ def send_string(message): seq.append(kc) return simple_key_sequence(seq) + + +IBUS_KEY_COMBO = simple_key_sequence((KC.LCTRL(KC.LSHIFT(KC.U)),)) +RALT_KEY = simple_key_sequence((KC.RALT,)) +U_KEY = simple_key_sequence((KC.U,)) +ENTER_KEY = simple_key_sequence((KC.ENTER,)) +RALT_DOWN_NO_RELEASE = simple_key_sequence((KC.RALT(no_release=True),)) +RALT_UP_NO_PRESS = simple_key_sequence((KC.RALT(no_press=True),)) + + +def compile_unicode_string_sequences(string_table): + for k, v in string_table.items(): + string_table[k] = unicode_string_sequence(v) + + return AttrDict(string_table) + + +def unicode_string_sequence(unistring): + ''' + Allows sending things like (╯°□°)╯︵ ┻━┻ directly, without + manual conversion to Unicode codepoints. + ''' + return unicode_codepoint_sequence([ + hex(get_wide_ordinal(s))[2:] + for s in unistring + ]) + + +def generate_codepoint_keysym_seq(codepoint, expected_length=4): + # To make MacOS and Windows happy, always try to send + # sequences that are of length 4 at a minimum + # On Linux systems, we can happily send longer strings. + # They will almost certainly break on MacOS and Windows, + # but this is a documentation problem more than anything. + # 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)): + seq[-(idx + 1)] = KC.get(codepoint_fragment) + + 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 + ) + + kc_macros = [ + simple_key_sequence(kc_seq) + for kc_seq in kc_seqs + ] + + def _unicode_sequence(key, state, *args, **kwargs): + if state.config.unicode_mode == UnicodeMode.IBUS: + state.process_key( + simple_key_sequence(_ibus_unicode_sequence(kc_macros, state)), + True, + ) + elif state.config.unicode_mode == UnicodeMode.RALT: + state.process_key( + simple_key_sequence(_ralt_unicode_sequence(kc_macros, state)), + True, + ) + elif state.config.unicode_mode == UnicodeMode.WINC: + state.process_key( + simple_key_sequence(_winc_unicode_sequence(kc_macros, state)), + True, + ) + + return make_key(on_press=_unicode_sequence) + + +def _ralt_unicode_sequence(kc_macros, state): + for kc_macro in kc_macros: + yield RALT_DOWN_NO_RELEASE + yield kc_macro + yield RALT_UP_NO_PRESS + + +def _ibus_unicode_sequence(kc_macros, state): + for kc_macro in kc_macros: + yield IBUS_KEY_COMBO + yield kc_macro + yield ENTER_KEY + + +def _winc_unicode_sequence(kc_macros, state): + ''' + Send unicode sequence using WinCompose: + + http://wincompose.info/ + https://github.com/SamHocevar/wincompose + ''' + for kc_macro in kc_macros: + yield RALT_KEY + yield U_KEY + yield kc_macro diff --git a/kmk/macros/__init__.py b/kmk/macros/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/kmk/macros/unicode.py b/kmk/macros/unicode.py deleted file mode 100644 index 1eac257..0000000 --- a/kmk/macros/unicode.py +++ /dev/null @@ -1,112 +0,0 @@ -from kmk.consts import UnicodeMode -from kmk.handlers.sequences import simple_key_sequence -from kmk.keycodes import KC, make_key -from kmk.types import AttrDict -from kmk.util import get_wide_ordinal - -IBUS_KEY_COMBO = simple_key_sequence((KC.LCTRL(KC.LSHIFT(KC.U)),)) -RALT_KEY = simple_key_sequence((KC.RALT,)) -U_KEY = simple_key_sequence((KC.U,)) -ENTER_KEY = simple_key_sequence((KC.ENTER,)) -RALT_DOWN_NO_RELEASE = simple_key_sequence((KC.RALT(no_release=True),)) -RALT_UP_NO_PRESS = simple_key_sequence((KC.RALT(no_press=True),)) - - -def compile_unicode_string_sequences(string_table): - for k, v in string_table.items(): - string_table[k] = unicode_string_sequence(v) - - return AttrDict(string_table) - - -def unicode_string_sequence(unistring): - ''' - Allows sending things like (╯°□°)╯︵ ┻━┻ directly, without - manual conversion to Unicode codepoints. - ''' - return unicode_codepoint_sequence([ - hex(get_wide_ordinal(s))[2:] - for s in unistring - ]) - - -def generate_codepoint_keysym_seq(codepoint, expected_length=4): - # To make MacOS and Windows happy, always try to send - # sequences that are of length 4 at a minimum - # On Linux systems, we can happily send longer strings. - # They will almost certainly break on MacOS and Windows, - # but this is a documentation problem more than anything. - # 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)): - seq[-(idx + 1)] = KC.get(codepoint_fragment) - - 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 - ) - - kc_macros = [ - simple_key_sequence(kc_seq) - for kc_seq in kc_seqs - ] - - def _unicode_sequence(key, state, *args, **kwargs): - if state.config.unicode_mode == UnicodeMode.IBUS: - state.process_key( - simple_key_sequence(_ibus_unicode_sequence(kc_macros, state)), - True, - ) - elif state.config.unicode_mode == UnicodeMode.RALT: - state.process_key( - simple_key_sequence(_ralt_unicode_sequence(kc_macros, state)), - True, - ) - elif state.config.unicode_mode == UnicodeMode.WINC: - state.process_key( - simple_key_sequence(_winc_unicode_sequence(kc_macros, state)), - True, - ) - - return make_key(on_press=_unicode_sequence) - - -def _ralt_unicode_sequence(kc_macros, state): - for kc_macro in kc_macros: - yield RALT_DOWN_NO_RELEASE - yield kc_macro - yield RALT_UP_NO_PRESS - - -def _ibus_unicode_sequence(kc_macros, state): - for kc_macro in kc_macros: - yield IBUS_KEY_COMBO - yield kc_macro - yield ENTER_KEY - - -def _winc_unicode_sequence(kc_macros, state): - ''' - Send unicode sequence using WinCompose: - - http://wincompose.info/ - https://github.com/SamHocevar/wincompose - ''' - for kc_macro in kc_macros: - yield RALT_KEY - yield U_KEY - yield kc_macro diff --git a/user_keymaps/klardotsh/klarank_featherm4.py b/user_keymaps/klardotsh/klarank_featherm4.py index 5393759..c9fbf2c 100644 --- a/user_keymaps/klardotsh/klarank_featherm4.py +++ b/user_keymaps/klardotsh/klarank_featherm4.py @@ -1,8 +1,8 @@ from kmk.boards.klarank import Firmware from kmk.consts import LeaderMode, UnicodeMode +from kmk.handlers.sequences import compile_unicode_string_sequences as cuss from kmk.handlers.sequences import send_string -from kmk.keycodes import KC -from kmk.macros.unicode import compile_unicode_string_sequences as cuss +from kmk.keycodes import KC, make_key keyboard = Firmware() @@ -65,6 +65,31 @@ HELLA_TD = KC.TD( ) +def shrek_is_life(*args, **kwargs): + ''' + Proof macros are a thing and don't actually have to care about the state. At all. + ''' + + print('⢀⡴⠑⡄⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀') + print('⠸⡇⠀⠿⡀⠀⠀⠀⣀⡴⢿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠑⢄⣠⠾⠁⣀⣄⡈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⢀⡀⠁⠀⠀⠈⠙⠛⠂⠈⣿⣿⣿⣿⣿⠿⡿⢿⣆⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⢀⡾⣁⣀⠀⠴⠂⠙⣗⡀⠀⢻⣿⣿⠭⢤⣴⣦⣤⣹⠀⠀⠀⢀⢴⣶⣆') + print('⠀⠀⢀⣾⣿⣿⣿⣷⣮⣽⣾⣿⣥⣴⣿⣿⡿⢂⠔⢚⡿⢿⣿⣦⣴⣾⠁⠸⣼⡿') + print('⠀⢀⡞⠁⠙⠻⠿⠟⠉⠀⠛⢹⣿⣿⣿⣿⣿⣌⢤⣼⣿⣾⣿⡟⠉⠀⠀⠀⠀⠀') + print('⠀⣾⣷⣶⠇⠀⠀⣤⣄⣀⡀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀') + print('⠀⠉⠈⠉⠀⠀⢦⡈⢻⣿⣿⣿⣶⣶⣶⣶⣤⣽⡹⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠀⠀⠀⠉⠲⣽⡻⢿⣿⣿⣿⣿⣿⣿⣷⣜⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣷⣶⣮⣭⣽⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠀⠀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀') + print('⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠛⠉') + + +SHREK_IS_LOVE = make_key(on_press=shrek_is_life) + + 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], @@ -81,7 +106,7 @@ keyboard.keymap = [ ], [ - [KC.GESC, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.BSLS, KC.LBRC, KC.RBRC, KC.DEL], + [KC.GESC, SHREK_IS_LOVE, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.BSLS, KC.LBRC, KC.RBRC, KC.DEL], [KC.TAB, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.MINS], [KC.LGUI, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.LBRC, xxxxxxx, xxxxxxx, KC.INS], [KC.LCTL, xxxxxxx, _______, _______, xxxxxxx, _______, xxxxxxx, xxxxxxx, KC.HOME, KC.PGDN, KC.PGUP, KC.END],