Refactor OS4A et CapsList

This commit is contained in:
Kawamashi 2025-10-01 18:22:59 +02:00
commit c7214feb75
19 changed files with 231 additions and 196 deletions

View file

@ -19,19 +19,19 @@
#include "clever_keys.h" #include "clever_keys.h"
void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) { void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record) {
uint16_t prev_keycode = recent[RECENT_SIZE - 1]; uint16_t prev_keycode = get_recent_keycode(-1);
// Apostrophe // Apostrophe
if (is_followed_by_apos(*next_keycode, prev_keycode)) { if (is_followed_by_apos(*ongoing_keycode, prev_keycode)) {
set_last_keycode(PG_APOS); set_last_keycode(PG_APOS);
} }
switch (prev_keycode) { switch (prev_keycode) {
case NNB_SPC: case NNB_SPC:
switch (*next_keycode) { switch (*ongoing_keycode) {
// Shift auto de la ponctuation après une espace fine insécable // Shift auto de la ponctuation après une espace fine insécable
case PG_POIN: case PG_POIN:
// uses less space than process_word // uses less space than process_word
@ -39,19 +39,18 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
process_key(SAGR(KC_SPC), record); process_key(SAGR(KC_SPC), record);
case PG_TIRE: case PG_TIRE:
case PG_VIRG: case PG_VIRG:
return replace_ongoing_key(S(*next_keycode), next_keycode, record); return replace_ongoing_key(S(*ongoing_keycode), ongoing_keycode, record);
} }
break; break;
case KC_SPC: case KC_SPC:
switch (recent[RECENT_SIZE - 2]) { switch (get_recent_keycode(-2)) {
case PG_EXCL: case PG_EXCL:
case PG_QUES: case PG_QUES:
case PG_3PTS: case PG_3PTS:
case PG_POIN: case PG_POIN:
// Shift the letter at the beginning of sentences. // Shift the letter at the beginning of sentences.
if (is_letter(*next_keycode) || is_send_string_macro(*next_keycode)) { if (is_letter(*ongoing_keycode) || is_send_string_macro(*ongoing_keycode)) {
//if (!is_caps_lock_on()) { add_weak_mods(MOD_BIT(KC_LSFT)); }
set_oneshot_mods(MOD_BIT(KC_LSFT)); // Don't use weak mods! set_oneshot_mods(MOD_BIT(KC_LSFT)); // Don't use weak mods!
} }
break; break;
@ -59,7 +58,7 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
break; break;
case PG_Q: case PG_Q:
switch (*next_keycode) { switch (*ongoing_keycode) {
// Ajout automatique du "u" après le "q" // Ajout automatique du "u" après le "q"
case PG_E: case PG_E:
@ -69,39 +68,39 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
case PG_EACU: case PG_EACU:
case PG_APOS: case PG_APOS:
invoke_key(PG_U, record); invoke_key(PG_U, record);
set_last_keycode(*next_keycode); set_last_keycode(*ongoing_keycode);
break; break;
// Raccourci pour "quoi" // Raccourci pour "quoi"
case PG_H: case PG_H:
finish_word((uint16_t[]) {PG_U, PG_O, PG_I}, 3, next_keycode, record); finish_word((uint16_t[]) {PG_U, PG_O, PG_I}, 3, ongoing_keycode, record);
break; break;
// Raccourci pour "quand" // Raccourci pour "quand"
case PG_N: case PG_N:
return finish_word((uint16_t[]) {PG_U, PG_A, PG_N, PG_D}, 4, next_keycode, record); return finish_word((uint16_t[]) {PG_U, PG_A, PG_N, PG_D}, 4, ongoing_keycode, record);
} }
break; break;
case PG_P: case PG_P:
switch (*next_keycode) { switch (*ongoing_keycode) {
case PG_C: case PG_C:
// "pas" // "pas"
return finish_word((uint16_t[]) {PG_A, PG_S}, 2, next_keycode, record); return finish_word((uint16_t[]) {PG_A, PG_S}, 2, ongoing_keycode, record);
case PG_J: case PG_J:
// "pour" // "pour"
return finish_word((uint16_t[]) {PG_O, PG_U, PG_R}, 3, next_keycode, record); return finish_word((uint16_t[]) {PG_O, PG_U, PG_R}, 3, ongoing_keycode, record);
case PG_X: case PG_X:
// "plus" // "plus"
return finish_word((uint16_t[]) {PG_L, PG_U, PG_S}, 3, next_keycode, record); return finish_word((uint16_t[]) {PG_L, PG_U, PG_S}, 3, ongoing_keycode, record);
} }
break; break;
} }
switch (*next_keycode) { switch (*ongoing_keycode) {
case MAGIC: case MAGIC:
switch (prev_keycode) { switch (prev_keycode) {
@ -110,91 +109,91 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
process_key(PG_U, record); process_key(PG_U, record);
case PG_U: case PG_U:
// ui SFB // ui SFB
return replace_ongoing_key(PG_I, next_keycode, record); return replace_ongoing_key(PG_I, ongoing_keycode, record);
case PG_EACU: case PG_EACU:
// éa SFB // éa SFB
return replace_ongoing_key(PG_A, next_keycode, record); return replace_ongoing_key(PG_A, ongoing_keycode, record);
case PG_S: case PG_S:
// sc SFB // sc SFB
return replace_ongoing_key(PG_C, next_keycode, record); return replace_ongoing_key(PG_C, ongoing_keycode, record);
case PG_C: case PG_C:
// cs SFB // cs SFB
return replace_ongoing_key(PG_S, next_keycode, record); return replace_ongoing_key(PG_S, ongoing_keycode, record);
case PG_N: case PG_N:
// n. SFB // n. SFB
return replace_ongoing_key(PG_POIN, next_keycode, record); return replace_ongoing_key(PG_POIN, ongoing_keycode, record);
case PG_P: case PG_P:
// ph SFB // ph SFB
return replace_ongoing_key(PG_H, next_keycode, record); return replace_ongoing_key(PG_H, ongoing_keycode, record);
case PG_G: case PG_G:
// gt SFB // gt SFB
return replace_ongoing_key(PG_T, next_keycode, record); return replace_ongoing_key(PG_T, ongoing_keycode, record);
case PG_Q: case PG_Q:
// qué scissor // qué scissor
//return finish_word((uint16_t[]) {PG_U, PG_EACU}, 2, next_keycode, record); //return finish_word((uint16_t[]) {PG_U, PG_EACU}, 2, ongoing_keycode, record);
process_key(PG_U,record); process_key(PG_U,record);
return replace_ongoing_key(PG_EACU, next_keycode, record); return replace_ongoing_key(PG_EACU, ongoing_keycode, record);
case PG_Y: case PG_Y:
// you bad redirection // you bad redirection
//return finish_word((uint16_t[]) {PG_O, PG_U}, 2, next_keycode, record); //return finish_word((uint16_t[]) {PG_O, PG_U}, 2, ongoing_keycode, record);
process_key(PG_O,record); process_key(PG_O,record);
return replace_ongoing_key(PG_U, next_keycode, record); return replace_ongoing_key(PG_U, ongoing_keycode, record);
case PG_T: case PG_T:
// "the" // "the"
//return finish_word((uint16_t[]) {PG_H, PG_E}, 2, next_keycode, record); //return finish_word((uint16_t[]) {PG_H, PG_E}, 2, ongoing_keycode, record);
process_key(PG_H,record); process_key(PG_H,record);
return replace_ongoing_key(PG_E, next_keycode, record); return replace_ongoing_key(PG_E, ongoing_keycode, record);
case PG_I: case PG_I:
//return finish_word((uint16_t[]) {PG_O, PG_N}, 2, next_keycode, record); //return finish_word((uint16_t[]) {PG_O, PG_N}, 2, ongoing_keycode, record);
process_key(PG_O,record); process_key(PG_O,record);
return replace_ongoing_key(PG_N, next_keycode, record); return replace_ongoing_key(PG_N, ongoing_keycode, record);
case PG_M: case PG_M:
if (is_letter(recent[RECENT_SIZE - 2])) { if (is_letter(get_recent_keycode(-2))) {
// "ment" // "ment"
return finish_word((uint16_t[]) {PG_E, PG_N, PG_T}, 3, next_keycode, record); return finish_word((uint16_t[]) {PG_E, PG_N, PG_T}, 3, ongoing_keycode, record);
} else { } else {
// "même" // "même"
return finish_word((uint16_t[]) {PG_ODK, PG_O, PG_M, PG_E}, 4, next_keycode, record); return finish_word((uint16_t[]) {PG_ODK, PG_O, PG_M, PG_E}, 4, ongoing_keycode, record);
} }
case PG_B: case PG_B:
// "beaucoup" // "beaucoup"
return finish_word((uint16_t[]) {PG_E, PG_A, PG_U, PG_C, PG_O, PG_U, PG_P}, 7, next_keycode, record); return finish_word((uint16_t[]) {PG_E, PG_A, PG_U, PG_C, PG_O, PG_U, PG_P}, 7, ongoing_keycode, record);
case PG_D: case PG_D:
// "déjà" // "déjà"
return finish_word((uint16_t[]) {PG_EACU, PG_J, PG_ODK, PG_A}, 4, next_keycode, record); return finish_word((uint16_t[]) {PG_EACU, PG_J, PG_ODK, PG_A}, 4, ongoing_keycode, record);
default: default:
// "à" // "à"
process_key(PG_ODK, record); process_key(PG_ODK, record);
return replace_ongoing_key(PG_A, next_keycode, record); return replace_ongoing_key(PG_A, ongoing_keycode, record);
} }
case PG_AROB: case PG_AROB:
if (!is_letter(recent[RECENT_SIZE - 2])) { if (!is_letter(get_recent_keycode(-2))) {
switch (prev_keycode) { switch (prev_keycode) {
case PG_P: case PG_P:
// "p@" -> "problème" // "p@" -> "problème"
layer_off(_ODK); layer_off(_ODK);
return finish_word((uint16_t[]) {PG_R, PG_O, PG_B, PG_L, PG_ODK, PG_E, PG_M, PG_E}, 8, next_keycode, record); return finish_word((uint16_t[]) {PG_R, PG_O, PG_B, PG_L, PG_ODK, PG_E, PG_M, PG_E}, 8, ongoing_keycode, record);
case PG_A: case PG_A:
// "a@" -> "aujourd'hui" // "a@" -> "aujourd'hui"
layer_off(_ODK); layer_off(_ODK);
return finish_word((uint16_t[]) {PG_U, PG_J, PG_O, PG_U, PG_R, PG_D, PG_APOS, PG_H, PG_U, PG_I}, 10, next_keycode, record); return finish_word((uint16_t[]) {PG_U, PG_J, PG_O, PG_U, PG_R, PG_D, PG_APOS, PG_H, PG_U, PG_I}, 10, ongoing_keycode, record);
} }
} }
break; break;
@ -202,29 +201,44 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
case PG_M: case PG_M:
if (prev_keycode == PG_C) { if (prev_keycode == PG_C) {
// "cm" -> "ch" // "cm" -> "ch"
bkspc_countdown = 0; update_bkspc_countdown(0);
return replace_ongoing_key(PG_H, next_keycode, record); return replace_ongoing_key(PG_H, ongoing_keycode, record);
} }
break; break;
case PG_H: case PG_H:
if (prev_keycode == PG_M) { if (prev_keycode == PG_M) {
// "mh" -> "mb" // "mh" -> "mb"
bkspc_countdown = 0; update_bkspc_countdown(0);
return replace_ongoing_key(PG_B, next_keycode, record); return replace_ongoing_key(PG_B, ongoing_keycode, record);
} else if (prev_keycode == PG_I) { } else if (prev_keycode == PG_I) {
// "ih" -> "ique" // "ih" -> "ique"
return finish_word((uint16_t[]) {PG_Q, PG_U, PG_E}, 3, next_keycode, record); return finish_word((uint16_t[]) {PG_Q, PG_U, PG_E}, 3, ongoing_keycode, record);
} }
break; break;
case OU_GRV: case OU_GRV:
layer_off(_ODK); layer_off(_ODK);
return finish_word((uint16_t[]) {PG_O, PG_ODK, PG_N}, 3, next_keycode, record); return finish_word((uint16_t[]) {PG_O, PG_ODK, PG_N}, 3, ongoing_keycode, record);
case PG_APOS: case PG_APOS:
if (is_apos_dr) { return replace_ongoing_key(PG_APOD, next_keycode, record); } if (replace_apos()) { return replace_ongoing_key(PG_APOD, ongoing_keycode, record); }
break; break;
} }
} }
/* Boucle de CapsWord :
on press:
clear_weak_mods();
if (caps_word_press_user(keycode)) {
send_keyboard_report();
return true;
}
}
caps_word_off();
return true;
*/

View file

@ -25,7 +25,7 @@
extern "C" { extern "C" {
#endif #endif
void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record); void get_clever_keycode(uint16_t* ongoing_keycode, keyrecord_t* record);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -1,10 +1,8 @@
#include "capslist.h" #include "capslist.h"
static bool caps_list_active = false; static bool caps_list_active = false;
//static unsigned short int capslist_countdown = 0; static signed char capslist_countdown = 1;
unsigned short int capslist_countdown = 0; static unsigned char countdown_end = 6;
//static unsigned short int countdown_end = 5;
unsigned short int countdown_end = 5;
bool is_caps_list_on(void) { return caps_list_active; } bool is_caps_list_on(void) { return caps_list_active; }
@ -12,8 +10,8 @@ void enable_caps_list(void) {
if (is_caps_lock_on()) { tap_code(KC_CAPS); } if (is_caps_lock_on()) { tap_code(KC_CAPS); }
caps_word_on(); caps_word_on();
caps_list_active = true; caps_list_active = true;
capslist_countdown = 0; capslist_countdown = 1;
countdown_end = 5; countdown_end = 6;
} }
void disable_caps_list(void) { void disable_caps_list(void) {
@ -29,6 +27,19 @@ void toggle_caps_list(void) {
} }
} }
bool update_capslist_countdown(signed char i) {
capslist_countdown = capslist_countdown + i;
return true;
}
bool word_check(uint16_t keycodes[], uint8_t num_keycodes, unsigned char new_countdown_end) {
for (int i = 0; i < num_keycodes; ++i) {
if (get_recent_keycode(- 2 - i) != keycodes[num_keycodes - 1 - i]) { return false; }
}
countdown_end = new_countdown_end;
return true;
}
bool process_caps_list(uint16_t keycode, keyrecord_t *record) { bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
// Handle the custom keycodes that go with this feature // Handle the custom keycodes that go with this feature
if (keycode == CAPSLIST) { if (keycode == CAPSLIST) {
@ -59,9 +70,11 @@ bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
} }
if (should_continue_caps_list(keycode)) { if (should_continue_caps_list(keycode)) {
if (caps_word_reactivation()) { if (caps_word_reactivation()) {
caps_word_on(); // Reactivate Caps Word for a new word caps_word_on(); // Reactivate Caps Word for a new word
capslist_countdown = 0; capslist_countdown = 1;
return true;
} }
if (capslist_countdown < countdown_end) { return true; } if (capslist_countdown < countdown_end) { return true; }
} }

View file

@ -3,8 +3,6 @@
#include "quantum.h" #include "quantum.h"
#include "keymap.h" #include "keymap.h"
extern unsigned short int capslist_countdown;
extern unsigned short int countdown_end;
bool is_caps_list_on(void); bool is_caps_list_on(void);
@ -12,6 +10,9 @@ void enable_caps_list(void);
void disable_caps_list(void); void disable_caps_list(void);
void toggle_caps_list(void); void toggle_caps_list(void);
bool update_capslist_countdown(signed char i);
bool word_check(uint16_t keycodes[], uint8_t num_keycodes, unsigned char new_countdown_end);
bool process_caps_list(uint16_t keycode, keyrecord_t *record); bool process_caps_list(uint16_t keycode, keyrecord_t *record);
bool should_continue_caps_list(uint16_t keycode); bool should_continue_caps_list(uint16_t keycode);

View file

@ -16,14 +16,22 @@
#include "clever_keys_utilities.h" #include "clever_keys_utilities.h"
uint16_t recent[RECENT_SIZE] = {KC_NO}; static uint16_t recent[RECENT_SIZE] = {KC_NO};
uint16_t deadline = 0; uint16_t deadline = 0;
unsigned short int bkspc_countdown = RECENT_SIZE + 1; static unsigned char bkspc_countdown = RECENT_SIZE + 1;
// Copy of the record argument for the clever key. // Copy of the record argument for the clever key.
static keyrecord_t mod_record; static keyrecord_t mod_record;
static bool processingCK = false; static bool processingCK = false;
uint16_t get_recent_keycode(signed char i) {
return recent[RECENT_SIZE + i];
}
void update_bkspc_countdown(unsigned char i) {
bkspc_countdown = i;
}
void clear_recent_keys(void) { void clear_recent_keys(void) {
memset(recent, 0, sizeof(recent)); // Set all zeros (KC_NO). memset(recent, 0, sizeof(recent)); // Set all zeros (KC_NO).
bkspc_countdown = RECENT_SIZE + 1; bkspc_countdown = RECENT_SIZE + 1;

View file

@ -26,9 +26,10 @@ extern "C" {
#define RECENT_SIZE 8 // Number of keys in `recent` buffer. #define RECENT_SIZE 8 // Number of keys in `recent` buffer.
extern uint16_t recent[RECENT_SIZE];
uint16_t deadline; uint16_t deadline;
extern unsigned short int bkspc_countdown;
uint16_t get_recent_keycode(signed char);
void update_bkspc_countdown(unsigned char i);
void clear_recent_keys(void); void clear_recent_keys(void);
void recent_keys_task(void); void recent_keys_task(void);

View file

@ -70,20 +70,11 @@ combo_t key_combos[] = {
[ALTESC] = COMBO(altesc_combo, LALT(KC_ESC)) [ALTESC] = COMBO(altesc_combo, LALT(KC_ESC))
}; };
/* uint16_t get_combo_term(uint16_t combo_index, combo_t *combo) {
switch (combo_index) {
case L_APOST:
case D_APOST:
return 100;
default:
return COMBO_TERM;
}
} */
bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) {
// Chorded mods shouldn't be considered as combos. // Chorded mods shouldn't be considered as combos.
if (os4a_layer != 0) { if (get_os4a_layer() != 0) {
return (os4a_layer == _R_MODS) == on_left_hand(record->event.key); return (get_os4a_layer() == _R_MODS) == on_left_hand(record->event.key);
} }
// Some combos shouldn't be affected by global_quick_tap_timer. // Some combos shouldn't be affected by global_quick_tap_timer.
switch (combo_index) { switch (combo_index) {
@ -95,10 +86,8 @@ bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode
return true; return true;
default: default:
//return timer_elapsed(global_quick_tap_timer) > TAP_INTERVAL; //return enough_time_before_combo(); // takes more space
if (timer_elapsed(global_quick_tap_timer) < TAP_INTERVAL) { if (!enough_time_before_combo()) { return false; }
return false;
}
} }
return true; return true;
} }
@ -129,7 +118,6 @@ bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key
return true; return true;
} }
break; break;
} }
return false; return false;
} }

