This commit is contained in:
Kawamashi 2025-03-20 19:11:25 +01:00
commit c749b224b0
49 changed files with 3449 additions and 116 deletions

View file

@ -0,0 +1,132 @@
/* Copyright 2022 Thomas Baart <thomas@splitkb.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef RGBLIGHT_ENABLE
# define RGBLIGHT_EFFECT_BREATHING
# define RGBLIGHT_EFFECT_RAINBOW_MOOD
# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
# define RGBLIGHT_EFFECT_SNAKE
# define RGBLIGHT_EFFECT_KNIGHTis
# define RGBLIGHT_EFFECT_CHRISTMAS
# define RGBLIGHT_EFFECT_STATIC_GRADIENT
# define RGBLIGHT_EFFECT_RGB_TEST
# define RGBLIGHT_EFFECT_ALTERNATING
# define RGBLIGHT_EFFECT_TWINKLE
# define RGBLIGHT_HUE_STEP 8
# define RGBLIGHT_SAT_STEP 8
# define RGBLIGHT_VAL_STEP 8
# define RGBLIGHT_LIMIT_VAL 150
#endif
//#define TAPPING_TOGGLE 1
// combo
#define COMBO_TERM 50
//#define COMBO_TERM_PER_COMBO
#define COMBO_ONLY_FROM_LAYER 0
#define COMBO_SHOULD_TRIGGER
#define COMBO_PROCESS_KEY_REPRESS
#define TAP_INTERVAL 300
// mod tap
#define TAPPING_TERM 200
#define PERMISSIVE_HOLD_PER_KEY
#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
#define TAPPING_TOGGLE 1
// EC11K encoders have a different resolution than other EC11 encodeisrs.
// When using the default resolution of 4, if you notice your encoder skipping
// every other tick, lower the resolution to 2.
/* #define ENCODER_RESOLUTION 2
#if defined(KEYBOARD_splitkb_kyria_rev1)
# define ENCODER_DIRECTION_FLIP
#endif */
// One shot modifiers
//#define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped once again. */
//#define ONESHOT_TIMEOUT 5000 /* Time (in ms) before the one shot key is released */
// Recent keys
#define RECENT_KEYS_TIMEOUT 5000 // Timeout in milliseconds.
//Faire de la place !
#undef LOCKING_SUPPORT_ENABLE
#undef LOCKING_RESYNC_ENABLE
#define NO_MUSIC_MODE
#undef RGBLIGHT_ANIMATIONS
#undef RGBLIGHT_EFFECT_BREATHING
#undef RGBLIGHT_EFFECT_RAINBOW_MOOD
#undef RGBLIGHT_EFFECT_RAINBOW_SWIRL
#undef RGBLIGHT_EFFECT_SNAKE
#undef RGBLIGHT_EFFECT_KNIGHT
#undef RGBLIGHT_EFFECT_CHRISTMAS
#undef RGBLIGHT_EFFECT_STATIC_GRADIENT
#undef RGBLIGHT_EFFECT_RGB_TEST
#undef RGBLIGHT_EFFECT_ALTERNATING
#undef RGBLIGHT_EFFECT_TWINKLE
#undef ENABLE_RGB_MATRIX_ALPHAS_MODS
#undef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
#undef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
#undef ENABLE_RGB_MATRIX_BREATHING
#undef ENABLE_RGB_MATRIX_BAND_SAT
#undef ENABLE_RGB_MATRIX_BAND_VAL
#undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
#undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
#undef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
#undef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
#undef ENABLE_RGB_MATRIX_CYCLE_ALL
#undef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
#undef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
#undef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
#undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN
#undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
#undef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
#undef ENABLE_RGB_MATRIX_CYCLE_SPIRAL
#undef ENABLE_RGB_MATRIX_DUAL_BEACON
#undef ENABLE_RGB_MATRIX_RAINBOW_BEACON
#undef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
#undef ENABLE_RGB_MATRIX_RAINDROPS
#undef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
#undef ENABLE_RGB_MATRIX_HUE_BREATHING
#undef ENABLE_RGB_MATRIX_HUE_PENDULUM
#undef ENABLE_RGB_MATRIX_HUE_WAVE
#undef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
#undef ENABLE_RGB_MATRIX_PIXEL_FLOW
#undef ENABLE_RGB_MATRIX_PIXEL_RAIN
#undef ENABLE_RGB_MATRIX_TYPING_HEATMAP
#undef ENABLE_RGB_MATRIX_DIGITAL_RAIN
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
#undef ENABLE_RGB_MATRIX_SPLASH
#undef ENABLE_RGB_MATRIX_MULTISPLASH
#undef ENABLE_RGB_MATRIX_SOLID_SPLASH
#undef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH

View file

@ -0,0 +1,221 @@
// Correction automatique
#include "clever_keys.h"
bool process_clever_keys(uint16_t keycode, keyrecord_t* record) {
uint16_t next_keycode = get_next_keycode(keycode, record);
const uint8_t mods = get_mods();
if (next_keycode != KC_NO) {
uint16_t prev_keycode = recent[RECENT_SIZE - 1];
//const uint8_t mods = get_mods();
if (isLetter(next_keycode) || next_keycode == E_CIRC) {
switch (prev_keycode) {
case FR_EXLM:
case FR_QUES:
case FR_3PTS:
case FR_2PTS:
// Add space between punctuation and letters.
process_next_key(KC_SPC, record);
case KC_SPC:
switch (recent[RECENT_SIZE - 2]) {
case FR_EXLM:
case FR_QUES:
case FR_3PTS:
case FR_POIN:
// Add OS shift at the beginning of a sentence.
if (!is_caps_lock_on()) { set_oneshot_mods(MOD_BIT(KC_LSFT)); }
break;
}
}
}
// Ajout automatique du "u" après le "q"
if (prev_keycode == FR_Q) {
switch (next_keycode) {
case FR_E:
case FR_I:
case FR_A:
case FR_O:
case FR_EACU:
case E_CIRC:
case FR_APOS:
process_next_key(FR_U, record);
break;
// Raccourci pour "quelq"
case FR_Q:
clear_recent_keys(); // To prevent infinite loop
process_word((uint16_t[]) {FR_U, FR_E, FR_L}, 3, record);
break;
// Raccourci pour "quoi", ça évite un aller-retour sur la main gauche.
case FR_Z:
return finish_word((uint16_t[]) {FR_U, FR_O, FR_I}, 3, record);
// Raccourci pour "quand"
case FR_D:
process_word((uint16_t[]) {FR_U, FR_A, FR_N}, 3, record);
break;
}
} else if (next_keycode == FR_AROB && !isLetter(recent[RECENT_SIZE - 2])) {
switch (prev_keycode) {
case FR_T:
// "t@" -> "toujours"
return finish_word((uint16_t[]) {FR_O, FR_U, FR_J, FR_O, FR_U, FR_R, FR_S}, 7, record);
case FR_P:
// "p@" -> "peut-être"
return finish_word((uint16_t[]) {FR_E, FR_U, FR_T, FR_MOIN, FR_ACIR, FR_E, FR_T, FR_R, FR_E}, 9, record);
case FR_A:
// "a@" -> "aujourd'hui"
return finish_word((uint16_t[]) {FR_U, FR_J, FR_O, FR_U, FR_R, FR_D, FR_APOS, FR_H, FR_U, FR_I}, 10, record);
case FR_B:
// "b@" -> "beaucoup"
return finish_word((uint16_t[]) {FR_E, FR_A, FR_U, FR_C, FR_O, FR_U, FR_P}, 7, record);
case FR_E:
// "e@" -> "est-ce qu"
return finish_word((uint16_t[]) {FR_S, FR_T, FR_MOIN, FR_C, FR_E, KC_SPC, FR_Q}, 7, record);
case FR_D:
// "d@" -> "déjà"
return finish_word((uint16_t[]) {FR_EACU, FR_J, FR_AGRV}, 3, record);
}
} else if (prev_keycode == FR_P) {
switch (next_keycode) {
case FR_M:
// "pas"
return finish_word((uint16_t[]) {FR_A, FR_S}, 2, record);
case FR_APOS:
// "par"
return finish_word((uint16_t[]) {FR_A, FR_R}, 2, record);
case FR_POIN:
if (!isLetter(recent[RECENT_SIZE - 2])) {
// "pour"
return finish_word((uint16_t[]) {FR_O, FR_U, FR_R}, 3, record);
}
}
} else if (next_keycode == FR_A && prev_keycode == FR_O) {
// "oa" -> "oi"
process_next_key(FR_I, record);
return false;
} else if (next_keycode == FR_O && prev_keycode == FR_U && recent[RECENT_SIZE - 2] != FR_Q) {
// "uo" -> "un"
process_next_key(FR_N, record);
return false;
}
switch (next_keycode) {
case FR_QUES:
case FR_EXLM:
// On ajoute un espace insécable s'il n'a pas été entré avant le point d'exclamation.
// Il ne faut pas tester cette fonctionnalité avec Word, qui ajoute cet espace automatiquement.
if (isLetter(recent[RECENT_SIZE - 1])) {
if ((mods | get_oneshot_mods() | get_weak_mods()) & MOD_MASK_SHIFT) {
del_weak_mods(MOD_MASK_SHIFT);
del_oneshot_mods(MOD_MASK_SHIFT);
unregister_mods(MOD_MASK_SHIFT);
}
process_next_key(ALGR(KC_SPC), record);
set_mods(mods);
process_next_key(next_keycode, record);
return false;
}
break;
case MAGIC:
switch (prev_keycode) {
case FR_T:
process_next_key(FR_I, record);
case FR_I:
return finish_word((uint16_t[]) {FR_O, FR_N}, 2, record);
case FR_C:
return finish_word((uint16_t[]) {FR_APOS, FR_E, FR_S, FR_T}, 4, record);
case FR_D:
return finish_word((uint16_t[]) {FR_A, FR_N, FR_S}, 3, record);
case FR_P:
return finish_word((uint16_t[]) {FR_L, FR_U, FR_S}, 3, record);
case FR_A:
return finish_word((uint16_t[]) {FR_V, FR_E, FR_C}, 3, record);
case FR_S:
return finish_word((uint16_t[]) {FR_U, FR_R}, 2, record);
case FR_B:
process_word((uint16_t[]) {FR_O, FR_N, FR_J}, 3, record);
case FR_J:
return finish_word((uint16_t[]) {FR_O, FR_U, FR_R}, 3, record);
case FR_M:
// "même"
return finish_word((uint16_t[]) {FR_ACIR, FR_E, FR_M, FR_E}, 4, record);
default:
return false;
}
case FR_Q:
if (prev_keycode == FR_J) {
// "jq" -> "jusqu"
process_word((uint16_t[]) {FR_U, FR_S}, 2, record);
}
break;
case CA_CED:
return finish_word((uint16_t[]) {FR_CCED, FR_A}, 2, record);
case OU_GRV:
return finish_word((uint16_t[]) {FR_O, ALGR(FR_U)}, 2, record);
case AGRV_SPC:
return finish_word((uint16_t[]) {FR_AGRV, KC_SPC}, 2, record);
case E_CIRC:
return process_accent(FR_ACIR, FR_E, record);
case I_CIRC:
return process_accent(FR_ACIR, FR_I, record);
case A_CIRC:
return process_accent(FR_ACIR, FR_A, record);
case O_CIRC:
return process_accent(FR_ACIR, FR_O, record);
case U_CIRC:
return process_accent(FR_ACIR, FR_U, record);
case I_TREM:
return process_accent(FR_TREM, FR_I, record);
}
store_keycode(next_keycode, record);
}
return true; // Process all other keycodes normally
}

View file

@ -0,0 +1,115 @@
#include QMK_KEYBOARD_H
//#include "combos.h"
#include "keymap.h"
enum combos {
R_BKSPC,
DELETE,
BK_WORD,
DEL_WORD,
L_BKSPC,
HOME,
END,
ENTER,
TAB,
ESC,
HELP,
PANIC,
NUMWRD,
ALTTAB,
CTRLALT
};
const uint16_t PROGMEM del_combo_d[] = {FR_S, FR_N, COMBO_END};
const uint16_t PROGMEM bkspc_combo_d[] = {FR_N, FR_R, COMBO_END};
const uint16_t PROGMEM del_word_combo[] = {FR_M, FR_L, COMBO_END};
const uint16_t PROGMEM bk_word_combo[] = {FR_L, FR_APOS, COMBO_END};
const uint16_t PROGMEM enter_combo[] = {FR_P, FR_EACU, COMBO_END};
const uint16_t PROGMEM tab_combo[] = {FR_T, FR_I, COMBO_END};
const uint16_t PROGMEM esc_combo[] = {FR_T, FR_A, COMBO_END};
const uint16_t PROGMEM bkspc_combo_g[] = {FR_A, FR_I, COMBO_END};
const uint16_t PROGMEM home_combo[] = {FR_Z, FR_Y, COMBO_END};
const uint16_t PROGMEM end_combo[] = {FR_EACU, FR_VIRG, COMBO_END};
const uint16_t PROGMEM help_combo[] = {FR_VIRG, FR_APOS, COMBO_END};
const uint16_t PROGMEM panic_combo[] = {FR_EACU, FR_L, COMBO_END};
const uint16_t PROGMEM numword_combo[] = {FR_S, FR_R, COMBO_END};
const uint16_t PROGMEM alttab_combo[] = {LT_D, FR_Y, COMBO_END};
const uint16_t PROGMEM ctrlalt_combo[] = {FR_A, FR_I, FR_T, COMBO_END};
combo_t key_combos[] = {
[R_BKSPC] = COMBO(bkspc_combo_d, KC_BSPC),
[DELETE] = COMBO(del_combo_d, KC_DEL),
[BK_WORD] = COMBO(bk_word_combo, LCTL(KC_BSPC)),
[DEL_WORD] = COMBO(del_word_combo, LCTL(KC_DEL)),
[L_BKSPC] = COMBO(bkspc_combo_g, KC_BSPC),
[HOME] = COMBO(home_combo, KC_HOME),
[END] = COMBO(end_combo, KC_END),
[ENTER] = COMBO(enter_combo, KC_ENT),
[TAB] = COMBO(tab_combo, KC_TAB),
[ESC] = COMBO(esc_combo, KC_ESC),
[HELP] = COMBO(help_combo, AIDE_MEM),
[PANIC] = COMBO(panic_combo, RAZ),
[NUMWRD] = COMBO(numword_combo, NUMWORD),
[ALTTAB] = COMBO(alttab_combo, KC_NO),
[CTRLALT] = COMBO(ctrlalt_combo, RCTL(RALT(KC_DEL)))
};
/* uint16_t get_combo_term(uint16_t combo_index, combo_t *combo) {
switch (combo_index) {
case HOME:
return COMBO_TERM - 10;
default:
return COMBO_TERM;
}
} */
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.
if (os4a_layer != 0) {
return (os4a_layer == _R_MODS) == on_left_hand(record->event.key);
}
// Some combos shouldn't be affected by global_quick_tap_timer.
switch (combo_index) {
case R_BKSPC:
case BK_WORD:
case ENTER:
return true;
default:
//return timer_elapsed(global_quick_tap_timer) > TAP_INTERVAL;
if (timer_elapsed(global_quick_tap_timer) < TAP_INTERVAL) {
return false;
}
}
return true;
}
void process_combo_event(uint16_t combo_index, bool pressed) {
switch (combo_index) {
case ALTTAB:
if (pressed) {
register_mods(MOD_LALT);
tap_code(KC_TAB);
} else {
unregister_mods(MOD_LALT);
}
break;
}
}
bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) {
switch (combo_index) {
case ALTTAB:
switch (keycode) {
case FR_Y:
tap_code16(S(KC_TAB));
return true;
case LT_D:
tap_code(KC_TAB);
return true;
}
}
return false;
}

