~ruther/qmk_firmware

46d523c29a9b5d133886035738ad2419bf2fc62d — Rutherther 9 months ago c80fa1c
refactor: cz accent, work only with proper czech accented characters
M keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.c => keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.c +53 -38
@@ 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;

M keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.h => keyboards/zsa/moonlander/keymaps/rutherther/features/cz_accent.h +8 -0
@@ 1,5 1,8 @@
#pragma once

#include <stdint.h>
#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);


Do not follow this link