123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- #include "process_autocorrect.h"
- #include <string.h>
- #include "keycode_config.h"
- #if __has_include("autocorrect_data.h")
- # include "autocorrect_data.h"
- #else
- # pragma message "Autocorrect is using the default library."
- # include "autocorrect_data_default.h"
- #endif
- static uint8_t typo_buffer[AUTOCORRECT_MAX_LENGTH] = {KC_SPC};
- static uint8_t typo_buffer_size = 1;
- bool autocorrect_is_enabled(void) {
- return keymap_config.autocorrect_enable;
- }
- void autocorrect_enable(void) {
- keymap_config.autocorrect_enable = true;
- eeconfig_update_keymap(keymap_config.raw);
- }
- void autocorrect_disable(void) {
- keymap_config.autocorrect_enable = false;
- typo_buffer_size = 0;
- eeconfig_update_keymap(keymap_config.raw);
- }
- void autocorrect_toggle(void) {
- keymap_config.autocorrect_enable = !keymap_config.autocorrect_enable;
- typo_buffer_size = 0;
- eeconfig_update_keymap(keymap_config.raw);
- }
- __attribute__((weak)) bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) {
-
- switch (*keycode) {
-
- case KC_LSFT:
- case KC_RSFT:
- case KC_CAPS:
- case QK_TO ... QK_ONE_SHOT_LAYER_MAX:
- case QK_LAYER_TAP_TOGGLE ... QK_LAYER_MOD_MAX:
- case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
- return false;
-
- case QK_LSFT ... QK_LSFT + 255:
- case QK_RSFT ... QK_RSFT + 255:
- if (*keycode >= QK_LSFT && *keycode <= (QK_LSFT + 255)) {
- *mods |= MOD_LSFT;
- } else {
- *mods |= MOD_RSFT;
- }
- *keycode &= 0xFF;
- return true;
- #ifndef NO_ACTION_TAPPING
-
-
- case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
- # ifdef NO_ACTION_LAYER
-
-
- return false;
- # endif
- case QK_MOD_TAP ... QK_MOD_TAP_MAX:
-
- if (!record->tap.count) {
- return false;
- }
- *keycode &= 0xFF;
- break;
- #else
- case QK_MOD_TAP ... QK_MOD_TAP_MAX:
- case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
-
- return false;
- #endif
-
-
- case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
- #ifdef SWAP_HANDS_ENABLE
- if (*keycode >= 0x56F0 || !record->tap.count) {
- return false;
- }
- *keycode &= 0xFF;
- break;
- #else
-
- return false;
- #endif
- }
-
- if ((*mods & ~MOD_MASK_SHIFT) != 0) {
- *typo_buffer_size = 0;
- return false;
- }
- return true;
- }
- __attribute__((weak)) bool apply_autocorrect(uint8_t backspaces, const char *str) {
- return true;
- }
- bool process_autocorrect(uint16_t keycode, keyrecord_t *record) {
- uint8_t mods = get_mods();
- #ifndef NO_ACTION_ONESHOT
- mods |= get_oneshot_mods();
- #endif
- if ((keycode >= AUTOCORRECT_ON && keycode <= AUTOCORRECT_TOGGLE) && record->event.pressed) {
- if (keycode == AUTOCORRECT_ON) {
- autocorrect_enable();
- } else if (keycode == AUTOCORRECT_OFF) {
- autocorrect_disable();
- } else if (keycode == AUTOCORRECT_TOGGLE) {
- autocorrect_toggle();
- } else {
- return true;
- }
- return false;
- }
- if (!keymap_config.autocorrect_enable) {
- typo_buffer_size = 0;
- return true;
- }
- if (!record->event.pressed) {
- return true;
- }
-
- if (!process_autocorrect_user(&keycode, record, &typo_buffer_size, &mods)) {
- return true;
- }
-
- switch (keycode) {
- case KC_A ... KC_Z:
-
- break;
- case KC_1 ... KC_0:
- case KC_TAB ... KC_SEMICOLON:
- case KC_GRAVE ... KC_SLASH:
-
- keycode = KC_SPC;
- break;
- case KC_ENTER:
-
-
- typo_buffer_size = 0;
- keycode = KC_SPC;
- break;
- case KC_BSPC:
-
- if (typo_buffer_size > 0) {
- --typo_buffer_size;
- }
- return true;
- case KC_QUOTE:
-
- if ((mods & MOD_MASK_SHIFT) != 0) {
- keycode = KC_SPC;
- }
- break;
- default:
-
- typo_buffer_size = 0;
- return true;
- }
-
- if (typo_buffer_size >= AUTOCORRECT_MAX_LENGTH) {
- memmove(typo_buffer, typo_buffer + 1, AUTOCORRECT_MAX_LENGTH - 1);
- typo_buffer_size = AUTOCORRECT_MAX_LENGTH - 1;
- }
-
- typo_buffer[typo_buffer_size++] = keycode;
-
- if (typo_buffer_size < AUTOCORRECT_MIN_LENGTH) {
- return true;
- }
-
- uint16_t state = 0;
- uint8_t code = pgm_read_byte(autocorrect_data + state);
- for (int8_t i = typo_buffer_size - 1; i >= 0; --i) {
- uint8_t const key_i = typo_buffer[i];
- if (code & 64) {
- code &= 63;
- for (; code != key_i; code = pgm_read_byte(autocorrect_data + (state += 3))) {
- if (!code) return true;
- }
-
- state = (pgm_read_byte(autocorrect_data + state + 1) | pgm_read_byte(autocorrect_data + state + 2) << 8);
-
- } else if (code != key_i) {
- return true;
- } else if (!(code = pgm_read_byte(autocorrect_data + (++state)))) {
- ++state;
- }
-
-
- if (state >= DICTIONARY_SIZE) {
- return true;
- }
- code = pgm_read_byte(autocorrect_data + state);
- if (code & 128) {
- const uint8_t backspaces = (code & 63) + !record->event.pressed;
- if (apply_autocorrect(backspaces, (char const *)(autocorrect_data + state + 1))) {
- for (uint8_t i = 0; i < backspaces; ++i) {
- tap_code(KC_BSPC);
- }
- send_string_P((char const *)(autocorrect_data + state + 1));
- }
- if (keycode == KC_SPC) {
- typo_buffer[0] = KC_SPC;
- typo_buffer_size = 1;
- return true;
- } else {
- typo_buffer_size = 0;
- return false;
- }
- }
- }
- return true;
- }
|