View file

@ -0,0 +1,81 @@
#include "macros.h"
//bool is_alt_tab_active = false;
/* static bool process_swapper(uint16_t keycode) {
if (!is_alt_tab_active) {
is_alt_tab_active = true;
register_code(KC_LALT);
}
tap_code16(keycode);
return false;
} */
/* void swapper_task(void) {
if (is_alt_tab_active) {
if (IS_LAYER_OFF(_SHORTNAV)){
unregister_code(KC_LALT);
is_alt_tab_active = false;
}
}
} */
bool process_macros(uint16_t keycode, keyrecord_t *record) {
//const uint8_t mods = get_mods();
if (record->event.pressed) { // Handling of other macros (on press).
switch (keycode) {
/* case ALT_TAB:
return process_swapper(KC_TAB);
case REV_TAB:
return process_swapper(S(KC_TAB)); */
case OS_TYPO:
if ((get_mods() | get_weak_mods() | get_oneshot_mods()) & MOD_BIT(KC_ALGR)) {
tap_code16(ALGR(FR_TYPO));
return false;
}
return true;
case AIDE_MEM:
switch(get_highest_layer(layer_state|default_layer_state)) {
case _BASE:
tap_code(KC_F13);
return false;
/* case _SYMBOLS:
tap_code(KC_F14); */
return false;
case _SHORTNAV:
tap_code(KC_F15);
return false;
case _FUNCAPPS:
tap_code(KC_F16);
return false;
}
case RAZ:
//led_t led_usb_state = host_keyboard_led_state();
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
if (!host_keyboard_led_state().num_lock) { tap_code(KC_NUM_LOCK); }
layer_clear();
clear_oneshot_mods();
caps_word_off();
disable_num_word();
clear_recent_keys();
break;
case KC_CAPS:
caps_word_off();
return true;
case CAPSWORD:
// I can't use CW_TOGG because QMK dosn't reach process_record_user when processing it.
// Deactivating Caps Lock when Caps Word activates.
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
caps_word_toggle();
return false;
}
}
return true; // Process all other keycodes normally
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "quantum.h"
#include "keymap.h"
#ifdef __cplusplus
extern "C" {
#endif
bool process_macros(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,123 @@
/* Copyright 2021 Joshua T.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "numword.h"
//static uint16_t num_word_timer = 0;
//static bool is_num_word_on = false;
bool is_num_word_on = false;
bool exit_num_word = false;
bool is_num_word_enabled(void) {
return is_num_word_on;
}
void enable_num_word(void) {
//if (is_num_word_on) return;
is_num_word_on = true;
layer_on(_NUMBERS);
}
void disable_num_word(void) {
//if (!is_num_word_on) return;
is_num_word_on = false;
layer_off(_NUMBERS);
exit_num_word = false;
}
void toggle_num_word(void) {
if (is_num_word_on) {
disable_num_word();
}
else {
enable_num_word();
}
}
bool should_terminate_num_word(uint16_t keycode, const keyrecord_t *record) {
switch (keycode) {
// Keycodes which should not disable num word mode.
// Numpad keycodes
case KC_P1 ... KC_P0:
case KC_PDOT:
case FR_VIRG:
case FR_MOIN:
case FR_ASTX:
case FR_PLUS:
case FR_SLSH:
case FR_ACIR:
//case FR_CARN:
// Misc
case KC_BSPC:
case NUMWORD: // For the combo NUMWORD to work
/*
case FR_EGAL:
case FR_BSLS:
// Misc
//case KC_BSPC:
case FR_UNDS: */
return false;
/* default:
if (record->event.pressed) { return true; }
return false; */
}
//if (!on_left_hand(record->event.key)) { return false; }
return true;
}
bool process_numword(uint16_t keycode, const keyrecord_t *record) {
// Handle the custom keycodes that go with this feature
if (keycode == NUMWORD) {
if (record->event.pressed) {
toggle_num_word();
return false;
}
}
// Other than the custom keycodes, nothing else in this feature will activate
// if the behavior is not on, so allow QMK to handle the event as usual.
if (!is_num_word_on) { return true; }
// Get the base keycode of a mod or layer tap key
switch (keycode) {
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
// Earlier return if this has not been considered tapped yet
if (record->tap.count == 0) { return true; }
keycode = keycode & 0xFF;
break;
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: // `LT(layer, key)` keys.
// Release event on a held layer-tap key when numword is on.
if (record->tap.count == 0 && !record->event.pressed && is_num_word_on) {
return false; // Skip default handling so that layer stays on.
} else {
keycode = keycode & 0xFF; // Get tapping keycode.
}
break;
/* default:
break; */
}
exit_num_word = should_terminate_num_word(keycode, record);
return true;
}

View file

@ -0,0 +1,29 @@
/* Copyright 2021 Joshua T.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include QMK_KEYBOARD_H
#include "keymap.h"
bool is_num_word_enabled(void);
extern bool exit_num_word;
extern bool is_num_word_on;
void enable_num_word(void);
extern void disable_num_word(void);
void toggle_num_word(void);
bool process_numword(uint16_t keycode, const keyrecord_t *record);

View file

@ -0,0 +1,52 @@
#include "oneshot.h"
void update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record) {
if (keycode == trigger) {
if (record->event.pressed) {
// Trigger keydown
if (*state == os_up_unqueued) {
register_code(mod);
}
*state = os_down_unused;
} else {
// Trigger keyup
switch (*state) {
case os_down_unused:
// If we didn't use the mod while trigger was held, queue it.
*state = os_up_queued;
break;
case os_down_used:
// If we did use the mod while trigger was held, unregister it.
*state = os_up_unqueued;
unregister_code(mod);
break;
default:
break;
}
}
} else {
if (record->event.pressed) {
if (is_oneshot_cancel_key(keycode) && *state != os_up_unqueued) {
// Cancel oneshot on designated cancel keydown.
*state = os_up_unqueued;
unregister_code(mod);
}
} else {
if (!is_oneshot_ignored_key(keycode)) {
// On non-ignored keyup, consider the oneshot used.
switch (*state) {
case os_down_unused:
*state = os_down_used;
break;
case os_up_queued:
*state = os_up_unqueued;
unregister_code(mod);
break;
default:
break;
}
}
}
}
}

View file

@ -0,0 +1,31 @@
#pragma once
#include QMK_KEYBOARD_H
// Represents the four states a oneshot key can be in
typedef enum {
os_up_unqueued,
os_up_queued,
os_down_unused,
os_down_used,
} oneshot_state;
// Custom oneshot mod implementation that doesn't rely on timers. If a mod is
// used while it is held it will be unregistered on keyup as normal, otherwise
// it will be queued and only released after the next non-mod keyup.
void update_oneshot(
oneshot_state *state,
uint16_t mod,
uint16_t trigger,
uint16_t keycode,
keyrecord_t *record
);
// To be implemented by the consumer. Defines keys to cancel oneshot mods.
bool is_oneshot_cancel_key(uint16_t keycode);
// To be implemented by the consumer. Defines keys to ignore when determining
// whether a oneshot mod has been used. Setting this to modifiers and layer
// change keys allows stacking multiple oneshot modifiers, and carrying them
// between layers.
bool is_oneshot_ignored_key(uint16_t keycode);

View file

@ -0,0 +1,99 @@
#include "os4a.h"
oneshot_state os_shft_state = os_up_unqueued;
oneshot_state os_ctrl_state = os_up_unqueued;
oneshot_state os_alt_state = os_up_unqueued;
oneshot_state os_altgr_state = os_up_unqueued;
oneshot_state os_win_state = os_up_unqueued;
uint8_t os4a_layer = 0;
bool exit_os4a_layer = false;
bool pending_OSL = false;
void os4a_layer_on(uint8_t layer) {
layer_on(layer);
os4a_layer = layer;
}
void os4a_layer_off(uint8_t layer) {
layer_off(layer);
os4a_layer = 0;
exit_os4a_layer = false;
}
void os4a_tap(uint16_t keycode) {
if (os4a_layer == 0) {
// Activate OS4A layer
os4a_layer_on(get_os4a_layer(keycode));
} else {
// Press again an OS4A key to exit the OS4A layer and clear the OS mods.
os4a_layer_off(os4a_layer);
}
}
bool process_os4a_keys(uint16_t keycode, keyrecord_t *record) {
// tap action
if (record->event.pressed && record->tap.count) {
os4a_tap(keycode);
return false;
}
// normal processing if held
return true;
}
/* void update_osl(uint16_t keycode) {
//if (os4a_layer_changer(keycode)) { pending_OSL = true; }
pending_OSL = os4a_layer_changer(keycode);
} */
bool process_os4a_layers(uint16_t keycode, keyrecord_t *record) {
// Should keycode exit the OS4A layer ?
if (is_oneshot_ignored_key(keycode)) { return false; }
// Add OS Shift when no other mods are active.
// Testing exit_os4a_layer is necessary to prevent OS shift to be added when other features create keyrecords
// to be processed (ex: custom altgr, clever keys).
uint8_t mods = get_mods() | get_oneshot_mods();
if (!exit_os4a_layer && !pending_OSL && to_be_shifted(keycode, record) && mods == 0) {
set_oneshot_mods(MOD_BIT(KC_LSFT));
}
return true;
}
void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record) {
// The OS4A layer must be exited only when ctrl or shift are registered,
// not when the OSM are released without having being held.
//if (get_mods() & QK_ONE_SHOT_MOD_GET_MODS(keycode)) {
// When ctrl or shift are released after being held, exit the OS4A layer.
if (!record->event.pressed && !record->tap.count) {
os4a_layer_off(os4a_layer);
}
}
bool process_mods(uint16_t keycode, keyrecord_t *record) {
// Handling Callum's OSM on OS4A layers
update_oneshot(&os_shft_state, KC_LSFT, OS_SHFT, keycode, record);
update_oneshot(&os_ctrl_state, KC_LCTL, OS_CTRL, keycode, record);
update_oneshot(&os_alt_state, KC_LALT, OS_LALT, keycode, record);
update_oneshot(&os_altgr_state, KC_RALT, OS_RALT, keycode, record);
update_oneshot(&os_win_state, KC_LWIN, OS_WIN, keycode, record);
// Handling OS4A keys
if (IS_OS4A_KEY(keycode)) { return process_os4a_keys(keycode, record); }
// Behaviour of the OS4A layers
if (os4a_layer != 0) { exit_os4a_layer = process_os4a_layers(keycode, record); }
// Updating OSL status on OS4A layers
pending_OSL = os4a_layer_changer(keycode);
// When Ctrl or Shift are released, for mouse use.
//if (mods_for_mouse(keycode)) { mouse_mods_key_up(keycode, record); }
return true;
}

View file

@ -0,0 +1,31 @@
#pragma once
#include "quantum.h"
#include "keymap.h"
#ifdef __cplusplus
extern "C" {
#endif
extern uint8_t os4a_layer;
extern bool exit_os4a_layer;
extern bool pending_OSL;
void os4a_layer_off(uint8_t layer);
void os4a_layer_on(uint8_t layer);
void os4a_tap(uint16_t keycode);
bool process_os4a_keys(uint16_t keycode, keyrecord_t *record);
void update_osl(uint16_t keycode);
bool process_os4a_layers(uint16_t keycode, keyrecord_t *record);
void mouse_mods_key_up(uint16_t keycode, keyrecord_t *record);
bool process_mods(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,81 @@
#include "tap_hold_utilities.h"
void tap_converter(uint16_t keycode, keyrecord_t *record) {
if (IS_OS4A_KEY(keycode)) {
// Instant OS4A processing
os4a_tap(keycode);
/* } else if (keycode == LT_REPT) { // Je pense que dans les faits, cette ligne ne sert à rien.
repeat_key_invoke(&record->event); */
} else {
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
// Tranform the record to send the tap event
record->keycode = tap_hold_extractor(keycode);
}
process_record(record);
}
// Send the base keycode key up event
record->event.pressed = false;
process_record(record);
}
// Returns true if `pos` on the left hand of the keyboard, false if right.
bool on_left_hand(keypos_t pos) {
#ifdef SPLIT_KEYBOARD
return pos.row < MATRIX_ROWS / 2;
#else
return (MATRIX_COLS > MATRIX_ROWS) ? pos.col < MATRIX_COLS / 2
: pos.row < MATRIX_ROWS / 2;
#endif
}
bool same_side_combination(const keyrecord_t* tap_hold_record, const keyrecord_t* other_record) {
return on_left_hand(tap_hold_record->event.key) == on_left_hand(other_record->event.key);
}
// By default, use the BILATERAL_COMBINATIONS rule to consider the tap-hold key
// "held" only when it and the other key are on opposite hands.
__attribute__((weak)) bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_record,
uint16_t other_keycode, keyrecord_t* other_record) {
return same_side_combination(tap_hold_record, other_record);
}
static bool process_tap_hold(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { // On press
tap_code16(keycode);
return false;
}
return true;
}
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record) {
if (record->tap.count) { // Handling of special tap-hold keys (on tap).
switch (keycode) {
/* case ALGR_T(FR_LACL):
return process_tap_hold(FR_LACL, record); */
case RCTL_T(FEN_B):
return process_tap_hold(LWIN(KC_DOWN), record);
case SFT_T(COPY):
return process_tap_hold(C(FR_C), record);
case LT_REPT:
repeat_key_invoke(&record->event);
return false;
case LT_MGC:
alt_repeat_key_invoke(&record->event);
return false;
}
}
return true; // Process all other keycodes normally
}

View file

