diff options
author | Drashna Jaelre <drashna@live.com> | 2021-12-14 20:53:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-14 20:53:36 -0800 |
commit | 3fa592a4024a24a636fa0c562e6761667a94f565 (patch) | |
tree | 4ce826128e29e36dfe606fa2b5a3d25b3bd0afcc | |
parent | c10bc9f91e737dd3675b2e4492daa09092655af9 (diff) |
[Keymap] Unicode and Pointing Device and Autocorect for drashna keymaps (#15415)
45 files changed, 815 insertions, 187 deletions
diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f411/f411.c b/keyboards/handwired/tractyl_manuform/5x6_right/f411/f411.c index 700b0685f2..5cd269e311 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/f411/f411.c +++ b/keyboards/handwired/tractyl_manuform/5x6_right/f411/f411.c @@ -16,7 +16,7 @@ #include "f411.h" -void matrix_init_sub_kb(void) { setPinInputHigh(A0); } +void keyboard_pre_init_sub(void) { setPinInputHigh(A0); } void matrix_scan_sub_kb(void) { if (!readPin(A0)) { @@ -24,6 +24,33 @@ void matrix_scan_sub_kb(void) { } } +void bootmagic_lite(void) { + // We need multiple scans because debouncing can't be turned off. + matrix_scan(); +#if defined(DEBOUNCE) && DEBOUNCE > 0 + wait_ms(DEBOUNCE * 2); +#else + wait_ms(30); +#endif + matrix_scan(); + + uint8_t row = BOOTMAGIC_LITE_ROW; + uint8_t col = BOOTMAGIC_LITE_COLUMN; + +#if defined(SPLIT_KEYBOARD) && defined(BOOTMAGIC_LITE_ROW_RIGHT) && defined(BOOTMAGIC_LITE_COLUMN_RIGHT) + if (!is_keyboard_left()) { + row = BOOTMAGIC_LITE_ROW_RIGHT; + col = BOOTMAGIC_LITE_COLUMN_RIGHT; + } +#endif + + if (matrix_get_row(row) & (1 << col) || !readPin(A0)) { + eeconfig_disable(); + bootloader_jump(); + } +} + + #ifdef USB_VBUS_PIN bool usb_vbus_state(void) { setPinInputLow(USB_VBUS_PIN); diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f411/readme.md b/keyboards/handwired/tractyl_manuform/5x6_right/f411/readme.md index b387435122..f732295ba3 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/f411/readme.md +++ b/keyboards/handwired/tractyl_manuform/5x6_right/f411/readme.md @@ -1,7 +1,7 @@ # Drashna's Blackpill Tractyl Manuform (5x6) with a right side trackball * System Timer on TIM5 -* ~~VBUS mod, using PB10~~ (*doesn't seem to work for me*) +* VBUS mod, using PB10 -- does work, but not on my tractyl... bad soldering probably * Split Hand Pin, using PC14 * Full Duplex Serial/USART using PA2 and PA3 on USART2 * PWM Audio using PB1 and TIM3 and GPT on TIM4 @@ -12,7 +12,8 @@ * SSD1306 OLED display (128x64) using PB8-PB9 on I2C1 * Pull-up resistor (22k) on PA10 to fix reset issue. * Pull-up resistor (5.1k) on PA1 for WS2812 LED support, and wire it's VCC to the 5V pin. -* Pins PA9, PA11, A12 are not useable because they're used for USB connection, and can't be shared. +* Pins PA9 is meant for VBUS sense, and has an internal pulldown resistor. A 5.1k pullup resistor can work (but should be avoided) +* Pins PA11 and A12 are not useable because they're used for USB connection, and can't be shared. * Pin PB2 is used by BOOT1, and is unusable ## Keyboard Info diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/keymap.c b/keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/keymap.c index f893a8cc41..958f694172 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/keymap.c +++ b/keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/keymap.c @@ -16,11 +16,6 @@ #include "drashna.h" -enum tractyl_keycodes { - KC_ACCEL = NEW_SAFE_RANGE, -}; - -bool enable_acceleration = false; // clang-format off #define LAYOUT_5x6_right_wrapper(...) LAYOUT_5x6_right(__VA_ARGS__) #define LAYOUT_5x6_right_base( \ @@ -129,10 +124,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EEP_RST, KEYLOCK, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS, UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, KC_MPLY, - HPT_DWLI, HPT_DWLD, TG_GAME, TG_DBLO, - HPT_TOG, HPT_BUZ, KC_NUKE, + TG(_DIABLOII), AUTO_CTN, TG_GAME, TG_DBLO, + _______, _______, KC_NUKE, _______, _______, _______, - _______, TG(_DIABLOII),KC_NUKE, _______ + _______, _______, KC_NUKE, _______ ), }; @@ -169,116 +164,6 @@ bool encoder_update_user(uint8_t index, bool clockwise) { } #endif -#ifdef POINTING_DEVICE_ENABLE -static uint16_t mouse_timer = 0; -static uint16_t mouse_debounce_timer = 0; -static uint8_t mouse_keycode_tracker = 0; -bool tap_toggling = false; - -# ifdef TAPPING_TERM_PER_KEY -# define TAP_CHECK get_tapping_term(KC_BTN1, NULL) -# else -# ifndef TAPPING_TERM -# define TAPPING_TERM 200 -# endif -# define TAP_CHECK TAPPING_TERM -# endif - -report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { - int8_t x = mouse_report.x, y = mouse_report.y; - mouse_report.x = 0; - mouse_report.y = 0; - - if (x != 0 && y != 0) { - mouse_timer = timer_read(); -# ifdef OLED_ENABLE - oled_timer = timer_read32(); -# endif - if (timer_elapsed(mouse_debounce_timer) > TAP_CHECK) { - if (enable_acceleration) { - x = (x > 0 ? x * x / 16 + x : -x * x / 16 + x); - y = (y > 0 ? y * y / 16 + y : -y * y / 16 + y); - } - mouse_report.x = x; - mouse_report.y = y; - if (!layer_state_is(_MOUSE)) { - layer_on(_MOUSE); - } - } - } - return mouse_report; -} - -void matrix_scan_keymap(void) { - if (timer_elapsed(mouse_timer) > 650 && layer_state_is(_MOUSE) && !mouse_keycode_tracker && !tap_toggling) { - layer_off(_MOUSE); - } - if (tap_toggling) { - if (!layer_state_is(_MOUSE)) { - layer_on(_MOUSE); - } - } -} - -bool process_record_keymap(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - case TT(_MOUSE): - if (record->event.pressed) { - mouse_keycode_tracker++; - } else { -# if TAPPING_TOGGLE != 0 - if (record->tap.count == TAPPING_TOGGLE) { - tap_toggling ^= 1; -# if TAPPING_TOGGLE == 1 - if (!tap_toggling) mouse_keycode_tracker -= record->tap.count + 1; -# else - if (!tap_toggling) mouse_keycode_tracker -= record->tap.count; -# endif - } else { - mouse_keycode_tracker--; - } -# endif - } - mouse_timer = timer_read(); - break; - case TG(_MOUSE): - if (record->event.pressed) { - tap_toggling ^= 1; - } - break; - case MO(_MOUSE): - case DPI_CONFIG: - case KC_MS_UP ... KC_MS_WH_RIGHT: - record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--; - mouse_timer = timer_read(); - case KC_ACCEL: - enable_acceleration = record->event.pressed; - break; - default: - if (IS_NOEVENT(record->event)) break; - if ((keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) && (((keycode >> 0x8) & 0xF) == _MOUSE)) { - record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--; - mouse_timer = timer_read(); - break; - } - if (layer_state_is(_MOUSE) && !mouse_keycode_tracker) { - layer_off(_MOUSE); - } - mouse_keycode_tracker = 0; - mouse_debounce_timer = timer_read(); - break; - } - return true; -} - -layer_state_t layer_state_set_keymap(layer_state_t state) { - if (layer_state_cmp(state, _GAMEPAD) || layer_state_cmp(state, _DIABLO)) { - state |= ((layer_state_t)1 << _MOUSE); - } - return state; -} -#endif - #ifdef OLED_ENABLE // WPM-responsive animation stuff here # define SLEEP_FRAMES 2 diff --git a/keyboards/handwired/tractyl_manuform/tm_sync.c b/keyboards/handwired/tractyl_manuform/tm_sync.c index 733f09a22e..549a17a22f 100644 --- a/keyboards/handwired/tractyl_manuform/tm_sync.c +++ b/keyboards/handwired/tractyl_manuform/tm_sync.c @@ -1,5 +1,6 @@ /* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> - * + * Copyright 2021 Dasky (@daskygit) + * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or diff --git a/keyboards/handwired/tractyl_manuform/tractyl_manuform.c b/keyboards/handwired/tractyl_manuform/tractyl_manuform.c index 4b36fab54f..6095bfb7e2 100644 --- a/keyboards/handwired/tractyl_manuform/tractyl_manuform.c +++ b/keyboards/handwired/tractyl_manuform/tractyl_manuform.c @@ -70,6 +70,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t* record) { return true; } __attribute__((weak)) void keyboard_pre_init_sync(void) {} +__attribute__((weak)) void keyboard_pre_init_sub(void) {} void keyboard_pre_init_kb(void) { // debug_enable = true; // debug_matrix = true; @@ -82,6 +83,7 @@ void keyboard_pre_init_kb(void) { writePin(DEBUG_LED_PIN, !debug_enable); #endif + keyboard_pre_init_sub(); keyboard_pre_init_sync(); keyboard_pre_init_user(); } diff --git a/keyboards/keebio/iris/keymaps/drashna/rules.mk b/keyboards/keebio/iris/keymaps/drashna/rules.mk index 41c67b573d..ca140d76ce 100644 --- a/keyboards/keebio/iris/keymaps/drashna/rules.mk +++ b/keyboards/keebio/iris/keymaps/drashna/rules.mk @@ -1,17 +1,17 @@ -BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite -MOUSEKEY_ENABLE = no # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = no # Console for debug(+400) -COMMAND_ENABLE = no # Commands for debug and configuration -TAP_DANCE_ENABLE = no -RGBLIGHT_ENABLE = yes -AUDIO_ENABLE = no -NKRO_ENABLE = yes -BACKLIGHT_ENABLE = no -SWAP_HANDS_ENABLE = no -SPACE_CADET_ENABLE = no - -INDICATOR_LIGHTS = no -RGBLIGHT_STARTUP_ANIMATION = no - +BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite +MOUSEKEY_ENABLE = no # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +TAP_DANCE_ENABLE = no +RGBLIGHT_ENABLE = yes +AUDIO_ENABLE = no +NKRO_ENABLE = yes +BACKLIGHT_ENABLE = no +SWAP_HANDS_ENABLE = no BOOTLOADER = qmk-dfu + +INDICATOR_LIGHTS = no +RGBLIGHT_STARTUP_ANIMATION = no +CUSTOM_UNICODE_ENABLE = no +CUSTOM_SPLIT_TRANSPORT_SYNC = no diff --git a/keyboards/moonlander/keymaps/drashna/keymap.c b/keyboards/moonlander/keymaps/drashna/keymap.c index cd53b1e100..1b5280e742 100644 --- a/keyboards/moonlander/keymaps/drashna/keymap.c +++ b/keyboards/moonlander/keymaps/drashna/keymap.c @@ -110,7 +110,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { VRSN, _________________ADJUST_L1_________________, TG(_DIABLOII), _______, _________________ADJUST_R1_________________, EEP_RST, KEYLOCK, _________________ADJUST_L2_________________, _______, _______, _________________ADJUST_R2_________________, RGB_IDL, UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PAUS, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, AUTO_CTN, _______, _______, _______, _______, _______, _______ ), }; diff --git a/keyboards/orthodox/keymaps/drashna/rules.mk b/keyboards/orthodox/keymaps/drashna/rules.mk index 6f72712d84..9637d3b395 100644 --- a/keyboards/orthodox/keymaps/drashna/rules.mk +++ b/keyboards/orthodox/keymaps/drashna/rules.mk @@ -11,6 +11,6 @@ SPACE_CADET_ENABLE = no INDICATOR_LIGHTS = yes RGBLIGHT_STARTUP_ANIMATION = yes - +CUSTOM_UNICODE_ENABLE = no BOOTLOADER = qmk-dfu diff --git a/keyboards/splitkb/zima/keymaps/drashna/config.h b/keyboards/splitkb/zima/keymaps/drashna/config.h index 8d0908182e..b4457ec4b8 100644 --- a/keyboards/splitkb/zima/keymaps/drashna/config.h +++ b/keyboards/splitkb/zima/keymaps/drashna/config.h @@ -17,7 +17,7 @@ #pragma once -#define OLED_FONT_H "users/drashna/drashna_font.h" +#define OLED_FONT_H "users/drashna/oled/drashna_font.h" #define OLED_UPDATE_INTERVAL 15 #define OLED_DISABLE_TIMEOUT #define OLED_FONT_END 255 diff --git a/layouts/community/ergodox/drashna/rules.mk b/layouts/community/ergodox/drashna/rules.mk index 853f1efd24..61b6263071 100644 --- a/layouts/community/ergodox/drashna/rules.mk +++ b/layouts/community/ergodox/drashna/rules.mk @@ -1,4 +1,4 @@ -BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite TAP_DANCE_ENABLE = no COMMAND_ENABLE = no # Commands for debug and configuration CONSOLE_ENABLE = no @@ -9,12 +9,12 @@ ifeq ($(strip $(KEYBOARD)), ergodox_ez) RGB_MATRIX_ENABLE = yes INDICATOR_LIGHTS = no RGBLIGHT_STARTUP_ANIMATION = yes - PIMORONI_TRACKBALL_ENABLE = yes + PIMORONI_TRACKBALL_ENABLE = no MOUSEKEY_ENABLE = no endif -UNICODE_ENABLE = no -UNICDOEMAP_ENABLE = no - +UNICODE_ENABLE = no +UNICDOEMAP_ENABLE = no +CUSTOM_UNICODE_ENABLE = no DEBOUNCE_TYPE = sym_eager_pr diff --git a/layouts/community/ortho_5x12/drashna/rules.mk b/layouts/community/ortho_5x12/drashna/rules.mk index 69a025cc03..98ac829092 100644 --- a/layouts/community/ortho_5x12/drashna/rules.mk +++ b/layouts/community/ortho_5x12/drashna/rules.mk @@ -14,4 +14,5 @@ ifeq ($(strip $(KEYBOARD)), fractal) RGBLIGHT_ENABLE = yes RGBLIGHT_STARTUP_ANIMATION = yes BOOTLOADER = qmk-dfu + CUSTOM_UNICODE_ENABLE = no endif diff --git a/layouts/community/split_3x6_3/drashna/rules.mk b/layouts/community/split_3x6_3/drashna/rules.mk index edc9304fec..cf2dfbdc88 100644 --- a/layouts/community/split_3x6_3/drashna/rules.mk +++ b/layouts/community/split_3x6_3/drashna/rules.mk @@ -32,6 +32,7 @@ ifeq ($(strip $(CTPC)), yes) SWAP_HANDS_ENABLE = yes WPM_ENABLE = yes else + CUSTOM_UNICODE_ENABLE = no BOOTLOADER = qmk-hid BOOTLOADER_SIZE = 512 endif diff --git a/users/drashna/config.h b/users/drashna/config.h index 8b5d5ba937..cc8f9ac83c 100644 --- a/users/drashna/config.h +++ b/users/drashna/config.h @@ -77,7 +77,7 @@ # endif #endif // !AUDIO_ENABLE -#define UNICODE_SELECTED_MODES UC_WIN, UC_MAC +#define UNICODE_SELECTED_MODES UC_WINC, UC_MAC #ifdef RGBLIGHT_ENABLE # define RGBLIGHT_SLEEP @@ -200,7 +200,7 @@ # ifdef OLED_FONT_H # undef OLED_FONT_H # endif -# define OLED_FONT_H "drashna_font.h" +# define OLED_FONT_H "oled/drashna_font.h" # define OLED_FONT_END 255 // # define OLED_FONT_5X5 // # define OLED_FONT_AZTECH diff --git a/users/drashna/drashna.c b/users/drashna/drashna.c index 7e07a2c7c5..9c1233ed90 100644 --- a/users/drashna/drashna.c +++ b/users/drashna/drashna.c @@ -70,7 +70,9 @@ void matrix_init_user(void) { DDRB &= ~(1 << 0); PORTB &= ~(1 << 0); #endif - +#ifdef CUSTOM_UNICODE_ENABLE + matrix_init_unicode(); +#endif matrix_init_secret(); matrix_init_keymap(); } @@ -152,6 +154,9 @@ void matrix_scan_user(void) { #if defined(RGB_MATRIX_ENABLE) matrix_scan_rgb_matrix(); #endif +#if defined(POINTING_DEVICE_ENABLE) + matrix_scan_pointing(); +#endif matrix_scan_secret(); @@ -171,6 +176,9 @@ layer_state_t layer_state_set_user(layer_state_t state) { } state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST); +#if defined(POINTING_DEVICE_ENABLE) + state = layer_state_set_pointing(state); +#endif #if defined(RGBLIGHT_ENABLE) state = layer_state_set_rgb_light(state); #endif // RGBLIGHT_ENABLE diff --git a/users/drashna/drashna.h b/users/drashna/drashna.h index 6a45141d9a..7bcae881e4 100644 --- a/users/drashna/drashna.h +++ b/users/drashna/drashna.h @@ -18,25 +18,25 @@ #include QMK_KEYBOARD_H #include "eeprom.h" -#include "wrappers.h" -#include "process_records.h" +#include "keyrecords/wrappers.h" +#include "keyrecords/process_records.h" #ifdef TAP_DANCE_ENABLE -# include "tap_dances.h" +# include "keyrecords/tap_dances.h" #endif // TAP_DANCE_ENABLE #if defined(RGBLIGHT_ENABLE) -# include "rgb_stuff.h" +# include "rgb/rgb_stuff.h" #endif #if defined(RGB_MATRIX_ENABLE) -# include "rgb_matrix_stuff.h" +# include "rgb/rgb_matrix_stuff.h" #endif #if defined(OLED_ENABLE) -# include "oled_stuff.h" -#endif -#if defined(PIMORONI_TRACKBALL_ENABLE) -# include "drivers/sensors/pimoroni_trackball.h" +# include "oled/oled_stuff.h" #endif #ifdef SPLIT_KEYBOARD -# include "transport_sync.h" +# include "split/transport_sync.h" +#endif +#ifdef POINTING_DEVICE_ENABLE +# include "pointing/pointing.h" #endif /* Define layer names */ @@ -113,6 +113,7 @@ typedef union { bool nuke_switch :1; bool swapped_numbers :1; bool rgb_matrix_idle_anim :1; + bool autocorrection :1; }; } userspace_config_t; // clang-format on diff --git a/users/drashna/keyrecords/autocorrection/autocorrection.c b/users/drashna/keyrecords/autocorrection/autocorrection.c new file mode 100644 index 0000000000..7c8c28c674 --- /dev/null +++ b/users/drashna/keyrecords/autocorrection/autocorrection.c @@ -0,0 +1,143 @@ +// Copyright 2021 Google LLC +// Copyright 2022 @filterpaper +// SPDX-License-Identifier: Apache-2.0 +// Original source: https://getreuer.info/posts/keyboards/autocorrection + +#include "autocorrection.h" +#include <string.h> + +#if __has_include("autocorrection_data.h") +# include "autocorrection_data.h" +# if AUTOCORRECTION_MIN_LENGTH < 4 +# error Minimum Length is too short and may cause overflows +# endif + +bool process_autocorrection(uint16_t keycode, keyrecord_t* record) { + static uint8_t typo_buffer[AUTOCORRECTION_MAX_LENGTH] = {KC_SPC}; + static uint8_t typo_buffer_size = 1; + + if (keycode == AUTO_CTN) { + if (record->event.pressed) { + typo_buffer_size = 0; + userspace_config.autocorrection ^= 1; + eeconfig_update_user(userspace_config.raw); + } + return false; + } + + if (!userspace_config.autocorrection) { + typo_buffer_size = 0; + return true; + } + + switch (keycode) { + case KC_LSFT: + case KC_RSFT: + return true; +# ifndef NO_ACTION_TAPPING + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + if (((keycode >> 8) & 0xF) == MOD_LSFT) { + return true; + } +# ifndef NO_ACTION_LAYER + case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: +# endif + if (record->event.pressed || !record->tap.count) { + return true; + } + keycode &= 0xFF; + break; +# endif +# ifndef NO_ACTION_ONESHOT + case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: + if ((keycode & 0xF) == MOD_LSFT) { + return true; + } +# endif + default: + if (!record->event.pressed) { + return true; + } + } + + // Subtract buffer for Backspace key, reset for other non-alpha. + if (!(KC_A <= keycode && keycode <= KC_Z)) { + if (keycode == KC_BSPC) { + // Remove last character from the buffer. + if (typo_buffer_size > 0) { + --typo_buffer_size; + } + return true; + } else if (KC_1 <= keycode && keycode <= KC_SLSH && keycode != KC_ESC) { + // Set a word boundary if space, period, digit, etc. is pressed. + // Behave more conservatively for the enter key. Reset, so that enter + // can't be used on a word ending. + if (keycode == KC_ENT) { + typo_buffer_size = 0; + } + keycode = KC_SPC; + } else { + // Clear state if some other non-alpha key is pressed. + typo_buffer_size = 0; + return true; + } + } + + // Rotate oldest character if buffer is full. + if (typo_buffer_size >= AUTOCORRECTION_MAX_LENGTH) { + memmove(typo_buffer, typo_buffer + 1, AUTOCORRECTION_MAX_LENGTH - 1); + typo_buffer_size = AUTOCORRECTION_MAX_LENGTH - 1; + } + + // Append `keycode` to buffer. + typo_buffer[typo_buffer_size++] = keycode; + // Return if buffer is smaller than the shortest word. + if (typo_buffer_size < AUTOCORRECTION_MIN_LENGTH) { + return true; + } + + // Check for typo in buffer using a trie stored in `autocorrection_data`. + uint16_t state = 0; + uint8_t code = pgm_read_byte(autocorrection_data + state); + for (uint8_t i = typo_buffer_size - 1; i >= 0; --i) { + uint8_t const key_i = typo_buffer[i]; + + if (code & 64) { // Check for match in node with multiple children. + code &= 63; + for (; code != key_i; code = pgm_read_byte(autocorrection_data + (state += 3))) { + if (!code) return true; + } + // Follow link to child node. + state = (pgm_read_byte(autocorrection_data + state + 1) | pgm_read_byte(autocorrection_data + state + 2) << 8); + // Check for match in node with single child. + } else if (code != key_i) { + return true; + } else if (!(code = pgm_read_byte(autocorrection_data + (++state)))) { + ++state; + } + + code = pgm_read_byte(autocorrection_data + state); + + if (code & 128) { // A typo was found! Apply autocorrection. + const uint8_t backspaces = code & 63; + for (uint8_t i = 0; i < backspaces; ++i) { + tap_code(KC_BSPC); |