diff options
Diffstat (limited to 'quantum/process_keycode/process_autocorrect.c')
| -rw-r--r-- | quantum/process_keycode/process_autocorrect.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/quantum/process_keycode/process_autocorrect.c b/quantum/process_keycode/process_autocorrect.c index 7c9cb814e5..cc1f19e4f9 100644 --- a/quantum/process_keycode/process_autocorrect.c +++ b/quantum/process_keycode/process_autocorrect.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | // Copyright 2021 Google LLC | 1 | // Copyright 2021 Google LLC |
| 2 | // Copyright 2021 @filterpaper | 2 | // Copyright 2021 @filterpaper |
| 3 | // Copyright 2023 Pablo Martinez (@elpekenin) <elpekenin@elpekenin.dev> | ||
| 3 | // SPDX-License-Identifier: Apache-2.0 | 4 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | // Original source: https://getreuer.info/posts/keyboards/autocorrection | 5 | // Original source: https://getreuer.info/posts/keyboards/autocorrection |
| 5 | 6 | ||
| @@ -174,10 +175,12 @@ bool process_autocorrect_default_handler(uint16_t *keycode, keyrecord_t *record, | |||
| 174 | * | 175 | * |
| 175 | * @param backspaces number of characters to remove | 176 | * @param backspaces number of characters to remove |
| 176 | * @param str pointer to PROGMEM string to replace mistyped seletion with | 177 | * @param str pointer to PROGMEM string to replace mistyped seletion with |
| 178 | * @param typo the wrong string that triggered a correction | ||
| 179 | * @param correct what it would become after the changes | ||
| 177 | * @return true apply correction | 180 | * @return true apply correction |
| 178 | * @return false user handled replacement | 181 | * @return false user handled replacement |
| 179 | */ | 182 | */ |
| 180 | __attribute__((weak)) bool apply_autocorrect(uint8_t backspaces, const char *str) { | 183 | __attribute__((weak)) bool apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct) { |
| 181 | return true; | 184 | return true; |
| 182 | } | 185 | } |
| 183 | 186 | ||
| @@ -301,11 +304,57 @@ bool process_autocorrect(uint16_t keycode, keyrecord_t *record) { | |||
| 301 | 304 | ||
| 302 | if (code & 128) { // A typo was found! Apply autocorrect. | 305 | if (code & 128) { // A typo was found! Apply autocorrect. |
| 303 | const uint8_t backspaces = (code & 63) + !record->event.pressed; | 306 | const uint8_t backspaces = (code & 63) + !record->event.pressed; |
| 304 | if (apply_autocorrect(backspaces, (char const *)(autocorrect_data + state + 1))) { | 307 | const char * changes = (const char *)(autocorrect_data + state + 1); |
| 308 | |||
| 309 | /* Gather info about the typo'd word | ||
| 310 | * | ||
| 311 | * Since buffer may contain several words, delimited by spaces, we | ||
| 312 | * iterate from the end to find the start and length of the typo | ||
| 313 | */ | ||
| 314 | char typo[AUTOCORRECT_MAX_LENGTH + 1] = {0}; // extra char for null terminator | ||
| 315 | |||
| 316 | uint8_t typo_len = 0; | ||
| 317 | uint8_t typo_start = 0; | ||
| 318 | bool space_last = typo_buffer[typo_buffer_size - 1] == KC_SPC; | ||
| 319 | for (uint8_t i = typo_buffer_size; i > 0; --i) { | ||
| 320 | // stop counting after finding space (unless it is the last thing) | ||
| 321 | if (typo_buffer[i - 1] == KC_SPC && i != typo_buffer_size) { | ||
| 322 | typo_start = i; | ||
| 323 | break; | ||
| 324 | } | ||
| 325 | |||
| 326 | ++typo_len; | ||
| 327 | } | ||
| 328 | |||
| 329 | // when detecting 'typo:', reduce the length of the string by one | ||
| 330 | if (space_last) { | ||
| 331 | --typo_len; | ||
| 332 | } | ||
| 333 | |||
| 334 | // convert buffer of keycodes into a string | ||
| 335 | for (uint8_t i = 0; i < typo_len; ++i) { | ||
| 336 | typo[i] = typo_buffer[typo_start + i] - KC_A + 'a'; | ||
| 337 | } | ||
| 338 | |||
| 339 | /* Gather the corrected word | ||
| 340 | * | ||
| 341 | * A) Correction of 'typo:' -- Code takes into account | ||
| 342 | * an extra backspace to delete the space (which we dont copy) | ||
| 343 | * for this reason the offset is correct to "skip" the null terminator | ||
| 344 | * | ||
| 345 | * B) When correcting 'typo' -- Need extra offset for terminator | ||
| 346 | */ | ||
| 347 | char correct[AUTOCORRECT_MAX_LENGTH + 10] = {0}; // let's hope this is big enough | ||
| 348 | |||
| 349 | uint8_t offset = space_last ? backspaces : backspaces + 1; | ||
| 350 | strcpy(correct, typo); | ||
| 351 | strcpy_P(correct + typo_len - offset, changes); | ||
| 352 | |||
| 353 | if (apply_autocorrect(backspaces, changes, typo, correct)) { | ||
| 305 | for (uint8_t i = 0; i < backspaces; ++i) { | 354 | for (uint8_t i = 0; i < backspaces; ++i) { |
| 306 | tap_code(KC_BSPC); | 355 | tap_code(KC_BSPC); |
| 307 | } | 356 | } |
| 308 | send_string_P((char const *)(autocorrect_data + state + 1)); | 357 | send_string_P(changes); |
| 309 | } | 358 | } |
| 310 | 359 | ||
| 311 | if (keycode == KC_SPC) { | 360 | if (keycode == KC_SPC) { |