@ -0,0 +1,71 @@
// Copyright 2022-2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file achordion.h
* @brief Achordion: Customizing the tap-hold decision.
*
* Overview
* --------
*
* This library customizes when tap-hold keys are considered held vs. tapped
* based on the next pressed key, like Manna Harbour's Bilateral Combinations or
* ZMK's positional hold. The library works on top of QMK's existing tap-hold
* implementation. You define mod-tap and layer-tap keys as usual and use
* Achordion to fine-tune the behavior.
*
* When QMK settles a tap-hold key as held, Achordion intercepts the event.
* Achordion then revises the event as a tap or passes it along as a hold:
*
* * Chord condition: On the next key press, a customizable `achordion_chord()`
* function is called, which takes the tap-hold key and the next key pressed
* as args. When the function returns true, the tap-hold key is settled as
* held, and otherwise as tapped.
*
* * Timeout: If no other key press occurs within a timeout, the tap-hold key
* is settled as held. This is customizable with `achordion_timeout()`.
*
* Achordion only changes the behavior when QMK considered the key held. It
* changes some would-be holds to taps, but no taps to holds.
*
* @note Some QMK features handle events before the point where Achordion can
* intercept them, particularly: Combos, Key Lock, and Dynamic Macros. It's
* still possible to use these features and Achordion in your keymap, but beware
* they might behave poorly when used simultaneously with tap-hold keys.
*
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/achordion>
*/
#pragma once
#include "quantum.h"
#include "keymap.h"
#ifdef __cplusplus
extern "C" {
#endif
bool on_left_hand(keypos_t pos);
bool same_side_combination(const keyrecord_t* tap_hold_record, const keyrecord_t* other_record);
void tap_converter(uint16_t keycode, keyrecord_t *record);
bool process_custom_tap_hold(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,183 @@
#include "features_conf.h"
bool is_caps_lock_on(void) { return host_keyboard_led_state().caps_lock; }
bool isLetter(uint16_t keycode) {
switch (keycode) {
case KC_A ... KC_N:
case KC_Q ... KC_V:
case KC_X ... KC_Z:
case FR_E:
case KC_SCLN ... KC_DOT:
return true;
default:
return false;
}
}
uint16_t tap_hold_extractor(uint16_t keycode) {
switch (keycode) {
case ALGR_T(FR_E):
return FR_E;
default:
return keycode &= 0xff;
}
}
// Caps Word
bool caps_word_press_user(uint16_t keycode) {
// Managing underscore on alt gr + E.
// Underscore must continue Caps Word, without shifting.
if ((get_mods() & MOD_BIT(KC_ALGR)) && keycode == FR_E) { return true; }
// Keycodes that continue Caps Word, with shift applied.
if (isLetter(keycode)) {
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
return true;
}
switch (keycode) {
// Keycodes that continue Caps Word, without shifting.
case FR_TYPO:
//case FR_GRV:
case FR_MOIN:
case FR_UNDS:
case FR_SLSH:
case KC_KP_1 ... KC_KP_0:
case KC_LEFT:
case KC_RIGHT:
case KC_BSPC:
case KC_DEL:
case FR_APOS:
case FR_ACIR:
return true;
default:
return false; // Deactivate Caps Word.
}
}
// Custom AltGr keys
/* const custom_altgr_key_t custom_altgr_keys[] = {
{FR_C, FR_COPY},
{FR_Y, FR_TM},
//{FR_I, FR_LDAQ},
//{FR_T, FR_RDAQ},
{FR_J, FR_CURR},
//{FR_H, FR_HASH},
{FR_Q, FR_SECT},
{KC_KP_8, FR_INFN},
{FR_F, FR_DEG}
};
uint8_t NUM_CUSTOM_ALTGR_KEYS =
sizeof(custom_altgr_keys) / sizeof(custom_altgr_key_t);*/
// One-shot 4 all configuration
uint8_t get_os4a_layer(uint16_t keycode) {
switch (keycode) {
case L_OS4A: return _L_MODS;
case R_OS4A: return _R_MODS;
default: return 0;
}
}
bool os4a_layer_changer(uint16_t keycode) {
switch (keycode) {
case OS_FA:
case NUMWORD:
case TT_FA:
return true;
default:
return false;
}
}
bool to_be_shifted(uint16_t keycode, keyrecord_t *record) {
// Combos and encoder events.
if (!IS_KEYEVENT(record->event)) { return true; }
switch (keycode) {
case KC_CAPS:
case CAPSWORD:
return false;
default:
return (os4a_layer == _R_MODS) == on_left_hand(record->event.key);
}
}
// Callum mods
bool is_oneshot_cancel_key(uint16_t keycode) {
switch (keycode) {
case L_OS4A:
case R_OS4A:
return true;
default:
return false;
}
}
bool is_oneshot_ignored_key(uint16_t keycode) {
// Alt-gr et shift s'appliquent à la touche typo, pour permettre de faire les majuscules plus facilement ainsi que ] avec.
// Autrement, la touche typo est ignorée par les Callum mods.
// Ça permet de transmettre les mods à la touche suivante, par ex pour faire Ctrl + K.
//uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods();
//if (keycode == OS_TYPO && (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR)))) { return true;}
//if (keycode == OS_TYPO && (mods & ~MOD_BIT(KC_ALGR))) { return true;}
switch (keycode) {
case OS_TYPO:
case L_OS4A:
case R_OS4A:
case OS_SHFT:
case OS_CTRL:
case OS_RALT:
case OS_LALT:
case OS_WIN:
case OS_FA:
case NUMWORD:
case TT_FA:
return true;
default:
return false;
}
}
// Repeat and Magic keys
bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) {
switch (keycode) {
case KC_BSPC:
case LT_REPT:
case LT_MGC:
return false;
}
return true;
}
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) {
switch (keycode) {
case C(FR_Z):
return C(FR_Y);
case C(FR_Y):
return C(FR_Z);
}
keycode = tap_hold_extractor(keycode);
if (isLetter(keycode)) { return MAGIC; }
return KC_TRNS; // Defer to default definitions.
}

View file

@ -0,0 +1,13 @@
#pragma once
#include "quantum.h"
#include "keymap.h"
bool isLetter(uint16_t keycode);
bool is_caps_lock_on(void);
uint16_t tap_hold_extractor(uint16_t keycode);
uint8_t get_os4a_layer(uint16_t keycode);
bool os4a_layer_changer(uint16_t keycode);
bool to_be_shifted(uint16_t keycode, keyrecord_t *record);
//bool mods_for_mouse(uint16_t keycode);

View file

@ -0,0 +1,326 @@
/* Copyright 2019 Thomas Baart <thomas@splitkb.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "keymap.h"
#include "features/layer_lock.h"
bool is_caps_lock_on(void) { return host_keyboard_led_state().caps_lock; }
bool isLetter(uint16_t keycode) {
switch (keycode) {
case KC_A ... KC_L:
case FR_M:
case KC_N ... KC_Z:
case FR_AGRV:
case FR_EACU:
case FR_EGRV:
case FR_CCED:
return true;
default:
return false;
}
}
// Achordion
uint16_t achordion_timeout(uint16_t tap_hold_keycode) { return 500; }
bool achordion_eager_mod(uint8_t mod) {
switch (mod) {
case MOD_LSFT:
case MOD_RSFT:
case MOD_LCTL:
case MOD_RCTL:
return true; // Eagerly apply Shift and Ctrl mods.
default:
return false;
}
}
// Caps Word
bool caps_word_press_user(uint16_t keycode) {
// Keycodes that continue Caps Word, with shift applied.
if (isLetter(keycode)) {
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
return true;
} else {
switch (keycode) {
// Keycodes that continue Caps Word, without shifting.
case FR_MOIN:
case KC_KP_1 ... KC_KP_0:
case KC_LEFT:
case KC_RIGHT:
case KC_BSPC:
case KC_DEL:
case FR_APOS:
return true;
default:
return false; // Deactivate Caps Word.
}
}
}
// Combo
combo_t key_combos[] = {};
uint16_t COMBO_LEN = 0;
// Custom altGr keys
const custom_altgr_key_t custom_altgr_keys[] = {
{FR_AGRV, FR_AE},
{FR_B, FR_SS},
{FR_A, FR_LDAQ},
{FR_I, FR_RDAQ},
{FR_T, FR_ESPR},
{FR_S, FR_AROB},
{ALGR_T(FR_A), FR_LDAQ},
{LCTL_T(FR_I), FR_RDAQ},
{RCTL_T(FR_T), FR_ESPR},
{ALGR_T(FR_S), FR_AROB},
{FR_X, FR_TM},
{KC_KP_8, FR_INFN},
{FR_H, FR_HASH},
{FR_V, FR_DEG},
{FR_CCED, FR_CEDL},
{FR_Q, FR_SECT},
{FR_POIN, FR_PVIR},
{FR_C, FR_COPY},
};
uint8_t NUM_CUSTOM_ALTGR_KEYS =
sizeof(custom_altgr_keys) / sizeof(custom_altgr_key_t);
void matrix_scan_user(void) {
//achordion_task();
recent_keys_task();
swapper_task();
}
// Tap-hold configuration
// Handle keyrecord before quantum processing
static uint16_t next_keycode;
static keyrecord_t next_record;
bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) {
static uint16_t prev_keycode;
static bool tap_condition;
if (record->event.pressed) {
// Store the previous keycode for instant tap decision
prev_keycode = next_keycode;
// Cache the next input for mod-tap decisions
next_keycode = keycode;
next_record = *record;
}
// Match mod-tap keys. Tweak this to limit conditions that matches your keyboard and habits.
tap_condition = ((IS_LAYER_ON(_BASE)) && IS_QK_MOD_TAP(keycode) && !IS_QK_LAYER_TAP(prev_keycode) && !is_mod_tap_control(prev_keycode));
return process_instant_tap(keycode, record, prev_keycode, tap_condition);
}
bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_record, uint16_t other_keycode, keyrecord_t* other_record) {
switch (tap_hold_keycode) {
case LT_VIRG:
case OSM(MOD_LSFT):
case OSM(MOD_RSFT):
return false;
default:
// Otherwise, follow the opposite hands rule.
return same_side_combination(tap_hold_record, other_record);
}
}
bool first_of_chorded_mods(uint16_t keycode) {
switch (keycode) {
case LT_TAB: // Pour pouvoir faire OSM shift + LT_TAB (win + shift + flèche).
case LT_CCED: // Pour pouvoir faire Alt + F4, Alt + F11.
case LCTL_T(FR_I):
case RCTL_T(FR_T):
case OSM(MOD_LSFT): // Pour pouvoir faire OSM shift + LT_TAB (win + shift + flèche).
return true;
default:
return false;
}
}
bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
if (record->event.key.col != next_record.event.key.col) {
// Sinon on a des effets de bord quand on veut taper des chiffres.
if (IS_LAYER_ON(_BASE)) {
// When a mod-tap key overlaps with another non-Ctrl key on the same hand, send its base keycode
if (forbidden_chord(keycode, record, next_keycode, &next_record) && !first_of_chorded_mods(keycode)) {
tap_converter(keycode, record);
}
}
}
return false;
}
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
if (forbidden_chord(keycode, record, next_keycode, &next_record)) {
tap_converter(keycode, record);
return false;
}
return true;
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Achordion
//if (!process_achordion(keycode, record)) { return false; }
// Custom alt gr
if (!process_custom_altgr_keys(keycode, record)) { return false; }
// Recent keys
if (!process_clever_keys(keycode, record)) { return false; }
// Numword
if (!process_numword(keycode, record)) { return false; }
// Layer lock
if (!process_layer_lock(keycode, record, LAYER_LCK)) { return false; }
// Select word
if (!process_select_word(keycode, record, SELWORD)) { return false; }
// Macros
if (!process_macros(keycode, record)) { return false; }
return true; // Process all other keycodes normally
}
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* Base Layer: ALPHAS
*»\
* ,-------------------------------------------. ,-------------------------------------------.
* | Helpsc | À | B | É | . | - | | ^ | V | L | M | X | W |
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|0
* | Enter | O | U |A/AltG|I/Ctrl| J | | G | T | S | N | R | F |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | Tab | Q | Y | È |P/Win | "" | Bksp | End | | Home |Delete| K | D | Z | H | C | Ç/Alt |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* |NavNum| Space|Shift | E | , | | ' | Space|Shift| Win | Mute |
* | | | |NavNum|Symb. | |Funct.|NavNum| | | |
* `----------------------------------' `----------------------------------'
*/
[_BASE] = LAYOUT(
KC_ESC, FR_AGRV, FR_B, FR_EACU, FR_POIN, FR_MOIN, FR_ACIR, FR_V, FR_L, FR_M, FR_X, FR_W,
KC_ENT, ALT_T(FR_O), SFT_T(FR_U), ALGR_T(FR_A), LCTL_T(FR_I), FR_J, FR_G, RCTL_T(FR_T), ALGR_T(FR_S), RSFT_T(FR_N), ALT_T(FR_R), FR_F,
LT_TAB, FR_Q, FR_Y, FR_EGRV, LWIN_T(FR_P), FR_DQUO, KC_BSPC, KC_END, KC_HOME, KC_DEL, FR_K, RWIN_T(FR_D), FR_Z, FR_H, FR_C, LT_CCED,
TG(_SYMBOLS), KC_SPC, OSM(MOD_LSFT), LT(_SYMBOLS,FR_E), LT_VIRG, LT_APOS, LT(_SYMBOLS,KC_SPC), OSM(MOD_RSFT), KC_RGUI, KC_MUTE
),
/*
* Layer 1 : Numpad + symbols
*
* ,-------------------------------------------. ,-------------------------------------------.
* | Helpsc | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) | LOCK | | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | |Expos.| 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_SYMBOLS] = LAYOUT(
KC_ESC, FR_EXLM, FR_QUES, FR_ESPR, FR_PVIR, FR_PIPE, FR_MOIN, KC_P7, KC_P8, KC_P9, FR_ASTX, KC_NUM,
_______, FR_LACL, SFT_T(FR_RACL), ALGR_T(FR_LPRN), FR_RPRN, LAYER_LCK, FR_EGAL, RCTL_T(KC_P4), ALGR_T(KC_P5), KC_P6, FR_SLSH, FR_BSLS,
_______, FR_LBKT, FR_RBKT, FR_INF, FR_SUP, FR_CARN, _______, _______, _______, _______, FR_ACIR, KC_P1, KC_P2, KC_P3, FR_PLUS, FR_PERC,
_______, _______, _______, KC_SPC, FR_VIRG, NUMWORD, KC_P0, KC_PDOT, _______ , _______
),
/*
* Layer 2 : Symbols + function keys
*
* ,-------------------------------------------. ,-------------------------------------------.
* | Helpsc | F1 | F2 | F3 | F4 | F5 | | | ; | ! | # | ° | |
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | |Ctrl A|Ctrl X|Ctrl V|Ctrl C| LOCK | | Mute | ( | ) | @ | & | Mute |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | F6 | F7 | F8 | F9 | F10 | | | | | | |Ctrl Z|Ctrl Y| F11 | F12 | |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | | | | |
* | | | | | | | !!! | , | | | |
* `----------------------------------' `----------------------------------'
*/
[_SHORTNAV] = LAYOUT(
KC_ESC, A(KC_F4), ALT_TAB, LWIN(FR_V), _______, _______, _______, C(KC_LEFT), KC_UP, C(KC_RIGHT), _______, _______,
_______, C(FR_A), C(FR_X), C(FR_V), C(FR_C), LAYER_LCK, KC_MUTE, RCTL_T(KC_LEFT), KC_DOWN, KC_RIGHT, KC_F2 , KC_MUTE,
_______, SELWORD, LWIN(KC_TAB), REV_TAB, ALT_TAB, _______, _______, S(KC_END), S(KC_HOME), _______, _______, C(FR_Z), C(FR_Y), _______, _______, _______,
_______, _______, _______, QUES_PT, QUES_PT, EXCL_PT, EXCL_PT, _______, _______, _______
),
/*
* Layer 3 : Function keys + windows management
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | F12 | F7 | F8 | F9 | | | | | | | | |
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | F11 | F4 | F5 | F6 | LOCK | | | | | | | |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | F10 | F1 | F2 | F3 | | | | | | | | | | | | |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | | | | |
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
*/
[_FUNCAPPS] = LAYOUT(
KC_ESC, KC_F12, KC_F9, KC_F8, KC_F7, C(KC_PAUS), _______, SWIN(KC_LEFT), LWIN(KC_UP), SWIN(KC_RIGHT), _______, QK_BOOT,
_______, ALT_T(KC_F11), SFT_T(KC_F6), KC_F5, KC_F4, LAYER_LCK, _______, RCTL_T(FEN_G), LWIN(KC_DOWN), LWIN(KC_RIGHT), _______, _______,
_______, KC_F10, KC_F3, KC_F2, KC_F1, _______, _______, _______, _______, _______, _______, LWIN(FR_D), LWIN(KC_HOME), _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
// /*
// * Layer template
// *
// * ,-------------------------------------------. ,-------------------------------------------.
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------| |------+------+------+------+------+--------|
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
// * | | | | | | | | | | | | | | | | | |
// * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
// * | | | | | | | | | | | |
// * | | | | | | | | | | | |
// * `----------------------------------' `----------------------------------'
// */
// [_LAYERINDEX] = LAYOUT(
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
// ),
};