View file

@ -16,7 +16,11 @@
#include "macros.h" #include "macros.h"
bool is_apos_dr = false; static bool is_apos_dr = false;
bool replace_apos(void) {
return is_apos_dr;
}
bool process_macros(uint16_t keycode, keyrecord_t *record) { bool process_macros(uint16_t keycode, keyrecord_t *record) {

View file

@ -23,8 +23,7 @@
extern "C" { extern "C" {
#endif #endif
extern bool is_apos_dr; bool replace_apos(void);
bool process_macros(uint16_t keycode, keyrecord_t *record); bool process_macros(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -18,7 +18,7 @@
//static uint16_t num_word_timer = 0; //static uint16_t num_word_timer = 0;
//static bool is_num_word_on = false; //static bool is_num_word_on = false;
bool is_num_word_on = false; static bool is_num_word_on = false;
static bool exit_num_word = false; static bool exit_num_word = false;
bool is_num_word_enabled(void) { bool is_num_word_enabled(void) {

View file

@ -19,7 +19,6 @@
#include "keymap.h" #include "keymap.h"
bool is_num_word_enabled(void); bool is_num_word_enabled(void);
extern bool is_num_word_on;
void enable_num_word(void); void enable_num_word(void);
void disable_num_word(void); void disable_num_word(void);

View file

@ -23,9 +23,13 @@ oneshot_state os_alt_state = os_up_unqueued;
oneshot_state os_altgr_state = os_up_unqueued; oneshot_state os_altgr_state = os_up_unqueued;
oneshot_state os_win_state = os_up_unqueued; oneshot_state os_win_state = os_up_unqueued;
uint8_t os4a_layer = 0; static uint8_t os4a_layer = 0;
static bool exit_os4a_layer = false; static bool exit_os4a_layer = false;
uint8_t get_os4a_layer(void) {
return (os4a_layer);
}
void os4a_layer_on(uint8_t layer) { void os4a_layer_on(uint8_t layer) {
layer_on(layer); layer_on(layer);
os4a_layer = layer; os4a_layer = layer;
@ -40,7 +44,7 @@ void os4a_layer_off(uint8_t layer) {
void os4a_tap(uint16_t keycode) { void os4a_tap(uint16_t keycode) {
if (os4a_layer == 0) { if (os4a_layer == 0) {
// Activate OS4A layer // Activate OS4A layer
os4a_layer_on(get_os4a_layer(keycode)); os4a_layer_on(os4a_layer_from_trigger(keycode));
} else { } else {
// Press again an OS4A key to exit the OS4A layer and clear the OS mods. // Press again an OS4A key to exit the OS4A layer and clear the OS mods.
os4a_layer_off(os4a_layer); os4a_layer_off(os4a_layer);
@ -57,25 +61,27 @@ bool process_os4a_keys(uint16_t keycode, keyrecord_t *record) {
return true; return true;
} }
bool os4a_layer_process_outcome(uint16_t keycode, keyrecord_t *record) {
// Should keycode exit the OS4A layer without further process ? bool add_shift(uint16_t keycode, keyrecord_t *record) {
if (should_exit_os4a_layer(keycode)) { return true; }
// Should keycode stay on the OS4A layer, to be possibly combined with another one, e.g. Callum mod? // Testing exit_os4a_layer is necessary to prevent OS shift to be added in case of rolled keys
if (is_oneshot_ignored_key(keycode)) { return false; } // or when other features invoke keycodes to be processed (ex: custom altgr, clever keys).
if (exit_os4a_layer) { return false; }
// Add OS Shift when no other mods are active. // Shift shouldn't be added if other mods are active
// Testing exit_os4a_layer is necessary to prevent OS shift to be added when other features create keyrecords if ((get_mods() | get_oneshot_mods()) != 0) { return false; }
// to be processed (ex: custom altgr, clever keys).
const uint8_t mods = get_mods() | get_oneshot_mods(); // Combos and encoder events.
if (!exit_os4a_layer && to_be_shifted(keycode, record) && mods == 0) { if (!IS_KEYEVENT(record->event)) { return true; }
set_oneshot_mods(MOD_BIT(KC_LSFT));
// Don't use weak mods, it interferes with Capsword. // Specific exceptions
} if (not_to_be_shifted(keycode)) { return false; }
return true;
// Otherwise, add shift if the key is on the other side of the keyboard.
return (os4a_layer == _R_MODS) == on_left_hand(record->event.key);
} }
void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record) { void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record) {
// The OS4A layer must be exited only when ctrl or shift are registered, // The OS4A layer must be exited only when ctrl or shift are registered,
@ -104,7 +110,14 @@ bool process_mods(uint16_t keycode, keyrecord_t *record) {
if (os4a_layer != 0) { if (os4a_layer != 0) {
if (record->event.pressed) { if (record->event.pressed) {
exit_os4a_layer = os4a_layer_process_outcome(keycode, record);
if (should_stay_os4a_layer(keycode)) {
exit_os4a_layer = false;
} else {
if (add_shift(keycode, record)) { set_oneshot_mods(MOD_BIT(KC_LSFT)); }
exit_os4a_layer = true;
}
} else { } else {
// When Ctrl or Shift are released, for mouse use. // When Ctrl or Shift are released, for mouse use.
//if (mods_for_mouse(keycode)) { mouse_mods_key_up(keycode, record); } //if (mods_for_mouse(keycode)) { mouse_mods_key_up(keycode, record); }

View file

@ -24,18 +24,15 @@
extern "C" { extern "C" {
#endif #endif
extern uint8_t os4a_layer; uint8_t get_os4a_layer(void);
void os4a_layer_off(uint8_t layer); void os4a_layer_off(uint8_t layer);
void os4a_layer_on(uint8_t layer); void os4a_layer_on(uint8_t layer);
void os4a_tap(uint16_t keycode); void os4a_tap(uint16_t keycode);
bool process_os4a_keys(uint16_t keycode, keyrecord_t *record); bool process_os4a_keys(uint16_t keycode, keyrecord_t *record);
void update_osl(uint16_t keycode); bool add_shift(uint16_t keycode, keyrecord_t *record);
bool os4a_layer_process_outcome(uint16_t keycode, keyrecord_t *record);
void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record); void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record);

View file

@ -27,7 +27,7 @@ uint16_t tap_hold_extractor(uint16_t keycode) {
case LT_NBSPC: case LT_NBSPC:
return NNB_SPC; return NNB_SPC;
default: default:
return keycode &= 0xff; return keycode &= 0xff; //QK_MOD_TAP_GET_TAP_KEYCODE(keycode)
} }
} }
@ -86,7 +86,7 @@ uint16_t get_ongoing_keycode_user(uint16_t keycode) {
// One-shot 4 all configuration // One-shot 4 all configuration
uint8_t get_os4a_layer(uint16_t keycode) { uint8_t os4a_layer_from_trigger(uint16_t keycode) {
switch (keycode) { switch (keycode) {
case L_OS4A: return _L_MODS; case L_OS4A: return _L_MODS;
case R_OS4A: return _R_MODS; case R_OS4A: return _R_MODS;
@ -94,30 +94,31 @@ uint8_t get_os4a_layer(uint16_t keycode) {
} }
} }
bool should_exit_os4a_layer(uint16_t keycode) { bool should_stay_os4a_layer(uint16_t keycode) {
// keycodes that stay on os4a layers w/o being shifted
switch (keycode) { switch (keycode) {
case OS_FA: case OS_SHFT:
case NUMWORD: case OS_CTRL:
case TG_FA: case OS_RALT:
case OS_RSA: case OS_LALT:
case NUM_ODK: case OS_WIN:
return true; return true;
default: default:
return false; return false;
} }
} }
bool to_be_shifted(uint16_t keycode, keyrecord_t *record) { bool not_to_be_shifted(uint16_t keycode) {
// Combos and encoder events. // keycodes that exit os4a layers w/o being shifted
if (!IS_KEYEVENT(record->event)) { return true; }
switch (keycode) { switch (keycode) {
case KC_CAPS: case KC_CAPS:
case CAPSWORD: case CAPSWORD:
case CAPSLIST: case CAPSLIST:
return false; return true;
default: default:
return (os4a_layer == _R_MODS) == on_left_hand(record->event.key); return false;
} }
} }
@ -155,10 +156,10 @@ bool is_oneshot_ignored_key(uint16_t keycode) {
case OS_RALT: case OS_RALT:
case OS_LALT: case OS_LALT:
case OS_WIN: case OS_WIN:
// OS_FA must be on the list, to be combined with Alt case OS_FA: // to be combined with Alt
case OS_FA:
case NUMWORD:
case TG_FA: case TG_FA:
case NUMWORD: // to combine numbers with mods
//case NUM_ODK: // NUM_ODK sends PG_ODK when pressed. When shifted, PG_ODK sends one-shot shift.
return true; return true;
} }
return false; return false;
@ -186,7 +187,7 @@ uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
return C(PG_Z); return C(PG_Z);
} }
if (recent[RECENT_SIZE - 1] != KC_NO) { return MAGIC; } if (get_recent_keycode(-1) != KC_NO) { return MAGIC; }
if (get_last_keycode() == KC_NO) { return MAGIC; } if (get_last_keycode() == KC_NO) { return MAGIC; }
return KC_TRNS; // Defer to default definitions. return KC_TRNS; // Defer to default definitions.

View file

@ -26,7 +26,7 @@ bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record);
uint16_t get_ongoing_keycode_user(uint16_t keycode); uint16_t get_ongoing_keycode_user(uint16_t keycode);
uint8_t get_os4a_layer(uint16_t keycode); uint8_t os4a_layer_from_trigger(uint16_t keycode);
bool should_exit_os4a_layer(uint16_t keycode); bool should_stay_os4a_layer(uint16_t keycode);
bool to_be_shifted(uint16_t keycode, keyrecord_t *record); bool not_to_be_shifted(uint16_t keycode);
//bool mods_for_mouse(uint16_t keycode); //bool mods_for_mouse(uint16_t keycode);

View file

@ -20,7 +20,14 @@
#include "keymap.h" #include "keymap.h"
uint16_t global_quick_tap_timer = 0; static uint16_t global_quick_tap_timer = 0;
bool enough_time_before_combo(void) {
return timer_elapsed(global_quick_tap_timer) > TAP_INTERVAL;
}
static uint16_t next_keycode;
static keyrecord_t next_record;
// Tap-hold configuration // Tap-hold configuration
@ -65,9 +72,6 @@ void matrix_scan_user(void) {
// Key processing // Key processing
uint16_t next_keycode;
keyrecord_t next_record;
bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) { bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { if (record->event.pressed) {
@ -113,8 +117,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
void post_process_record_user(uint16_t keycode, keyrecord_t* record) { void post_process_record_user(uint16_t keycode, keyrecord_t* record) {
//os4a_layer_exit_check();
//numword_exit_check();
end_CK(record); end_CK(record);
} }

View file

@ -65,30 +65,28 @@ enum custom_keycodes {
PG_DEG PG_DEG
}; };
// Layer taps // Layer changers
#define LT_SPC LT(_SYMBOLS, KC_SPC) #define LT_SPC LT(_SYMBOLS, KC_SPC)
#define LT_E LT(_SYMBOLS, PG_E) #define LT_E LT(_SYMBOLS, PG_E)
#define LT_REPT LT(_NUMBERS, KC_1) #define LT_REPT LT(_NUMBERS, KC_1)
#define LT_MGC LT(_SHORTNAV, KC_1) #define LT_MGC LT(_SHORTNAV, KC_1)
#define OS_FA OSL(_FUNCAPPS)
#define TG_FA TT(_FUNCAPPS)
#define MT_SLSH SFT_T(PG_SLSH)
#define MT_1 SFT_T(KC_1)
#define LT_0 LT(_SYMBOLS, KC_0) #define LT_0 LT(_SYMBOLS, KC_0)
#define LT_NBSPC LT(_SHORTNAV, NNB_SPC) #define LT_NBSPC LT(_SHORTNAV, NNB_SPC)
#define E_CIRC S(FG_0)
#define OS_ODK OSL(_ODK)
#define OS_RSA OSM(MOD_RALT | MOD_LSFT)
#define NUM_ODK OSL(_NUMBERS)
// One shot mods #define OS_ODK OSL(_ODK)
#define NUM_ODK OSL(_NUMBERS)
#define OS_FA OSL(_FUNCAPPS)
#define TG_FA TT(_FUNCAPPS)
// Mods
#define MT_SLSH SFT_T(PG_SLSH)
#define MT_1 SFT_T(KC_1)
#define OS_RSA OSM(MOD_RALT | MOD_LSFT)
// OS4A
#define L_OS4A LSFT_T(OS4A) #define L_OS4A LSFT_T(OS4A)
#define R_OS4A RSFT_T(OS4A) #define R_OS4A RSFT_T(OS4A)
#define IS_OS4A_KEY(keycode) (get_os4a_layer(keycode) != 0) #define IS_OS4A_KEY(keycode) (os4a_layer_from_trigger(keycode) != 0)
bool enough_time_before_combo(void);
bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_record, uint16_t other_keycode, keyrecord_t* other_record); bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_record, uint16_t other_keycode, keyrecord_t* other_record);
extern uint16_t global_quick_tap_timer;
extern uint16_t next_keycode;
extern keyrecord_t next_record;

View file

@ -79,7 +79,7 @@ bool oled_task_user(void) {
oled_write_P(((mods & MOD_BIT(KC_LALT)) == MOD_BIT(KC_LALT)) ? PSTR("ALT ") : PSTR(" "), false); oled_write_P(((mods & MOD_BIT(KC_LALT)) == MOD_BIT(KC_LALT)) ? PSTR("ALT ") : PSTR(" "), false);
oled_write_P(is_caps_word_on() ? PSTR("CAPSWORD\n") : PSTR(" \n"), false); oled_write_P(is_caps_word_on() ? PSTR("CAPSWORD\n") : PSTR(" \n"), false);
oled_write_P(is_num_word_on ? PSTR("NUMWORD\n") : PSTR(" \n"), false); oled_write_P(is_num_word_enabled() ? PSTR("NUMWORD\n") : PSTR(" \n"), false);
// Write host Keyboard LED Status to OLEDs // Write host Keyboard LED Status to OLEDs
led_t led_usb_state = host_keyboard_led_state(); led_t led_usb_state = host_keyboard_led_state();

View file

@ -146,28 +146,20 @@ bool should_exit_num_word(uint16_t keycode, const keyrecord_t *record) {
// Caps List // Caps List
bool should_continue_caps_list(uint16_t keycode) { bool should_continue_caps_list(uint16_t keycode) {
if (keycode == KC_BSPC) { if (keycode == KC_BSPC) { return update_capslist_countdown(-1); }
capslist_countdown--;
return true; if (is_letter(keycode) || is_send_string_macro(keycode)) { return update_capslist_countdown(1); }
}
if (is_letter(keycode) || is_send_string_macro(keycode)) {
capslist_countdown++;
return true;
}
if (caps_word_press_user(keycode)) {
// This condition can't be merged with the previous one // This condition can't be merged with the previous one
// because caps_word_press_user adds shift to letters and send-string macros. // because caps_word_press_user adds shift to letters and send-string macros.
capslist_countdown++; if (caps_word_press_user(keycode)) { return update_capslist_countdown(1); }
return true;
}
// Keycodes that continue Caps List, but not Caps Word. // Keycodes that continue Caps List, but not Caps Word.
// These keycodes trigger the countdown to end Caps List. // These keycodes trigger the countdown to end Caps List.
switch (keycode) { switch (keycode) {
case PG_VIRG: case PG_VIRG:
case KC_SPC: case KC_SPC:
capslist_countdown++; return update_capslist_countdown(1);
return true;
} }
return false; // Deactivate Caps List. return false; // Deactivate Caps List.
} }
@ -176,18 +168,23 @@ bool should_continue_caps_list(uint16_t keycode) {
bool caps_word_reactivation(void) { bool caps_word_reactivation(void) {
// Words that continue Caps List. // Words that continue Caps List.
if (recent[RECENT_SIZE - 1] == KC_SPC) { if (get_recent_keycode(-1) == KC_SPC) {
if (recent[RECENT_SIZE - 4] == KC_SPC && recent[RECENT_SIZE - 3] == PG_E && recent[RECENT_SIZE - 2] == PG_T) {
countdown_end = 1; if (get_recent_keycode(-2) == PG_VIRG) { return true; }
if (word_check((uint16_t[]) {KC_SPC, PG_E, PG_T}, 3, 2)) { return true; }
if (word_check((uint16_t[]) {KC_SPC, PG_O, PG_U}, 3, 2)) { return true; }
/* if (get_recent_keycode(-4) == KC_SPC && get_recent_keycode(-3) == PG_E && get_recent_keycode(-2) == PG_T) {
countdown_end = 2;
return true; return true;
} }
if (recent[RECENT_SIZE - 4] == KC_SPC && recent[RECENT_SIZE - 3] == PG_O && recent[RECENT_SIZE - 2] == PG_U) { if (get_recent_keycode(-4) == KC_SPC && get_recent_keycode(-3) == PG_O && get_recent_keycode(-2) == PG_U) {
countdown_end = 1; countdown_end = 2;
return true; return true;
} } */
if (recent[RECENT_SIZE - 2] == PG_VIRG) {
return true;
}
} }
return false; return false;
} }