Use sequence_transform lib

This commit is contained in:
Matt Skalecki 2024-02-26 10:39:30 -05:00
commit 7996617d44
16 changed files with 252 additions and 798 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "keyboards/moonlander/keymaps/ikcelaks/sequence_transform"]
path = keyboards/moonlander/keymaps/ikcelaks/sequence_transform
url = git@github.com:Ikcelaks/qmk_sequence_transform.git

View file

@ -3,4 +3,4 @@
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "general/custom_keys.h" #include "general/custom_keys.h"
#include "magic_sturdy/context_magic.h" #include "sequence_transform/sequence_transform.h"

View file

@ -1,41 +0,0 @@
// Copyright 2024 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************/
#pragma once
// Autocorrection dictionary with longest match semantics:
// Autocorrection dictionary (3 entries):
// aa -> ab
// baa -> bac
// caa -> cad
#define AUTOCORRECT_MIN_LENGTH 2 // "aa"
#define AUTOCORRECT_MAX_LENGTH 3 // "baa"
#define DICTIONARY_SIZE 19
static const uint8_t autocorrect_data[DICTIONARY_SIZE] PROGMEM = {
0x04, 0x04, 0x00, 0xC0, 0x62, 0x00, 0x45, 0x0D, 0x00, 0x06, 0x10, 0x00, 0x00, 0x80, 0x63, 0x00,
0x80, 0x64, 0x00
};

View file

@ -9,3 +9,5 @@ enum custom_keycodes {
US_D_UND, US_D_UND,
US_QUOT_S, US_QUOT_S,
}; };
#define SEQUENCE_TRANSFORM_SPECIAL_KEY_0 US_MAG1

View file