View file

@ -0,0 +1,358 @@
/* Copyright 2019 Thomas Baart <thomas@splitkb.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "keymap.h"
uint16_t global_quick_tap_timer = 0;
// Tap-hold configuration
bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_record, uint16_t other_keycode, keyrecord_t* other_record) {
switch (tap_hold_keycode) {
case LT_REPT:
case LT_MGC:
return false;
}
// Otherwise, follow the opposite hands rule.
return same_side_combination(tap_hold_record, other_record);
}
bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
if (record->event.key.col != next_record.event.key.col) {
// J'avais mis cette ligne pour faire les "". Je pense que ce n'est plus nécessaire maintenant que que
//if (keycode == OS_TYPO) { return true; }
if (forbidden_chord(keycode, record, next_keycode, &next_record)) {
// When a layer-tap key overlaps with another key on the same hand, send its base keycode.
tap_converter(keycode, record);
}
}
return false;
}
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
return !forbidden_chord(keycode, record, next_keycode, &next_record);
}
// Matrix scan
void matrix_scan_user(void) {
recent_keys_task();
//swapper_task();
}
// Key processing
uint16_t next_keycode;
keyrecord_t next_record;
bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
// Cache the next input for mod-tap decisions
next_keycode = keycode;
next_record = *record;
}
return true;
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Global quick tap for combos.
// IS_KEYEVENT prevents combos from updating global_quick_tap_timer, to allow combos to be chained.
if ((IS_KEYEVENT(record->event) && get_highest_layer(layer_state) == _BASE) && !IS_OS4A_KEY(keycode)) {
global_quick_tap_timer = timer_read();
}
// Multi One-Shot Mods
if (!process_mods(keycode, record)) { return false; }
// Numword
if (!process_numword(keycode, record)) { return false; }
// Custom tap-hold keys
if (!process_custom_tap_hold(keycode, record)) { return false; }
if (IS_LAYER_ON(_TYPO) && record->event.pressed) {
switch (keycode) {
case FR_AROB:
case FR_K:
case FR_J:
case CA_CED:
case AGRV_SPC:
case OU_GRV:
break;
default:
const bool is_shifted = (get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT;
if (is_shifted) {
del_weak_mods(MOD_MASK_SHIFT);
del_oneshot_mods(MOD_MASK_SHIFT);
unregister_mods(MOD_MASK_SHIFT);
}
tap_code(FR_TYPO);
//set_mods(mods);
if (is_shifted) { set_oneshot_mods(MOD_BIT(KC_LSFT)); }
}
}
// Macros
if (!process_macros(keycode, record)) { return false; }
// Custom alt gr
//if (!process_custom_altgr_keys(keycode, record)) { return false; }
// Clever keys
if (!process_clever_keys(keycode, record)) { return false; }
// Process all other keycodes normally
return true;
}
void post_process_record_user(uint16_t keycode, keyrecord_t* record) {
//
if (os4a_layer != 0 && exit_os4a_layer) {
os4a_layer_off(os4a_layer);
}
if (exit_num_word) {
disable_num_word();
}
}
// Keymap
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* Base Layer: ALPHAS
*»\
* ,-------------------------------------------. ,-------------------------------------------.
* | | X | È | É | . | K | | V | B | L | M | X | |
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | Enter | O | U | A | I | J | | G | T | S | N | R | F |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | Tab | Q | Z | W | P | | | | | | | | D | Y | H | C | Ç |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | |Shift | E | , | | ' | Space| Shift| | |
* | | | |NavNum|Symb. | |Funct.|NavNum| | | |
* `----------------------------------' `----------------------------------'
*/
[_BASE] = LAYOUT(
KC_NO, FR_X, FR_VIRG, FR_EACU, FR_P, FR_B, FR_F, FR_M, FR_L, FR_APOS, FR_POIN, KC_NO,
KC_NO, FR_O, FR_A, FR_I, FR_T, FR_G, FR_V, FR_S, FR_N, FR_R, FR_U, KC_NO,
KC_NO, FR_Q, FR_Z, FR_Y, LT_D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, LT_C, FR_H, FR_W, OS_TYPO, KC_NO,
KC_NO, KC_SPC, L_OS4A, LT_E, LT_MGC, LT_REPT, LT_SPC, R_OS4A, KC_RGUI, KC_NO
),
/*
* Layer 1 : Mods gauche
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) | LOCK | | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | |Expos.| 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_L_MODS] = LAYOUT(
KC_NO, KC_NO, KC_NO, OS_WIN, KC_RGUI, KC_NO, _______, _______, _______, _______, _______, _______,
KC_NO, OS_RALT, OS_FA, OS_CTRL, OS_SHFT, KC_NO, _______, _______, _______, _______, _______, _______,
KC_NO, OS_LALT, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, _______, _______, _______, _______, _______, _______, _______, _______,
KC_NO, KC_NO, _______, _______, _______, CAPSWORD, _______, KC_CAPS, _______, _______
),
/*
* Layer : Mods droite
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) | LOCK | | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | |Expos.| 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_R_MODS] = LAYOUT(
_______, _______, _______, _______, _______, _______, KC_NO, KC_RGUI, OS_WIN, KC_NO, KC_NO, KC_NO,
_______, _______, _______, _______, _______, _______, TT_FA, OS_SHFT, OS_CTRL, NUMWORD, OS_TYPO, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, OS_FA, OS_LALT, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO
),
/*
* Layer 3 : Numpad + symbols
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | | & | ; | | | ^ | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) | ˇ | | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > | | | | | | | | 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
/* [_SYMBOLS] = LAYOUT(
_______, CIRC, FR_EXLM, FR_EGAL, FR_DLR, FR_AROB, FR_HASH, FR_INF, FR_SUP, FR_QUES, FR_2PTS, _______,
_______, FR_ASTX, FR_PLUS, FR_MOIN, FR_SLSH, FR_BSLS, GRAVE, FR_LPRN, FR_RPRN, FR_PVIR, FR_DQUO, _______,
_______, FR_PERC, TILDE, FR_PIPE, FR_ESPR, KC_NO, _______, _______, _______, _______, KC_NO, FR_LACL, FR_RACL, FR_LBKT, FR_RBKT, _______,
_______, _______, _______, FR_UNDS, _______, _______, FR_UNDS, KC_PDOT, _______, _______
), */
/*
* Layer 1 : Numpad
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) | LOCK | | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | |Expos.| 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_NUMBERS] = LAYOUT(
_______, _______, FR_ASTX, FR_EGAL, _______, S(FR_ACIR), KC_6, _______, FR_PLUS, FR_MOIN, _______, _______,
_______, KC_8, KC_6, KC_4, KC_2, FR_CARN, _______, KC_1, KC_3, KC_5, KC_7, _______,
_______, _______, _______, _______, FR_SLSH, _______, _______, _______, _______, _______, _______, KC_9, _______, _______, _______, _______,
_______, _______, FR_VIRG, KC_0 , NUMWORD, LT_REPT, KC_SPC, KC_PDOT, _______, _______
),
/*
* Layer 2 : Symbols
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) |Expos.| | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | | | 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
/* [_SYMBOLS] = LAYOUT(
_______, _______, _______, FR_DQUO, FR_PVIR, FR_ACIR, _______, KC_HOME, KC_UP, KC_END, _______, _______,
_______, FR_LACL, FR_RACL, FR_LPRN, FR_RPRN, FR_CARN, _______, KC_LEFT, KC_DOWN, ALGR_T(KC_RIGHT), KC_F2 , KC_MUTE,
_______, FR_LBKT, FR_RBKT, FR_INF, FR_SUP, KC_NO, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_SPC, FR_VIRG, NUMWORD, KC_P0, KC_PDOT, _______, _______
), */
/*
* Layer 2 : Symbols
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) |Expos.| | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | | | 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_TYPO] = LAYOUT(
_______, _______, _______, _______, _______, FR_J, FR_K, FR_F, FR_D, _______, _______, _______,
_______, OU_GRV, _______, _______, _______, _______, FR_M, FR_J, FR_L, FR_AROB, _______, _______,
_______, _______, _______, _______, CA_CED, _______, _______, _______, _______, _______, _______, _______, _______, FR_K, TG_ACC, _______,
_______, _______, _______, _______, FR_O, _______, AGRV_SPC, _______, _______, _______
),
/*
* Layer 3 : Symbols + function keys
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | ; | ! | # | ° | |
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | |Ctrl A|Ctrl X|Ctrl V|Ctrl C| LOCK | | Mute | ( | ) | @ | & | Mute |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | F6 | F7 | F8 | F9 | F10 | | | | | | |Ctrl Z|Ctrl Y| F11 | F12 | |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | | | | |
* | | | | | | | !!! | , | | | |
* `----------------------------------' `----------------------------------'
*/
[_SHORTNAV] = LAYOUT(
_______, KC_BSPC, LWIN(KC_TAB), LWIN(FR_V), RCS(FR_V), _______, KC_PGUP, C(KC_LEFT), KC_UP, C(KC_RGHT), _______, _______,
_______, C(FR_A), C(FR_X), C(FR_V), SFT_T(COPY), _______, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F2 , _______,
_______, KC_SPC, KC_SPC, KC_SPC, C(FR_Z), C(FR_Y), _______, _______, _______, _______, _______, KC_VOLD, KC_VOLU, KC_MUTE, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/*
* Layer 4 : Function keys + windows management
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | F12 | F7 | F8 | F9 | | | | | | | | |
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | F11 | F4 | F5 | F6 | LOCK | | | | | | | |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | F10 | F1 | F2 | F3 | | | | | | | | | | | | |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | | | | |au
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
*/
[_FUNCAPPS] = LAYOUT(
_______, KC_F12, KC_F9, KC_F8, KC_F7, QK_BOOT, _______, SWIN(KC_LEFT), LWIN(KC_UP), SWIN(KC_RIGHT), KC_NUM, _______,
_______, KC_F11, KC_F6, KC_F5, SFT_T(KC_F4), C(KC_PAUS), TT_FA, LWIN(KC_LEFT), RCTL_T(FEN_B), LWIN(KC_RIGHT), A(KC_ESC), _______,
_______, ALT_T(KC_F10), KC_F3, KC_F2, KC_F1, _______, _______, _______, _______, _______, _______, C(KC_PGUP), A(KC_ESC), C(KC_PGDN), _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
// /*
// * Layer template
// *
// * ,-------------------------------------------. ,-------------------------------------------.
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------| |------+------+------+------+------+--------|
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
// * | | | | | | | | | | | | | | | | | |
// * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
// * | | | | | | | | | | | |
// * | | | | | | | | | | | |
// * `----------------------------------' `----------------------------------'
// */
// [_LAYERINDEX] = LAYOUT(
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
// ),
};

View file

@ -0,0 +1,96 @@
/* Copyright 2019 Thomas Baart <thomas@splitkb.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include QMK_KEYBOARD_H
#include "keymap_french_frgo.h"
#include "features_conf.h"
#include "features/custom_altgr_keys.h"
#include "features/tap_hold_utilities.h"
#include "features/next_keycode.h"
#include "features/clever_keys.h"
#include "features/numword.h"
#include "features/macros.h"
#include "features/os4a.h"
#include "features/oneshot.h"
enum layers {
_BASE = 0,
// OS4A layers should be as closed as base layer as possible
_L_MODS,
_R_MODS,
_TYPO,
_NUMBERS,
_SHORTNAV,
_FUNCAPPS,
};
enum custom_keycodes {
NUMWORD = SAFE_RANGE,
FEN_B,
COPY,
/* ALT_TAB,
REV_TAB, */
AIDE_MEM,
OS4A,
RAZ,
CAPSWORD,
AGRV_SPC,
OU_GRV,
E_CIRC,
I_CIRC,
A_CIRC,
O_CIRC,
U_CIRC,
I_TREM,
CA_CED,
CIRC,
TILDE,
GRAVE,
MAGIC,
OS_SHFT,
OS_CTRL,
OS_RALT,
OS_LALT,
OS_WIN
};
// Layer taps
#define LT_SPC ALGR_T(KC_SPC)
#define LT_E ALGR_T(FR_E)
#define LT_REPT LT(_NUMBERS, KC_0)
#define LT_MGC LT(_SHORTNAV, KC_0)
#define LT_D FR_D
#define LT_C FR_C
#define LT_VIRG LT(_SHORTNAV, FR_VIRG)
#define OS_TYPO OSL(_TYPO)
#define OS_FA OSL(_FUNCAPPS)
#define TT_FA TT(_FUNCAPPS)
#define TG_ACC TG(_TYPO)
// One shot mods
#define L_OS4A LSFT_T(OS4A)
#define R_OS4A RSFT_T(OS4A)
#define IS_OS4A_KEY(keycode) (get_os4a_layer(keycode) != 0)
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

