diff --git a/keyboards/moonlander/keymaps/ikcelaks/__init__.h b/keyboards/moonlander/keymaps/ikcelaks/__init__.h index abbb81ad..119b6b7e 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/__init__.h +++ b/keyboards/moonlander/keymaps/ikcelaks/__init__.h @@ -3,4 +3,4 @@ #include QMK_KEYBOARD_H #include "general/custom_keys.h" -#include "magic_sturdy/__init__.h" +#include "magic_sturdy/context_magic.h" diff --git a/keyboards/moonlander/keymaps/ikcelaks/config.h b/keyboards/moonlander/keymaps/ikcelaks/config.h index 814bbccf..28ea1bdd 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/config.h +++ b/keyboards/moonlander/keymaps/ikcelaks/config.h @@ -23,3 +23,5 @@ // User Added #define COMBO_COUNT 10 #define TAPPING_TOGGLE 2 +#define USER_PRINT +#define DEBUG diff --git a/keyboards/moonlander/keymaps/ikcelaks/keycodes.h b/keyboards/moonlander/keymaps/ikcelaks/keycodes-copy.h similarity index 100% rename from keyboards/moonlander/keymaps/ikcelaks/keycodes.h rename to keyboards/moonlander/keymaps/ikcelaks/keycodes-copy.h diff --git a/keyboards/moonlander/keymaps/ikcelaks/keymap.c b/keyboards/moonlander/keymaps/ikcelaks/keymap.c index 51712358..6e4b4879 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/keymap.c +++ b/keyboards/moonlander/keymaps/ikcelaks/keymap.c @@ -109,17 +109,21 @@ combo_t key_combos[COMBO_COUNT] = { COMBO(combo_RB_IR, US_QUOT_S), }; -extern rgb_config_t rgb_matrix_config; +// extern rgb_config_t rgb_matrix_config; -void keyboard_post_init_user(void) { - rgb_matrix_enable(); -} +// void keyboard_post_init_user(void) { +// rgb_matrix_enable(); +// } bool process_record_user(uint16_t keycode, keyrecord_t *record) { - bool return_value; + // bool return_value; - if (sturdy_pr(keycode, record, &return_value)) - return return_value; + // if (sturdy_pr(keycode, record, &return_value)) + // return return_value; + uprintf("Process_record_user for keycode: %d", keycode); + + if (!process_context_magic(keycode, record)) + return false; if (record->event.pressed) { switch (keycode) { diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/__init__.h b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/__init__.h deleted file mode 100644 index f245b42f..00000000 --- a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/__init__.h +++ /dev/null @@ -1,55 +0,0 @@ -// Originally from QKekos -#pragma once -#include "../__init__.h" - -#include "general.h" -#include "magic_keys.h" - -#define single_queue_check(p_key) queue(-1) == p_key -#define double_queue_check(pp_key, p_key) queue(-2) == pp_key && single_queue_check(p_key) -#define triple_queue_check(ppp_key, pp_key, p_key) queue(-3) == ppp_key && double_queue_check(pp_key, p_key) -#define quadruple_queue_check(pppp_key, ppp_key, pp_key, p_key) queue(-4) == pppp_key && triple_queue_check(ppp_key, pp_key, p_key) - -#define magic_case_core(trigger, condition, supplement) \ - case trigger: \ - if (condition) { \ - record_send_string(supplement); \ - return; \ - } \ - break - -#define magic_switch_core(trigger, body, index) \ - case trigger: \ - switch (queue(index)) { \ - body \ - } \ - break - -#define magic_case(trigger, supplement) \ - case trigger: \ - record_send_string(supplement); \ - return - -#define double_magic_switch(trigger, body) \ - magic_switch_core(trigger, body, -1) - -#define triple_magic_switch(trigger, body) \ - magic_switch_core(trigger, body, -2) - -#define quadruple_magic_switch(trigger, body) \ - magic_switch_core(trigger, body, -3) - -#define quintuple_magic_switch(trigger, body) \ - magic_switch_core(trigger, body, -4) - -#define double_magic_case(trigger, p_key, supplement) \ - magic_case_core(trigger, single_queue_check(p_key), supplement) - -#define triple_magic_case(trigger, pp_key, p_key, supplement) \ - magic_case_core(trigger, double_queue_check(pp_key, p_key), supplement) - -#define quadruple_magic_case(trigger, ppp_key, pp_key, p_key, supplement) \ - magic_case_core(trigger, triple_queue_check(ppp_key, pp_key, p_key), supplement) - -#define quintuple_magic_case(trigger, pppp_key, ppp_key, pp_key, p_key, supplement) \ - magic_case_core(trigger, quadruple_queue_check(pppp_key, ppp_key, pp_key, p_key), supplement) diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/context_magic.c b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/context_magic.c new file mode 100644 index 00000000..bcc22e8e --- /dev/null +++ b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/context_magic.c @@ -0,0 +1,396 @@ +// Copyright 2021 Google LLC +// Copyright 2021 @filterpaper +// Copyright 2023 Pablo Martinez (@elpekenin) +// Copyright 2024 Guillaume Stordeur +// SPDX-License-Identifier: Apache-2.0 +// Original source: https://getreuer.info/posts/keyboards/autocorrection + +#include "context_magic.h" +#include +#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; + + // Mask for base keycode from shifted keys. + 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 = 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); + 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 + for (int i = res->completion_offset; i < trie->completions_size; ++i) { + char ascii_code = CDATA(i); + if (!ascii_code) { + break; + } + tap_code16(char_to_keycode(ascii_code)); + } + + switch (res->func_code) { + case 1: // repeat + handle_repeat_key(); + return; + case 2: // set one-shot shift + set_oneshot_mods(MOD_LSFT); + return; + } +} + +/** + * @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: + // process normally + break; + case KC_MINUS ...KC_SLASH: + // treat " (shifted ') as a word boundary + if (keycode == KC_QUOTE && (mods & MOD_MASK_SHIFT) != 0) + keycode = KC_SPC; + break; + case S(KC_MINUS) ...S(KC_SLASH): + // treat " (shifted ') as a word boundary + if (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; +} diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/context_magic.h b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/context_magic.h new file mode 100644 index 00000000..d153a72e --- /dev/null +++ b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/context_magic.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#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); diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/general.c b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/general.c deleted file mode 100644 index 1f13d8ca..00000000 --- a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/general.c +++ /dev/null @@ -1,181 +0,0 @@ - -#include "magic_sturdy/general.h" -#include "../__init__.h" - -int mag1_key_count = 0; -int mag2_key_count = 0; -int mag3_key_count = 0; -int mag4_key_count = 0; -int last_key_pressed_time = 0; -int prev_key_time; - -int prev_keys_queue[PREV_KEYS_QUEUE_SIZE] = {KC_NO}; -deferred_token magic_timeout_token = INVALID_DEFERRED_TOKEN; - -uint32_t enqueue_space(uint32_t trigger_time, void *cb_arg) { - enqueue(KC_SPC); - return 0; -} - -void refresh_token(void) { - if (magic_timeout_token != INVALID_DEFERRED_TOKEN) - cancel_deferred_exec(magic_timeout_token); - - magic_timeout_token = defer_exec(MAGIC_KEY_TIMEOUT, enqueue_space, NULL); -} - -void record_send_string(const char *str) { - for (int i = 0; str[i] != '\0'; i++) { - if (str[i] == 8) dequeue(); // dequeue when sending backspace - else if (65 <= str[i] && str[i] <= 90) enqueue(str[i] - 61); - else if (97 <= str[i] && str[i] <= 122) enqueue(str[i] - 93); - } - - SEND_STRING(str); -} - -void enqueue(int keycode) { - for (int i = 0; i < PREV_KEYS_QUEUE_SIZE - 1; i += 1) - prev_keys_queue[i] = prev_keys_queue[i + 1]; - - prev_keys_queue[PREV_KEYS_QUEUE_SIZE - 1] = keycode; -} - -void dequeue(void) { - set_last_keycode(prev_keys_queue[PREV_KEYS_QUEUE_SIZE - 1]); - - for (int i = PREV_KEYS_QUEUE_SIZE - 1; i > 0; i -= 1) - prev_keys_queue[i] = prev_keys_queue[i - 1]; - - prev_keys_queue[0] = KC_NO; -} - -void print_queue(void) { - uprintf("queue: "); - - for (int i = 0; i < PREV_KEYS_QUEUE_SIZE - 1; i += 1) - uprintf("%d, ", prev_keys_queue[i]); - - uprintf("\n"); -} - -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; -} - -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* mods) { - keycode = normalize_keycode(keycode); - - switch (keycode) { - case KC_BSPC: - case KC_LEFT: - dequeue(); - return false; - } - - if ( - (*mods & MOD_MASK_CTRL) && - ((keycode == KC_BSPC && record->tap.count) || (keycode == KC_BSPC)) - ) keycode = KC_SPC; - - switch (keycode) { - case KC_ENT: - case KC_TAB: - case KC_BSPC: - case LCTL(KC_BSPC): - case KC_LEFT: - case KC_DQUO: - case KC_LPRN: - case KC_SPC: - keycode = KC_SPC; - break; - - case KC_A ... KC_Z: - if ((*mods & ~(MOD_MASK_SHIFT)) == 0) { - *mods &= ~MOD_MASK_SHIFT; - } - break; - - case US_MAG1: - case US_MAG2: - case US_MAG3: - case US_MAG4: - return false; - } - - enqueue(keycode); - print_queue(); - return true; -} - -bool sturdy_pr(uint16_t keycode, keyrecord_t *record, bool *return_value) { - *return_value = false; - prev_key_time = last_key_pressed_time; - - if (record->event.pressed) { - last_key_pressed_time = timer_read(); - refresh_token(); - - if (keycode != US_MAG1) mag1_key_count = 0; - else mag1_key_count += 1; - - if (keycode != US_MAG2) mag2_key_count = 0; - else mag2_key_count += 1; - - if (keycode != US_MAG4) mag3_key_count = 0; - else mag3_key_count += 1; - - if (keycode != US_MAG4) mag4_key_count = 0; - else mag4_key_count += 1; - } - - switch (keycode) { - case US_MAG1: - if (record->event.pressed) - process_magic_key_1(); - - return true; - - case US_MAG2: - if (record->event.pressed) - process_magic_key_2(); - - return true; - - case US_MAG3: - if (record->event.pressed) - process_magic_key_3(); - - return true; - - case US_MAG4: - if (record->event.pressed) - process_magic_key_4(); - - return true; - - // case KC_B: - // case KC_Z: - // case KC_F: - // return process_double_tap(keycode, record); - } - - return false; -} - -// bool process_double_tap(uint16_t keycode, keyrecord_t *record) { -// if ( -// !record->event.pressed || -// highest_layer != STURDY || -// queue(-2) != keycode || -// timer_elapsed(prev_key_time) > (get_tapping_term(keycode, NULL) + 50) -// ) return false; - -// dequeue(); -// process_magic_key(); - -// return true; -// } diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/general.h b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/general.h deleted file mode 100644 index 1645d028..00000000 --- a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/general.h +++ /dev/null @@ -1,32 +0,0 @@ -// Originally from QKekos - -#pragma once -#include "../__init__.h" - -#define PREV_KEYS_QUEUE_SIZE 10 -#define MAGIC_KEY_TIMEOUT 2000 - -bool sturdy_pr(uint16_t keycode, keyrecord_t *record, bool *return_value); -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* mods); -bool process_double_tap(uint16_t keycode, keyrecord_t *record); -void record_send_string(const char *str); -void enqueue(int keycode); -void dequeue(void); -void print_queue(void); - -uint32_t enqueue_space(uint32_t trigger_time, void *cb_arg); -void refresh_token(void); - -extern int prev_keys_queue[]; -extern int mag1_key_count; -extern int mag2_key_count; -extern int mag3_key_count; -extern int mag4_key_count; -extern int last_key_pressed_time; - -#define queue(i) prev_keys_queue[PREV_KEYS_QUEUE_SIZE + i] - -#define record_case(symbol, keycode) \ - case symbol: \ - enqueue(keycode); \ - continue diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/magic_keys.c b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/magic_keys.c deleted file mode 100644 index eecf0453..00000000 --- a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/magic_keys.c +++ /dev/null @@ -1,361 +0,0 @@ - -#include "../__init__.h" -#include "keycodes.h" -#include "keymap_us.h" -#include "magic_sturdy/__init__.h" -#include "magic_sturdy/general.h" - -void process_magic_key_1(void) { - if (mag1_key_count >= 2) { - switch (queue(-5)) { - quintuple_magic_case(KC_J, KC_U, KC_D, KC_G, KC_E, "\bment"); - } - switch (queue(-4)) { - quadruple_magic_case(KC_SPC, KC_A, KC_L, KC_R, "eady"); - quadruple_magic_switch(KC_J, - triple_magic_switch(KC_U, - double_magic_case(KC_D, KC_G, "ment"); - double_magic_case(KC_S, KC_T, "ment"); - ); - ); - } - - switch (queue(-3)) { - triple_magic_case(KC_A, KC_B, KC_O, "ve"); - default: record_send_string("n"); return; - } - } - - switch (queue(-5)) { - quintuple_magic_switch(KC_B, - quadruple_magic_case(KC_A, KC_L, KC_L, KC_I, "st"); - quadruple_magic_case(KC_L, KC_I, KC_V, KC_I, "on"); - ); - } - - switch (queue(-4)) { - quadruple_magic_case(KC_A, KC_B, KC_E, KC_T, "ment"); - quadruple_magic_case(KC_V, KC_I, KC_L, KC_I, "on"); - } - - switch (queue(-3)) { - triple_magic_switch(KC_SPC, - double_magic_switch(KC_A, - magic_case(KC_L, "r"); - magic_case(KC_N, "other"); - ); - - double_magic_switch(KC_E, - magic_case(KC_D, "ge"); - magic_case(KC_X, "ample"); - ); - - double_magic_switch(KC_T, - magic_case(KC_A, "ke"); - magic_case(KC_I, "me"); - ); - - double_magic_case(KC_M, KC_A, "ke"); - - double_magic_case(KC_U, KC_S, "e"); - double_magic_case(KC_I, KC_N, "form"); - ); - - triple_magic_switch(KC_B, - double_magic_switch(KC_E, - magic_case(KC_T, "ween"); - magic_case(KC_L, "ieve"); - ); - - double_magic_case(KC_U, KC_D, "ge"); - ); - - triple_magic_switch(KC_V, - double_magic_switch(KC_A, - magic_case(KC_R, "ious"); - ); - - double_magic_case(KC_I, KC_D, "eo"); - ); - - triple_magic_switch(KC_R, - double_magic_case(KC_I, KC_D, "ge"); - double_magic_case(KC_E, KC_D, "ge"); - ); - - triple_magic_switch(KC_S, - double_magic_case(KC_Y, KC_S, "tem"); - ); - - triple_magic_switch(KC_G, - double_magic_case(KC_E, KC_N, "ious"); - ); - - triple_magic_switch(KC_D, - double_magic_case(KC_I, KC_F, "feren"); - double_magic_case(KC_E, KC_F, "inite"); - ); - - triple_magic_switch(KC_L, - double_magic_case(KC_E, KC_D, "ge"); - double_magic_case(KC_L, KC_I, "on"); - ); - - triple_magic_switch(KC_A, - double_magic_case(KC_N, KC_Y, "way"); - ); - - triple_magic_case(KC_J, KC_U, KC_D, "ge"); - triple_magic_case(KC_O, KC_B, KC_V, "ious"); - triple_magic_case(KC_H, KC_I, KC_L, "arious"); - } - - switch (queue(-2)) { - double_magic_switch(KC_SPC, - magic_case(KC_T, "han"); - magic_case(KC_L, "ittle"); - ); - - double_magic_switch(KC_P, - magic_case(KC_L, "y"); - magic_case(KC_A, "ge"); - magic_case(KC_E, "ople"); - magic_case(KC_R, "evious"); - ); - - double_magic_switch(KC_D, - magic_case(KC_A, "y"); - magic_case(KC_R, "y"); - ); - - double_magic_case(KC_W, KC_A, "y"); - double_magic_case(KC_B, KC_E, "en"); - double_magic_case(KC_L, KC_I, "st"); - double_magic_case(KC_V, KC_I, "sion"); - double_magic_case(KC_A, KC_B, "ility"); - double_magic_case(KC_I, KC_B, "ility"); - } - - switch (queue(-1)) { - magic_case(KC_SPC, "the"); - - magic_case(KC_V, "er"); - magic_case(KC_S, "k"); - magic_case(KC_X, "es"); - - magic_case(KC_M, "ent"); - magic_case(KC_T, "ment"); - magic_case(KC_K, "s"); - - magic_case(KC_L, "k"); - magic_case(KC_R, "l"); - magic_case(KC_J, "ust"); - - magic_case(KC_C, "y"); - magic_case(KC_D, "y"); - magic_case(KC_G, "y"); - magic_case(KC_P, "y"); - magic_case(KC_Y, "p"); - magic_case(KC_W, "hich"); - magic_case(KC_Q, "uestion"); - - magic_case(KC_B, "efore"); - magic_case(KC_F, "irst"); - magic_case(KC_Z, "one"); - // US_MAG1 - magic_case(KC_N, "ion"); - magic_case(KC_H, "owever"); - - magic_case(KC_U, "e"); - magic_case(KC_E, "u"); - // KC_QUOT - - magic_case(KC_O, "a"); - magic_case(KC_A, "bo"); - // KC_QUES - - magic_case(KC_COMM, get_last_mods() & MOD_MASK_SHIFT ? "=" : " but"); - magic_case(KC_I, "on"); - magic_case(KC_DOT, get_last_mods() & MOD_MASK_SHIFT ? "=" : "\\"); - magic_case(KC_MINS, ">"); - } -} - -void process_magic_key_2(void) { - switch (queue(-5)) { - quintuple_magic_switch(KC_SPC, - quadruple_magic_case(KC_M, KC_A, KC_K, KC_E, "\bing"); - quadruple_magic_case(KC_T, KC_A, KC_K, KC_E, "\bing"); - ); - } - - switch (queue(-4)) { - quadruple_magic_switch(KC_SPC, - triple_magic_case(KC_A, KC_L, KC_R, "ight"); - triple_magic_case(KC_R, KC_E, KC_V, "iew"); - triple_magic_switch(KC_U, - double_magic_switch(KC_N, - magic_case(KC_F, "ollow"); - magic_case(KC_P, "roblem"); - ); - ); - ); - } - switch (queue(-3)) { - triple_magic_switch(KC_SPC, - double_magic_case(KC_O, KC_X, "ygen"); - double_magic_case(KC_S, KC_C, "hool"); - double_magic_case(KC_P, KC_S, "ych"); - ); - - triple_magic_switch(KC_A, - double_magic_case(KC_B, KC_O, "ut"); - double_magic_case(KC_N, KC_Y, "where"); - ); - - triple_magic_case(KC_R, KC_S, KC_C, "hool"); - triple_magic_case(KC_I, KC_T, KC_Y, "\bies"); - } - - switch (queue(-2)) { - double_magic_switch(KC_SPC, - magic_case(KC_V, "iew"); - magic_case(KC_S, "hould"); - // KC_X, "er" - - magic_case(KC_M, "ight"); - magic_case(KC_T, "hrough"); - // KC_K, "now" - - magic_case(KC_L, "ight"); - magic_case(KC_R, "ight"); - // KC_J, "oin" - - magic_case(KC_C, "ould"); - magic_case(KC_D, "on't"); - magic_case(KC_G, "eneral"); - - magic_case(KC_P, "roblem"); - // KC_Y, "ou" - // KC_W, "ould" - - magic_case(KC_B, "ecause"); - magic_case(KC_F, "ollow"); - magic_case(KC_Z, "ero"); - - // KC_MAG1 - magic_case(KC_N, "umber"); - magic_case(KC_H, "owever"); - - magic_case(KC_U, "pdate"); - magic_case(KC_E, "nough"); - // KC_QUOT - - magic_case(KC_O, "ften"); - // KC_A, "nd" - // KC_QUES, " " OSS - - // KC_COMM, " and" - magic_case(KC_I, "ncrease"); - // KC_DOT, " " OSS - ); - - double_magic_case(KC_F, KC_R, "om"); - double_magic_case(KC_A, KC_U, "ght"); - double_magic_case(KC_O, KC_U, "ght"); - } - - switch (queue(-1)) { - magic_case(KC_SPC, "for"); - magic_case(KC_A, "nd"); - magic_case(KC_X, "er"); - magic_case(KC_K, "now"); - magic_case(KC_I, "ng"); - magic_case(KC_Y, "ou"); - magic_case(KC_Q, "uick"); - magic_case(KC_J, "oin"); - magic_case(KC_W, "ould"); - magic_case(KC_C, "k"); - magic_case(KC_N, "f"); - magic_case(KC_H, "n"); - magic_case(KC_COMMA, " and"); - case KC_DOT: - case KC_QUES: - case KC_EXLM: - case KC_COLN: - case KC_SCLN: - unregister_weak_mods(MOD_MASK_CSAG); - send_char(' '); - add_oneshot_mods(MOD_MASK_SHIFT); - enqueue(KC_SPC); - return; - default: tap_code16(queue(-1)); enqueue(queue(-1)); - } -} - -void process_magic_key_3(void) { - switch (queue(-1)) { - magic_case(KC_V, "isit"); - magic_case(KC_S, "mall"); - // KC_X - - magic_case(KC_M, "anage"); - magic_case(KC_T, "hough"); - magic_case(KC_K, "new"); - - magic_case(KC_L, "ocation"); - magic_case(KC_R, "ecommend"); - magic_case(KC_J, "udge"); - - magic_case(KC_C, "onsider"); - magic_case(KC_D, "evelop"); - magic_case(KC_G, "overn"); - - magic_case(KC_P, "ower"); - // KC_Y - magic_case(KC_W, "here"); - magic_case(KC_Q, "mlativ"); - - magic_case(KC_B, "ecome"); - magic_case(KC_F, "ound"); - // KC_Z - - // KC_MAG1 - magic_case(KC_N, "eighbor"); - magic_case(KC_H, "appen"); - - magic_case(KC_U, "pgrade"); - magic_case(KC_E, "'ll"); - // KC_QUOT - - magic_case(KC_O, "ther"); - magic_case(KC_A, "fter"); - // KC_QUES - - magic_case(KC_COMM, " however"); - magic_case(KC_I, "'ll"); - magic_case(KC_DOT, "org"); - default: return; - } -} - -void process_magic_key_4(void) { - switch (queue(-1)) { - magic_case(KC_B, "etween"); - magic_case(KC_N, "ation"); - magic_case(KC_U, "nivers"); - magic_case(KC_O, "ption"); - magic_case(KC_A, "gainst"); - magic_case(KC_P, "rogram"); - magic_case(KC_I, "'m"); - magic_case(KC_T, "echnology"); - magic_case(KC_C, "rowd"); - magic_case(KC_W, "orld"); - magic_case(KC_S, "ervice"); - magic_case(KC_E, "'re"); - magic_case(KC_Q, "uiet"); - magic_case(KC_DOT, "com"); - magic_case(KC_COMM, " since"); - default: return; - } -} diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/magic_keys.h b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/magic_keys.h deleted file mode 100644 index 5edd796e..00000000 --- a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/magic_keys.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "../__init__.h" - -void process_magic_key_1(void); -void process_magic_key_2(void); -void process_magic_key_3(void); -void process_magic_key_4(void); diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/utils.c b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/utils.c new file mode 100644 index 00000000..503b2bce --- /dev/null +++ b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/utils.c @@ -0,0 +1,82 @@ +#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); +} diff --git a/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/utils.h b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/utils.h new file mode 100644 index 00000000..44c6d1d4 --- /dev/null +++ b/keyboards/moonlander/keymaps/ikcelaks/magic_sturdy/utils.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +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); diff --git a/keyboards/moonlander/keymaps/ikcelaks/magickey_data.h b/keyboards/moonlander/keymaps/ikcelaks/magickey_data.h index 9d443c61..61a75312 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/magickey_data.h +++ b/keyboards/moonlander/keymaps/ikcelaks/magickey_data.h @@ -26,18 +26,8 @@ #pragma once // Autocorrection dictionary with longest match semantics: -// Autocorrection dictionary (25 entries): -// c👆 -> cy -// p👆 -> py -// d👆 -> dy -// y👆 -> yp -// g👆 -> gy +// Autocorrection dictionary (59 entries): // 👍 -> ↻ -// i👍 -> ing -// a👍 -> and -// :👆 -> the -// :👍 -> for -// .👍 -> .:⇑ // j👆 -> just // j👆👆 -> justment // 👆👆 -> 👆n @@ -52,28 +42,87 @@ // :i👍m -> I'm // :i👍d -> I'd // :i👍l -> I'll +// :👆 -> the +// v👆 -> ver +// s👆 -> sk +// x👆 -> es +// m👆 -> ment +// t👆 -> tment +// k👆 -> ks +// l👆 -> lk +// r👆 -> rl +// c👆 -> cy +// p👆 -> py +// d👆 -> dy +// y👆 -> yp +// g👆 -> gy +// w👆 -> which +// q👆 -> question +// b👆 -> before +// f👆 -> first +// z👆 -> zone +// n👆 -> nion +// h👆 -> however +// u👆 -> eu +// e👆 -> ue +// o👆 -> oa +// a👆 -> abo +// ,👆 -> ,:but +// i👆 -> ion +// .👆 -> .\ [escape] +// :👍 -> for +// a👍 -> and +// x👍 -> xer +// k👍 -> know +// i👍 -> ing +// y👍 -> you +// q👍 -> quick +// w👍 -> would +// c👍 -> ck +// n👍 -> nf +// h👍 -> hn +// ,👍 -> ,:and +// .👍 -> .:⇑ +// ?👍 -> ?:⇑ +// ;👍 -> ;:⇑ +// !👍 -> !:⇑ #define MAGICKEY_MIN_LENGTH 1 // "👍" #define MAGICKEY_MAX_LENGTH 5 // "jud👆👆" -#define DICTIONARY_SIZE 134 -#define COMPLETIONS_SIZE 64 +#define DICTIONARY_SIZE 270 +#define COMPLETIONS_SIZE 161 #define MAGICKEY_COUNT 4 static const uint16_t magickey_data[DICTIONARY_SIZE] PROGMEM = { - 0x4007, 0x0011, 0x000F, 0x001F, 0x0010, 0x0025, 0x0015, 0x002B, 0x0017, 0x0030, 0x0102, 0x0035, 0x0100, 0x0039, 0x0101, 0x006B, + 0x4007, 0x0011, 0x000F, 0x001F, 0x0010, 0x0025, 0x0015, 0x002B, 0x0017, 0x0030, 0x0102, 0x0035, 0x0100, 0x0039, 0x0101, 0x00C3, 0x0000, 0x4102, 0x0016, 0x0101, 0x001A, 0x0000, 0x0007, 0x0000, 0x8000, 0x0000, 0x000C, 0x002C, 0x0000, 0x8000, 0x0003, 0x0101, 0x000C, 0x002C, 0x0000, 0x8000, 0x0006, 0x0101, 0x000C, 0x002C, 0x0000, 0x8000, 0x000A, 0x0102, 0x0007, 0x0000, 0x8000, 0x000D, - 0x0102, 0x0007, 0x0000, 0x8000, 0x0010, 0x0007, 0x0000, 0x8000, 0x0015, 0x402C, 0x004A, 0x0006, 0x004C, 0x0007, 0x004E, 0x000A, - 0x0055, 0x000D, 0x0057, 0x0013, 0x0059, 0x001C, 0x005B, 0x0100, 0x005D, 0x0000, 0x8000, 0x001C, 0x8000, 0x0020, 0xC000, 0x0020, - 0x0018, 0x000D, 0x0000, 0x8000, 0x0022, 0x8000, 0x0020, 0x8000, 0x0025, 0x8000, 0x0020, 0x8000, 0x0029, 0xC000, 0x002B, 0x4007, - 0x0064, 0x000D, 0x0069, 0x0000, 0x0018, 0x000D, 0x0000, 0x8001, 0x0010, 0x8000, 0x0010, 0xC800, 0x002D, 0x4037, 0x0078, 0x002C, - 0x007A, 0x0004, 0x007C, 0x000C, 0x007E, 0x000D, 0x0084, 0x0000, 0x9000, 0x002E, 0x8000, 0x0030, 0x8000, 0x0034, 0xC000, 0x0037, - 0x002C, 0x0000, 0x8001, 0x003A, 0x8000, 0x003C + 0x0102, 0x0007, 0x0000, 0x8000, 0x0010, 0x0007, 0x0000, 0x8000, 0x0015, 0x4036, 0x0076, 0x0037, 0x0078, 0x002C, 0x007A, 0x0004, + 0x007C, 0x0005, 0x007E, 0x0006, 0x0080, 0x0007, 0x0082, 0x0008, 0x0089, 0x0009, 0x008B, 0x000A, 0x008D, 0x000B, 0x008F, 0x000C, + 0x0091, 0x000D, 0x0093, 0x000E, 0x0095, 0x000F, 0x0097, 0x0010, 0x0099, 0x0011, 0x009B, 0x0012, 0x009D, 0x0013, 0x009F, 0x0014, + 0x00A1, 0x0015, 0x00A3, 0x0016, 0x00A5, 0x0017, 0x00A7, 0x0018, 0x00A9, 0x0019, 0x00AB, 0x001A, 0x00AD, 0x001B, 0x00AF, 0x001C, + 0x00B1, 0x001D, 0x00B3, 0x0100, 0x00B5, 0x0000, 0x8000, 0x001C, 0x8000, 0x0021, 0x8000, 0x0023, 0x8000, 0x0027, 0x8000, 0x002A, + 0x8000, 0x0030, 0xC000, 0x0030, 0x0018, 0x000D, 0x0000, 0x8000, 0x0032, 0x8001, 0x0035, 0x8000, 0x0038, 0x8000, 0x0030, 0x8000, + 0x003D, 0x8000, 0x0044, 0x8000, 0x0047, 0x8000, 0x004B, 0x8000, 0x004D, 0x8000, 0x004F, 0x8000, 0x0053, 0x8000, 0x0057, 0x8000, + 0x0030, 0x8000, 0x0059, 0x8000, 0x0061, 0x8000, 0x004D, 0x8000, 0x0010, 0x8001, 0x0063, 0x8000, 0x000D, 0x8000, 0x0066, 0x8001, + 0x006B, 0x8000, 0x006E, 0x8000, 0x0070, 0xC000, 0x0074, 0x4007, 0x00BC, 0x000D, 0x00C1, 0x0000, 0x0018, 0x000D, 0x0000, 0x8001, + 0x0010, 0x8000, 0x0010, 0xC800, 0x0076, 0x421E, 0x00E8, 0x0036, 0x00EA, 0x0037, 0x00EC, 0x002C, 0x00EE, 0x0033, 0x00F0, 0x0238, + 0x00F2, 0x0004, 0x00F4, 0x0006, 0x00F6, 0x000B, 0x00F8, 0x000C, 0x00FA, 0x000D, 0x0100, 0x000E, 0x0102, 0x0011, 0x0104, 0x0014, + 0x0106, 0x001A, 0x0108, 0x001B, 0x010A, 0x001C, 0x010C, 0x0000, 0x9000, 0x0077, 0x8000, 0x0079, 0x9000, 0x0077, 0x8000, 0x007E, + 0x9000, 0x0077, 0x9000, 0x0077, 0x8000, 0x0082, 0x8000, 0x004D, 0x8000, 0x0074, 0xC000, 0x0085, 0x002C, 0x0000, 0x8001, 0x0088, + 0x8000, 0x008A, 0x8000, 0x008E, 0x8000, 0x0092, 0x8000, 0x0094, 0x8000, 0x0099, 0x8000, 0x000D, 0x8000, 0x009E }; static const uint8_t magickey_completions_data[COMPLETIONS_SIZE] PROGMEM = { 0x65, 0x64, 0x00, 0x27, 0x64, 0x00, 0x27, 0x6C, 0x6C, 0x00, 0x27, 0x6D, 0x00, 0x65, 0x72, 0x00, - 0x6D, 0x65, 0x6E, 0x74, 0x00, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x00, 0x74, 0x68, 0x65, 0x00, - 0x79, 0x00, 0x67, 0x65, 0x00, 0x75, 0x73, 0x74, 0x00, 0x70, 0x00, 0x6E, 0x00, 0x00, 0x3A, 0x00, - 0x66, 0x6F, 0x72, 0x00, 0x6E, 0x64, 0x00, 0x6E, 0x67, 0x00, 0x49, 0x00, 0x6F, 0x69, 0x6E, 0x00 + 0x6D, 0x65, 0x6E, 0x74, 0x00, 0x65, 0x76, 0x65, 0x6C, 0x6F, 0x70, 0x00, 0x20, 0x62, 0x75, 0x74, + 0x00, 0x5C, 0x00, 0x74, 0x68, 0x65, 0x00, 0x62, 0x6F, 0x00, 0x65, 0x66, 0x6F, 0x72, 0x65, 0x00, + 0x79, 0x00, 0x67, 0x65, 0x00, 0x75, 0x65, 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, 0x75, 0x00, 0x68, 0x69, 0x63, 0x68, 0x00, 0x65, 0x73, 0x00, 0x70, 0x00, + 0x6F, 0x6E, 0x65, 0x00, 0x6E, 0x00, 0x00, 0x20, 0x00, 0x20, 0x61, 0x6E, 0x64, 0x00, 0x66, 0x6F, + 0x72, 0x00, 0x6E, 0x64, 0x00, 0x6E, 0x67, 0x00, 0x49, 0x00, 0x6F, 0x69, 0x6E, 0x00, 0x6E, 0x6F, + 0x77, 0x00, 0x66, 0x00, 0x75, 0x69, 0x63, 0x6B, 0x00, 0x6F, 0x75, 0x6C, 0x64, 0x00, 0x6F, 0x75, + 0x00 }; diff --git a/keyboards/moonlander/keymaps/ikcelaks/magickey_dict.txt b/keyboards/moonlander/keymaps/ikcelaks/magickey_dict.txt index 31018d9c..c38a4a9f 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/magickey_dict.txt +++ b/keyboards/moonlander/keymaps/ikcelaks/magickey_dict.txt @@ -1,17 +1,7 @@ # 👆👍★✪ # ↻⇑ -c👆 ⇒ cy -p👆 ⇒ py -d👆 ⇒ dy -y👆 ⇒ yp -g👆 ⇒ gy 👍 ⇒ ↻ -i👍 ⇒ ing -a👍 ⇒ and -:👆 ⇒ the -:👍 ⇒ for -.👍 ⇒ .:⇑ j👆 ⇒ just j👆👆 ⇒ justment @@ -28,3 +18,63 @@ d★d ⇒ developed :i👍m ⇒ I'm :i👍d ⇒ I'd :i👍l ⇒ I'll + +# final + +:👆 ⇒ the + +v👆 ⇒ ver +s👆 ⇒ sk +x👆 ⇒ es + +m👆 ⇒ ment +t👆 ⇒ tment +k👆 ⇒ ks + +l👆 ⇒ lk +r👆 ⇒ rl +j👆 ⇒ just + +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👆 ⇒ eu +e👆 ⇒ ue + +o👆 ⇒ oa +a👆 ⇒ abo + +,👆 ⇒ ,:but +i👆 ⇒ ion +.👆 ⇒ .\ + +:👍 ⇒ for +a👍 ⇒ and +x👍 ⇒ xer +k👍 ⇒ know +i👍 ⇒ ing +y👍 ⇒ you +q👍 ⇒ quick +j👍 ⇒ join +w👍 ⇒ would +c👍 ⇒ ck +n👍 ⇒ nf +h👍 ⇒ hn +,👍 ⇒ ,:and +.👍 ⇒ .:⇑ +?👍 ⇒ ?:⇑ +:👍 ⇒ ::⇑ +;👍 ⇒ ;:⇑ +!👍 ⇒ !:⇑ diff --git a/keyboards/moonlander/keymaps/ikcelaks/rules.mk b/keyboards/moonlander/keymaps/ikcelaks/rules.mk index 224b341f..1a7b709d 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/rules.mk +++ b/keyboards/moonlander/keymaps/ikcelaks/rules.mk @@ -1,11 +1,11 @@ # Set any rules.mk overrides for your specific keymap here. # See rules at https://docs.qmk.fm/#/config_options?id=the-rulesmk-file -CONSOLE_ENABLE = no +CONSOLE_ENABLE = yes COMMAND_ENABLE = no SPACE_CADET_ENABLE = no COMBO_ENABLE = yes REPEAT_KEY_ENABLE = yes DEFERRED_EXEC_ENABLE = yes -SRC += magic_sturdy/general.c -SRC += magic_sturdy/magic_keys.c +SRC += magic_sturdy/context_magic.c +SRC += magic_sturdy/utils.c diff --git a/keyboards/moonlander/keymaps/ikcelaks/trie2.cpp b/keyboards/moonlander/keymaps/ikcelaks/trie2.cpp index d579891d..74dabfc9 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/trie2.cpp +++ b/keyboards/moonlander/keymaps/ikcelaks/trie2.cpp @@ -3,7 +3,7 @@ #include #include "trie2.h" #include "stack.h" -#include "util.h" +#include "util2.h" #define KEY_BUFFER_MAX_LENGTH MAGICKEY_MAX_LENGTH #define TDATA(i) trie->dict[i] @@ -80,9 +80,9 @@ bool search_trie2(const trie2_t *trie, int offset, trie2_visitor_t *v) search_buffer_t *search = (search_buffer_t*)v->cb_data; uint16_t code = TDATA(offset); assert(code); - // MATCH node if bit 16 is set + // MATCH node if bit 15 is set if (code & 0x8000) { - // If bit 15 is also set, there's a child node after the completion string + // If bit 14 is also set, there's a child node after the completion string if ((code & 0x4000) && search_trie2(trie, offset+2, v)) return true; // If no better match found deeper, this is the result! @@ -94,7 +94,7 @@ bool search_trie2(const trie2_t *trie, int offset, trie2_visitor_t *v) // Found a match so return true! return true; } - // BRANCH node if bit 15 is set + // BRANCH node if bit 14 is set if (code & 0x4000) { if ((v->stack.size+1) > search->size) return false; @@ -104,7 +104,7 @@ bool search_trie2(const trie2_t *trie, int offset, trie2_visitor_t *v) for (; code; offset += 2, code = TDATA(offset)) { const char c = keycode_to_char(code); if (cur_char == c) { - // Get 16bit offset to child node + // Get 15bit offset to child node const int child_offset = TDATA(offset+1); // Traverse down child node stack_push(&v->stack, c); diff --git a/keyboards/moonlander/keymaps/ikcelaks/util.cpp b/keyboards/moonlander/keymaps/ikcelaks/util2.cpp similarity index 96% rename from keyboards/moonlander/keymaps/ikcelaks/util.cpp rename to keyboards/moonlander/keymaps/ikcelaks/util2.cpp index 84420e54..73599487 100644 --- a/keyboards/moonlander/keymaps/ikcelaks/util.cpp +++ b/keyboards/moonlander/keymaps/ikcelaks/util2.cpp @@ -1,5 +1,5 @@ -#include "keycodes.h" -#include "util.h" +#include "keycodes-copy.h" +#include "util2.h" #define QK_LSFT 0x0200 #define pgm_read_byte(address_short) *((uint8_t*)(address_short)) diff --git a/keyboards/moonlander/keymaps/ikcelaks/util.h b/keyboards/moonlander/keymaps/ikcelaks/util2.h similarity index 100% rename from keyboards/moonlander/keymaps/ikcelaks/util.h rename to keyboards/moonlander/keymaps/ikcelaks/util2.h