@ -1,412 +0,0 @@
// Copyright 2021 Google LLC
// Copyright 2021 @filterpaper
// Copyright 2023 Pablo Martinez (@elpekenin) <elpekenin@elpekenin.dev>
// Copyright 2024 Guillaume Stordeur <guillaume.stordeur@gmail.com>
// SPDX-License-Identifier: Apache-2.0
// Original source: https://getreuer.info/posts/keyboards/autocorrection
#include "context_magic.h"
#include <string.h>
#include "keycodes.h"
#include "quantum.h"
#include "quantum_keycodes.h"
#include "keycode_config.h"
#include "send_string.h"
#include "action_util.h"
#include "magickey_data.h"
#include "../general/custom_keys.h"
#include "print.h"
#include "utils.h"
// todo: compute max in script
#define CONTEXT_MAGIC_MAX_LENGTH MAGICKEY_MAX_LENGTH
#define MAGIC_DICTIONARY_SIZE DICTIONARY_SIZE
#define TDATA(L) pgm_read_word(&trie->data[L])
#define CDATA(L) pgm_read_byte(&trie->completions[L])
#define IS_ALPHA_KEYCODE(code) ((code) >= KC_A && (code) <= KC_Z)
//////////////////////////////////////////////////////////////////////////////////////////
// Add KC_SPC on timeout
#if MAGIC_IDLE_TIMEOUT > 0
static uint32_t magic_timer = 0;
void context_magic_task(void)
{
if (timer_elapsed32(magic_timer) > MAGIC_IDLE_TIMEOUT) {
reset_buffer();
magic_timer = timer_read32();
}
}
#endif
//////////////////////////////////////////////////////////////////
// Key history buffer
static uint16_t key_buffer[CONTEXT_MAGIC_MAX_LENGTH] = {KC_SPC};
static uint16_t key_buffer_size = 1;
//////////////////////////////////////////////////////////////////
// List of tries
static trie_t trie = {
MAGIC_DICTIONARY_SIZE, magickey_data, COMPLETIONS_SIZE, magickey_completions_data
};
/**
* @brief determine if context_magic should process this keypress,
* and remove any mods from keycode.
*
* @param keycode Keycode registered by matrix press, per keymap
* @param record keyrecord_t structure
* @param mods allow processing of mod status
* @return true Allow context_magic
* @return false Stop processing and escape from context_magic.
*/
bool process_check(uint16_t *keycode, keyrecord_t *record, uint8_t *mods)
{
// See quantum_keycodes.h for reference on these matched ranges.
switch (*keycode) {
// Exclude these keycodes from processing.
case KC_LSFT:
case KC_RSFT:
case KC_CAPS:
case QK_TO ... QK_TO_MAX:
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
case QK_LAYER_MOD ... QK_LAYER_MOD_MAX:
case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
return false;
// bake shift mod into keycode symbols
case KC_1 ... KC_SLASH:
if (*mods & MOD_MASK_SHIFT) {
*keycode |= QK_LSFT;
}
return true;
// Clear shift for alphas
case LSFT(KC_A) ... LSFT(KC_Z):
case RSFT(KC_A) ... RSFT(KC_Z):
if (*keycode >= QK_LSFT && *keycode <= (QK_LSFT + 255)) {
*mods |= MOD_LSFT;
} else {
*mods |= MOD_RSFT;
}
*keycode = QK_MODS_GET_BASIC_KEYCODE(*keycode); // Get the basic keycode.
return true;
#ifndef NO_ACTION_TAPPING
// Exclude tap-hold keys when they are held down
// and mask for base keycode when they are tapped.
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
# ifdef NO_ACTION_LAYER
// Exclude Layer Tap, if layers are disabled
// but action tapping is still enabled.
return false;
# else
// Exclude hold keycode
if (!record->tap.count) {
return false;
}
*keycode = QK_LAYER_TAP_GET_TAP_KEYCODE(*keycode);
break;
# endif
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
// Exclude hold keycode
if (!record->tap.count) {
return false;
}
*keycode = QK_MOD_TAP_GET_TAP_KEYCODE(*keycode);
if (*mods & MOD_MASK_SHIFT) {
*keycode |= QK_LSFT;
}
break;
#else
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
// Exclude if disabled
return false;
#endif
// Exclude swap hands keys when they are held down
// and mask for base keycode when they are tapped.
case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
#ifdef SWAP_HANDS_ENABLE
// Note: IS_SWAP_HANDS_KEYCODE() actually tests for the special action keycodes like SH_TOGG, SH_TT, ...,
// which currently overlap the SH_T(kc) range.
if (IS_SWAP_HANDS_KEYCODE(*keycode)
# ifndef NO_ACTION_TAPPING
|| !record->tap.count
# endif // NO_ACTION_TAPPING
) {
return false;
}
*keycode = QK_SWAP_HANDS_GET_TAP_KEYCODE(*keycode);
break;
#else
// Exclude if disabled
return false;
#endif
}
// Disable autocorrect while a mod other than shift is active.
if ((*mods & ~MOD_MASK_SHIFT) != 0) {
reset_buffer();
return false;
}
return true;
}
/**
* @brief Add keycode to our key buffer.
*
* @param keycode Keycode registered by matrix press, per keymap
*/
void enqueue_keycode(uint16_t keycode)
{
// Store all alpha chars as lowercase
const bool shifted = keycode & QK_LSFT;
const uint8_t lowkey = keycode & 0xFF;
if (shifted && IS_ALPHA_KEYCODE(lowkey))
keycode = lowkey;
// Rotate oldest character if buffer is full.
if (key_buffer_size >= CONTEXT_MAGIC_MAX_LENGTH) {
memmove(key_buffer, key_buffer + 1, sizeof(uint16_t) * (CONTEXT_MAGIC_MAX_LENGTH - 1));
key_buffer_size = CONTEXT_MAGIC_MAX_LENGTH - 1;
}
key_buffer[key_buffer_size++] = keycode;
}
//////////////////////////////////////////////////////////////////
void reset_buffer(void)
{
key_buffer[0] = KC_SPC;
key_buffer_size = 1;
}
/**
* @brief Remove num keys from our buffer.
*
* @param num number of keys to remove
*/
void dequeue_keycodes(uint8_t num)
{
key_buffer_size -= MIN(num, key_buffer_size);
if (!key_buffer_size)
reset_buffer();
}
/**
* @brief Find longest chain in trie matching our current key_buffer.
*
* @param trie trie_t struct containing trie data/size
* @param res result containing current best
* @param offset current offset in trie data
* @param depth current depth in trie
* @return true if match found
*/
bool find_longest_chain(trie_t *trie, trie_search_result_t *res, int offset, int depth)
{
// Sanity checks
if (offset >= trie->data_size) {
uprintf("find_longest_chain() Error: tried reading outside trie data! Offset: %d", offset);
return false;
}
uint16_t code = TDATA(offset);
if (!code) {
uprintf("find_longest_chain() Error: unexpected null code! Offset: %d", offset);
return false;
}
uprintf("FIND_LONGEST_CHAIN (%d, %d)", offset, code);
// Match Node if bit 15 is set
if (code & 0x8000) {
uprintf("Match found at Offset: %d", offset);
// match nodes are side attachments, so decrease depth
depth--;
// If bit 14 is also set, there is a child node after the completion string
if ((code & 0x4000) && find_longest_chain(trie, res, offset+2, depth+1)) {
uprintf("Looking for deeper match at Offset: %d", offset+2);
return true;
}
// If no better match found deeper, this is the result!
// char buf[20];
// sprintf(buf, "|0x%04x|", code);
// send_string(buf);
res->completion_offset = TDATA(offset + 1);
res->func_code = (code >> 11 & 0x0007);
res->num_backspaces = (code & 0x003F);
// Found a match so return true!
return true;
}
// Branch Node (with multiple children) if bit 14 is set
if (code & 0x4000) {
if (depth > key_buffer_size)
return false;
code &= 0x3FFF;
// Find child that matches our current buffer location
const uint16_t cur_key = key_buffer[key_buffer_size - depth];
for (; code; offset += 2, code = TDATA(offset)) {
if (code == cur_key) {
// 16bit offset to child node is built from next uint16_t
const int child_offset = TDATA(offset+1);
// Traverse down child node
return find_longest_chain(trie, res, child_offset, depth+1);
}
}
// Couldn't go deeper, so return false.
return false;
}
// No high bits set, so this is a chain node
// Travel down chain until we reach a zero byte, or we no longer match our buffer
for (; code; depth++, code = TDATA(++offset)) {
if (depth > key_buffer_size ||
code != key_buffer[key_buffer_size - depth])
return false;
}
// After a chain, there should be a leaf or branch
return find_longest_chain(trie, res, offset+1, depth);
}
//////////////////////////////////////////////////////////////////////////////////////////
void record_send_key(uint16_t keycode)
{
enqueue_keycode(keycode);
// Apply shift to sent key if caps word is enabled.
#ifdef CAPS_WORD_ENABLED
if (is_caps_word_on() && IS_ALPHA_KEYCODE(keycode))
add_weak_mods(MOD_BIT(KC_LSFT));
#endif
tap_code16(keycode);
}
//////////////////////////////////////////////////////////////////////////////////////////
void handle_repeat_key()
{
uint16_t keycode = KC_NO;
for (int i = key_buffer_size - 1; i >= 0; --i) {
keycode = key_buffer[i];
if (!(keycode & 0x0100)) {
break;
}
}
if (keycode && !(keycode & 0x0100)) {
dequeue_keycodes(1);
enqueue_keycode(keycode);
// Apply shift to sent key if caps word is enabled.
#ifdef CAPS_WORD_ENABLED
if (is_caps_word_on() && IS_ALPHA_KEYCODE(keycode))
add_weak_mods(MOD_BIT(KC_LSFT));
#endif
tap_code16(keycode);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void handle_result(trie_t *trie, trie_search_result_t *res)
{
// Send backspaces
multi_tap(KC_BSPC, res->num_backspaces);
// Send completion string
bool ends_with_wordbreak = false;
for (int i = res->completion_offset; i < trie->completions_size; ++i) {
char ascii_code = CDATA(i);
if (!ascii_code) {
if (i > 0 && CDATA(i-1) == KC_SPC) {
ends_with_wordbreak = true;
}
break;
}
tap_code16(char_to_keycode(ascii_code));
}
switch (res->func_code) {
case 1: // repeat
handle_repeat_key();
break;
case 2: // set one-shot shift
set_oneshot_mods(MOD_LSFT);
break;
case 3: // disable auto-wordbreak
ends_with_wordbreak = false;
}
if (ends_with_wordbreak) {
enqueue_keycode(KC_SPC);
}
}
/**
* @brief Handles magic/repeat key press
*
* @param keycode Keycode registered by matrix press, per keymap
* @return false if keycode isn't a registered magic key
*/
bool perform_magic()
{
// Do nothing if key buffer is empty
if (!key_buffer_size)
return false;
// Look for chain matching our buffer in the trie.
trie_search_result_t res = {0, 0};
if (find_longest_chain(&trie, &res, 0, 1)) {
handle_result(&trie, &res);
return true;
}
return false;
}
/**
* @brief Process handler for context_magic feature.
*
* @param keycode Keycode registered by matrix press, per keymap
* @param record keyrecord_t structure
* @return true Continue processing keycodes, and send to host
* @return false Stop processing keycodes, and don't send to host
*/
bool process_context_magic(uint16_t keycode, keyrecord_t *record)
{
uprintf("Process_context_magic for keycode: %d", keycode);
#if MAGIC_IDLE_TIMEOUT > 0
magic_timer = timer_read32();
#endif
uint8_t mods = get_mods();
#ifndef NO_ACTION_ONESHOT
mods |= get_oneshot_mods();
#endif
if (!record->event.pressed)
return true;
// keycode verification and extraction
if (!process_check(&keycode, record, &mods))
return true;
// keycode buffer check
switch (keycode) {
case US_MAG1 ... US_MAG4:
// convert to special 0x01nn code
keycode = 0x0100 + keycode - US_MAG1;
break;
case KC_A ... KC_0:
case S(KC_1) ... S(KC_0):
case KC_MINUS ...KC_SLASH:
// process normally
break;
case S(KC_MINUS) ...S(KC_SLASH):
// treat " (shifted ') as a word boundary
if (keycode == S(KC_QUOTE))
keycode = KC_SPC;
break;
case KC_BSPC:
// remove last character from the buffer
reset_buffer();
return true;
default:
// set word boundary if some other non-alpha key is pressed
keycode = KC_SPC;
}
// append `keycode` to buffer
enqueue_keycode(keycode);
uprintf(" translated keycode: %d", keycode);
// perform magic action if this is one of our registered keycodes
if (perform_magic())
return false;
return true;
}

View file

@ -1,45 +0,0 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "action.h"
//////////////////////////////////////////////////////////////////
// Public API
bool process_context_magic(uint16_t keycode, keyrecord_t *record);
#if MAGIC_IDLE_TIMEOUT > 0
void context_magic_task(void);
#else
static inline void context_magic_task(void) {}
#endif
//////////////////////////////////////////////////////////////////
// Internal
typedef void (*trie_fallback)(void);
typedef struct
{
int data_size;
const uint16_t *data;
int completions_size;
const uint8_t *completions;
} trie_t;
typedef struct
{
uint8_t func_code;
uint8_t num_backspaces;
int completion_offset;
} trie_search_result_t;
// trie_t *get_trie(uint16_t keycode);
bool process_check(uint16_t *keycode, keyrecord_t *record, uint8_t *mods);
void enqueue_keycode(uint16_t keycode);
void reset_buffer(void);
void dequeue_keycodes(uint8_t num);
bool find_longest_chain(trie_t *trie, trie_search_result_t *res, int offset, int depth);
void record_send_key(uint16_t keycode);
void repeat_key_fallback(void);
void handle_repeat_key(void);
void handle_result(trie_t *trie, trie_search_result_t *res);
bool perform_magic(void);

View file

@ -1 +0,0 @@
the be of and a to in he have it that for they I with as not on she at by this we you do but from or which one would all will there say who make when can more if no man out other so what time up go about than into could state only new year some take come these know see use get like then first any work now may such give over think most even find day also after way many must look before great back through long where much should well people down own just because good each those feel seem how high too place little world very still nation hand old life tell write become here show house both between need mean call develop under last right move thing general school never same another begin while number part turn real leave might want point form off child few small since against ask late home interest large person end open public follow during present without again hold govern around possible head consider word program problem however lead system set order eye plan run keep face fact group play stand increase early course change help line power powerschool oxygen already alright judge judgment above edge ledge bridge inform information various video different difference definite definitely anyway anywhere obvious hilarious page previous dry list vision division question view review light don't zero update upgrade enough often ought bought fought fraught caught success successful access crack quite quiet neighbor mother brother though thought crowd govern government manage management nation network service university universe location ability abilities responsibility responsibilities make making take taking qmlativ

View file

@ -1,82 +0,0 @@
#include "utils.h"
#include "send_string.h"
#include "quantum.h"
// Note: we bit-pack in "reverse" order to optimize loading
#define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01)
const char unshifted_keycode_to_ascii_lut[53] PROGMEM = {
// KC_A KC_B KC_C KC_D
'a', 'b', 'c', 'd',
// KC_E KC_F KC_G KC_H KC_I KC_J KC_K KC_L
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
// KC_M KC_N KC_O KC_P KC_Q KC_R KC_S KC_T
'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
// KC_U KC_V KC_W KC_X KC_Y KC_Z KC_1 KC_2
'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
// KC_3 KC_4 KC_5 KC_6 KC_7 KC_8 KC_9 KC_0
'3', '4', '5', '6', '7', '8', '9', '0',
// KC_ENTR KC_ESC KC_BSPC KC_TAB KC_SPC KC_MINS KC_EQL KC_LBRC
' ', ' ', ' ', ' ', ' ', '-', '=', '[',
// KC_RBRC KC_BSLS KC_NUHS KC_SCLN KC_QUOT KC_GRV KC_COMM KC_DOT
']', '\\', ' ', ';', '\'', '`', ',', '.',
// KC_SLSH
'/'
};
const char shifted_keycode_to_ascii_lut[53] PROGMEM = {
// KC_A KC_B KC_C KC_D
'A', 'B', 'C', 'D',
// KC_E KC_F KC_G KC_H KC_I KC_J KC_K KC_L
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
// KC_M KC_N KC_O KC_P KC_Q KC_R KC_S KC_T
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
// KC_U KC_V KC_W KC_X KC_Y KC_Z KC_EXLM KC_AT
'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
// KC_HASH KC_DLR KC_PERC KC_CIRC KC_AMPR KC_ASTR KC_LPRN KC_RPRN
'#', '$', '%', '^', '&', '*', '(', ')',
// KC_ENTR KC_ESC KC_BSPC KC_TAB KC_SPC KC_UNDS KC_PLUS KC_LCBR
' ', ' ', ' ', ' ', ' ', '_', '+', '{',
// KC_RCBR KC_PIPE KC_NUHS KC_COLN KC_DQUO KC_GRV KC_LABK KC_RABK
'}', '|', ' ', ':', '"', '~', '<', '>',
// KC_QUES
'?'
};
////////////////////////////////////////////////////////////////////////////////
char keycode_to_char(uint16_t keycode)
{
const bool shifted = keycode & QK_LSFT;
keycode &= 0xFF;
if (keycode >= KC_A && keycode <= KC_SLASH) {
keycode -= KC_A;
return shifted ? pgm_read_byte(&shifted_keycode_to_ascii_lut[keycode]) :
pgm_read_byte(&unshifted_keycode_to_ascii_lut[keycode]);
}
return ' ';
}
////////////////////////////////////////////////////////////////////////////////
uint16_t char_to_keycode(char c)
{
uint16_t k = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)c]);
bool is_shifted = PGM_LOADBIT(ascii_to_shift_lut, (uint8_t)c);
if (is_shifted)
k = S(k);
return k;
}
////////////////////////////////////////////////////////////////////////////////
// removes mod or layer info from a keycode
uint16_t normalize_keycode(uint16_t keycode)
{
if (IS_QK_MOD_TAP(keycode))
return QK_MOD_TAP_GET_TAP_KEYCODE(keycode);
if (IS_QK_LAYER_TAP(keycode))
return QK_LAYER_TAP_GET_TAP_KEYCODE(keycode);
return keycode;
}
////////////////////////////////////////////////////////////////////////////////
void multi_tap(uint16_t keycode, int count)
{
for (int i = 0; i < count; ++i)
tap_code16(keycode);
}