@ -0,0 +1,207 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "keycodes.h"
//#include "keymap.h"
// clang-format off
/*
*
*  À  1  2  3  4  5  6  7  8  9  0  /  *        
*
*       X  ,  É  P  B  F  M  L  '  .  =  +      
*     
*        O  A  I  T  G  V  S  N  R  U  Ù  Ç     
*
*      E  Q  Z  Y  D  J  K  C  H  W  **          
*
*                                                     
*
*/
// Row 1
#define FR_AGRV KC_GRV // à
#define FR_1 KC_1 // 1
#define FR_2 KC_2 // 2
#define FR_3 KC_3 // 3
#define FR_4 KC_4 // 4
#define FR_5 KC_5 // 5
#define FR_6 KC_6 // 6
#define FR_7 KC_7 // 7
#define FR_8 KC_8 // 8
#define FR_9 KC_9 // 9
#define FR_0 KC_0 // 0
#define FR_SLSH KC_MINS // /
#define FR_ASTX KC_EQL // *
// Row 2
#define FR_X KC_Q // X
#define FR_VIRG KC_W // ,
#define FR_EACU KC_E // É
#define FR_P KC_R // P
#define FR_B KC_T // B
#define FR_F KC_Y // F
#define FR_M KC_U // M
#define FR_L KC_I // L
#define FR_APOS KC_O // '
#define FR_POIN KC_P // .
#define FR_EGAL KC_LBRC // =
#define FR_PLUS KC_RBRC // +
// Row 3
#define FR_O KC_A // O
#define FR_A KC_S // A
#define FR_I KC_D // I
#define FR_T KC_F // T
#define FR_G KC_G // G
#define FR_V KC_H // V
#define FR_S KC_J // S
#define FR_N KC_K // N
#define FR_R KC_L // R
#define FR_U KC_SCLN // U
#define FR_UGRV KC_QUOT // Ù
#define FR_CCED KC_NUHS // Ç
// Row 4
#define FR_E KC_NUBS // E
#define FR_Q KC_Z // Q
#define FR_Z KC_X // Z
#define FR_Y KC_C // Y
#define FR_D KC_V // D
#define FR_J KC_B // J
#define FR_K KC_N // K
#define FR_C KC_M // C
#define FR_H KC_COMM // H
#define FR_W KC_DOT // W
#define FR_TYPO KC_SLSH // **
/* Shifted symbols
*
*                                               
*
*          !                    ?  :           
*     
*                                               
*
*                                                
*
*                                                     
*
*/
// Row 2
#define FR_EXLM S(FR_VIRG) // !
#define FR_QUES S(FR_APOS) // ?
#define FR_2PTS S(FR_POIN) // :
#define FR_DIFF S(FR_EGAL) // ≠
// Row 5
#define FR_NBSP S(KC_SPC) // Espace insecable
/* AltGr symbols
*
*                                     
*
*       ^  !  =  $  @  #  <  >  ?  :            
*     
*        *  +  -  /  \  `  (  )  ;  " │   │   │    │
*
*      _  %  ~  |  &        {  }  [  ]           
*
*                                                     
*
*/
// Row 2
#define FR_ACIR ALGR(FR_X) // ^
//#define FR_EXLM ALGR(FR_VIRG) // !
//#define FR_EGAL ALGR(FR_EACU) // =
#define FR_DLR ALGR(FR_P) // $
#define FR_AROB ALGR(FR_B) // @
#define FR_HASH ALGR(FR_F) // #
#define FR_INF ALGR(FR_M) // <
#define FR_SUP ALGR(FR_L) // >
//#define FR_QUES ALGR(FR_APOS) // ?
//#define FR_2PTS ALGR(FR_POIN) // :
// Row 3
/* #define FR_ASTX ALGR(FR_O) // *
#define FR_PLUS ALGR(FR_A) // +
#define FR_SLSH ALGR(FR_T) // / */
#define FR_MOIN ALGR(FR_I) // -
#define FR_BSLS ALGR(FR_G) // '\'
#define FR_GRV ALGR(FR_V) // `
#define FR_LPRN ALGR(FR_S) // (
#define FR_RPRN ALGR(FR_N) // )
#define FR_PVIR ALGR(FR_R) // ;
#define FR_DQUO ALGR(FR_U) // "
// Row 4
#define FR_UNDS ALGR(FR_E) // _
#define FR_PERC ALGR(FR_Q) // %
#define FR_TILD ALGR(FR_Z) // ~
#define FR_PIPE ALGR(FR_Y) // |
#define FR_ESPR ALGR(FR_D) // &
#define FR_LCBR ALGR(FR_C) // {
#define FR_RCBR ALGR(FR_H) // }
#define FR_LSBR ALGR(FR_W) // [
#define FR_RSBR ALGR(FR_TYPO) // ]
/* Shift+AltGr symbols
*
*   ̑                  ̏                          
*
*       *^ ¬    *¤ *˚           *ˇ           
*     
*        ×  ±  *¯ ÷    *` *´    *˘ *          
*
*           *~ ¦           *¸ *, *˛             
*
*                                                     
*
*/
#define FR_CARN S(ALGR(FR_POIN)) // ˇ (dead)
/* // Row 1
#define FR_IBRV S(ALGR(FR_AROB)) //  ̑ (dead)
#define FR_DACU S(ALGR(FR_LPRN)) // ˝ (dead)
#define FR_DGRV S(ALGR(FR_RPRN)) //  ̏ (dead)
#define FR_MDSH S(ALGR(FR_RSQU)) // —
#define FR_LSAQ S(ALGR(FR_LDAQ)) //
#define FR_RSAQ S(ALGR(FR_RDAQ)) //
#define FR_IQUE S(ALGR(FR_APOS)) // ¿
// Row 2
#define FR_TM S(ALGR(FR_T)) // ™
#define FR_DOTB S(ALGR(FR_I)) //  ̣ (dead)
#define FR_PERM S(ALGR(FR_P)) // ‰
#define FR_NBHY S(ALGR(FR_MOIN)) // (non-breaking hyphen)
#define FR_DDAG S(ALGR(FR_PLUS)) // ‡
// Row 3
#define FR_MACB S(ALGR(FR_H)) // ˍ (dead)
#define FR_SQRT S(ALGR(FR_SLSH)) // √
#define FR_QRTR S(ALGR(FR_ASTX)) // ¼
// Row 4
#define FR_GEQL S(ALGR(FR_INF)) // ≥
#define FR_OGON S(ALGR(FR_V)) // ˛ (dead)
#define FR_IEXL S(ALGR(FR_VIRG)) //  ̦ (dead)
//#define FR_NEQL S(ALGR(FR_EGAL)) // ≠ */

View file

