fix compose bug

This commit is contained in:
Charlotte 🦝 Delenk 2023-02-22 15:49:36 +01:00
parent c22f25a597
commit d7aeb6cc5d
11 changed files with 36291 additions and 36244 deletions

View file

@ -11,7 +11,7 @@
#define MATRIX_COLS 6
#define DEBUG_MATRIX_SCAN_RATE
#define UNICODE_SELECTED_MODES UC_LNX, UC_MAC, UC_WINC
#define UNICODE_SELECTED_MODES UNICODE_MODE_LINUX, UNICODE_MODE_MACOS, UNICODE_MODE_WINCOMPOSE, UNICODE_MODE_EMACS
#define OLED_DISPLAY_128X64

View file

@ -10,118 +10,115 @@
static int charsWritten, currentState;
static void resetState(void) {
print("resetState()\n");
charsWritten = 0;
currentState = 0;
print("resetState()\n");
charsWritten = 0;
currentState = 0;
}
static void finishCompose(const char* result) {
uprintf("Finishing compose with result: %s (%d chars written)\n", result, charsWritten);
while(charsWritten) {
tap_code(KC_BACKSPACE);
charsWritten--;
}
send_unicode_string(result);
resetState();
static void finishCompose(const char *result) {
uprintf("Finishing compose with result: %s (%d chars written)\n", result, charsWritten);
while (charsWritten) {
tap_code(KC_BACKSPACE);
charsWritten--;
}
send_unicode_string(result);
resetState();
}
typedef struct {
uint16_t first_edge_idx;
uint16_t edge_count;
uint16_t first_edge_idx;
uint16_t edge_count;
} compose_node_t;
typedef struct {
const char * value;
uint16_t c;
uint16_t next_node;
const char *value;
uint16_t c;
uint16_t next_node;
} compose_edge_t;
#include "composeTable.h"
static void checkComposeState(void) {
print("checkComposeState()\n");
if(currentState * sizeof(compose_node_t) > sizeof(nodes)) {
finishCompose("[error in compose]");
}
print("checkComposeState()\n");
if (currentState * sizeof(compose_node_t) > sizeof(nodes)) {
finishCompose("[error in compose]");
}
}
static const compose_edge_t *findEdge(uint16_t keycode) {
checkComposeState();
uint32_t uc = keystroke_to_unicode(keycode);
uprintf("Resolved keycode %d: %ld\n", keycode, uc);
checkComposeState();
uint32_t uc = keystroke_to_unicode(keycode);
uprintf("Resolved keycode %d: %ld\n", keycode, uc);
uint16_t match1 = (uint16_t)uc; // yes only bmp support, keyboard doesnt have any astral keycodes anyways
uint16_t match2 = 0;
if(keycode < 256) {
match2 = 0xD800 + keycode;
print("(low keycode)\n");
} else if(keycode == KC_LEAD) {
match2 = 0xD800;
print("(leader key)\n");
}
for(int i = nodes[currentState].first_edge_idx; i < nodes[currentState].first_edge_idx + nodes[currentState].edge_count; i++) {
if(compose_edges[i].c == match1 || compose_edges[i].c == match2) {
uprintf("found matching node: %d -> %d\n", currentState, i);
return &compose_edges[i];
uint16_t match1 = (uint16_t)uc; // yes only bmp support, keyboard doesnt have any astral keycodes anyways
uint16_t match2 = 0;
if (keycode < 256) {
match2 = 0xD800 + keycode;
print("(low keycode)\n");
} else if (keycode == QK_LEAD) {
match2 = 0xD800;
print("(leader key)\n");
}
}
print("no matching edge found.\n");
return NULL;
for (int i = nodes[currentState].first_edge_idx; i < nodes[currentState].first_edge_idx + nodes[currentState].edge_count; i++) {
if (compose_edges[i].c == match1 || compose_edges[i].c == match2) {
uprintf("found matching node: %d -> %d\n", currentState, i);
return &compose_edges[i];
}
}
print("no matching edge found.\n");
return NULL;
}
// yes this breaks with emoji
static size_t charcount_utf8(const char * s) {
size_t n = 0;
while(*s)
if((*(s++) & 0xC0) != 0x80)
n++; // only count non-continuation characters
return n;
static size_t charcount_utf8(const char *s) {
size_t n = 0;
while (*s)
if ((*(s++) & 0xC0) != 0x80) n++; // only count non-continuation characters
return n;
}
static void transEdge(const compose_edge_t *edge) {
uprintf("Transitioning to node %d\n", edge->next_node);
if(edge->value) {
uprintf("new node has value %s\n", edge->value);
finishCompose(edge->value);
if(edge->next_node != 0) // not necessarily the final product
charsWritten = charcount_utf8(edge->value);
}
currentState = edge->next_node;
checkComposeState();
uprintf("Transitioning to node %d\n", edge->next_node);
if (edge->value) {
uprintf("new node has value %s\n", edge->value);
finishCompose(edge->value);
if (edge->next_node != 0) // not necessarily the final product
charsWritten = charcount_utf8(edge->value);
}
currentState = edge->next_node;
checkComposeState();
}
static bool isCombining(uint32_t uc) {
// yes it is not all of them, but all of them that matter for us
if(uc >= 0x300 && uc < 0x370)
return true;
if(uc == 0x20d7)
return true;
return false;
// yes it is not all of them, but all of them that matter for us
if (uc >= 0x300 && uc < 0x370) return true;
if (uc == 0x20d7) return true;
return false;
}
void process_compose(uint16_t keycode, keyrecord_t *record) {
if(!record->event.pressed)
return;
uint32_t uc = keystroke_to_unicode(keycode);
const compose_edge_t * edge = findEdge(keycode);
if(edge == NULL && uc != 0) { // no matching edge found, reset and try again
print("No matching edge found, reset.\n");
resetState();
edge = findEdge(keycode);
}
if(edge == NULL) {
print("No compose edge found.\n");
return; // nothing found
}
// before we can advance the compose state, we need to prepare certain keys (dead keys, the leader key) because otherwise our deletion will delete too much (which of course is something we do not want)
if(isCombining(uc)) {
print("keycode refers to deadkey, writing space\n");
tap_code(KC_SPACE);
} else if(keycode == KC_LEAD) {
print("keycode refers to leader key, writing compose symbol\n");
send_unicode_string("");
}
charsWritten++;
transEdge(edge);
}
if (!record->event.pressed) return;
uint32_t uc = keystroke_to_unicode(keycode);
const compose_edge_t *edge = findEdge(keycode);
if (edge == NULL && uc != 0) { // no matching edge found, reset and try again
uprintf("uc: %ld", uc);
print("No matching edge found, reset.\n");
resetState();
edge = findEdge(keycode);
}
if (edge == NULL) {
print("No compose edge found.\n");
return; // nothing found
}
// before we can advance the compose state, we need to prepare certain keys (dead keys, the leader key) because otherwise our deletion will delete too much (which of course is something we do not want)
if (isCombining(uc)) {
print("keycode refers to deadkey, writing space\n");
tap_code(KC_SPACE);
} else if (keycode == QK_LEAD) {
print("keycode refers to leader key, writing compose symbol\n");
send_unicode_string("");
}
charsWritten++;
transEdge(edge);
}

View file

@ -2,4 +2,4 @@
#include <stdint.h>
#include "action.h"
void process_compose(uint16_t keycode, keyrecord_t *record);
void process_compose(uint16_t keycode, keyrecord_t *record);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,17 +5,7 @@
#include "raw_hid.h"
#include "neo2.h"
#include "compose.h"
enum {
_MAIN,
_NUMPAD,
_PLOVER,
_MOUSE,
_GAMING,
_SYS,
_NAV,
_FN,
_EMPTY
};
enum { _MAIN, _NUMPAD, _PLOVER, _MOUSE, _GAMING, _SYS, _NAV, _FN, _EMPTY };
#define LAYOUT(k0A, k0B, k0C, k0D, k0E, k0F, k5A, k5B, k5C, k5D, k5E, k5F, k1A, k1B, k1C, k1D, k1E, k1F, k6A, k6B, k6C, k6D, k6E, k6F, k2A, k2B, k2C, k2D, k2E, k2F, k7A, k7B, k7C, k7D, k7E, k7F, k3A, k3B, k3C, k3D, k3E, k3F, k8A, k8B, k8C, k8D, k8E, k8F, k4C, k4D, k4E, k4F, k9C, k9D, k9E, k9F) LAYOUT_ortho_4x6_2x2uc(k0A, k0B, k0C, k0D, k0E, k0F, k1A, k1B, k1C, k1D, k1E, k1F, k2A, k2B, k2C, k2D, k2E, k2F, k3A, k3B, k3C, k3D, k3E, k3F, k4C, k4D, k4E, k4F, k5A, k5B, k5C, k5D, k5E, k5F, k6A, k6B, k6C, k6D, k6E, k6F, k7A, k7B, k7C, k7D, k7E, k7F, k8A, k8B, k8C, k8D, k8E, k8F, k9C, k9D, k9E, k9F)
#define STN_PLS STN_NB
@ -27,8 +17,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_MAIN] = LAYOUT(
KC_ESC , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_LBRC,
KC_TAB , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN , KC_QUOT,
KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_LEAD,
KC_LCTL, KC_LGUI, KC_LALT, KC_NUBS , TT(_FN), _______, KC_LOCK, TG(_PLOVER), KC_RALT , KC_RGUI, KC_APP , KC_RCTL,
KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , QK_LEAD,
KC_LCTL, KC_LGUI, KC_LALT, KC_NUBS , TT(_FN), _______, QK_LOCK, TG(_PLOVER), KC_RALT , KC_RGUI, KC_APP , KC_RCTL,
KC_CAPS, TT(_GAMING), KC_SPC , KC_LSFT, TT(_MOUSE), TT(_NUMPAD), TT(_NAV), TT(_SYS)
),
[_NUMPAD] = LAYOUT(
@ -166,7 +156,7 @@ void register_unicode(uint32_t codepoint) {
buffer[1] = 0x80 | (uint8_t)(codepoint & 0x3F);
codepoint >>= 6;
buffer[0] = 0xC0 | (uint8_t)(codepoint);
size = 2;
size = 2;
} else if(codepoint < 0x10000) {
buffer[2] = 0x80 | (uint8_t)(codepoint & 0x3F);
codepoint >>= 6;

View file

@ -247,4 +247,4 @@ for edge in edges:
if "next_node" in edge:
print(f" .next_node = {edge['next_node']},")
print(" },")
print("};")
print("};")

View file

@ -57,7 +57,7 @@ bool caps_word_press_user(uint16_t keycode) {
// Keycodes that continue Caps Word, with shift applied.
case KC_A ... KC_Z:
case KC_MINS:
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
return true;
// Keycodes that continue Caps Word, without shifting.
@ -74,6 +74,6 @@ bool caps_word_press_user(uint16_t keycode) {
return true;
default:
return getLayer() != 3; // Deactivate Caps Word.
return getLayer() != 3; // Deactivate Caps Word.
}
}
}

View file

@ -3,5 +3,5 @@
#include "quantum/action.h"
#include <stdint.h>
void track_neo2_modifier_state(uint16_t keycode, keyrecord_t *record);
void track_neo2_modifier_state(uint16_t keycode, keyrecord_t *record);
uint32_t keystroke_to_unicode(uint16_t keycode);

View file

@ -1 +1 @@
SRC += neo2.c compose.c
SRC += neo2.c compose.c

View file

@ -79,4 +79,4 @@ struct SparseTable<T, 0, entryBits> {
const T *operator[](size_t index) const {
return &value;
}
};
};