View file

@ -1,8 +0,0 @@
#pragma once
#include <stdint.h>
uint16_t char_to_keycode(char c);
char keycode_to_char(uint16_t keycode);
uint16_t normalize_keycode(uint16_t keycode);
void multi_tap(uint16_t keycode, int count);

View file

@ -1,8 +0,0 @@
{
"rules_file_name": "./magickey_dict.txt",
"magic_chars": "👆👍★✪",
"wordbreak_char": "⎵",
"output_func_chars": "↻⇑",
"comment_char": "#",
"separator": "⇒"
}

View file

@ -1,193 +0,0 @@
// Copyright 2024 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************/
#pragma once
// Autocorrection dictionary with longest match semantics:
// Autocorrection dictionary (98 entries):
// 👍 -> ↻
// d★ -> develop
// d★t -> development
// d★r -> developer
// d★d -> developed
// ⎵i👍 -> I
// ⎵i👍m -> I'm
// ⎵i👍d -> I'd
// ⎵i👍l -> I'll
// ⎵c👍 -> come
// ⎵s👍 -> some
// ⎵c👍u -> could
// ⎵w👍u -> would
// ⎵s👍u -> should
// ⎵c👍ut -> couldn't
// ⎵w👍ut -> wouldn't
// ⎵s👍ut -> shouldn't
// ⎵c👍uv -> could've
// ⎵w👍uv -> would've
// ⎵s👍uv -> should've
// ⎵👆 -> the
// ⎵👆r -> there
// ⎵👆rs -> there's
// ⎵👆i -> their
// ⎵👆yr -> they're
// ⎵👆yl -> they'll
// ⎵👆d -> they'd
// ⎵👆s -> these
// ⎵👆t -> that
// ⎵👆a -> than
// ⎵👆o -> those
// ⎵t👍 -> time
// ⎵t👍g -> though
// ⎵t👍t -> thought
// ⎵t👍r -> through
// ⎵t👍c -> technology
// ⎵t👍a -> take
// ⎵w👍 -> why
// ⎵w👍n -> when
// ⎵w👍e -> where
// ⎵w👍t -> what
// ⎵w👍r -> we're
// ⎵w👍d -> we'd
// ⎵w👍l -> we'll
// ⎵w👍v -> we've
// a👆 -> abo
// a👆👍 -> about
// a👆👆 -> above
// v👆 -> ver
// s👆 -> sk
// x👆 -> es
// m👆 -> ment
// t👆 -> tment
// k👆 -> ks
// l👆 -> lk
// r👆 -> rl
// j👆 -> just
// j👆👆 -> justment
// ⎵j👍 -> join
// ⎵j👍d -> judge
// ⎵j👍dt -> judgment
// ⎵j👍dta -> judgmental
// c👆 -> cy
// p👆 -> py
// d👆 -> dy
// y👆 -> yp
// g👆 -> gy
// w👆 -> which
// q👆 -> question
// b👆 -> before
// f👆 -> first
// z👆 -> zone
// 👆👆 -> 👆n
// n👆 -> nion
// h👆 -> however
// u👆 -> ue
// e👆 -> eu
// o👆 -> oa
// ,👆 -> ,⎵but
// i👆 -> ion
// .👆 -> .\ [escape]
// ⎵👍 -> for
// a👍 -> and
// x👍 -> xer
// k👍 -> know
// i👍 -> ing
// y👍 -> you
// q👍 -> quick
// j👍 -> join
// c👍 -> ck
// n👍 -> nf
// h👍 -> hn
// ,👍 -> ,⎵and
// .👍 -> .⎵⇑
// ?👍 -> ?⎵⇑
// :👍 -> :⎵⇑
// ;👍 -> ;⎵⇑
// !👍 -> !⎵⇑
#define MAGICKEY_MIN_LENGTH 1 // "👍"
#define MAGICKEY_MAX_LENGTH 6 // "⎵j👍dta"
#define DICTIONARY_SIZE 558
#define COMPLETIONS_SIZE 295
#define MAGICKEY_COUNT 4
static const uint16_t magickey_data[DICTIONARY_SIZE] PROGMEM = {
0x4004, 0x0025, 0x0006, 0x003C, 0x0007, 0x0042, 0x0008, 0x0064, 0x000A, 0x006A, 0x000C, 0x0070, 0x000F, 0x0075, 0x0010, 0x008C,
0x0011, 0x0092, 0x0012, 0x0098, 0x0015, 0x009D, 0x0016, 0x00C0, 0x0017, 0x00CE, 0x0018, 0x0109, 0x0019, 0x011E, 0x0102, 0x013D,
0x0100, 0x0141, 0x0101, 0x01C3, 0x0000, 0x4017, 0x002C, 0x0100, 0x0033, 0x0101, 0x0037, 0x0000, 0x0007, 0x0101, 0x000D, 0x002C,
0x0000, 0x8000, 0x0000, 0x002C, 0x0000, 0x8001, 0x0003, 0x0017, 0x002C, 0x0000, 0x8003, 0x0006, 0x0101, 0x0017, 0x002C, 0x0000,
0x8003, 0x000A, 0x4102, 0x0049, 0x0100, 0x004D, 0x0101, 0x0051, 0x0000, 0x0007, 0x0000, 0x8000, 0x0014, 0x002C, 0x0000, 0x8000,
0x0017, 0x400C, 0x0058, 0x000D, 0x005C, 0x001A, 0x0060, 0x0000, 0x002C, 0x0000, 0x8000, 0x001B, 0x002C, 0x0000, 0x8003, 0x001E,
0x002C, 0x0000, 0x8002, 0x0023, 0x0101, 0x001A, 0x002C, 0x0000, 0x8001, 0x0027, 0x0101, 0x0017, 0x002C, 0x0000, 0x8003, 0x002B,
0x0100, 0x002C, 0x0000, 0x8000, 0x0031, 0x401C, 0x007A, 0x0101, 0x007F, 0x0000, 0x0100, 0x002C, 0x0000, 0x8003, 0x0034, 0x400C,
0x0084, 0x001A, 0x0088, 0x0000, 0x002C, 0x0000, 0x8000, 0x0039, 0x002C, 0x0000, 0x8002, 0x003D, 0x0101, 0x000C, 0x002C, 0x0000,
0x8000, 0x0042, 0x0101, 0x001A, 0x002C, 0x0000, 0x8001, 0x0045, 0x0100, 0x002C, 0x0000, 0x8001, 0x0048, 0x401C, 0x00A6, 0x0102,
0x00AB, 0x0100, 0x00AF, 0x0101, 0x00B3, 0x0000, 0x0100, 0x002C, 0x0000, 0x8003, 0x004C, 0x0007, 0x0000, 0x8000, 0x0051, 0x002C,
0x0000, 0x8000, 0x0054, 0x4017, 0x00B8, 0x001A, 0x00BC, 0x0000, 0x002C, 0x0000, 0x8003, 0x0057, 0x002C, 0x0000, 0x8002, 0x005E,
0x4015, 0x00C5, 0x0100, 0x00CA, 0x0000, 0x0100, 0x002C, 0x0000, 0x8000, 0x0063, 0x002C, 0x0000, 0x8000, 0x0066, 0x4007, 0x00D9,
0x0018, 0x00DF, 0x0102, 0x00F4, 0x0100, 0x00F8, 0x0101, 0x00FC, 0x0000, 0x0101, 0x000D, 0x002C, 0x0000, 0x8001, 0x0069, 0x0101,
0x0000, 0x4006, 0x00E8, 0x0016, 0x00EC, 0x001A, 0x00F0, 0x0000, 0x002C, 0x0000, 0x8000, 0x006E, 0x002C, 0x0000, 0x8000, 0x006E,
0x002C, 0x0000, 0x8000, 0x006E, 0x0007, 0x0000, 0x8000, 0x0069, 0x002C, 0x0000, 0x8001, 0x0072, 0x4017, 0x0101, 0x001A, 0x0105,
0x0000, 0x002C, 0x0000, 0x8003, 0x0075, 0x002C, 0x0000, 0x8001, 0x0072, 0x0101, 0x0000, 0x4006, 0x0112, 0x0016, 0x0116, 0x001A,
0x011A, 0x0000, 0x002C, 0x0000, 0x8002, 0x007C, 0x002C, 0x0000, 0x8003, 0x0080, 0x002C, 0x0000, 0x8002, 0x0086, 0x4018, 0x0123,
0x0101, 0x0138, 0x0000, 0x0101, 0x0000, 0x4006, 0x012C, 0x0016, 0x0130, 0x001A, 0x0134, 0x0000, 0x002C, 0x0000, 0x8000, 0x008B,
0x002C, 0x0000, 0x8000, 0x008B, 0x002C, 0x0000, 0x8000, 0x008B, 0x001A, 0x002C, 0x0000, 0x8002, 0x008F, 0x0007, 0x0000, 0x8000,
0x0094, 0x4036, 0x017E, 0x0037, 0x0180, 0x0004, 0x0182, 0x0005, 0x0184, 0x0006, 0x0186, 0x0007, 0x0188, 0x0008, 0x018A, 0x0009,
0x018C, 0x000A, 0x018E, 0x000B, 0x0190, 0x000C, 0x0192, 0x000D, 0x0194, 0x000E, 0x0196, 0x000F, 0x0198, 0x0010, 0x019A, 0x0011,
0x019C, 0x0012, 0x019E, 0x0013, 0x01A0, 0x0014, 0x01A2, 0x0015, 0x01A4, 0x0016, 0x01A6, 0x0017, 0x01A8, 0x0018, 0x01AA, 0x0019,
0x01AC, 0x001A, 0x01AE, 0x001B, 0x01B0, 0x001C, 0x01B2, 0x001D, 0x01B4, 0x002C, 0x01B6, 0x0100, 0x01B8, 0x0000, 0x8000, 0x009B,
0x8000, 0x00A0, 0x8000, 0x00A2, 0x8000, 0x00A5, 0x8000, 0x00AB, 0x8000, 0x00AB, 0x8000, 0x00AD, 0x8000, 0x00AF, 0x8000, 0x00AB,
0x8000, 0x00B4, 0x8000, 0x00BB, 0x8000, 0x00BE, 0x8000, 0x00C2, 0x8000, 0x00C4, 0x8000, 0x00C6, 0x8000, 0x00CA, 0x8000, 0x00CE,
0x8000, 0x00AB, 0x8000, 0x00D0, 0x8000, 0x00D8, 0x8000, 0x00C4, 0x8000, 0x0069, 0x8000, 0x00DA, 0x8000, 0x0051, 0x8000, 0x00DC,
0x8001, 0x00E1, 0x8000, 0x00E4, 0x8000, 0x00E6, 0x8000, 0x00EA, 0xC000, 0x00EE, 0x4004, 0x01BF, 0x000D, 0x01C1, 0x0000, 0x8000,
0x00F0, 0x8000, 0x0069, 0xC800, 0x00F3, 0x421E, 0x01F0, 0x0036, 0x01F2, 0x0037, 0x01F4, 0x0233, 0x01F6, 0x0033, 0x01F8, 0x0238,
0x01FA, 0x0004, 0x01FC, 0x0006, 0x01FE, 0x000B, 0x0204, 0x000C, 0x0206, 0x000D, 0x020C, 0x000E, 0x0212, 0x0011, 0x0214, 0x0014,
0x0216, 0x0016, 0x0218, 0x0017, 0x021C, 0x001A, 0x0220, 0x001B, 0x0224, 0x001C, 0x0226, 0x002C, 0x0228, 0x0100, 0x022A, 0x0000,
0x9000, 0x00F4, 0x8000, 0x00F6, 0x9000, 0x00F4, 0x9000, 0x00F4, 0x9000, 0x00F4, 0x9000, 0x00F4, 0x8000, 0x00FB, 0xC000, 0x00C4,
0x002C, 0x0000, 0x8000, 0x00FE, 0x8000, 0x00EE, 0xC000, 0x0102, 0x002C, 0x0000, 0x8001, 0x0105, 0xC000, 0x0107, 0x002C, 0x0000,
0x8000, 0x0107, 0x8000, 0x010B, 0x8000, 0x010F, 0x8000, 0x0111, 0x002C, 0x0000, 0x8000, 0x00FE, 0x002C, 0x0000, 0x8000, 0x0116,
0x002C, 0x0000, 0x8000, 0x011A, 0x8000, 0x0051, 0x8000, 0x011D, 0x8000, 0x0120, 0x0004, 0x0000, 0x8000, 0x0124
};
static const uint8_t magickey_completions_data[COMPLETIONS_SIZE] PROGMEM = {
0x61, 0x6C, 0x00, 0x61, 0x6E, 0x00, 0x61, 0x6B, 0x65, 0x00, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C,
0x6F, 0x67, 0x79, 0x00, 0x65, 0x64, 0x00, 0x79, 0x27, 0x64, 0x00, 0x27, 0x64, 0x00, 0x75, 0x64,
0x67, 0x65, 0x00, 0x65, 0x27, 0x64, 0x00, 0x65, 0x72, 0x65, 0x00, 0x68, 0x6F, 0x75, 0x67, 0x68,
0x00, 0x69, 0x72, 0x00, 0x79, 0x27, 0x6C, 0x6C, 0x00, 0x27, 0x6C, 0x6C, 0x00, 0x65, 0x27, 0x6C,
0x6C, 0x00, 0x27, 0x6D, 0x00, 0x65, 0x6E, 0x00, 0x6F, 0x73, 0x65, 0x00, 0x79, 0x27, 0x72, 0x65,
0x00, 0x65, 0x72, 0x00, 0x72, 0x65, 0x00, 0x68, 0x72, 0x6F, 0x75, 0x67, 0x68, 0x00, 0x65, 0x27,
0x72, 0x65, 0x00, 0x27, 0x73, 0x00, 0x73, 0x65, 0x00, 0x6D, 0x65, 0x6E, 0x74, 0x00, 0x6E, 0x27,
0x74, 0x00, 0x61, 0x74, 0x00, 0x68, 0x6F, 0x75, 0x67, 0x68, 0x74, 0x00, 0x75, 0x6C, 0x64, 0x00,
0x68, 0x6F, 0x75, 0x6C, 0x64, 0x00, 0x6F, 0x75, 0x6C, 0x64, 0x00, 0x27, 0x76, 0x65, 0x00, 0x65,
0x27, 0x76, 0x65, 0x00, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x00, 0x20, 0x62, 0x75, 0x74, 0x00,
0x5C, 0x00, 0x62, 0x6F, 0x00, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x00, 0x79, 0x00, 0x75, 0x00, 0x69,
0x72, 0x73, 0x74, 0x00, 0x6F, 0x77, 0x65, 0x76, 0x65, 0x72, 0x00, 0x6F, 0x6E, 0x00, 0x75, 0x73,
0x74, 0x00, 0x73, 0x00, 0x6B, 0x00, 0x65, 0x6E, 0x74, 0x00, 0x69, 0x6F, 0x6E, 0x00, 0x61, 0x00,
0x75, 0x65, 0x73, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x68, 0x69, 0x63, 0x68,
0x00, 0x65, 0x73, 0x00, 0x70, 0x00, 0x6F, 0x6E, 0x65, 0x00, 0x74, 0x68, 0x65, 0x00, 0x6E, 0x00,
0x76, 0x65, 0x00, 0x00, 0x20, 0x00, 0x20, 0x61, 0x6E, 0x64, 0x00, 0x6E, 0x64, 0x00, 0x6F, 0x6D,
0x65, 0x00, 0x6E, 0x67, 0x00, 0x49, 0x00, 0x6F, 0x69, 0x6E, 0x00, 0x6E, 0x6F, 0x77, 0x00, 0x66,
0x00, 0x75, 0x69, 0x63, 0x6B, 0x00, 0x69, 0x6D, 0x65, 0x00, 0x68, 0x79, 0x00, 0x6F, 0x75, 0x00,
0x66, 0x6F, 0x72, 0x00, 0x75, 0x74, 0x00
};