@ -0,0 +1,164 @@
/* Copyright 2020 @frogm0uth
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty ofo
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "keymap.h"
/* The default OLED and rotary encoder code can be found at the bottom of qmk_firmware/keyboards/splitkb/kyria/rev1/rev1.c
* These default settings can be overriden by your own settings in your keymap.c
* For your convenience, here's a copy of those settings so that you can uncomment them if you wish to apply your own modifications.
* DO NOT edit the rev1.c file; instead override the weakly defined default functions by your own.
*/
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; }
bool oled_task_user(void) {
if (is_keyboard_master()) {
// QMK Logo and version information
// clang-format off
static const char PROGMEM qmk_logo[] = {
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0};
// clang-format on
oled_write_P(qmk_logo, false);
oled_write_P(PSTR("\n"), false);
//oled_write_P(PSTR("Kyria rev2.1\n"), false);
// Host Keyboard Layer Status
oled_write_P(PSTR("Layer: "), false);
switch (get_highest_layer(layer_state|default_layer_state)) {
case _BASE:
oled_write_P(PSTR("FR-Go\n"), false);
break;
case _L_MODS:
oled_write_P(PSTR("Mods G\n"), false);
break;
case _R_MODS:
oled_write_P(PSTR("Mods D\n"), false);
break;
/* case _SYMBOLS:
oled_write_P(PSTR("SymNum\n"), false); */
break;
case _SHORTNAV:
oled_write_P(PSTR("ShortNav\n"), false);
break;
case _FUNCAPPS:
oled_write_P(PSTR("FuncApps\n"), false);
break;
case _TYPO:
oled_write_P(PSTR("Accents\n"), false);
break;
default:
oled_write_P(PSTR("Undefined\n"), false);
}
// Statut des mods
const uint8_t mods = (get_mods() | get_oneshot_mods());
//bool is_shift_active = ((mods | get_oneshot_mods()) & MOD_MASK_SHIFT);
//oled_write_P(is_shift_active ? PSTR("SHIFT ") : PSTR(" "), false);
oled_write_P((mods & MOD_MASK_SHIFT) ? PSTR("SHIFT ") : PSTR(" "), false);
oled_write_P((mods & MOD_MASK_CTRL) ? PSTR("CTRL ") : PSTR(" "), false);
oled_write_P(((mods & MOD_BIT(KC_RALT)) == MOD_BIT(KC_RALT)) ? PSTR("ALT GR ") : 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_num_word_on() ? PSTR("NUMWORD\n") : PSTR(" \n"), false);
// Write host Keyboard LED Status to OLEDs
led_t led_usb_state = host_keyboard_led_state();
oled_write_P(led_usb_state.num_lock ? PSTR("NUMLCK ") : PSTR(" "), false);
oled_write_P(led_usb_state.caps_lock ? PSTR("CAPLCK ") : PSTR(" "), false);
oled_write_P(led_usb_state.scroll_lock ? PSTR("SCRLCK ") : PSTR(" "), false);
} else {
// clang-format off
static const char PROGMEM Gentleman_logo[] = {
// 'Gentleman', 128x64px
// 'OLED', 128x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,
0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0xe0, 0xf0, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf0,
0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0xff, 0xff, 0x00, 0x00, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xce, 0xce, 0xce, 0x0e, 0x0e, 0x4e, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe0, 0xf8, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0f, 0xc3,
0xf9, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf9, 0xe3, 0x07, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0x0f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x1f,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe0, 0x87,
0x9f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x1f, 0x8f, 0xe0, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
0xfe, 0xff, 0x07, 0x03, 0x03, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x8f, 0x87, 0xc3, 0xe3, 0xff, 0xff,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x7f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3e, 0x7e, 0x7c, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
0xff, 0xff, 0xc0, 0x80, 0x80, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xe1, 0xc3, 0xc7, 0x8f, 0xff, 0xff,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x1f, 0x7f, 0xff, 0xff, 0xf3, 0xe1, 0xcf, 0x8f, 0x8f, 0x87,
0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xc0, 0x80,
0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x87, 0x8f, 0x8f, 0x8f, 0xc5, 0xe1, 0xff,
0xff, 0xff, 0xff, 0x7f, 0x1f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0xe0, 0xf1, 0x71, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x31, 0xf1, 0xe0,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3f,
0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x0f, 0x07,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x0f, 0x1f, 0x1c, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x18, 0x1f, 0x0f,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// clang-format on
oled_write_raw_P(Gentleman_logo, sizeof(Gentleman_logo));
}
return false;
}

View file

@ -0,0 +1,249 @@
# Kyria's Default Keymap
![KLE render of the default Kyria keymap with QWERTY as the base layer. Layers are shown in sublegends.](https://i.ibb.co/RQZx2dY/default-kyria2.jpg)
The default keymap contains 5 layers which allows it to include all keys found on an ANSI layout TKL keyboard plus media keys.
Hardware features of the Kyria such as OLEDs, rotary encoders and underglow are also supported.
The five different layers are the following:
1. Base layer (QWERTY, Colemak-DH or Dvorak)
2. Navigation layer
3. Symbols/Numbers layer
4. Function layer
5. Adjust layer
## Base layer(s)
```
Base Layer: -
,-------------------------------------------. ,-------------------------------------------.
| Tab | - | - | - | - | - | | - | - | - | - | - | Bksp |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
|Ctrl/Esc| - | - | - | - | - | | - | - | - | - | - |Ctrl/ - |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| LShift | - | - | - | - | - | [ { |CapsLk| |F-Keys| ] } | - | - | - | - | - | RShift |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
|Adjust| LGUI | LAlt/| Space| Nav | | Sym | Space| AltGr| RGUI | Menu |
| | | Enter| | | | | | | | |
`----------------------------------' `----------------------------------'
```
Three different well-known keyboard layouts are provided to fill in the placeholder `-` keys: QWERTY, Colemak-DH, and Dvorak. The default layer can be changed at runtime, more info on that in the section on the [adjust layer](#adjust-layer).
For the rest of this write-up, the base layer will be assumed to be QWERTY and will be used as a reference to describe physical keys, e.g. “<kbd>B</kbd> key” vs, the much more verbose, “lower inner index key”.
```
Base Layer: QWERTY
,-------------------------------------------. ,-------------------------------------------.
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
|Ctrl/Esc| A | S | D | F | G | | H | J | K | L | ; : |Ctrl/' "|
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| LShift | Z | X | C | V | B | [ { |CapsLk| |F-keys| ] } | N | M | , < | . > | / ? | RShift |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
|Adjust| LGUI | LAlt/| Space| Nav | | Sym | Space| AltGr| RGUI | Menu |
| | | Enter| | | | | | | | |
`----------------------------------' `----------------------------------'
```
Aside from variations in the alpha cluster, the rest of the base keys remain the same and are designed to feel familiar.
![Step-by-step animation of the transformation of an ortholinear TKL to a Kyria](https://i.imgur.com/uVDCOek.gif)
<details>
After making transformations to the classic ANSI US QWERTY TKL 60% to arrive to the layout of the Kyria, as illustrated in the animation above, the result looks like this:
```
,-------------------------------------------. ,-------------------------------------------.
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
| Cap Lk | A | S | D | F | G | | H | J | K | L | ; : | ' " |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| LShift | Z | X | C | V | B | | | | | | N | M | , < | . > | / ? | RShift |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
| LCtrl| LGUI | LAlt | Space| | | | Space| AltGr| RGUI | Menu |
| | | | | | | | | | | |
`----------------------------------' '----------------------------------'
```
First thing to notice is the presence of blank keys. To fill in the blank keys above the <kbd>Space</kbd> keys, we can take inspiration from other split keyboards featuring an extra inner index column on each half. A common mapping for those kind of keys are the bracket keys that got removed in the fourth step of the animated transformation. The thumb keys besides <kbd>Space</kbd>s is prime real estate for dedicated layer-switching keys. It doesn't matter on which side is assigned the sym-layer-switch key but it helps to keep the nav-layer-switch on the left in order to keep the arrow keys on the right side like on a classic keyboard, so we'll put nav on the left and sym on the right. We'll address the remaining blank thumb keys later.
The base layer is starting to form but there remains some flaws. One glaring issue is the position of Control. Control is a very commonly used function but the key on which it sits right now is way too tucked in under the hand to be able to press it comfortably with either the thumb or the pinky from resting position. In fact, installing a rotary encoder there is a common move among Kyria users and I guarantee you that activating Control by holding down a rotary encoder does not spark joy. Instead, let's employ a popular trick that involves remapping the current Caps Lock key, which is positioned at a comfortable position on the keyboard, to Control.
We can go further though; a variant of this trick makes the Control key produce Escape when tapped. This is called a “modtap”. There is no use to tapping Control by itself without chording it with another key and there is no use to holding down the Esc key so why not combine the two into a single key?
All of this leaves us with three blank keys.
```
,-------------------------------------------. ,-------------------------------------------.
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
|Ctrl/Esc| A | S | D | F | G | | H | J | K | L | ; : | ' " |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| LShift | Z | X | C | V | B | [ { | | | | ] } | N | M | , < | . > | / ? | RShift |
`--------+-------------+--------------------+------+------| |------+------+--------------------+------+---------------'
| | LGUI | LAlt | Space| Nav | | Sym | Space| AltGr| RGUI | Menu |
| | | | | | | | | | | |
`----------------------------------' '----------------------------------'
```
These keys are not easily reachable while touch typing (that is, not reachable without picking up your hand) and should thus be associated with functions that you are not likely to be typed within a stream of text. The idea is that if you have to pick up your hand to hit a key, you want it to be at a time when you are likely to be pausing your interaction with the machine, rather than in the midst of a flurry of typing. They're thus well suited for accessing the adjust layer and the function layer. We can also toss in Caps Lock even though it is an editing-type function that gets used within a stream of text because shouting in ALL-CAPS should be a deliberate action.
```
,-------------------------------------------. ,-------------------------------------------.
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
|Ctrl/Esc| A | S | D | F | G | | H | J | K | L | ; : | ' " |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| LShift | Z | X | C | V | B | [ { |CapsLk| |F-keys| ] } | N | M | , < | . > | / ? | RShift |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
|Adjust| LGUI | LAlt | Space| Nav | | Sym | Space| AltGr| RGUI | Menu |
| | | | | | | | | | | |
`----------------------------------' `----------------------------------'
```
The next glaring issue is the absence of an Enter key on the current base layer this far. Enter is a very frequently used key so it deserves to be placed at a good spot in the keymap. The best way to insert it in the keymap with minimal changes to the current layout is to use modtaps. A tempting solution is to turn the <kbd>RShift</kbd> key into a <kbd>RShift/Enter</kbd> modtap but that can result in chat messages sent too frustratingly early when you're not used to it. Using GUI is also sub-optimal because tapping the GUI modifier actually has a use as opposed to taps of the Control or the Shift key. Pressing and releasing the GUI key by itself opens the App menu in many desktop environments. The natural choice is thus <kbd>LAlt/Enter</kbd>. That way, Enter is 1u away from resting thumb position and is unlikely to get accidentally activated because Alt is very rarely used in the midst of prose.
Finally, we're one Quality-Of-Life update away from the actual base layer. <kbd>Ctrl/' "</kbd> not only preserves symmetry in the keymap with <kbd>Ctrl/Esc</kbd> but also helps balance the load between your pinkies and invites you to use both hands instead of contortions. Perhaps more importantly, it also frees you from the necessity of picking up your hand, breaking touch typing position and pressing a pinky key with your ring finger in order to execute Ctrl+A or Ctrl+Z. That becomes even more important on a board with such an aggressive pinky columnar stagger like the Kyria.
```
,-------------------------------------------. ,-------------------------------------------.
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
|Ctrl/Esc| A | S | D | F | G | | H | J | K | L | ; : |Ctrl/' "|
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| LShift | Z | X | C | V | B | [ { |CapsLk| |F-keys| ] } | N | M | , < | . > | / ? | RShift |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
|Adjust| LGUI | LAlt/| Space| Nav | | Sym | Space| AltGr| RGUI | Menu |
| | | Enter| | | | | | | | |
`----------------------------------' `----------------------------------'
```
</details>
## Navigation layer
```
Nav Layer: Media, navigation
,-------------------------------------------. ,-------------------------------------------.
| | | | | | | | PgUp | Home | ↑ | End | VolUp| Delete |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
| | GUI | Alt | Ctrl | Shift| | | PgDn | ← | ↓ | → | VolDn| Insert |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| | | | | | | |ScLck | | | | Pause|M Prev|M Play|M Next|VolMut| PrtSc |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
| | | | | | | | | | | |
| | | | | | | | | | | |
`----------------------------------' `----------------------------------'
```
This is where you'll find all the keys that are generally between the main block of a classic keyboard and the numpad in addition to media controls and modifiers on easy access on the home row for fast and comfortable chording with navigation keys.
Useful mnemonics:
- “GACS” to remember the order of the modifiers on the left-hand home row
- <kbd>Scroll Lock</kbd> is on the same key as <kbd>Caps Lock</kbd> because they're both locks
- <kbd>Delete</kbd> is on the same key as <kbd>Backspace</kbd> because they both erase characters
- <kbd>Home</kbd> is the leftmost position on the current line so it is above <kbd>←</kbd>. Same logic applies for <kbd>End</kbd>.
- <kbd>Media Previous</kbd> = ⏮, <kbd>Media Next</kbd> = ⏭
- <kbd>Page Up</kbd>, <kbd>Page Down</kbd> and <kbd>Volume Up</kbd>, <kbd>Volume Down</kbd> are positioned like the main <kbd>Up</kbd> and <kbd>Down</kbd> keys.
## Sym layer
```
Sym Layer: Numbers, symbols
,-------------------------------------------. ,-------------------------------------------.
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | = |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
| ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | + |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| | | \ | : | ; | - | [ | { | | | | } | ] | _ | , | . | / | ? |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
| | | | | | | | | | | |
| | | | | | | | | | | |
`----------------------------------' `----------------------------------'
```
The top row is the unshifted num row, the home row of the layer is the shifted num row and the bottom row contains the hyphen `-` and the underscore `_` on the best lower row spot because of how frequent they are as well as redundant symbols that are already present on the base layer but are reproduced here to avoid juggling back and forth between base, shift, and sym when typing a string of symbols.
The layout of the first two rows needs no introduction, you're already used to them but it's worth looking into the structure of the bottom row.
The two halves are mirrored in a sense. On the right, you can find <kbd>,</kbd> <kbd>.</kbd> <kbd>/</kbd> at their usual spots with the addition of <kbd>Shift</kbd>+<kbd>/</kbd>=<kbd>?</kbd> to the right of the <kbd>/</kbd> key to remove the need to press simultaneously <kbd>Sym</kbd> and a <kbd>Shift</kbd> key to access `?`.
Now, if you look at the left side, you'll notice that the mirror of <kbd>,</kbd> is <kbd>;</kbd>, the mirror of <kbd>.</kbd> is <kbd>:</kbd> and the mirror of <kbd>/</kbd> is <kbd>\\</kbd>. The same logic used for <kbd>Shift</kbd>+<kbd>/</kbd>=<kbd>?</kbd> also applies to <kbd>Shift</kbd>+<kbd>\\</kbd>=<kbd>|</kbd>.
In case you wish to combine <kbd>Shift</kbd> with a symbol key anyways, you can hold down <kbd>Shift</kbd> on the base layer with your pinky, activate <kbd>Sym</kbd> with your right thumb and while still holding down the <kbd>Shift</kbd> key, tap your desired symbol key. Same thing if you need <kbd>Ctrl</kbd>+<kbd>Digit</kbd>.
## Function layer
```
Function Layer: Function keys
,-------------------------------------------. ,-------------------------------------------.
| | F9 | F10 | F11 | F12 | | | | | | | | |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
| | F5 | F6 | F7 | F8 | | | | Shift| Ctrl | Alt | GUI | |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| | F1 | F2 | F3 | F4 | | | | | | | | | | | | |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
| | | | | | | | | | | |
| | | | | | | | | | | |
`----------------------------------' `----------------------------------'
```
In a similar fashion to the nav layer, pressing down `FKEYS` with the right thumb enables a numpad of function keys on the opposite hand and modifiers on the right-hand home row. Once again, mirror symmetry is leveraged in this keymap for the order of the right-hand modifiers.
The <kbd>Alt</kbd> modifier, despite being situated on the right half of the keyboard is *not* `KC_RALT`, it is `KC_LALT`. `KC_RALT` is actually the <kbd>AltGr</kbd> key which generally acts very differently to the left <kbd>Alt</kbd> key. Keyboard shortcuts involving <kbd>AltGr</kbd>+<kbd>F#</kbd> are rare and infrequent as opposed to the much more common <kbd>Alt</kbd>+<kbd>F#</kbd> shortcuts. Consequently, `KC_LALT` was chosen for the function layer.
Since there are more than 10 function keys, the cluster of F-keys does not follow the usual 3×3+1 numpad arrangement.
## Adjust layer
```
Adjust Layer: Default layer settings, RGB
,-------------------------------------------. ,-------------------------------------------.
| | | |QWERTY| | | | | | | | | |
|--------+------+------+------+------+------| |------+------+------+------+------+--------|
| | | |Dvorak| | | | TOG | SAI | HUI | VAI | MOD | |
|--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
| | | |Colmak| | | | | | | | | SAD | HUD | VAD | RMOD | |
`----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
| | | | | | | | | | | |
| | | | | | | | | | | |
`----------------------------------' `----------------------------------'
```
Default layer settings on the left and various RGB underglow controls on the right.
The default layer settings are lined up on the middle finger column because the home middle finger key is <kbd>D</kbd> on QWERTY (like the “D” in “Dvorak”) and the lower middle finger key is <kbd>C</kbd> on QWERTY (like the “C” in “Colemak”). I can hear you say that “QWERTY” doesn't start with “E” but Dvorak and Colemak were already aligned in a column so the QWERTY may as well join the formation.
NOTE: The default layer settings set by those keys are *NOT* stored in EEPROM and thus do not persist through boots. If you wish to change the default layer in a non-volatile manner, either change the order of the layers in the firmware, for example like so if you want to set Dvorak as the new default:
```c
enum layers {
_DVORAK = 0,
_QWERTY,
_COLEMAK_DH,
_NAV,
_SYM,
_FUNCTION,
_ADJUST
};
```
or re-define the `QWERTY`, `COLEMAK` and `DVORAK` keys to point to custom keycodes starting on `SAFE_RANGE` and calling the `set_single_persistent_default_layer` function inside of `process_record_user`.
## Hardware Features
### Rotary Encoder
The left rotary encoder is programmed to control the volume whereas the right encoder sends <kbd>PgUp</kbd> or <kbd>PgDn</kbd> on every turn.
### OLEDs
The OLEDs display the current layer at the top of the active layers stack, the Kyria logo and lock status (caps lock, num lock, scroll lock).
### Underglow
The underglow LEDs should be red.
## Going further…
This default keymap can be used as is, unchanged, as a daily driver for your Kyria but you're invited to treat your keymap like a bonsai. At the beginning, it's just like the default keymap but from time to time, you can tweak it a little. Cut a little key here, let another combo grow there. Slowly but surely it will be a unique keymap that will fit you like a glove.
Check out the #keymap-ideas channel on the official SplitKB Discord server for inspiration.

View file

@ -0,0 +1,43 @@
OLED_ENABLE = yes
ENCODER_ENABLE = no # Enables the use of one or more encoders
RGB_MATRIX_ENABLE = no # Disable keyboard RGB matrix, as it is enabled by default on rev3
RGBLIGHT_ENABLE = no # Disable keyboard RGB underglow
#SPLIT_KEYBOARD = yes
#OLED_DRIVER = ssd1306 # Enables the use of OLED displays
#OLED_DRIVER_ENABLE = yes # Enables the use of OLED displays
LTO_ENABLE = yes
ENCODER_MAP_ENABLE = no
TAP_DANCE_ENABLE = no
DEFERRED_EXEC_ENABLE = no
KEY_OVERRIDE_ENABLE = no
CAPS_WORD_ENABLE = yes
COMBO_ENABLE = yes
#LAYER_LOCK_ENABLE = yes
REPEAT_KEY_ENABLE = yes
SRC += features/tap_hold_utilities.c
SRC += features/os4a.c
SRC += features/custom_altgr_keys.c
#SRC += encoder.c
SRC += oled.c
SRC += features/next_keycode.c
SRC += features/clever_keys.c
SRC += features/numword.c
SRC += features/macros.c
SRC += features/oneshot.c
SRC += features_conf.c
INTROSPECTION_KEYMAP_C = features/combos.c
MUSIC_ENABLE = no
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no

View file

@ -0,0 +1,285 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Correction automatique
#include "clever_keys.h"
bool clever_key_finder(uint16_t next_keycode, keyrecord_t* record) {
uint16_t prev_keycode = recent[RECENT_SIZE - 1];
//const uint8_t mods = get_mods();
//const bool isCaps = is_caps_lock_on() || is_caps_word_on();
if (isLetter(next_keycode) || next_keycode == E_CIRC) {
switch (prev_keycode) {
case FR_EXLM:
case FR_QUES:
//case FR_3PTS:
case FR_2PTS:
// Add space between punctuation and letters.
invoke_key(KC_SPC, record);
case KC_SPC:
switch (recent[RECENT_SIZE - 2]) {
case FR_EXLM:
case FR_QUES:
//case FR_3PTS:
case FR_POIN:
// Add OS shift at the beginning of sentences.
if (!is_caps_lock_on()) { set_oneshot_mods(MOD_BIT(KC_LSFT)); }
break;
}
}
}
switch (prev_keycode) {
case FR_Q:
switch (next_keycode) {
// Ajout automatique du "u" après le "q"
case FR_E:
case FR_I:
case FR_A:
case FR_O:
case FR_EACU:
case E_CIRC:
case FR_APOS:
invoke_key(FR_U, record);
break;
// Raccourci pour "quelq"
case FR_Q:
clear_recent_keys(); // To prevent infinite loop
process_word((uint16_t[]) {FR_U, FR_E, FR_L}, 3, record);
break;
// Raccourci pour "quoi", ça évite un aller-retour sur la main gauche.
case FR_Z:
return finish_word((uint16_t[]) {FR_U, FR_O, FR_I}, 3, record);
// Raccourci pour "quand"
case FR_D:
process_word((uint16_t[]) {FR_U, FR_A, FR_N}, 3, record);
break;
}
break;
case FR_P:
switch (next_keycode) {
case FR_M:
// "pas"
return finish_word((uint16_t[]) {FR_A, FR_S}, 2, record);
case FR_APOS:
// "par"
return finish_word((uint16_t[]) {FR_A, FR_R}, 2, record);
case FR_POIN:
if (!isLetter(recent[RECENT_SIZE - 2])) {
// "pour"
return finish_word((uint16_t[]) {FR_O, FR_U, FR_R}, 3, record);
}
break;
}
}
switch (next_keycode) {
case FR_QUES:
case FR_EXLM:
// On ajoute un espace insécable s'il n'a pas été entré avant le point d'exclamation.
// Il ne faut pas tester cette fonctionnalité avec Word, qui ajoute cet espace automatiquement.
if (isLetter(recent[RECENT_SIZE - 1])) {
/* if ((mods | get_oneshot_mods() | get_weak_mods()) & MOD_MASK_SHIFT) {
del_weak_mods(MOD_MASK_SHIFT);
del_oneshot_mods(MOD_MASK_SHIFT);
unregister_mods(MOD_MASK_SHIFT);
} */
invoke_key(S(KC_SPC), record);
//set_mods(mods);
return replace_next_key(next_keycode, record);
}
break;
case MAGIC:
switch (prev_keycode) {
case FR_T:
invoke_key(FR_I, record);
case FR_I:
return finish_magic((uint16_t[]) {FR_O, FR_N}, 2, record);
case FR_C:
return finish_magic((uint16_t[]) {FR_APOS, FR_E, FR_S, FR_T}, 4, record);
case FR_D:
return finish_magic((uint16_t[]) {FR_A, FR_N, FR_S}, 3, record);
case FR_P:
return finish_magic((uint16_t[]) {FR_L, FR_U, FR_S}, 3, record);
case FR_O:
return finish_magic((uint16_t[]) {FR_N, FR_T}, 2, record);
case FR_A:
if (isLetter(recent[RECENT_SIZE - 2])) {
// "ant"
return finish_magic((uint16_t[]) {FR_N, FR_T}, 2, record);
} else {
// "avec"
return finish_magic((uint16_t[]) {FR_V, FR_E, FR_C}, 3, record);
}
case FR_S:
return finish_magic((uint16_t[]) {FR_U, FR_R}, 2, record);
case FR_B:
process_word((uint16_t[]) {FR_O, FR_N, FR_J}, 3, record);
case FR_J:
return finish_magic((uint16_t[]) {FR_O, FR_U, FR_R}, 3, record);
case FR_M:
if (isLetter(recent[RECENT_SIZE - 2])) {
// "ment"
return finish_magic((uint16_t[]) {FR_E, FR_N, FR_T}, 3, record);
} else {
// "même"
return finish_magic((uint16_t[]) {FR_TYPO, FR_O, FR_M, FR_E}, 4, record);
}
default:
return false;
}
case FR_AROB:
if (!isLetter(recent[RECENT_SIZE - 2])) {
switch (prev_keycode) {
case FR_T:
// "t@" -> "toujours"
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_O, FR_U, FR_J, FR_O, FR_U, FR_R, FR_S}, 7, record);
case FR_P:
// "p@" -> "peut-être"
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_E, FR_U, FR_T, FR_MOIN, FR_TYPO, FR_O, FR_T, FR_R, FR_E}, 9, record);
case FR_A:
// "a@" -> "aujourd'hui"
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_U, FR_J, FR_O, FR_U, FR_R, FR_D, FR_APOS, FR_H, FR_U, FR_I}, 10, record);
case FR_B:
// "b@" -> "beaucoup"
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_E, FR_A, FR_U, FR_C, FR_O, FR_U, FR_P}, 7, record);
case FR_E:
// "e@" -> "est-ce qu"
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_S, FR_T, FR_MOIN, FR_C, FR_E, KC_SPC, FR_Q}, 7, record);
case FR_D:
// "d@" -> "déjà"
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_EACU, FR_J, FR_AGRV}, 3, record);
}
}
break;
case FR_Q:
if (prev_keycode == FR_J) {
// "jq" -> "jusqu"
process_word((uint16_t[]) {FR_U, FR_S}, 2, record);
}
break;
case FR_A:
//if (prev_keycode == FR_O && !isCaps) {
if (prev_keycode == FR_O) {
// "oa" -> "oi"
clear_recent_keys(); // To prevent infinite loop
return replace_next_key(FR_I, record);
}
break;
case FR_I:
//if (prev_keycode == FR_O && !isCaps && recent[RECENT_SIZE - 3] != FR_Q) {
if (prev_keycode == FR_O && recent[RECENT_SIZE - 3] != FR_Q) {
// "oi" -> "oa", for "keyboard"
clear_recent_keys(); // To prevent infinite loop
return replace_next_key(FR_A, record);
}
break;
case FR_O:
if (prev_keycode == FR_U && recent[RECENT_SIZE - 2] != FR_Q) {
// "uo" -> "un"
return replace_next_key(FR_N, record);
}
break;
case CA_CED:
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_CCED, FR_A}, 2, record);
case OU_GRV:
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_O, FR_UGRV}, 2, record);
case AGRV_SPC:
layer_off(_TYPO);
return finish_word((uint16_t[]) {FR_AGRV, KC_SPC}, 2, record);
/* case E_CIRC:
return process_accent(FR_ACIR, FR_E, record);
case I_CIRC:
return process_accent(FR_ACIR, FR_I, record);
case A_CIRC:
return process_accent(FR_ACIR, FR_A, record);
case O_CIRC:
return process_accent(FR_ACIR, FR_O, record);
case U_CIRC:
return process_accent(FR_ACIR, FR_U, record);
case I_TREM:
return process_accent(FR_TREM, FR_I, record);
case CIRC:
return process_accent(FR_ACIR, KC_SPC, record);
case TILDE:
return process_accent(FR_TILD, KC_SPC, record);
case GRAVE:
return process_accent(FR_GRV, KC_SPC, record);*/
}
return false; // Process next keycode normally
}

View file

@ -0,0 +1,33 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#include "keymap.h"
//#include <string.h>
//#include "keymap_french_frgo.h"
#ifdef __cplusplus
extern "C" {
#endif
bool clever_key_finder(uint16_t next_keycode, keyrecord_t* record);
#ifdef __cplusplus
}
#endif

View file

@ -1,4 +1,4 @@
/* Copyright 2022 Thomas Baart <thomas@splitkb.com> /* Copyright 2025 @Kawamashi
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -46,7 +46,8 @@
// mod tap // mod tap
#define TAPPING_TERM 200 #define TAPPING_TERM 200
#define PERMISSIVE_HOLD_PER_KEY #define PERMISSIVE_HOLD
//#define PERMISSIVE_HOLD_PER_KEY
#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY #define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
#define TAPPING_TOGGLE 1 #define TAPPING_TOGGLE 1

View file

@ -0,0 +1,182 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clever_keys_utilities.h"
uint16_t recent[RECENT_SIZE] = {KC_NO};
uint16_t deadline = 0;
unsigned short int bkspc_countdown = RECENT_SIZE + 1;
// Copy of the record argument for the clever key.
static keyrecord_t mod_record;
void clear_recent_keys(void) {
memset(recent, 0, sizeof(recent)); // Set all zeros (KC_NO).
bkspc_countdown = RECENT_SIZE + 1;
}
void recent_keys_task(void) {
if (recent[RECENT_SIZE - 1] && timer_expired(timer_read(), deadline)) {
clear_recent_keys(); // Timed out; clear the buffer.
}
}
// Handles one event. Returns false if the key was appended to `recent`.
uint16_t get_next_keycode(uint16_t keycode, keyrecord_t* record) {
if (!record->event.pressed) { return KC_NO; }
uint8_t mods = get_mods() | get_oneshot_mods();
if (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR))) {
clear_recent_keys(); // Avoid interfering with ctrl, left alt and gui.
return KC_NO;
}
// Sticky keys don't type anything on their own.
if (IS_QK_ONE_SHOT_MOD(keycode) || IS_QK_ONE_SHOT_LAYER(keycode)) { return KC_NO; }
// Handle backspace.
if (keycode == KC_BSPC) {
bkspc_countdown--;
if (bkspc_countdown == 0) {
// Clear the key buffers.
clear_recent_keys();
} else {
// Rewind the key buffers.
memmove(recent + 1, recent, (RECENT_SIZE - 1) * sizeof(uint16_t));
recent[0] = KC_NO;
// Setting the key to be repeated to match the key buffer.
set_last_keycode(recent[RECENT_SIZE - 1]);
}
return KC_NO;
}
// Extract keycode from regular tap-hold keys.
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
if (record->tap.count == 0) { return KC_NO; }
// Get tapping keycode.
keycode = tap_hold_extractor(keycode);
}
// Handles custom keycodes.
if IS_QK_USER(keycode) { return keycode; }
uint8_t basic_keycode = keycode;
// Handle keys carrying a modifier, for ex on layers(! and ?).
if (IS_QK_MODS(keycode)) { basic_keycode = QK_MODS_GET_BASIC_KEYCODE(keycode); }
switch (basic_keycode) {
case KC_A ... KC_SLASH: // These keys type letters, digits, symbols.
case FR_E:
if (isLetter(basic_keycode) && (mods & ~MOD_BIT(KC_ALGR))) {
// Shift doesn't matter for letters.
return basic_keycode;
} else if (basic_keycode != keycode) {
// For keys carrying a modifier, for ex on layers.
return keycode;
} else {
// Convert 8-bit mods to the 5-bit format used in keycodes. This is lossy: if
// left and right handed mods were mixed, they all become right handed.
mods = ((mods & 0xf0) ? /* set right hand bit */ 0x10 : 0)
// Combine right and left hand mods.
| (((mods >> 4) | mods) & 0xf);
// Combine basic keycode with mods.
keycode = (mods << 8) | basic_keycode;
return keycode;
}
default: // Avoid acting otherwise, particularly on navigation keys.
clear_recent_keys();
return KC_NO;
}
return KC_NO;
}
void store_keycode(uint16_t keycode, keyrecord_t* record) {
// Slide the buffer left by one element.
memmove(recent, recent + 1, (RECENT_SIZE - 1) * sizeof(*recent));
recent[RECENT_SIZE - 1] = keycode;
bkspc_countdown++;
deadline = record->event.time + RECENT_KEYS_TIMEOUT;
}
void process_key(uint16_t keycode, keyrecord_t* record) {
mod_record = *record;
mod_record.keycode = keycode;
// Send the next keycode key down event
process_record(&mod_record);
// Send the next keycode key up event
mod_record.event.pressed = false;
process_record(&mod_record);
}
void invoke_key(uint16_t keycode, keyrecord_t* record) {
process_key(keycode, record);
bkspc_countdown = 1;
}
bool replace_next_key(uint16_t keycode, keyrecord_t* record) {
invoke_key(keycode, record);
return true;
}
void process_word(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record) {
for (int i = 0; i < num_keycodes; ++i) {
invoke_key(keycodes[i], record);
}
bkspc_countdown = num_keycodes;
}
bool finish_word(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record) {
process_word(keycodes, num_keycodes, record);
return true;
}
bool finish_magic(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record) {
// Setting the key to be repeated to match the key buffer.
set_last_keycode(keycodes[num_keycodes - 1]);
return finish_word(keycodes, num_keycodes, record);
}
bool process_clever_keys(uint16_t keycode, keyrecord_t* record) {
uint16_t next_keycode = get_next_keycode(keycode, record);
if (next_keycode != KC_NO) {
if (clever_key_finder(next_keycode, record)) { return false; }
store_keycode(next_keycode, record);
}
return true; // If no clever key was found, process keycode normally.
}
bool process_accent(uint16_t accent, uint16_t letter, keyrecord_t* record) {
const bool is_shifted = (get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT;
if (is_shifted) {
del_weak_mods(MOD_MASK_SHIFT);
del_oneshot_mods(MOD_MASK_SHIFT);
unregister_mods(MOD_MASK_SHIFT);
}
tap_code16(accent);
//set_mods(mods);
if (is_shifted) { set_oneshot_mods(MOD_BIT(KC_LSFT)); }
invoke_key(letter, record);
return true;
}

View file

@ -0,0 +1,51 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#include "keymap.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RECENT_SIZE 8 // Number of keys in `recent` buffer.
extern uint16_t recent[RECENT_SIZE];
uint16_t deadline;
extern unsigned short int bkspc_countdown;
void clear_recent_keys(void);
void recent_keys_task(void);
uint16_t get_next_keycode(uint16_t keycode, keyrecord_t* record);
void store_keycode(uint16_t keycode, keyrecord_t* record);
void process_key(uint16_t keycode, keyrecord_t* record);
void invoke_key(uint16_t keycode, keyrecord_t* record);
bool replace_next_key(uint16_t keycode, keyrecord_t* record);
void process_word(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record);
bool finish_word(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record);
bool finish_magic(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record);
bool process_clever_keys(uint16_t keycode, keyrecord_t* record);
bool process_accent(uint16_t accent, uint16_t letter, keyrecord_t* record);
#ifdef __cplusplus
}
#endif

View file

@ -1,6 +1,21 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
//#include "combos.h"
#include "keymap.h" #include "keymap.h"
enum combos { enum combos {
@ -34,8 +49,8 @@ const uint16_t PROGMEM end_combo[] = {FR_EACU, FR_VIRG, COMBO_END};
const uint16_t PROGMEM help_combo[] = {FR_VIRG, FR_APOS, COMBO_END}; const uint16_t PROGMEM help_combo[] = {FR_VIRG, FR_APOS, COMBO_END};
const uint16_t PROGMEM panic_combo[] = {FR_EACU, FR_L, COMBO_END}; const uint16_t PROGMEM panic_combo[] = {FR_EACU, FR_L, COMBO_END};
const uint16_t PROGMEM numword_combo[] = {FR_S, FR_R, COMBO_END}; const uint16_t PROGMEM numword_combo[] = {FR_S, FR_R, COMBO_END};
const uint16_t PROGMEM alttab_combo[] = {LT_D, FR_Y, COMBO_END}; const uint16_t PROGMEM alttab_combo[] = {FR_D, FR_Y, COMBO_END};
const uint16_t PROGMEM ctrlalt_combo[] = {FR_A, FR_I, FR_T, COMBO_END}; const uint16_t PROGMEM ctrlaFR_Combo[] = {FR_A, FR_I, FR_T, COMBO_END};
combo_t key_combos[] = { combo_t key_combos[] = {
[R_BKSPC] = COMBO(bkspc_combo_d, KC_BSPC), [R_BKSPC] = COMBO(bkspc_combo_d, KC_BSPC),
@ -52,7 +67,7 @@ combo_t key_combos[] = {
[PANIC] = COMBO(panic_combo, RAZ), [PANIC] = COMBO(panic_combo, RAZ),
[NUMWRD] = COMBO(numword_combo, NUMWORD), [NUMWRD] = COMBO(numword_combo, NUMWORD),
[ALTTAB] = COMBO(alttab_combo, KC_NO), [ALTTAB] = COMBO(alttab_combo, KC_NO),
[CTRLALT] = COMBO(ctrlalt_combo, RCTL(RALT(KC_DEL))) [CTRLALT] = COMBO(ctrlaFR_Combo, RCTL(RALT(KC_DEL)))
}; };
/* uint16_t get_combo_term(uint16_t combo_index, combo_t *combo) { /* uint16_t get_combo_term(uint16_t combo_index, combo_t *combo) {
@ -106,7 +121,7 @@ bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key
case FR_Y: case FR_Y:
tap_code16(S(KC_TAB)); tap_code16(S(KC_TAB));
return true; return true;
case LT_D: case FR_D:
tap_code(KC_TAB); tap_code(KC_TAB);
return true; return true;
} }

View file

@ -1,24 +1,21 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "macros.h" #include "macros.h"
//bool is_alt_tab_active = false;
/* static bool process_swapper(uint16_t keycode) {
if (!is_alt_tab_active) {
is_alt_tab_active = true;
register_code(KC_LALT);
}
tap_code16(keycode);
return false;
} */
/* void swapper_task(void) {
if (is_alt_tab_active) {
if (IS_LAYER_OFF(_SHORTNAV)){
unregister_code(KC_LALT);
is_alt_tab_active = false;
}
}
} */
bool process_macros(uint16_t keycode, keyrecord_t *record) { bool process_macros(uint16_t keycode, keyrecord_t *record) {
//const uint8_t mods = get_mods(); //const uint8_t mods = get_mods();

View file

@ -1,3 +1,19 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "quantum.h" #include "quantum.h"

View file

@ -1,4 +1,4 @@
/* Copyright 2021 Joshua T. /* Copyright 2025 @Kawamashi
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -53,7 +53,7 @@ bool should_terminate_num_word(uint16_t keycode, const keyrecord_t *record) {
// Keycodes which should not disable num word mode. // Keycodes which should not disable num word mode.
// Numpad keycodes // Numpad keycodes
case KC_P1 ... KC_P0: case KC_1 ... KC_0:
case KC_PDOT: case KC_PDOT:
case FR_VIRG: case FR_VIRG:
case FR_MOIN: case FR_MOIN:
@ -61,7 +61,7 @@ bool should_terminate_num_word(uint16_t keycode, const keyrecord_t *record) {
case FR_PLUS: case FR_PLUS:
case FR_SLSH: case FR_SLSH:
case FR_ACIR: case FR_ACIR:
//case FR_CARN: case FR_CARN:
// Misc // Misc
case KC_BSPC: case KC_BSPC:

View file

@ -1,4 +1,4 @@
/* Copyright 2021 Joshua T. /* Copyright 2025 @Kawamashi
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View file

@ -1,3 +1,19 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os4a.h" #include "os4a.h"

View file

@ -1,3 +1,20 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "quantum.h" #include "quantum.h"

View file

@ -1,5 +1,20 @@
#include "tap_hold_utilities.h" /* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tap_hold_utilities.h"
void tap_converter(uint16_t keycode, keyrecord_t *record) { void tap_converter(uint16_t keycode, keyrecord_t *record) {
@ -8,9 +23,6 @@ void tap_converter(uint16_t keycode, keyrecord_t *record) {
// Instant OS4A processing // Instant OS4A processing
os4a_tap(keycode); os4a_tap(keycode);
/* } else if (keycode == LT_REPT) { // Je pense que dans les faits, cette ligne ne sert à rien.
repeat_key_invoke(&record->event); */
} else { } else {
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) { if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
// Tranform the record to send the tap event // Tranform the record to send the tap event

View file

@ -1,52 +1,17 @@
// Copyright 2022-2023 Google LLC /* Copyright 2025 @Kawamashi
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file achordion.h
* @brief Achordion: Customizing the tap-hold decision.
* *
* Overview * This program is free software: you can redistribute it and/or modify
* -------- * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* *
* This library customizes when tap-hold keys are considered held vs. tapped * This program is distributed in the hope that it will be useful,
* based on the next pressed key, like Manna Harbour's Bilateral Combinations or * but WITHOUT ANY WARRANTY; without even the implied warranty of
* ZMK's positional hold. The library works on top of QMK's existing tap-hold * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* implementation. You define mod-tap and layer-tap keys as usual and use * GNU General Public License for more details.
* Achordion to fine-tune the behavior.
* *
* When QMK settles a tap-hold key as held, Achordion intercepts the event. * You should have received a copy of the GNU General Public License
* Achordion then revises the event as a tap or passes it along as a hold: * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* * Chord condition: On the next key press, a customizable `achordion_chord()`
* function is called, which takes the tap-hold key and the next key pressed
* as args. When the function returns true, the tap-hold key is settled as
* held, and otherwise as tapped.
*
* * Timeout: If no other key press occurs within a timeout, the tap-hold key
* is settled as held. This is customizable with `achordion_timeout()`.
*
* Achordion only changes the behavior when QMK considered the key held. It
* changes some would-be holds to taps, but no taps to holds.
*
* @note Some QMK features handle events before the point where Achordion can
* intercept them, particularly: Combos, Key Lock, and Dynamic Macros. It's
* still possible to use these features and Achordion in your keymap, but beware
* they might behave poorly when used simultaneously with tap-hold keys.
*
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/achordion>
*/ */
#pragma once #pragma once

View file

@ -1,3 +1,19 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "features_conf.h" #include "features_conf.h"
bool is_caps_lock_on(void) { return host_keyboard_led_state().caps_lock; } bool is_caps_lock_on(void) { return host_keyboard_led_state().caps_lock; }
@ -8,7 +24,7 @@ bool isLetter(uint16_t keycode) {
case KC_Q ... KC_V: case KC_Q ... KC_V:
case KC_X ... KC_Z: case KC_X ... KC_Z:
case FR_E: case FR_E:
case KC_SCLN ... KC_DOT: case KC_NUHS ... KC_DOT:
return true; return true;
default: default:
@ -18,9 +34,6 @@ bool isLetter(uint16_t keycode) {
uint16_t tap_hold_extractor(uint16_t keycode) { uint16_t tap_hold_extractor(uint16_t keycode) {
switch (keycode) { switch (keycode) {
case ALGR_T(FR_E):
return FR_E;
default: default:
return keycode &= 0xff; return keycode &= 0xff;
} }
@ -54,7 +67,6 @@ bool caps_word_press_user(uint16_t keycode) {
case KC_BSPC: case KC_BSPC:
case KC_DEL: case KC_DEL:
case FR_APOS: case FR_APOS:
case FR_ACIR:
return true; return true;
default: default:
@ -148,6 +160,7 @@ bool is_oneshot_ignored_key(uint16_t keycode) {
case OS_FA: case OS_FA:
case NUMWORD: case NUMWORD:
case TT_FA: case TT_FA:
case FR_TYPO:
return true; return true;
default: default:
return false; return false;

View file

@ -1,3 +1,19 @@
/* Copyright 2025 @Kawamashi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include "quantum.h" #include "quantum.h"

View file

@ -156,7 +156,7 @@ bool forbidden_chord(uint16_t tap_hold_keycode, keyrecord_t* tap_hold_record, ui
bool first_of_chorded_mods(uint16_t keycode) { bool first_of_chorded_mods(uint16_t keycode) {
switch (keycode) { switch (keycode) {
case LT_TAB: // Pour pouvoir faire OSM shift + LT_TAB (win + shift + flèche). case LT_TAB: // Pour pouvoir faire OSM shift + LT_TAB (win + shift + flèche).
case LT_CCED: // Pour pouvoir faire Alt + F4, Alt + F11. case FR_CCED: // Pour pouvoir faire Alt + F4, Alt + F11.
case LCTL_T(FR_I): case LCTL_T(FR_I):
case RCTL_T(FR_T): case RCTL_T(FR_T):
case OSM(MOD_LSFT): // Pour pouvoir faire OSM shift + LT_TAB (win + shift + flèche). case OSM(MOD_LSFT): // Pour pouvoir faire OSM shift + LT_TAB (win + shift + flèche).
@ -236,7 +236,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT( [_BASE] = LAYOUT(
KC_ESC, FR_AGRV, FR_B, FR_EACU, FR_POIN, FR_MOIN, FR_ACIR, FR_V, FR_L, FR_M, FR_X, FR_W, KC_ESC, FR_AGRV, FR_B, FR_EACU, FR_POIN, FR_MOIN, FR_ACIR, FR_V, FR_L, FR_M, FR_X, FR_W,
KC_ENT, ALT_T(FR_O), SFT_T(FR_U), ALGR_T(FR_A), LCTL_T(FR_I), FR_J, FR_G, RCTL_T(FR_T), ALGR_T(FR_S), RSFT_T(FR_N), ALT_T(FR_R), FR_F, KC_ENT, ALT_T(FR_O), SFT_T(FR_U), ALGR_T(FR_A), LCTL_T(FR_I), FR_J, FR_G, RCTL_T(FR_T), ALGR_T(FR_S), RSFT_T(FR_N), ALT_T(FR_R), FR_F,
LT_TAB, FR_Q, FR_Y, FR_EGRV, LWIN_T(FR_P), FR_DQUO, KC_BSPC, KC_END, KC_HOME, KC_DEL, FR_K, RWIN_T(FR_D), FR_Z, FR_H, FR_C, LT_CCED, LT_TAB, FR_Q, FR_Y, FR_EGRV, LWIN_T(FR_P), FR_DQUO, KC_BSPC, KC_END, KC_HOME, KC_DEL, FR_K, RWIN_T(FR_D), FR_Z, FR_H, FR_C, FR_CCED,
TG(_SYMBOLS), KC_SPC, OSM(MOD_LSFT), LT(_SYMBOLS,FR_E), LT_VIRG, LT_APOS, LT(_SYMBOLS,KC_SPC), OSM(MOD_RSFT), KC_RGUI, KC_MUTE TG(_SYMBOLS), KC_SPC, OSM(MOD_LSFT), LT(_SYMBOLS,FR_E), LT_VIRG, LT_APOS, LT(_SYMBOLS,KC_SPC), OSM(MOD_RSFT), KC_RGUI, KC_MUTE
), ),

View file

@ -1,4 +1,4 @@
/* Copyright 2019 Thomas Baart <thomas@splitkb.com> /* Copyright 2025 @Kawamashi
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,6 +13,8 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "keymap.h" #include "keymap.h"
@ -38,7 +40,8 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
if (record->event.key.col != next_record.event.key.col) { if (record->event.key.col != next_record.event.key.col) {
// J'avais mis cette ligne pour faire les "". Je pense que ce n'est plus nécessaire maintenant que que // La ligne suivante n'est nécessaire que si on a besoin de doubler rapidement un caractère présent sur la moitié droite du clavier.
// Ce n'est pas nécessaire pour l'instant, vu que les guillemets sont passés à gauche.
//if (keycode == OS_TYPO) { return true; } //if (keycode == OS_TYPO) { return true; }
if (forbidden_chord(keycode, record, next_keycode, &next_record)) { if (forbidden_chord(keycode, record, next_keycode, &next_record)) {
@ -49,9 +52,9 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
return false; return false;
} }
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { /* bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
return !forbidden_chord(keycode, record, next_keycode, &next_record); return !forbidden_chord(keycode, record, next_keycode, &next_record);
} } */
// Matrix scan // Matrix scan
@ -162,7 +165,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT( [_BASE] = LAYOUT(
KC_NO, FR_X, FR_VIRG, FR_EACU, FR_P, FR_B, FR_F, FR_M, FR_L, FR_APOS, FR_POIN, KC_NO, KC_NO, FR_X, FR_VIRG, FR_EACU, FR_P, FR_B, FR_F, FR_M, FR_L, FR_APOS, FR_POIN, KC_NO,
KC_NO, FR_O, FR_A, FR_I, FR_T, FR_G, FR_V, FR_S, FR_N, FR_R, FR_U, KC_NO, KC_NO, FR_O, FR_A, FR_I, FR_T, FR_G, FR_V, FR_S, FR_N, FR_R, FR_U, KC_NO,
KC_NO, FR_Q, FR_Z, FR_Y, LT_D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, LT_C, FR_H, FR_W, OS_TYPO, KC_NO, KC_NO, FR_Q, FR_Z, FR_Y, FR_D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, FR_C, FR_H, FR_W, OS_TYPO, KC_NO,
KC_NO, KC_SPC, L_OS4A, LT_E, LT_MGC, LT_REPT, LT_SPC, R_OS4A, KC_RGUI, KC_NO KC_NO, KC_SPC, L_OS4A, LT_E, LT_MGC, LT_REPT, LT_SPC, R_OS4A, KC_RGUI, KC_NO
), ),
@ -203,7 +206,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/ */
[_R_MODS] = LAYOUT( [_R_MODS] = LAYOUT(
_______, _______, _______, _______, _______, _______, KC_NO, KC_RGUI, OS_WIN, KC_NO, KC_NO, KC_NO, _______, _______, _______, _______, _______, _______, KC_NO, KC_RGUI, OS_WIN, KC_NO, KC_NO, KC_NO,
_______, _______, _______, _______, _______, _______, TT_FA, OS_SHFT, OS_CTRL, NUMWORD, OS_TYPO, KC_NO, _______, _______, _______, _______, _______, _______, TT_FA, OS_SHFT, OS_CTRL, NUMWORD, FR_TYPO, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, OS_FA, OS_LALT, KC_NO, _______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, OS_FA, OS_LALT, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO _______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO
), ),
@ -245,7 +248,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/ */
[_NUMBERS] = LAYOUT( [_NUMBERS] = LAYOUT(
_______, _______, FR_ASTX, FR_EGAL, _______, S(FR_ACIR), KC_6, _______, FR_PLUS, FR_MOIN, _______, _______, _______, _______, FR_ASTX, FR_EGAL, _______, S(FR_ACIR), KC_6, _______, FR_PLUS, FR_MOIN, _______, _______,
_______, KC_8, KC_6, KC_4, KC_2, FR_CARN, _______, KC_1, KC_3, KC_5, KC_7, _______, _______, KC_8, KC_6, KC_4, KC_2, FR_CARN, _______, KC_1, KC_3, KC_5, KC_7, _______,
_______, _______, _______, _______, FR_SLSH, _______, _______, _______, _______, _______, _______, KC_9, _______, _______, _______, _______, _______, _______, _______, _______, FR_SLSH, _______, _______, _______, _______, _______, _______, KC_9, _______, _______, _______, _______,
_______, _______, FR_VIRG, KC_0 , NUMWORD, LT_REPT, KC_SPC, KC_PDOT, _______, _______ _______, _______, FR_VIRG, KC_0 , NUMWORD, LT_REPT, KC_SPC, KC_PDOT, _______, _______
), ),
@ -288,7 +291,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_TYPO] = LAYOUT( [_TYPO] = LAYOUT(
_______, _______, _______, _______, _______, FR_J, FR_K, FR_F, FR_D, _______, _______, _______, _______, _______, _______, _______, _______, FR_J, FR_K, FR_F, FR_D, _______, _______, _______,
_______, OU_GRV, _______, _______, _______, _______, FR_M, FR_J, FR_L, FR_AROB, _______, _______, _______, OU_GRV, _______, _______, _______, _______, FR_M, FR_J, FR_L, FR_AROB, _______, _______,
_______, _______, _______, _______, CA_CED, _______, _______, _______, _______, _______, _______, _______, _______, FR_K, TG_ACC, _______, _______, _______, _______, _______, CA_CED, _______, _______, _______, _______, _______, _______, _______, _______, FR_K, TG_TYPO, _______,
_______, _______, _______, _______, FR_O, _______, AGRV_SPC, _______, _______, _______ _______, _______, _______, _______, FR_O, _______, AGRV_SPC, _______, _______, _______
), ),

View file

@ -1,4 +1,4 @@
/* Copyright 2019 Thomas Baart <thomas@splitkb.com> /* Copyright 2025 @Kawamashi
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,16 +13,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "keymap_french_frgo.h" #include "keymap_french_frgo.h"
#include "features_conf.h" #include "features_conf.h"
#include "clever_keys.h"
#include "features/custom_altgr_keys.h" #include "features/custom_altgr_keys.h"
#include "features/tap_hold_utilities.h" #include "features/tap_hold_utilities.h"
#include "features/next_keycode.h" #include "features/clever_keys_utilities.h"
#include "features/clever_keys.h"
#include "features/numword.h" #include "features/numword.h"
#include "features/macros.h" #include "features/macros.h"
#include "features/os4a.h" #include "features/os4a.h"
@ -44,8 +45,6 @@ enum custom_keycodes {
NUMWORD = SAFE_RANGE, NUMWORD = SAFE_RANGE,
FEN_B, FEN_B,
COPY, COPY,
/* ALT_TAB,
REV_TAB, */
AIDE_MEM, AIDE_MEM,
OS4A, OS4A,
RAZ, RAZ,
@ -75,13 +74,10 @@ enum custom_keycodes {
#define LT_E ALGR_T(FR_E) #define LT_E ALGR_T(FR_E)
#define LT_REPT LT(_NUMBERS, KC_0) #define LT_REPT LT(_NUMBERS, KC_0)
#define LT_MGC LT(_SHORTNAV, KC_0) #define LT_MGC LT(_SHORTNAV, KC_0)
#define LT_D FR_D
#define LT_C FR_C
#define LT_VIRG LT(_SHORTNAV, FR_VIRG)
#define OS_TYPO OSL(_TYPO) #define OS_TYPO OSL(_TYPO)
#define OS_FA OSL(_FUNCAPPS) #define OS_FA OSL(_FUNCAPPS)
#define TT_FA TT(_FUNCAPPS) #define TT_FA TT(_FUNCAPPS)
#define TG_ACC TG(_TYPO) #define TG_TYPO TG(_TYPO)
// One shot mods // One shot mods
#define L_OS4A LSFT_T(OS4A) #define L_OS4A LSFT_T(OS4A)

View file

@ -1,4 +1,4 @@
/* Copyright 2020 @frogm0uth /* Copyright 2025 @Kawamashi
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -6,23 +6,19 @@
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty ofo * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "keymap.h" #include "keymap.h"
/* The default OLED and rotary encoder code can be found at the bottom of qmk_firmware/keyboards/splitkb/kyria/rev1/rev1.c
* These default settings can be overriden by your own settings in your keymap.c
* For your convenience, here's a copy of those settings so that you can uncomment them if you wish to apply your own modifications.
* DO NOT edit the rev1.c file; instead override the weakly defined default functions by your own.
*/
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; } oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; }

View file

@ -21,16 +21,15 @@ DEFERRED_EXEC_ENABLE = no
KEY_OVERRIDE_ENABLE = no KEY_OVERRIDE_ENABLE = no
CAPS_WORD_ENABLE = yes CAPS_WORD_ENABLE = yes
COMBO_ENABLE = yes COMBO_ENABLE = yes
#LAYER_LOCK_ENABLE = yes
REPEAT_KEY_ENABLE = yes REPEAT_KEY_ENABLE = yes
SRC += features/tap_hold_utilities.c SRC += features/tap_hold_utilities.c
SRC += features/os4a.c SRC += features/os4a.c
SRC += features/custom_altgr_keys.c #SRC += features/custom_altgr_keys.c
#SRC += encoder.c #SRC += encoder.c
SRC += oled.c SRC += oled.c
SRC += features/next_keycode.c SRC += features/clever_keys_utilities.c
SRC += features/clever_keys.c SRC += clever_keys.c
SRC += features/numword.c SRC += features/numword.c
SRC += features/macros.c SRC += features/macros.c
SRC += features/oneshot.c SRC += features/oneshot.c