From 46d523c29a9b5d133886035738ad2419bf2fc62d Mon Sep 17 00:00:00 2001 From: Rutherther Date: Wed, 10 Jul 2024 18:38:33 +0200 Subject: [PATCH] refactor: cz accent, work only with proper czech accented characters --- .../keymaps/rutherther/features/cz_accent.c | 91 +++++++++++-------- .../keymaps/rutherther/features/cz_accent.h | 8 ++ 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.c b/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.c index df7bda1d52..aa1f45d529 100644 --- a/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.c +++ b/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.c @@ -1,6 +1,47 @@ #include "cz_accent.h" #include "keymap_czech.h" +const uint16_t cz_acute_keycodes[] = { + KC_A, KC_E, KC_I, KC_O, KC_U +}; +const uint8_t NUM_ACUTE_KEYCODES = sizeof(cz_acute_keycodes) / sizeof(uint16_t); + +const uint16_t cz_caret_keycodes[] = { + KC_Z, KC_S, KC_C, KC_R, KC_E, KC_D, KC_T, KC_N, KC_U +}; +const uint8_t NUM_CARET_KEYCODES = sizeof(cz_caret_keycodes) / sizeof(uint16_t); + +const uint16_t cz_scln_char = KC_U; + +void process_prefixed_accent(uint16_t keycode, keyrecord_t* record, const uint16_t accent_prefix, const uint16_t *filters, const uint8_t filters_size) { + // TODO wait for the actual key, this can trigger hold condition, I think + if (!record->event.pressed) { + return; + } + + bool found = false; + for (int i = 0; i < filters_size; i++) { + if (QK_MODS_GET_BASIC_KEYCODE(keycode) == filters[i]) { + found = true; + break; + } + } + + if (!found) { + return; + } + + const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods(); + + clear_mods(); + clear_weak_mods(); + clear_oneshot_mods(); + + tap_code16(accent_prefix); + + set_mods(mods); +} + bool process_czech_acute(uint16_t keycode, keyrecord_t* record, uint16_t acute_keycode, int8_t plain_layer) { static bool cz_send_acuted = false; @@ -8,6 +49,11 @@ bool process_czech_acute(uint16_t keycode, keyrecord_t* record, if (keycode == acute_keycode) { cz_send_acuted = record->event.pressed; + // TODO: make sure that this works also for stuff like tap-hold + // without this plain layer hack. + // The problem is that here we don't know if it's tap or hold, at + // least I think. Maybe different function will have to be overriden + // somehow. if (record->event.pressed) { layer_move(plain_layer); } else { @@ -17,25 +63,8 @@ bool process_czech_acute(uint16_t keycode, keyrecord_t* record, return false; } - // TODO: Ignore everything else except for A - Z (or even just the letters that are actually used with acute in czech) - // 1. release shift if held, save if held to shift_held - // 2. send acute accent char with ralt - // 3. if shift_held, hold shift - // 4. process original - if (cz_send_acuted && - keycode != acute_keycode && - keycode != KC_LEFT_SHIFT && - keycode != KC_RIGHT_SHIFT && - record->event.pressed) { - const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods(); - - clear_mods(); - clear_weak_mods(); - clear_oneshot_mods(); - - tap_code16(RALT(CZ_ACUT)); - - set_mods(mods); + if (cz_send_acuted) { + process_prefixed_accent(keycode, record, QK_CZ_ACUTE, cz_acute_keycodes, NUM_ACUTE_KEYCODES); } return true; @@ -56,25 +85,11 @@ bool process_czech_caret(uint16_t keycode, keyrecord_t* record, return false; } - // TODO: Ignore everything else except for A - Z (or even just the letters that are actually used with acute in czech) - if (cz_send_careted && keycode != caret_keycode && - keycode != KC_LEFT_SHIFT && - keycode != KC_RIGHT_SHIFT && - record->event.pressed) { - - const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods(); - - clear_mods(); - clear_weak_mods(); - clear_oneshot_mods(); - - if (QK_MODS_GET_BASIC_KEYCODE(keycode) == KC_U) { - tap_code16(LSFT(RALT(CZ_SCLN))); - } else { - tap_code16(LSFT(RALT(CZ_ACUT))); - } - - set_mods(mods); + if (cz_send_careted) { + if (QK_MODS_GET_BASIC_KEYCODE(keycode) == cz_scln_char) + process_prefixed_accent(keycode, record, QK_CZ_SCLN, cz_caret_keycodes, NUM_CARET_KEYCODES); + else + process_prefixed_accent(keycode, record, QK_CZ_CARET, cz_caret_keycodes, NUM_CARET_KEYCODES); } return true; diff --git a/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.h b/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.h index 339d309403..0b558d8d41 100644 --- a/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.h +++ b/keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.h @@ -1,5 +1,8 @@ +#pragma once + #include #include "quantum.h" +#include "keymap_czech.h" // Type czech caret and acute symbols. // Uses czech programmer/coder layer from OS. @@ -8,6 +11,11 @@ // plain_layer, if it's not equal to -1. This is a hack for not having // to care about tap hold, tap dance characters. + +#define QK_CZ_ACUTE RALT(CZ_ACUT) +#define QK_CZ_CARET LSFT(RALT(CZ_ACUT)) +#define QK_CZ_SCLN LSFT(RALT(CZ_SCLN)) + bool process_czech_acute(uint16_t keycode, keyrecord_t* record, uint16_t acute_keycode, int8_t plain_layer); -- 2.48.1