View file

@ -7,5 +7,5 @@ COMBO_ENABLE = yes
REPEAT_KEY_ENABLE = yes REPEAT_KEY_ENABLE = yes
DEFERRED_EXEC_ENABLE = yes DEFERRED_EXEC_ENABLE = yes
SRC += magic_sturdy/context_magic.c SRC += sequence_transform/sequence_transform.c
SRC += magic_sturdy/utils.c SRC += sequence_transform/utils.c

@ -0,0 +1 @@
Subproject commit 48b1a6d0b4f85e3e228042bed0b5ba25b5a18c94

View file

@ -0,0 +1,8 @@
{
"rules_file_name": "./sequence_transform_dict.txt",
"magic_chars": "👆👍★✪",
"wordbreak_char": "⎵",
"output_func_chars": "↻⇑",
"comment_str": "#",
"separator_str": "⇒"
}

View file

@ -0,0 +1,212 @@
// Copyright 2024 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
88888888888 888 d8b .d888 d8b 888 d8b
888 888 Y8P d88P" Y8P 888 Y8P
888 888 888 888
888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
888 888 888 888 X88 888 888 888 Y8b. 888 X88
888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
888 888
888 888
888 888
.d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
"Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
888
Y8b d88P
"Y88P"
*******************************************************************************/
#pragma once
// Autocorrection dictionary with longest match semantics:
// Autocorrection dictionary (114 entries):
// 👍 -> ↻
// d★ -> develop
// d★t -> development
// d★r -> developer
// d★d -> developed
// ⎵i👍 -> I
// ⎵i👍m -> I'm
// ⎵i👍d -> I'd
// ⎵i👍l -> I'll
// ⎵c👍 -> come
// ⎵s👍 -> some
// ⎵c👍u -> could
// ⎵w👍u -> would
// ⎵s👍u -> should
// ⎵c👍ut -> couldn't
// ⎵w👍ut -> wouldn't
// ⎵s👍ut -> shouldn't
// ⎵c👍uv -> could've
// ⎵w👍uv -> would've
// ⎵s👍uv -> should've
// ⎵👆 -> the
// ⎵👆r⎵ -> there⎵
// ⎵👆rs -> there's
// ⎵👆i -> their
// ⎵👆yr -> they're
// ⎵👆yl -> they'll
// ⎵👆d -> they'd
// ⎵👆s -> these
// ⎵👆t -> that
// ⎵👆a -> than
// ⎵👆o⎵ -> those
// ⎵t👍 -> time
// ⎵t👍g -> though
// ⎵t👍t -> thought
// ⎵t👍r -> through
// ⎵t👍c -> technology
// ⎵t👍a -> take
// ⎵w👍 -> why
// ⎵w👍n -> when
// ⎵w👍e -> where
// ⎵w👍t -> what
// ⎵w👍r -> we're
// ⎵w👍d -> we'd
// ⎵w👍l -> we'll
// ⎵w👍v -> we've
// ⎵a👆 -> abo
// ⎵a👆t -> about
// ⎵a👆v -> above
// ⎵a👆d -> aboard
// ⎵a👆s -> absolute
// ⎵a👍r -> after
// ⎵a👍n -> again
// ⎵a👍t -> against
// ⎵a👍s -> answer
// ⎵a👍p -> appear
// ⎵a👍w -> always
// ⎵a👍y -> already
// ⎵a👍l -> alright
// ⎵u👍 -> use
// ⎵u👍f -> useful
// ⎵u👍t -> update
// ⎵u👍g -> upgrade
// ⎵u👍s -> upside
// ⎵u👍sd -> upsidedown
// v👆 -> ver
// s👆 -> sk
// x👆 -> es
// m👆 -> ment
// t👆 -> tment
// k👆 -> ks
// l👆 -> lk
// r👆 -> rl
// j👆 -> just
// j👆👆 -> justment
// ⎵j👍 -> join
// ⎵j👍d -> judge
// ⎵j👍dt -> judgment
// ⎵j👍dta -> judgmental
// c👆 -> cy
// p👆 -> py
// d👆 -> dy
// y👆 -> yp
// g👆 -> gy
// w👆 -> which
// q👆 -> question
// b👆 -> before
// f👆 -> first
// z👆 -> zone
// 👆👆 -> 👆n
// n👆 -> nion
// h👆 -> however
// u👆 -> ue
// e👆 -> eu
// o👆 -> oa
// ,👆 -> ,⎵but
// i👆 -> ion
// .👆 -> .\ [escape]
// ⎵👍 -> for
// a👍 -> and
// x👍 -> xer
// k👍 -> know
// i👍 -> ing
// y👍 -> you
// q👍 -> quick
// j👍 -> join
// c👍 -> ck
// n👍 -> nf
// h👍 -> hn
// ,👍 -> ,⎵and
// .👍 -> .⎵⇑
// ?👍 -> ?⎵⇑
// :👍 -> :⎵⇑
// ;👍 -> ;⎵⇑
// !👍 -> !⎵⇑
#define SEQUENCE_MIN_LENGTH 1 // "👍"
#define SEQUENCE_MAX_LENGTH 6 // "⎵j👍dta"
#define DICTIONARY_SIZE 684
#define COMPLETIONS_SIZE 213
#define SEQUENCE_TRANSFORM_COUNT 4
static const uint16_t sequence_transform_data[DICTIONARY_SIZE] PROGMEM = {
0x4004, 0x002D, 0x0006, 0x0044, 0x0007, 0x004A, 0x0008, 0x007B, 0x0009, 0x0081, 0x000A, 0x0087, 0x000C, 0x0096, 0x000F, 0x009B,
0x0010, 0x00B8, 0x0011, 0x00BE, 0x0013, 0x00CD, 0x0015, 0x00D3, 0x0016, 0x00F6, 0x0017, 0x011A, 0x0018, 0x0168, 0x0019, 0x017D,
0x001A, 0x01A3, 0x001C, 0x01A9, 0x002C, 0x01AF, 0x0102, 0x01BE, 0x0100, 0x01C2, 0x0101, 0x0241, 0x0000, 0x4017, 0x0034, 0x0100,
0x003B, 0x0101, 0x003F, 0x0000, 0x0007, 0x0101, 0x000D, 0x002C, 0x0000, 0x8002, 0x00CD, 0x002C, 0x0000, 0x8082, 0x0071, 0x0017,
0x002C, 0x0000, 0x8183, 0x00A1, 0x0101, 0x0017, 0x002C, 0x0000, 0x8189, 0x0000, 0x4016, 0x0053, 0x0102, 0x0059, 0x0100, 0x005D,
0x0101, 0x0068, 0x0000, 0x0101, 0x0018, 0x002C, 0x0000, 0x8004, 0x007C, 0x0007, 0x0000, 0x8002, 0x00C9, 0x4004, 0x0062, 0x002C,
0x0066, 0x0000, 0x002C, 0x0000, 0x8003, 0x00AD, 0x8003, 0x0098, 0x400C, 0x006F, 0x000D, 0x0073, 0x001A, 0x0077, 0x0000, 0x002C,
0x0000, 0x8002, 0x0099, 0x002C, 0x0000, 0x8184, 0x0080, 0x002C, 0x0000, 0x8103, 0x00B6, 0x0101, 0x001A, 0x002C, 0x0000, 0x8083,
0x0092, 0x0101, 0x0018, 0x002C, 0x0000, 0x8003, 0x00BF, 0x0101, 0x0000, 0x4017, 0x008E, 0x0018, 0x0092, 0x0000, 0x002C, 0x0000,
0x8185, 0x0010, 0x002C, 0x0000, 0x8106, 0x0022, 0x0100, 0x002C, 0x0000, 0x8002, 0x0064, 0x401C, 0x00A0, 0x0101, 0x00A5, 0x0000,
0x0100, 0x002C, 0x0000, 0x8003, 0x0095, 0x4004, 0x00AC, 0x000C, 0x00B0, 0x001A, 0x00B4, 0x0000, 0x002C, 0x0000, 0x8106, 0x0028,
0x002C, 0x0000, 0x8003, 0x0095, 0x002C, 0x0000, 0x8104, 0x0094, 0x0101, 0x000C, 0x002C, 0x0000, 0x8002, 0x00C7, 0x0101, 0x0000,
0x4004, 0x00C5, 0x001A, 0x00C9, 0x0000, 0x002C, 0x0000, 0x8104, 0x003A, 0x002C, 0x0000, 0x8082, 0x006D, 0x0101, 0x0004, 0x002C,
0x0000, 0x8105, 0x0055, 0x401C, 0x00DA, 0x0102, 0x00DF, 0x0101, 0x00E3, 0x0000, 0x0100, 0x002C, 0x0000, 0x8003, 0x0085, 0x0007,
0x0000, 0x8002, 0x0044, 0x4004, 0x00EA, 0x0017, 0x00EE, 0x001A, 0x00F2, 0x0000, 0x002C, 0x0000, 0x8104, 0x0090, 0x002C, 0x0000,
0x8186, 0x0034, 0x002C, 0x0000, 0x8104, 0x0084, 0x4015, 0x00FD, 0x0100, 0x0102, 0x0101, 0x010D, 0x0000, 0x0100, 0x002C, 0x0000,
0x8003, 0x00AA, 0x4004, 0x0107, 0x002C, 0x010B, 0x0000, 0x002C, 0x0000, 0x8086, 0x001C, 0x8002, 0x009C, 0x4004, 0x0112, 0x0018,
0x0116, 0x0000, 0x002C, 0x0000, 0x8084, 0x0068, 0x002C, 0x0000, 0x8105, 0x004B, 0x4007, 0x0125, 0x0018, 0x012B, 0x0102, 0x0140,
0x0100, 0x0144, 0x0101, 0x014F, 0x0000, 0x0101, 0x000D, 0x002C, 0x0000, 0x8084, 0x006C, 0x0101, 0x0000, 0x4006, 0x0134, 0x0016,
0x0138, 0x001A, 0x013C, 0x0000, 0x002C, 0x0000, 0x8003, 0x009E, 0x002C, 0x0000, 0x8003, 0x009E, 0x002C, 0x0000, 0x8003, 0x009E,
0x0007, 0x0000, 0x8004, 0x006C, 0x4004, 0x0149, 0x002C, 0x014D, 0x0000, 0x002C, 0x0000, 0x8002, 0x001F, 0x8082, 0x0048, 0x4004,
0x0158, 0x0017, 0x015C, 0x0018, 0x0160, 0x001A, 0x0164, 0x0000, 0x002C, 0x0000, 0x8106, 0x003A, 0x002C, 0x0000, 0x8186, 0x0010,
0x002C, 0x0000, 0x8105, 0x0046, 0x002C, 0x0000, 0x8082, 0x0048, 0x0101, 0x0000, 0x4006, 0x0171, 0x0016, 0x0175, 0x001A, 0x0179,
0x0000, 0x002C, 0x0000, 0x8103, 0x0061, 0x002C, 0x0000, 0x8185, 0x005F, 0x002C, 0x0000, 0x8104, 0x0060, 0x4018, 0x0184, 0x0100,
0x0199, 0x0101, 0x019E, 0x0000, 0x0101, 0x0000, 0x4006, 0x018D, 0x0016, 0x0191, 0x001A, 0x0195, 0x0000, 0x002C, 0x0000, 0x8003,
0x0089, 0x002C, 0x0000, 0x8003, 0x0089, 0x002C, 0x0000, 0x8003, 0x0089, 0x0004, 0x002C, 0x0000, 0x8002, 0x0017, 0x001A, 0x002C,
0x0000, 0x8104, 0x0088, 0x0101, 0x0004, 0x002C, 0x0000, 0x8105, 0x0050, 0x0101, 0x0004, 0x002C, 0x0000, 0x8106, 0x002E, 0x4012,
0x01B4, 0x0015, 0x01B9, 0x0000, 0x0100, 0x002C, 0x0000, 0x8203, 0x009B, 0x0100, 0x002C, 0x0000, 0x8002, 0x00C5, 0x0007, 0x0000,
0x8006, 0x0016, 0x4036, 0x01FF, 0x0037, 0x0201, 0x0004, 0x0203, 0x0005, 0x0207, 0x0006, 0x0209, 0x0007, 0x020B, 0x0008, 0x020D,
0x0009, 0x020F, 0x000A, 0x0211, 0x000B, 0x0213, 0x000C, 0x0215, 0x000D, 0x0217, 0x000E, 0x0219, 0x000F, 0x021B, 0x0010, 0x021D,
0x0011, 0x021F, 0x0012, 0x0221, 0x0013, 0x0223, 0x0014, 0x0225, 0x0015, 0x0227, 0x0016, 0x0229, 0x0017, 0x022B, 0x0018, 0x022D,
0x0019, 0x022F, 0x001A, 0x0231, 0x001B, 0x0233, 0x001C, 0x0235, 0x001D, 0x0237, 0x002C, 0x0239, 0x0100, 0x023B, 0x0000, 0x8004,
0x0078, 0x8001, 0x00D4, 0x002C, 0x0000, 0x8002, 0x00CB, 0x8005, 0x005A, 0x8001, 0x0008, 0x8001, 0x0008, 0x8001, 0x0009, 0x8004,
0x0064, 0x8001, 0x0008, 0x8006, 0x0040, 0x8002, 0x000E, 0x8003, 0x00B9, 0x8001, 0x000B, 0x8001, 0x0077, 0x8003, 0x006D, 0x8003,
0x000D, 0x8001, 0x0025, 0x8001, 0x0008, 0x8007, 0x0009, 0x8001, 0x0005, 0x8001, 0x0077, 0x8004, 0x006C, 0x8001, 0x0000, 0x8002,
0x0044, 0x8004, 0x008C, 0x8082, 0x000A, 0x8001, 0x001B, 0x8003, 0x00BC, 0x8003, 0x00B0, 0xC001, 0x0003, 0x000D, 0x0000, 0x8004,
0x006C, 0xC800, 0x0000, 0x421E, 0x026E, 0x0036, 0x0270, 0x0037, 0x0272, 0x0233, 0x0274, 0x0033, 0x0276, 0x0238, 0x0278, 0x0004,
0x027A, 0x0006, 0x027C, 0x000B, 0x0282, 0x000C, 0x0284, 0x000D, 0x028A, 0x000E, 0x0290, 0x0011, 0x0292, 0x0014, 0x0294, 0x0016,
0x0296, 0x0017, 0x029A, 0x0018, 0x029E, 0x001A, 0x02A2, 0x001B, 0x02A6, 0x001C, 0x02A8, 0x002C, 0x02AA, 0x0000, 0x9001, 0x0070,
0x8004, 0x0070, 0x9001, 0x0070, 0x9001, 0x0070, 0x9001, 0x0070, 0x9001, 0x0070, 0x8002, 0x0072, 0xC001, 0x0077, 0x002C, 0x0000,
0x8003, 0x00B3, 0x8001, 0x0003, 0xC002, 0x00CF, 0x002C, 0x0000, 0x8081, 0x00D3, 0xC003, 0x00A7, 0x002C, 0x0000, 0x8003, 0x00A7,
0x8003, 0x00C2, 0x8001, 0x005B, 0x8004, 0x0074, 0x002C, 0x0000, 0x8003, 0x00B3, 0x002C, 0x0000, 0x8003, 0x00A4, 0x002C, 0x0000,
0x8002, 0x009C, 0x002C, 0x0000, 0x8002, 0x00D1, 0x8002, 0x0044, 0x8002, 0x0011, 0x8003, 0x005B
};
static const uint8_t sequence_transform_completions_data[COMPLETIONS_SIZE] PROGMEM = {
0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x79, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6F, 0x6E,
0x68, 0x6F, 0x75, 0x67, 0x68, 0x74, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x73, 0x6F, 0x6C, 0x75,
0x74, 0x65, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x6C, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6C, 0x72,
0x65, 0x61, 0x64, 0x79, 0x68, 0x72, 0x6F, 0x75, 0x67, 0x68, 0x67, 0x61, 0x69, 0x6E, 0x73, 0x74,
0x6F, 0x77, 0x65, 0x76, 0x65, 0x72, 0x70, 0x64, 0x61, 0x74, 0x65, 0x70, 0x73, 0x69, 0x64, 0x65,
0x6C, 0x77, 0x61, 0x79, 0x73, 0x70, 0x70, 0x65, 0x61, 0x72, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x68,
0x6F, 0x75, 0x6C, 0x64, 0x69, 0x72, 0x73, 0x74, 0x73, 0x77, 0x65, 0x72, 0x6D, 0x65, 0x6E, 0x74,
0x20, 0x61, 0x6E, 0x64, 0x75, 0x69, 0x63, 0x6B, 0x20, 0x62, 0x75, 0x74, 0x64, 0x6F, 0x77, 0x6E,
0x75, 0x64, 0x67, 0x65, 0x65, 0x27, 0x72, 0x65, 0x65, 0x27, 0x76, 0x65, 0x68, 0x69, 0x63, 0x68,
0x66, 0x74, 0x65, 0x72, 0x65, 0x27, 0x6C, 0x6C, 0x79, 0x27, 0x64, 0x6F, 0x73, 0x65, 0x6E, 0x27,
0x74, 0x61, 0x6B, 0x65, 0x69, 0x6D, 0x65, 0x6F, 0x69, 0x6E, 0x65, 0x27, 0x73, 0x61, 0x72, 0x64,
0x74, 0x68, 0x65, 0x6F, 0x6D, 0x65, 0x65, 0x27, 0x64, 0x75, 0x73, 0x74, 0x6F, 0x6E, 0x65, 0x66,
0x75, 0x6C, 0x6E, 0x6F, 0x77, 0x65, 0x20, 0x27, 0x6D, 0x65, 0x64, 0x62, 0x6F, 0x61, 0x6C, 0x6E,
0x67, 0x68, 0x79, 0x49, 0x5C
};

View file

@ -29,7 +29,7 @@ d★d ⇒ developed
⎵👆 ⇒ the ⎵👆 ⇒ the
⎵👆r ⇒ there ⎵👆r⎵ ⇒ there⎵
⎵👆rs ⇒ there's ⎵👆rs ⇒ there's
⎵👆i ⇒ their ⎵👆i ⇒ their
⎵👆yr ⇒ they're ⎵👆yr ⇒ they're
@ -38,7 +38,7 @@ d★d ⇒ developed
⎵👆s ⇒ these ⎵👆s ⇒ these
⎵👆t ⇒ that ⎵👆t ⇒ that
⎵👆a ⇒ than ⎵👆a ⇒ than
⎵👆o ⇒ those ⎵👆o ⇒ those
⎵t👍 ⇒ time ⎵t👍 ⇒ time
⎵t👍g ⇒ though ⎵t👍g ⇒ though
@ -56,9 +56,27 @@ d★d ⇒ developed
⎵w👍l ⇒ we'll ⎵w👍l ⇒ we'll
⎵w👍v ⇒ we've ⎵w👍v ⇒ we've
a👆 ⇒ abo ⎵a👆 ⇒ abo
a👆👍 ⇒ about ⎵a👆t ⇒ about
a👆👆 ⇒ above ⎵a👆v ⇒ above
⎵a👆d ⇒ aboard
⎵a👆s ⇒ absolute
⎵a👍r ⇒ after
⎵a👍n ⇒ again
⎵a👍t ⇒ against
⎵a👍s ⇒ answer
⎵a👍p ⇒ appear
⎵a👍w ⇒ always
⎵a👍y ⇒ already
⎵a👍l ⇒ alright
⎵u👍 ⇒ use
⎵u👍f ⇒ useful
⎵u👍t ⇒ update
⎵u👍g ⇒ upgrade
⎵u👍s ⇒ upside
⎵u👍sd ⇒ upsidedown
v👆 ⇒ ver v👆 ⇒ ver
s👆 ⇒ sk s👆 ⇒ sk