Caps List initial commit

This commit is contained in:
Kawamashi 2025-08-28 23:22:09 +02:00
commit d31eef7e68
94 changed files with 161 additions and 10305 deletions

View file

@ -1,132 +0,0 @@
/* 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

@ -1,260 +0,0 @@
// 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(ALGR(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_ACIR, FR_E, 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"
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);
}
}
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:
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);
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

@ -1,17 +0,0 @@
#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,221 +0,0 @@
// 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

@ -1,115 +0,0 @@
#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

@ -1,79 +0,0 @@
// Copyright 2021-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 custom_shift_keys.c
* @brief Custom Shift Keys implementation
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/custom-shift-keys>
*/
#include "custom_altgr_keys.h"
#include "keymap.h"
bool process_custom_altgr_keys(uint16_t keycode, keyrecord_t *record) {
static uint16_t registered_keycode = KC_NO;
// If a custom shift key is registered, then this event is either releasing
// it or manipulating another key at the same time. Either way, we release
// the currently registered key.
if (registered_keycode != KC_NO) {
unregister_code16(registered_keycode);
registered_keycode = KC_NO;
}
if (record->event.pressed) { // Press event.
const uint8_t mods = get_mods();
#ifndef NO_ACTION_ONESHOT
if ((mods | get_weak_mods() | get_oneshot_mods()) & MOD_BIT(KC_ALGR)) {
#else
if ((mods | get_weak_mods()) & MOD_BIT(KC_ALGR)) { // altgr is held.
#endif // NO_ACTION_ONESHOT
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
// Continue default handling if this is a tap-hold key being held.
if (record->tap.count == 0) { return true; }
//keycode = tap_hold_extractor(keycode);
}
// On remplace les mod-tap par le keycode du tap.
//if (IS_QK_MOD_TAP(keycode)) { keycode &= 0xff; }
// Search for a custom altgr key whose keycode is `keycode`.
for (int i = 0; i < NUM_CUSTOM_ALTGR_KEYS; ++i) {
if (keycode == custom_altgr_keys[i].keycode) {
registered_keycode = custom_altgr_keys[i].altgr_keycode;
if (IS_QK_MODS(registered_keycode) && // Does keycode need alt-gr ?
(QK_MODS_GET_MODS(registered_keycode) & MOD_RALT) != 0) {
register_code16(registered_keycode); // If so, press it directly.
} else {
// Otherwise cancel shift mods, press the key, and restore mods.
del_weak_mods(MOD_BIT(KC_ALGR));
#ifndef NO_ACTION_ONESHOT
del_oneshot_mods(MOD_BIT(KC_ALGR));
#endif // NO_ACTION_ONESHOT
unregister_mods(MOD_BIT(KC_ALGR));
register_code16(registered_keycode);
set_mods(mods);
}
return false;
}
}
}
}
return true; // Continue with default handling.
}

View file

@ -1,100 +0,0 @@
// Copyright 2021-2022 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 custom_shift_keys.h
* @brief Custom shift keys: customize what keycode is produced when shifted.
*
* Overview
* --------
*
* This library implements custom shift keys, keys where you can customize
* what keycode is produced when shifted.
*
* Step 1: In your keymap.c, define a table of custom shift keys like
*
* #include "features/custom_shift_keys.h"
*
* const custom_shift_key_t custom_shift_keys[] = {
* {KC_DOT , KC_QUES}, // Shift . is ?
* {KC_COMM, KC_EXLM}, // Shift , is !
* {KC_MINS, KC_EQL }, // Shift - is =
* {KC_COLN, KC_SCLN}, // Shift : is ;
* };
*
* Each row defines one key. The first field is the keycode as it appears in
* your layout and determines what is typed normally. The second entry is what
* you want the key to type when shifted.
*
* Step 2: Handle custom shift keys from your `process_record_user` function as
*
* bool process_record_user(uint16_t keycode, keyrecord_t* record) {
* if (!process_custom_shift_keys(keycode, record)) { return false; }
* // Your macros ...
*
* return true;
* }
*
* Step 3: add `features/custom_shift_keys.c` to your rules.mk as
*
* SRC += features/custom_shift_keys.c
*
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/custom-shift-keys>
*/
#pragma once
#include "quantum.h"
#include "keymap.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Custom shift key entry. The `keycode` field is the keycode as it appears in
* your layout and determines what is typed normally. The `shifted_keycode` is
* what you want the key to type when shifted.
*/
typedef struct {
uint16_t keycode;
uint16_t altgr_keycode;
} custom_altgr_key_t;
/** Table of custom shift keys. */
extern const custom_altgr_key_t custom_altgr_keys[];
/** Number of entries in the `custom_shift_keys` table. */
extern uint8_t NUM_CUSTOM_ALTGR_KEYS;
/**
* Handler function for custom shift keys.
*
* In keymap.c, call this function from your `process_record_user` function as
*
* #include "features/custom_shift_keys.h"
*
* bool process_record_user(uint16_t keycode, keyrecord_t* record) {
* if (!process_custom_shift_keys(keycode, record)) { return false; }
* // Your macros ...
*
* return true;
* }
*/
bool process_custom_altgr_keys(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}
#endif

View file

@ -1,74 +0,0 @@
#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 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

@ -1,15 +0,0 @@
#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

@ -1,168 +0,0 @@
// Remembering recent keys
#include "next_keycode.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

@ -1,38 +0,0 @@
#pragma once
#include "quantum.h"
#include "keymap.h"
//#include "features_conf.h"
//#include <string.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,123 +0,0 @@
/* 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

@ -1,29 +0,0 @@
/* 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

@ -1,52 +0,0 @@
#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

@ -1,31 +0,0 @@
#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

@ -1,99 +0,0 @@
#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

@ -1,31 +0,0 @@
#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

@ -1,81 +0,0 @@
#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

@ -1,71 +0,0 @@
// 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

@ -1,184 +0,0 @@
#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_L:
case FR_M:
case KC_N ... KC_Z:
case FR_AGRV:
case FR_EACU:
case FR_EGRV:
case FR_CCED:
case ALGR(FR_U):
return true;
default:
return false;
}
}
uint16_t tap_hold_extractor(uint16_t keycode) {
switch (keycode) {
/* case LT_REPT:
return REPEAT;
case LT_MGC:
return MAGIC; */
default:
return keycode &= 0xff;
}
}
// Caps Word
bool caps_word_press_user(uint16_t keycode) {
//if (IS_LAYER_ON(_ACCENTS) && keycode == FR_A) { return false; }
// 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_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:
case OS_SN:
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 qu'un tréma 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_ACC && (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR)))) { return true;}
switch (keycode) {
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 OS_SN:
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

@ -1,13 +0,0 @@
#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

@ -1,326 +0,0 @@
/* 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

@ -1,338 +0,0 @@
/* 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_ACC) { 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(_ACCENTS) && record->event.pressed) {
tap_code16(FR_TREM); // Tap Ctrl+A.
} */
// 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_ACC, 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, OS_SN, 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_RALT, 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, _______, FR_ACIR, _______, _______, FR_PLUS, FR_MOIN, _______, _______,
_______, KC_P8, KC_P6, KC_P4, KC_P2, FR_CARN, _______, KC_P1, KC_P3, KC_P5, KC_P7, _______,
_______, _______, _______, _______, FR_SLSH, _______, _______, _______, _______, _______, _______, KC_P9, _______, _______, _______, _______,
_______, _______, FR_VIRG, KC_P0 , 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 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_ACCENTS] = LAYOUT(
_______, O_CIRC, A_CIRC, I_CIRC, U_CIRC, FR_LDAQ , FR_RDAQ, FR_3PTS, FR_MOIN, FR_APOS, FR_POIN, _______,
_______, OU_GRV, FR_AGRV, FR_MOIN, FR_DQUO, ALGR(FR_G), FR_SS, FR_J, FR_A, FR_AROB, _______, _______,
_______, FR_OE, FR_AE, I_TREM, CA_CED, _______ , _______, _______, _______, _______, _______, FR_CCED, FR_TREM, FR_K, TG_ACC, _______,
_______, _______, _______ , FR_EGRV, E_CIRC, _______, 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

@ -1,99 +0,0 @@
/* 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,
_SYMBOLS,
_NUMBERS,
_ACCENTS,
_SHORTNAV,
_FUNCAPPS,
//_NUMPAD
};
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 LT(_SYMBOLS,KC_SPC)
#define LT_E LT(_SYMBOLS,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_ACC OSL(_ACCENTS)
#define OS_FA OSL(_FUNCAPPS)
#define OS_SN OSL(_SHORTNAV)
#define TT_FA TT(_FUNCAPPS)
#define TG_ACC TG(_ACCENTS)
// 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

@ -1,253 +0,0 @@
/* Copyright 2020 Guillaume Gérard
*
* 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/>.
*/
/* French AZERTY - AFNOR NF Z71-300
*
* A standard for the French keyboard
*
* The project was launched at the end of 2015 on the proposal of the General
* Delegation for the French language and the languages of France (Ministry
* of Culture), starting from the observation that the current "azerty"
* keyboards constrain the writing of French, languages regional and European
* languages with Latin alphabet.
*
* For the first time, a standard (NF Z71-300) defines the placement of
* characters on the French keyboard. It offers two layouts, one of which
* closely follows the QWERTY keyboard used by most people who write in French.
*
* However, it is in many ways superior to the old keyboard:
*
* - it contains all the characters required to enter text in French (for example É, œ and ")
* - it is designed to be more ergonomic and allow faster typing
* - it includes almost 60 additional characters for entering foreign languages, technical content, etc
* - however, the characters remain easy to locate thanks to intuitive groupings
*
* Source: https://norme-azerty.fr
*/
#pragma once
#include "keycodes.h"
//#include "keymap.h"
// clang-format off
/*
*
*  @  à  é  è  &  (  )  ç    «  »  '  ^        
*
*       A  Z  E  R  T  Y  U  I  O  P  -  +      
*     
*        Q  S  D  F  G  H  J  K  L  M  /  *     
*
*      <  W  X  C  V  B  N  .  ,  " │ = │          │
*
*                                                     
*
*/
// Row 1
#define FR_AROB KC_GRV // @
#define FR_AGRV KC_1 // à
#define FR_EACU KC_2 // é
#define FR_EGRV KC_3 // è
#define FR_ESPR KC_4 // &
#define FR_LPRN KC_5 // (
#define FR_RPRN KC_6 // )
#define FR_CCED KC_7 // ç
#define FR_RSQU KC_8 //
#define FR_LDAQ KC_9 // «
#define FR_RDAQ KC_0 // »
#define FR_APOS KC_MINS // '
#define FR_ACIR KC_EQL // ^ (dead)
// Row 2
#define FR_A KC_Q // A
#define FR_Z KC_W // Z
#define FR_E KC_E // E
#define FR_R KC_R // R
#define FR_T KC_T // T
#define FR_Y KC_Y // Y
#define FR_U KC_U // U
#define FR_I KC_I // I
#define FR_O KC_O // O
#define FR_P KC_P // P
#define FR_MOIN KC_LBRC // -
#define FR_PLUS KC_RBRC // +
// Row 3
#define FR_Q KC_A // Q
#define FR_S KC_S // S
#define FR_D KC_D // D
#define FR_F KC_F // F
#define FR_G KC_G // G
#define FR_H KC_H // H
#define FR_J KC_J // J
#define FR_K KC_K // K
#define FR_L KC_L // L
#define FR_M KC_SCLN // M
#define FR_SLSH KC_QUOT // /
#define FR_ASTX KC_NUHS // *
// Row 4
#define FR_INF KC_NUBS // <
#define FR_W KC_Z // W
#define FR_X KC_X // X
#define FR_C KC_C // C
#define FR_V KC_V // V
#define FR_B KC_B // B
#define FR_N KC_N // N
#define FR_POIN KC_M // .
#define FR_VIRG KC_COMM // ,
#define FR_DQUO KC_DOT // ""
#define FR_EGAL KC_SLSH // =
/* Shifted symbols
*
*  #  À  É  È  °  [  ]  Ç  8  9  0  ?  ¨        
*
*                                       ±      
*     
*                                      \  ½     
*
*      >                    :  !               
*
*                                                     
*
*/
// Row 1
#define FR_HASH S(FR_AROB) // #
//#define FR_1 S(FR_AGRV) // 1
//#define FR_2 S(FR_EACU) // 2
//#define FR_3 S(FR_EGRV) // 3
#define FR_DEG S(FR_ESPR) // 4
#define FR_LBKT S(FR_LPRN) // 5
#define FR_RBKT S(FR_RPRN) // 6
//#define FR_7 S(FR_CCED) // 7
#define FR_8 S(FR_RSQU) // 8
#define FR_9 S(FR_LDAQ) // 9
#define FR_0 S(FR_RDAQ) // 0
#define FR_QUES S(FR_APOS) // ?
#define FR_TREM S(FR_ACIR) // ¨ (dead)
// Row 2
#define FR_NDSH S(FR_MOIN) //
#define FR_PLMN S(FR_PLUS) // ±
// Row 3
#define FR_BSLS S(FR_SLSH) // (backslash)
#define FR_HALF S(FR_ASTX) // ½
// Row 4
#define FR_SUP S(FR_INF) // >
#define FR_2PTS S(FR_POIN) // :
#define FR_EXLM S(FR_VIRG) // !
//#define FR_3PTS S(FR_DQUO) // …
#define FR_DIFF S(FR_EGAL) // ≠
/* AltGr symbols
*
*  ˘  §  ´  `     {  }  ¯  _      ˚  ˇ        
*
*       æ  £    ®  {  }  ù  ˙  œ  %          
*     
*        θ  ß  $  ¤  µ  Eu      |    ÷  ×     
*
*        ʒ  ©  ç  ¸    ~    ;  ·             
*
*                                                     
*
*/
// Row 1
#define FR_BREV ALGR(FR_AROB) // ˘ (dead)
#define FR_SECT ALGR(FR_AGRV) // §
#define FR_ACUT ALGR(FR_EACU) // ´ (dead)
#define FR_GRV ALGR(FR_EGRV) // ` (dead)
//#define FR_AMPR ALGR(FR_ESPR) // &
#define FR_LACL ALGR(FR_LPRN) // {
#define FR_RACL ALGR(FR_RPRN) // }
#define FR_MACR ALGR(FR_CCED) // ¯ (dead)
#define FR_UNDS ALGR(FR_RSQU) // _
#define FR_LDQU ALGR(FR_LDAQ) // “
#define FR_RDQU ALGR(FR_RDAQ) // ”
#define FR_RNGA ALGR(FR_APOS) // ˚ (dead)
#define FR_CARN ALGR(FR_ACIR) // ˇ (dead)
// Row 2
#define FR_AE ALGR(FR_A) // æ
#define FR_PND ALGR(FR_Z) // £
#define FR_EURO ALGR(FR_E) // €
#define FR_REGD ALGR(FR_R) // ®
#define FR_LCBR ALGR(FR_T) // {
#define FR_RCBR ALGR(FR_Y) // }
#define FR_UGRV ALGR(FR_U) // ù
#define FR_DOTA ALGR(FR_I) // ˙ (dead)
#define FR_OE ALGR(FR_O) // œ
#define FR_PERC ALGR(FR_P) // %
#define FR_MMNS ALGR(FR_MOIN) //
#define FR_DAGG ALGR(FR_PLUS) // †
// Row 3
#define FR_THET ALGR(FR_Q) // θ
#define FR_SS ALGR(FR_S) // ß
#define FR_DLR ALGR(FR_D) // $
#define FR_CURR ALGR(FR_F) // ¤ (dead monetary key)
#define FR_DGRK ALGR(FR_G) // µ (dead Greek key)
#define FR_EU ALGR(FR_H) // Eu (dead European symbol key)
#define FR_DSLS ALGR(FR_K) // (dead)
#define FR_PIPE ALGR(FR_L) // |
#define FR_INFN ALGR(FR_M) // ∞
#define FR_DIV ALGR(FR_SLSH) // ÷
#define FR_MUL ALGR(FR_ASTX) // ×
// Row 4
#define FR_LEQL ALGR(FR_INF) // ≤
#define FR_EZH ALGR(FR_W) // ʒ
#define FR_COPY ALGR(FR_X) // ©
//#define FR_CCED ALGR(FR_C) // ç
#define FR_CEDL ALGR(FR_V) // ¸ (dead)
#define FR_DMNS ALGR(FR_B) // (dead)
#define FR_TILD ALGR(FR_N) // ~ (dead)
#define FR_3PTS ALGR(FR_POIN) // ¿
#define FR_PVIR ALGR(FR_VIRG) // ;
#define FR_MDDT ALGR(FR_DQUO) // ·
#define FR_AEQL ALGR(FR_EGAL) // ≃
/* Shift+AltGr symbols
*
*   ̑              ˝   ̏           ¿           
*
*                            ̣               
*     
*                       ˍ                ¼     
*
*                 ˛           ¡                
*
*                                                     
*
*/
// 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

@ -1,164 +0,0 @@
/* 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 _ACCENTS:
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

@ -1,249 +0,0 @@
# 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

@ -1,43 +0,0 @@
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

@ -1,132 +0,0 @@
/* 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

@ -1,269 +0,0 @@
// 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(ALGR(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

@ -1,17 +0,0 @@
#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,221 +0,0 @@
// 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

@ -1,115 +0,0 @@
#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

@ -1,79 +0,0 @@
// Copyright 2021-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 custom_shift_keys.c
* @brief Custom Shift Keys implementation
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/custom-shift-keys>
*/
#include "custom_altgr_keys.h"
#include "keymap.h"
bool process_custom_altgr_keys(uint16_t keycode, keyrecord_t *record) {
static uint16_t registered_keycode = KC_NO;
// If a custom shift key is registered, then this event is either releasing
// it or manipulating another key at the same time. Either way, we release
// the currently registered key.
if (registered_keycode != KC_NO) {
unregister_code16(registered_keycode);
registered_keycode = KC_NO;
}
if (record->event.pressed) { // Press event.
const uint8_t mods = get_mods();
#ifndef NO_ACTION_ONESHOT
if ((mods | get_weak_mods() | get_oneshot_mods()) & MOD_BIT(KC_ALGR)) {
#else
if ((mods | get_weak_mods()) & MOD_BIT(KC_ALGR)) { // altgr is held.
#endif // NO_ACTION_ONESHOT
if (IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode)) {
// Continue default handling if this is a tap-hold key being held.
if (record->tap.count == 0) { return true; }
//keycode = tap_hold_extractor(keycode);
}
// On remplace les mod-tap par le keycode du tap.
//if (IS_QK_MOD_TAP(keycode)) { keycode &= 0xff; }
// Search for a custom altgr key whose keycode is `keycode`.
for (int i = 0; i < NUM_CUSTOM_ALTGR_KEYS; ++i) {
if (keycode == custom_altgr_keys[i].keycode) {
registered_keycode = custom_altgr_keys[i].altgr_keycode;
if (IS_QK_MODS(registered_keycode) && // Does keycode need alt-gr ?
(QK_MODS_GET_MODS(registered_keycode) & MOD_RALT) != 0) {
register_code16(registered_keycode); // If so, press it directly.
} else {
// Otherwise cancel shift mods, press the key, and restore mods.
del_weak_mods(MOD_BIT(KC_ALGR));
#ifndef NO_ACTION_ONESHOT
del_oneshot_mods(MOD_BIT(KC_ALGR));
#endif // NO_ACTION_ONESHOT
unregister_mods(MOD_BIT(KC_ALGR));
register_code16(registered_keycode);
set_mods(mods);
}
return false;
}
}
}
}
return true; // Continue with default handling.
}

View file

@ -1,100 +0,0 @@
// Copyright 2021-2022 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 custom_shift_keys.h
* @brief Custom shift keys: customize what keycode is produced when shifted.
*
* Overview
* --------
*
* This library implements custom shift keys, keys where you can customize
* what keycode is produced when shifted.
*
* Step 1: In your keymap.c, define a table of custom shift keys like
*
* #include "features/custom_shift_keys.h"
*
* const custom_shift_key_t custom_shift_keys[] = {
* {KC_DOT , KC_QUES}, // Shift . is ?
* {KC_COMM, KC_EXLM}, // Shift , is !
* {KC_MINS, KC_EQL }, // Shift - is =
* {KC_COLN, KC_SCLN}, // Shift : is ;
* };
*
* Each row defines one key. The first field is the keycode as it appears in
* your layout and determines what is typed normally. The second entry is what
* you want the key to type when shifted.
*
* Step 2: Handle custom shift keys from your `process_record_user` function as
*
* bool process_record_user(uint16_t keycode, keyrecord_t* record) {
* if (!process_custom_shift_keys(keycode, record)) { return false; }
* // Your macros ...
*
* return true;
* }
*
* Step 3: add `features/custom_shift_keys.c` to your rules.mk as
*
* SRC += features/custom_shift_keys.c
*
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/custom-shift-keys>
*/
#pragma once
#include "quantum.h"
#include "keymap.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Custom shift key entry. The `keycode` field is the keycode as it appears in
* your layout and determines what is typed normally. The `shifted_keycode` is
* what you want the key to type when shifted.
*/
typedef struct {
uint16_t keycode;
uint16_t altgr_keycode;
} custom_altgr_key_t;
/** Table of custom shift keys. */
extern const custom_altgr_key_t custom_altgr_keys[];
/** Number of entries in the `custom_shift_keys` table. */
extern uint8_t NUM_CUSTOM_ALTGR_KEYS;
/**
* Handler function for custom shift keys.
*
* In keymap.c, call this function from your `process_record_user` function as
*
* #include "features/custom_shift_keys.h"
*
* bool process_record_user(uint16_t keycode, keyrecord_t* record) {
* if (!process_custom_shift_keys(keycode, record)) { return false; }
* // Your macros ...
*
* return true;
* }
*/
bool process_custom_altgr_keys(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}
#endif

View file

@ -1,81 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,168 +0,0 @@
// Remembering recent keys
#include "next_keycode.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

@ -1,38 +0,0 @@
#pragma once
#include "quantum.h"
#include "keymap.h"
//#include "features_conf.h"
//#include <string.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,123 +0,0 @@
/* 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

@ -1,29 +0,0 @@
/* 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

@ -1,52 +0,0 @@
#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

@ -1,31 +0,0 @@
#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

@ -1,99 +0,0 @@
#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

@ -1,31 +0,0 @@
#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

@ -1,81 +0,0 @@
#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

@ -1,71 +0,0 @@
// 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

@ -1,183 +0,0 @@
#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

@ -1,13 +0,0 @@
#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

@ -1,326 +0,0 @@
/* 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

@ -1,358 +0,0 @@
/* 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

@ -1,96 +0,0 @@
/* 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

@ -1,207 +0,0 @@
/* 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

@ -1,164 +0,0 @@
/* 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

@ -1,249 +0,0 @@
# 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

@ -1,43 +0,0 @@
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

@ -1,269 +0,0 @@
/* 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"
void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
uint16_t prev_keycode = recent[RECENT_SIZE - 1];
if (isLetter(*next_keycode) || isSendStringMacro(*next_keycode)) {
switch (prev_keycode) {
case FG_EXLM:
case FG_QUES:
case FG_3PTS:
case FG_2PTS:
// Add space between punctuation and letters.
invoke_key(KC_SPC, record);
set_last_keycode(*next_keycode);
case KC_SPC:
switch (recent[RECENT_SIZE - 2]) {
case FG_EXLM:
case FG_QUES:
case FG_3PTS:
case FG_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 FG_Q:
switch (*next_keycode) {
// Ajout automatique du "u" après le "q"
case FG_E:
case FG_I:
case FG_A:
case FG_O:
case FG_EACU:
case FG_APOS:
invoke_key(FG_U, record);
set_last_keycode(*next_keycode);
break;
// Raccourci pour "quelq"
case FG_Q:
process_word((uint16_t[]) {FG_U, FG_E, FG_L}, 3, record);
break;
// Raccourci pour "quoi", ça évite un aller-retour sur la main gauche.
case FG_Z:
finish_word((uint16_t[]) {FG_U, FG_O, FG_I}, 3, next_keycode, record);
break;
// Raccourci pour "quand"
case FG_D:
process_word((uint16_t[]) {FG_U, FG_A, FG_N}, 3, record);
set_last_keycode(*next_keycode);
break;
}
break;
case FG_P:
switch (*next_keycode) {
case FG_M:
// "pas"
return finish_word((uint16_t[]) {FG_A, FG_S}, 2, next_keycode, record);
case FG_APOS:
// "par"
return finish_word((uint16_t[]) {FG_A, FG_R}, 2, next_keycode, record);
case FG_POIN:
if (!isLetter(recent[RECENT_SIZE - 2])) {
// "pour"
return finish_word((uint16_t[]) {FG_O, FG_U, FG_R}, 3, next_keycode, record);
}
break;
}
break;
/* case FG_CCED:
if (!isLetter(*next_keycode)) {
invoke_key(FG_A, record);
set_last_keycode(*next_keycode);
}
break; */
}
switch (*next_keycode) {
case FG_QUES:
case FG_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])) {
invoke_key(KC_SPC, record);
return replace_ongoing_key(*next_keycode, next_keycode, record);
}
break;
case MAGIC:
switch (prev_keycode) {
case FG_U:
bkspc_countdown = 0;
return replace_ongoing_key(FG_I, next_keycode, record);
case FG_EACU:
bkspc_countdown = 0;
return replace_ongoing_key(FG_I, next_keycode, record);
case FG_VIRG:
// éa SFB
bkspc_countdown = 0;
return replace_ongoing_key(FG_A, next_keycode, record);
case FG_S:
invoke_key(FG_I, record);
case FG_I:
return finish_word((uint16_t[]) {FG_O, FG_T}, 2, next_keycode, record);
//return finish_word((uint16_t[]) {FG_O, FG_N}, 2, next_keycode, record);
case FG_C:
return finish_word((uint16_t[]) {FG_APOS, FG_E, FG_S, FG_T}, 4, next_keycode, record);
case FG_D:
return finish_word((uint16_t[]) {FG_A, FG_N, FG_S}, 3, next_keycode, record);
case FG_P:
return finish_word((uint16_t[]) {FG_L, FG_U, FG_S}, 3, next_keycode, record);
case FG_A:
// "avec"
return finish_word((uint16_t[]) {FG_V, FG_E, FG_C}, 3, next_keycode, record);
case FG_N:
// sc SFB
bkspc_countdown = 0;
return replace_ongoing_key(FG_L, next_keycode, record);
case FG_B:
process_word((uint16_t[]) {FG_O, FG_N, FG_J}, 3, record);
case FG_J:
return finish_word((uint16_t[]) {FG_O, FG_U, FG_R}, 3, next_keycode, record);
case FG_M:
if (isLetter(recent[RECENT_SIZE - 2])) {
// "ment"
return finish_word((uint16_t[]) {FG_E, FG_N, FG_T}, 3, next_keycode, record);
} else {
// "même"
return finish_word((uint16_t[]) {FG_ODK, FG_O, FG_M, FG_E}, 4, next_keycode, record);
}
default:
return;
}
case FG_AROB:
if (!isLetter(recent[RECENT_SIZE - 2])) {
switch (prev_keycode) {
case FG_T:
// "t@" -> "toujours"
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_O, FG_U, FG_J, FG_O, FG_U, FG_R, FG_S}, 7, next_keycode, record);
case FG_P:
// "p@" -> "peut-être"
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_E, FG_U, FG_T, FG_MOIN, FG_ODK, FG_O, FG_T, FG_R, FG_E}, 9, next_keycode, record);
case FG_A:
// "a@" -> "aujourd'hui"
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_U, FG_J, FG_O, FG_U, FG_R, FG_D, FG_APOS, FG_H, FG_U, FG_I}, 10, next_keycode, record);
case FG_B:
// "b@" -> "beaucoup"
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_E, FG_A, FG_U, FG_C, FG_O, FG_U, FG_P}, 7, next_keycode, record);
case FG_E:
// "e@" -> "est-ce qu"
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_S, FG_T, FG_MOIN, FG_C, FG_E, KC_SPC, FG_Q}, 7, next_keycode, record);
case FG_D:
// "d@" -> "déjà"
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_EACU, FG_J, FG_ODK, FG_A}, 4, next_keycode, record);
}
}
break;
case FG_Q:
if (prev_keycode == FG_J) {
// "jq" -> "jusqu"
process_word((uint16_t[]) {FG_U, FG_S}, 2, record);
set_last_keycode(*next_keycode);
return;
}
break;
case FG_A:
//if (prev_keycode == FG_O && !isCaps) {
if (prev_keycode == FG_O) {
// "oa" -> "oi"
bkspc_countdown = 0;
return replace_ongoing_key(FG_I, next_keycode, record);
}
break;
case FG_I:
//if (prev_keycode == FG_O && !isCaps && recent[RECENT_SIZE - 3] != FG_Q) {
if (prev_keycode == FG_O && recent[RECENT_SIZE - 3] != FG_Q) {
// "oi" -> "oa", for "keyboard"
bkspc_countdown = 0;
return replace_ongoing_key(FG_A, next_keycode, record);
}
break;
/* case FG_O:
if (prev_keycode == FG_U && recent[RECENT_SIZE - 2] != FG_Q) {
// "uo" -> "un"
bkspc_countdown = 0;
return replace_ongoing_key(FG_N, next_keycode, record);
}
break; */
case OU_GRV:
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_O, FG_ODK, FG_T}, 3, next_keycode, record);
/* case CA_CED:
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_CCED, FG_A}, 2, next_keycode, record); */
/* case AGRV_SPC:
layer_off(_ODK);
return finish_word((uint16_t[]) {FG_AGR, KC_SPC}, 2, next_keycode, record); */
}
//return KC_NO; // Process next keycode normally
}

View file

@ -1,33 +0,0 @@
/* 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
void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record);
#ifdef __cplusplus
}
#endif

View file

@ -1,133 +0,0 @@
/* 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
#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
//#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

@ -1,221 +0,0 @@
// 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 FG_EXLM:
case FG_QUES:
case FG_3PTS:
case FG_2PTS:
// Add space between punctuation and letters.
process_next_key(KC_SPC, record);
case KC_SPC:
switch (recent[RECENT_SIZE - 2]) {
case FG_EXLM:
case FG_QUES:
case FG_3PTS:
case FG_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 == FG_Q) {
switch (next_keycode) {
case FG_E:
case FG_I:
case FG_A:
case FG_O:
case FG_EACU:
case E_CIRC:
case FG_APOS:
process_next_key(FG_U, record);
break;
// Raccourci pour "quelq"
case FG_Q:
clear_recent_keys(); // To prevent infinite loop
process_word((uint16_t[]) {FG_U, FG_E, FG_L}, 3, record);
break;
// Raccourci pour "quoi", ça évite un aller-retour sur la main gauche.
case FG_Z:
return finish_word((uint16_t[]) {FG_U, FG_O, FG_I}, 3, record);
// Raccourci pour "quand"
case FG_D:
process_word((uint16_t[]) {FG_U, FG_A, FG_N}, 3, record);
break;
}
} else if (next_keycode == FG_AROB && !isLetter(recent[RECENT_SIZE - 2])) {
switch (prev_keycode) {
case FG_T:
// "t@" -> "toujours"
return finish_word((uint16_t[]) {FG_O, FG_U, FG_J, FG_O, FG_U, FG_R, FG_S}, 7, record);
case FG_P:
// "p@" -> "peut-être"
return finish_word((uint16_t[]) {FG_E, FG_U, FG_T, FG_MOIN, FG_ACIR, FG_E, FG_T, FG_R, FG_E}, 9, record);
case FG_A:
// "a@" -> "aujourd'hui"
return finish_word((uint16_t[]) {FG_U, FG_J, FG_O, FG_U, FG_R, FG_D, FG_APOS, FG_H, FG_U, FG_I}, 10, record);
case FG_B:
// "b@" -> "beaucoup"
return finish_word((uint16_t[]) {FG_E, FG_A, FG_U, FG_C, FG_O, FG_U, FG_P}, 7, record);
case FG_E:
// "e@" -> "est-ce qu"
return finish_word((uint16_t[]) {FG_S, FG_T, FG_MOIN, FG_C, FG_E, KC_SPC, FG_Q}, 7, record);
case FG_D:
// "d@" -> "déjà"
return finish_word((uint16_t[]) {FG_EACU, FG_J, FG_AGRV}, 3, record);
}
} else if (prev_keycode == FG_P) {
switch (next_keycode) {
case FG_M:
// "pas"
return finish_word((uint16_t[]) {FG_A, FG_S}, 2, record);
case FG_APOS:
// "par"
return finish_word((uint16_t[]) {FG_A, FG_R}, 2, record);
case FG_POIN:
if (!isLetter(recent[RECENT_SIZE - 2])) {
// "pour"
return finish_word((uint16_t[]) {FG_O, FG_U, FG_R}, 3, record);
}
}
} else if (next_keycode == FG_A && prev_keycode == FG_O) {
// "oa" -> "oi"
process_next_key(FG_I, record);
return false;
} else if (next_keycode == FG_O && prev_keycode == FG_U && recent[RECENT_SIZE - 2] != FG_Q) {
// "uo" -> "un"
process_next_key(FG_N, record);
return false;
}
switch (next_keycode) {
case FG_QUES:
case FG_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 FG_T:
process_next_key(FG_I, record);
case FG_I:
return finish_word((uint16_t[]) {FG_O, FG_N}, 2, record);
case FG_C:
return finish_word((uint16_t[]) {FG_APOS, FG_E, FG_S, FG_T}, 4, record);
case FG_D:
return finish_word((uint16_t[]) {FG_A, FG_N, FG_S}, 3, record);
case FG_P:
return finish_word((uint16_t[]) {FG_L, FG_U, FG_S}, 3, record);
case FG_A:
return finish_word((uint16_t[]) {FG_V, FG_E, FG_C}, 3, record);
case FG_S:
return finish_word((uint16_t[]) {FG_U, FG_R}, 2, record);
case FG_B:
process_word((uint16_t[]) {FG_O, FG_N, FG_J}, 3, record);
case FG_J:
return finish_word((uint16_t[]) {FG_O, FG_U, FG_R}, 3, record);
case FG_M:
// "même"
return finish_word((uint16_t[]) {FG_ACIR, FG_E, FG_M, FG_E}, 4, record);
default:
return false;
}
case FG_Q:
if (prev_keycode == FG_J) {
// "jq" -> "jusqu"
process_word((uint16_t[]) {FG_U, FG_S}, 2, record);
}
break;
case CA_CED:
return finish_word((uint16_t[]) {FG_CCED, FG_A}, 2, record);
case OU_GRV:
return finish_word((uint16_t[]) {FG_O, ALGR(FG_U)}, 2, record);
case AGRV_SPC:
return finish_word((uint16_t[]) {FG_AGRV, KC_SPC}, 2, record);
case E_CIRC:
return process_accent(FG_ACIR, FG_E, record);
case I_CIRC:
return process_accent(FG_ACIR, FG_I, record);
case A_CIRC:
return process_accent(FG_ACIR, FG_A, record);
case O_CIRC:
return process_accent(FG_ACIR, FG_O, record);
case U_CIRC:
return process_accent(FG_ACIR, FG_U, record);
case I_TREM:
return process_accent(FG_TREM, FG_I, record);
}
store_keycode(next_keycode, record);
}
return true; // Process all other keycodes normally
}

View file

@ -1,195 +0,0 @@
/* 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;
//static unsigned short int bkspc_countdown = RECENT_SIZE + 1;
unsigned short int bkspc_countdown = RECENT_SIZE + 1;
// Copy of the record argument for the clever key.
static keyrecord_t mod_record;
static bool processingCK = false;
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_ongoing_keycode(uint16_t keycode, keyrecord_t* record) {
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 (isSendStringMacro(keycode)) { return keycode; }
//if (keycode == FG_CCED) { return FG_CCED; }
if (IS_LAYER_ON(_ODK)) {
switch (keycode) {
case FG_K:
case FG_J:
case FG_AROB:
case FG_ECIR:
case FG_CCED:
case FG_3PTS:
case KC_SPC: // In order to uppercase J after '?' for ex.
return keycode;
/* case FG_C:
return FG_CCED; */
default:
return KC_NO;
}
}
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 FG_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);
//record->keycode = keycode;
bkspc_countdown = 1;
}
void replace_ongoing_key(uint16_t clever_keycode, uint16_t* ongoing_keycode, keyrecord_t* record) {
record->keycode = clever_keycode;
*ongoing_keycode = clever_keycode;
set_last_keycode(clever_keycode);
processingCK = true;
}
void process_word(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record) {
for (int i = 0; i < num_keycodes; ++i) {
process_key(keycodes[i], record); // Better solution, if there is enought space in the chip.
//tap_code(keycodes[i]);
}
bkspc_countdown = num_keycodes;
}
void finish_word(uint16_t keycodes[], uint8_t num_keycodes, uint16_t* ongoing_keycode, keyrecord_t* record) {
process_word(keycodes, num_keycodes - 1, record);
replace_ongoing_key(keycodes[num_keycodes - 1], ongoing_keycode, record);
}
bool process_clever_keys(uint16_t keycode, keyrecord_t* record) {
if (record->event.pressed) {
uint16_t ongoing_keycode = get_ongoing_keycode(keycode, record);
if (ongoing_keycode != KC_NO) {
get_clever_keycode(&ongoing_keycode, record);
store_keycode(ongoing_keycode, record);
}
//return true; // If no clever key was found, process keycode normally.
}
return true;
}
void end_CK(keyrecord_t* record) {
if (processingCK) {
processingCK = false;
record->event.pressed = false;
process_record(record);
}
}

View file

@ -1,51 +0,0 @@
/* 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_ongoing_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);
void replace_ongoing_key(uint16_t clever_keycode, uint16_t* ongoing_keycode, keyrecord_t* record);
void process_word(uint16_t keycodes[], uint8_t num_keycodes, keyrecord_t* record);
void finish_word(uint16_t keycodes[], uint8_t num_keycodes, uint16_t* ongoing_keycode, keyrecord_t* record);
bool process_clever_keys(uint16_t keycode, keyrecord_t* record);
void end_CK(keyrecord_t* record);
//bool process_accent(uint16_t accent, uint16_t letter, keyrecord_t* record);
#ifdef __cplusplus
}
#endif

View file

@ -1,135 +0,0 @@
/* 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 "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[] = {FG_S, FG_N, COMBO_END};
const uint16_t PROGMEM bkspc_combo_d[] = {FG_N, FG_R, COMBO_END};
const uint16_t PROGMEM del_word_combo[] = {FG_M, FG_L, COMBO_END};
const uint16_t PROGMEM bk_word_combo[] = {FG_L, FG_APOS, COMBO_END};
const uint16_t PROGMEM enter_combo[] = {FG_P, FG_EACU, COMBO_END};
const uint16_t PROGMEM tab_combo[] = {FG_T, FG_I, COMBO_END};
const uint16_t PROGMEM esc_combo[] = {FG_T, FG_A, COMBO_END};
const uint16_t PROGMEM bkspc_combo_g[] = {FG_A, FG_I, COMBO_END};
const uint16_t PROGMEM home_combo[] = {FG_Z, FG_Y, COMBO_END};
const uint16_t PROGMEM end_combo[] = {FG_EACU, FG_VIRG, COMBO_END};
const uint16_t PROGMEM help_combo[] = {FG_VIRG, FG_APOS, COMBO_END};
const uint16_t PROGMEM panic_combo[] = {FG_EACU, FG_L, COMBO_END};
const uint16_t PROGMEM numword_combo[] = {FG_S, FG_R, COMBO_END};
const uint16_t PROGMEM alttab_combo[] = {FG_D, FG_Y, COMBO_END};
//const uint16_t PROGMEM ctrlalt_Combo[] = {FG_A, FG_I, FG_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:
case HOME:
case END:
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 FG_Y:
tap_code16(S(KC_TAB));
return true;
case FG_D:
tap_code(KC_TAB);
return true;
}
break;
}
return false;
}

View file

@ -1,72 +0,0 @@
/* 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"
bool is_odk_shifted = 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 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

@ -1,31 +0,0 @@
/* 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
extern bool is_odk_shifted;
bool process_macros(uint16_t keycode, keyrecord_t *record);
#ifdef __cplusplus
}
#endif

View file

@ -1,120 +0,0 @@
/* 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 "numword.h"
//static uint16_t num_word_timer = 0;
//static bool is_num_word_on = false;
bool is_num_word_on = false;
static 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_exit_num_word(uint16_t keycode, const keyrecord_t *record) {
switch (keycode) {
// Keycodes which should not disable num word mode.
// Numpad keycodes
case KC_1 ... KC_0:
case KC_PDOT:
case FG_POIN:
//case FG_VIRG:
case FG_MOIN:
case FG_ASTX:
case FG_PLUS:
case FG_SLSH:
case FG_ACIR:
case FG_CARN:
// Misc
case KC_BSPC:
case FG_ODK: // Not to exit Numword when chording it with ODK
case NUMWORD: // For the combo NUMWORD to work
/*
case FG_EGAL:
case FG_BSLS:*/
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_exit_num_word(keycode, record);
return true;
}
void numword_exit_check(void) {
if (exit_num_word) { disable_num_word(); }
}

View file

@ -1,30 +0,0 @@
/* 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 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);
void numword_exit_check(void);

View file

@ -1,122 +0,0 @@
/* 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 "odk_layer.h"
//static uint16_t odk_keycode = KC_NO;
bool process_odk_layer(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { // On press
const uint8_t mods = get_mods() | get_weak_mods() | get_oneshot_mods();
static bool is_shifted = false;
if (keycode == OS_ODK) {
// Handle the custom OSL that go with this feature
// It's timerless, to avoid problems when rolling with an other key, when shift is on.
// Custom behaviour when alt-gr
if (mods & MOD_BIT(KC_ALGR)) {
tap_code16(ALGR(FG_ODK));
return false;
}
is_shifted = mods & MOD_MASK_SHIFT;
if (is_shifted) {
del_weak_mods(MOD_MASK_SHIFT);
del_oneshot_mods(MOD_MASK_SHIFT);
unregister_mods(MOD_MASK_SHIFT);
}
/*layer_on(_ODK);
odk_keycode = KC_NO;
return false; */
} else if (keycode == FG_ODK) {
// Special behaviour of FR_ODK when shifted
// Shift must apply to the next keycode
/* is_shifted = 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_ODK);
return true;
} else if (IS_LAYER_ON(_ODK)) {
//if (odk_keycode == KC_NO) { odk_keycode = keycode; }
//if (!IS_QK_USER(keycode)) { odk_keycode = keycode; }
switch (keycode) {
case FG_AROB:
case FG_K:
case FG_J:
case FG_ECIR:
case OU_GRV:
case FG_CCED:
//case CA_CED:
//case AGRV_SPC:
case KC_SPC: // When space is added by Clever Keys
case FG_3PTS:
case CNL_ODK:
break;
default:
/* is_shifted = 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(FG_ODK);
}
if (!IS_LAYER_ON(_APOS_DR)) {
switch (keycode) {
case FG_M:
case FG_L:
is_shifted = true;
}
}
if (is_shifted) {
//set_mods(mods);
set_oneshot_mods(MOD_BIT(KC_LSFT));
is_shifted = false;
}
//exit_odk = true;
/* } else {
odk_keycode = KC_NO; */
}
/* } else { // On release
switch (keycode) {
case OS_ODK:
case FG_ODK:
break;
default:
//if (exit_odk) { odk_layer_exit_check(); }
if (keycode == odk_keycode) {
layer_off(_ODK);
odk_keycode = KC_NO;
}
} */
}
return true;
}
/* void odk_layer_exit_check(uint16_t keycode) {
if (keycode == odk_keycode) {
layer_off(_ODK);
odk_keycode = KC_NO;
}
} */

View file

@ -1,32 +0,0 @@
/* 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
bool process_odk_layer(uint16_t keycode, keyrecord_t *record);
//void odk_layer_exit_check(uint16_t keycode);
#ifdef __cplusplus
}
#endif

View file

@ -1,52 +0,0 @@
#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

@ -1,31 +0,0 @@
#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

@ -1,114 +0,0 @@
/* 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"
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;
static bool exit_os4a_layer = false;
static 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;
}
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;
}
void os4a_layer_exit_check(void) {
if (os4a_layer != 0 && exit_os4a_layer) { os4a_layer_off(os4a_layer); }
}

View file

@ -1,50 +0,0 @@
/* 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
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);
void os4a_layer_exit_check(void);
#ifdef __cplusplus
}
#endif

View file

@ -1,97 +0,0 @@
/* 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) {
if (IS_OS4A_KEY(keycode)) {
// Instant OS4A processing
os4a_tap(keycode);
} 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);
record->keycode = (keycode &= 0xff);
}
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(FG_LACL):
return process_tap_hold(FG_LACL, record); */
case RCTL_T(FEN_B):
return process_tap_hold(LWIN(KC_DOWN), record);
case SFT_T(COPY):
return process_tap_hold(C(FG_C), record);
case LT_NUMWORD:
return process_numword(NUMWORD, 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

@ -1,36 +0,0 @@
/* 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
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

@ -1,228 +0,0 @@
/* 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"
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 FG_U:
case FG_E:
case FG_AGR:
case FG_ECIR:
case KC_GRV ... KC_DOT:
return true;
default:
return false;
}
}
bool isSendStringMacro(uint16_t keycode) {
switch (keycode) {
//case AGRV_SPC:
//case CA_CED:
case OU_GRV:
case MAGIC:
return true;
default:
return false;
}
}
// This function extracts the base keycode of MT and LT,
// even if the tap/hold key is a custom one, with non-basic tap keycode.
uint16_t tap_hold_extractor(uint16_t keycode) {
switch (keycode) {
default:
return keycode &= 0xff;
}
}
// Caps Word
bool caps_word_press_user(uint16_t keycode) {
// Caps Word shouldn't be applied with Alt-gr
// Managing underscore and slash on alt gr + E/T.
// Underscore and slash must continue Caps Word, without shifting.
if ((get_mods() & MOD_BIT(KC_ALGR))) {
switch (keycode) {
case FG_E:
case FG_T:
return true;
default:
return false;
}
}
if (IS_LAYER_ON(_ODK)) {
switch (keycode) {
case FG_VIRG:
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
return true;
case FG_I:
case FG_H:
return true;
case FG_U:
case FG_D:
case FG_G:
case FG_B:
case FG_F:
case FG_M:
case FG_L:
case FG_S:
case FG_N:
return false;
}
}
// Keycodes that continue Caps Word, with shift applied.
// @ must be shifted, bc of CleverKeys using it.
if (isLetter(keycode) || isSendStringMacro(keycode) || keycode == FG_AROB) {
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
return true;
}
switch (keycode) {
// Keycodes that continue Caps Word, without shifting.
case FG_ODK:
//case FG_GRV:
case FG_MOIN:
case KC_KP_1 ... KC_KP_0:
case KC_LEFT:
case KC_RIGHT:
case KC_BSPC:
case KC_DEL:
case FG_APOS:
return true;
default:
return false; // Deactivate Caps Word.
}
}
// 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:
case TG_APOD:
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_ODK && (mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_ALGR)))) { return true;}
//if (keycode == OS_ODK && (mods & ~MOD_BIT(KC_ALGR))) { return true;}
switch (keycode) {
//case OS_ODK: /!\ A ne pas remettre, sous peine de ne pas pouvoir faire shift + typo + touche de l'autre côté
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:
case FG_ODK:
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(FG_Z):
return C(FG_Y);
case C(FG_Y):
return C(FG_Z);
}
if ((get_mods() | get_weak_mods()) & MOD_BIT(KC_ALGR)) {
return KC_SPC;
}
keycode = tap_hold_extractor(keycode);
if (isLetter(keycode)) { return MAGIC; }
return KC_TRNS; // Defer to default definitions.
}

View file

@ -1,30 +0,0 @@
/* 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"
bool isLetter(uint16_t keycode);
bool isSendStringMacro(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

@ -1,326 +0,0 @@
/* 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 FG_M:
case KC_N ... KC_Z:
case FG_AGRV:
case FG_EACU:
case FG_EGRV:
case FG_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 FG_MOIN:
case KC_KP_1 ... KC_KP_0:
case KC_LEFT:
case KC_RIGHT:
case KC_BSPC:
case KC_DEL:
case FG_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[] = {
{FG_AGRV, FG_AE},
{FG_B, FG_SS},
{FG_A, FG_LDAQ},
{FG_I, FG_RDAQ},
{FG_T, FG_ESPR},
{FG_S, FG_AROB},
{ALGR_T(FG_A), FG_LDAQ},
{LCTL_T(FG_I), FG_RDAQ},
{RCTL_T(FG_T), FG_ESPR},
{ALGR_T(FG_S), FG_AROB},
{FG_X, FG_TM},
{KC_KP_8, FG_INFN},
{FG_H, FG_HASH},
{FG_V, FG_DEG},
{FG_CCED, FG_CEDL},
{FG_Q, FG_SECT},
{FG_POIN, FG_PVIR},
{FG_C, FG_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 FG_CCED: // Pour pouvoir faire Alt + F4, Alt + F11.
case LCTL_T(FG_I):
case RCTL_T(FG_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, FG_AGRV, FG_B, FG_EACU, FG_POIN, FG_MOIN, FG_ACIR, FG_V, FG_L, FG_M, FG_X, FG_W,
KC_ENT, ALT_T(FG_O), SFT_T(FG_U), ALGR_T(FG_A), LCTL_T(FG_I), FG_J, FG_G, RCTL_T(FG_T), ALGR_T(FG_S), RSFT_T(FG_N), ALT_T(FG_R), FG_F,
LT_TAB, FG_Q, FG_Y, FG_EGRV, LWIN_T(FG_P), FG_DQUO, KC_BSPC, KC_END, KC_HOME, KC_DEL, FG_K, RWIN_T(FG_D), FG_Z, FG_H, FG_C, FG_CCED,
TG(_SYMBOLS), KC_SPC, OSM(MOD_LSFT), LT(_SYMBOLS,FG_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, FG_EXLM, FG_QUES, FG_ESPR, FG_PVIR, FG_PIPE, FG_MOIN, KC_P7, KC_P8, KC_P9, FG_ASTX, KC_NUM,
_______, FG_LACL, SFT_T(FG_RACL), ALGR_T(FG_LPRN), FG_RPRN, LAYER_LCK, FG_EGAL, RCTL_T(KC_P4), ALGR_T(KC_P5), KC_P6, FG_SLSH, FG_BSLS,
_______, FG_LBKT, FG_RBKT, FG_INF, FG_SUP, FG_CARN, _______, _______, _______, _______, FG_ACIR, KC_P1, KC_P2, KC_P3, FG_PLUS, FG_PERC,
_______, _______, _______, KC_SPC, FG_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(FG_V), _______, _______, _______, C(KC_LEFT), KC_UP, C(KC_RIGHT), _______, _______,
_______, C(FG_A), C(FG_X), C(FG_V), C(FG_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(FG_Z), C(FG_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(FG_D), LWIN(KC_HOME), _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
// /*
// * Layer template
// *
// * ,-------------------------------------------. ,-------------------------------------------.
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------| |------+------+------+------+------+--------|
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
// * | | | | | | | | | | | | | | | | | |
// * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
// * | | | | | | | | | | | |
// * | | | | | | | | | | | |
// * `----------------------------------' `----------------------------------'
// */
// [_LAYERINDEX] = LAYOUT(
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
// ),
};

View file

@ -1,317 +0,0 @@
/* 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 "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) {
// 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_ODK) { 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; }
// Macros
if (!process_macros(keycode, record)) { return false; }
// Custom behaviour of the typo dead-key
if (!process_odk_layer(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); }
os4a_layer_exit_check();
numword_exit_check();
//odk_layer_exit_check(keycode);
end_CK(record);
}
// 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, FG_X, FG_VIRG, FG_EACU, FG_P, FG_B, FG_F, FG_M, FG_L, FG_APOS, FG_POIN, KC_NO,
KC_NO, FG_O, FG_A, FG_I, FG_T, FG_G, FG_V, FG_S, FG_N, FG_R, FG_U, KC_NO,
KC_NO, FG_Q, FG_Z, FG_Y, FG_D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, FG_C, FG_H, FG_W, OS_ODK, KC_NO,
KC_NO, KC_SPC, L_OS4A, LT_E, LT_MGC, LT_REPT, LT_SPC, R_OS4A, KC_RGUI, KC_NO
),
// * Layer template
// *
// * ,-------------------------------------------. ,-------------------------------------------.
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------| |------+------+------+------+------+--------|
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
// * | | | | | | | | | | | | | | | | | |
// * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
// * | | | | | | | | | | | |
// * | | | | | | | | | | | |
// * `----------------------------------' `----------------------------------'
// */
[_APOS_DR] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, FG_APOD, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/*
* 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, TG_APOD, KC_NO, KC_NO,
_______, _______, _______, _______, _______, _______, TT_FA, OS_SHFT, OS_CTRL, NUMWORD, FG_ODK, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, OS_FA, OS_LALT, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO
),
/*
* Layer 1 : Numpad
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) | LOCK | | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | |Expos.| 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_NUMBERS] = LAYOUT(
_______, _______, FG_MOIN, FG_PLUS, KC_7, S(FG_ACIR), FG_PERC, _______, FG_EGAL, FG_ASTX, _______, _______,
_______, KC_4, KC_3, KC_2, MT_1, FG_CARN, _______, MT_SLSH, KC_6, KC_7, KC_8, _______,
_______, _______, _______, _______, KC_5, _______, _______, _______, _______, _______, _______, KC_9, KC_6, _______, FG_ODK, _______,
_______, _______, KC_PDOT, KC_0 , LT_NUMWORD, LT_REPT, KC_SPC, _______, _______, _______
),
/*
* Layer 2 : Symbols
*
* ,-------------------------------------------. ,-------------------------------------------.
* | | ! | ? | & | ; | | | | | 7 | 8 | 9 | * |NumLock|
* |--------+------+------+------+------+------| |------+------+------+------+------+--------|
* | | { | } | ( | ) |Expos.| | = | 4 | 5 | 6 | / | \ |
* |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
* | | [ | ] | < | > |Indice| | | | | | | 1 | 2 | 3 | + | % |
* `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
* | | | | | | | | 0 | . | | |
* | | | | | | | , | | | | |
* `----------------------------------' `----------------------------------'
*/
[_ODK] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, OU_GRV, _______, _______, FG_3PTS, _______, _______, FG_J, FG_D, FG_AROB, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, FG_K, CNL_ODK, _______,
_______, _______, _______, _______, FG_ECIR, _______, _______, _______, _______, _______
),
/*
* 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(FG_V), RCS(FG_V), KC_VOLU, KC_PGUP, C(KC_LEFT), KC_UP, C(KC_RGHT), _______, _______,
_______, C(FG_A), C(FG_X), C(FG_V), SFT_T(COPY), KC_VOLD, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F2 , _______,
_______, KC_SPC, KC_SPC, KC_MUTE, C(FG_Z), C(FG_Y), _______, _______, _______, _______, _______, C(KC_PGUP), C(KC_PGDN), C(FG_W), _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/*
* 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, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
// /*
// * Layer template
// *
// * ,-------------------------------------------. ,-------------------------------------------.
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------| |------+------+------+------+------+--------|
// * | | | | | | | | | | | | | |
// * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------|
// * | | | | | | | | | | | | | | | | | |
// * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------'
// * | | | | | | | | | | | |
// * | | | | | | | | | | | |
// * `----------------------------------' `----------------------------------'
// */
// [_LAYERINDEX] = LAYOUT(
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
// ),
};

View file

@ -1,99 +0,0 @@
/* 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 QMK_KEYBOARD_H
#include "keymap_french_frgo.h"
#include "features_conf.h"
#include "clever_keys.h"
#include "features/tap_hold_utilities.h"
#include "features/clever_keys_utilities.h"
#include "features/numword.h"
#include "features/macros.h"
#include "features/os4a.h"
#include "features/oneshot.h"
#include "features/odk_layer.h"
enum layers {
_BASE = 0,
_APOS_DR,
// OS4A layers should be as closed as base layer as possible
_L_MODS,
_R_MODS,
_ODK,
_NUMBERS,
_SHORTNAV,
_FUNCAPPS,
};
enum custom_keycodes {
NUMWORD = SAFE_RANGE,
FEN_B,
COPY,
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,
//OS_ODK,
CNL_ODK
};
// Layer taps
#define LT_SPC ALGR_T(KC_SPC)
#define LT_E ALGR_T(FG_E)
#define LT_REPT LT(_NUMBERS, KC_1)
#define LT_MGC LT(_SHORTNAV, KC_1)
#define OS_FA OSL(_FUNCAPPS)
#define TT_FA TT(_FUNCAPPS)
#define TG_APOD TG(_APOS_DR)
#define MT_SLSH SFT_T(FG_SLSH)
#define MT_1 SFT_T(KC_1)
#define LT_NUMWORD LT(_SHORTNAV, NUMWORD)
#define E_CIRC S(FG_0)
#define OS_ODK OSL(_ODK)
// 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

@ -1,221 +0,0 @@
/* 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 FG_CCED KC_GRV // ç
#define FG_1 KC_1 // 1
#define FG_2 KC_2 // 2
#define FG_3 KC_3 // 3
#define FG_4 KC_4 // 4
#define FG_5 KC_5 // 5
#define FG_6 KC_6 // 6
#define FG_7 KC_7 // 7
#define FG_8 KC_8 // 8
#define FG_9 KC_9 // 9
#define FG_0 KC_0 // 0
#define FG_SLSH KC_MINS // /
#define FG_ASTX KC_EQL // *
// Row 2
#define FG_X KC_Q // X
#define FG_VIRG KC_W // ,
#define FG_EACU KC_E // É
#define FG_P KC_R // P
#define FG_B KC_T // B
#define FG_F KC_Y // F
#define FG_M KC_U // M
#define FG_L KC_I // L
#define FG_APOS KC_O //
#define FG_POIN KC_P // .
#define FG_EGAL KC_LBRC // =
#define FG_PLUS KC_RBRC // +
// Row 3
#define FG_O KC_A // O
#define FG_A KC_S // A
#define FG_I KC_D // I
#define FG_T KC_F // T
#define FG_G KC_G // G
#define FG_V KC_H // V
#define FG_S KC_J // S
#define FG_N KC_K // N
#define FG_R KC_L // R
#define FG_U KC_SCLN // U
#define FG_MOIN KC_QUOT // -
#define FG_APOD KC_NUHS // '
// Row 4
#define FG_E KC_NUBS // E
#define FG_Q KC_Z // Q
#define FG_Z KC_X // Z
#define FG_Y KC_C // Y
#define FG_D KC_V // D
#define FG_J KC_B // J
#define FG_K KC_N // K
#define FG_C KC_M // C
#define FG_H KC_COMM // H
#define FG_W KC_DOT // W
#define FG_ODK KC_SLSH // **
/* Shifted symbols
*
*                                              
*
*          !                    ?  :           
*     
*                                         ?     
*
*                                    ;           
*
*                                                     
*
*/
// Row 3
#define FG_3PTS S(FG_0) // …
// Row 2
#define FG_EXLM S(FG_VIRG) // !
#define FG_QUES S(FG_APOS) // ?
#define FG_2PTS S(FG_POIN) // :
#define FG_DIFF S(FG_EGAL) // ≠
// Row 4
//#define FG_PVIR S(FG_ODK)
// Row 5
#define FG_NBSP S(KC_SPC) // Espace insecable
/* AltGr symbols
*
*                         à  ê        
*
*       ^  !  =  $  %  #  ;  '  ?  :            
*     
*        *  +  -  /  \  `  (  )  <  >           
*
*      _  ~  |  &  " │ @ │   │ { │ } │ [ │ ] │          │
*
*                                                     
*
*/
// Row 1
#define FG_AGR ALGR(FG_SLSH)
#define FG_ECIR ALGR(FG_ASTX)
// Row 2
#define FG_ACIR ALGR(FG_X) // ^
//#define FG_EXLM ALGR(FG_VIRG) // !
//#define FG_EGAL ALGR(FG_EACU) // =
#define FG_DLR ALGR(FG_P) // $
#define FG_PERC ALGR(FG_B) // %
#define FG_HASH ALGR(FG_F) // #
#define FG_PVIR ALGR(FG_M) // ;
//#define FG_QUES ALGR(FG_APOS) // ?
//#define FG_2PTS ALGR(FG_POIN) // :
// Row 3
/* #define FG_ASTX ALGR(FG_O) // *
#define FG_PLUS ALGR(FG_A) // +
#define FG_SLSH ALGR(FG_T) // /
#define FG_MOIN ALGR(FG_I) // - */
#define FG_BSLS ALGR(FG_G) // '\'
#define FG_GRV ALGR(FG_V) // `
#define FG_LPRN ALGR(FG_S) // (
#define FG_RPRN ALGR(FG_N) // )
#define FG_INF ALGR(FG_R) // <
#define FG_SUP ALGR(FG_U) // >
//#define FG_DQUO ALGR(FG_U) // "
#define FG_AROB ALGR(FG_J)
// Row 4
#define FG_UNDS ALGR(FG_E) // _
#define FG_TILD ALGR(FG_Q) // ~
#define FG_PIPE ALGR(FG_Z) // |
#define FG_ESPR ALGR(FG_Y) // &
#define FG_DQUO ALGR(FG_D) // "
#define FG_LCBR ALGR(FG_C) // {
#define FG_RCBR ALGR(FG_H) // }
#define FG_LSBR ALGR(FG_W) // [
#define FG_RSBR ALGR(FG_ODK) // ]
/* Shift+AltGr symbols
*
*   ̑                  ̏                          
*
*       *^ ¬    *¤ *˚           *ˇ           
*     
*        ×  ±  *¯ ÷    *` *´    *˘ *          
*
*           *~ ¦           *¸ *, *˛             
*
*                                                     
*
*/
#define FG_CARN S(ALGR(FG_POIN)) // ˇ (dead)
/* // Row 1
#define FG_IBRV S(ALGR(FG_AROB)) //  ̑ (dead)
#define FG_DACU S(ALGR(FG_LPRN)) // ˝ (dead)
#define FG_DGRV S(ALGR(FG_RPRN)) //  ̏ (dead)
#define FG_MDSH S(ALGR(FG_RSQU)) // —
#define FG_LSAQ S(ALGR(FG_LDAQ)) //
#define FG_RSAQ S(ALGR(FG_RDAQ)) //
#define FG_IQUE S(ALGR(FG_APOS)) // ¿
// Row 2
#define FG_TM S(ALGR(FG_T)) // ™
#define FG_DOTB S(ALGR(FG_I)) //  ̣ (dead)
#define FG_PERM S(ALGR(FG_P)) // ‰
#define FG_NBHY S(ALGR(FG_MOIN)) // (non-breaking hyphen)
#define FG_DDAG S(ALGR(FG_PLUS)) // ‡
// Row 3
#define FG_MACB S(ALGR(FG_H)) // ˍ (dead)
#define FG_SQRT S(ALGR(FG_SLSH)) // √
#define FG_QRTR S(ALGR(FG_ASTX)) // ¼
// Row 4
#define FG_GEQL S(ALGR(FG_INF)) // ≥
#define FG_OGON S(ALGR(FG_V)) // ˛ (dead)
#define FG_IEXL S(ALGR(FG_VIRG)) //  ̦ (dead)
//#define FG_NEQL S(ALGR(FG_EGAL)) // ≠ */

View file

@ -1,160 +0,0 @@
/* 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 "keymap.h"
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 _ODK:
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

@ -1,249 +0,0 @@
# 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

@ -1,44 +0,0 @@
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
#CONSOLE_ENABLE = yes
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
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/clever_keys_utilities.c
SRC += clever_keys.c
SRC += features/numword.c
SRC += features/macros.c
SRC += features/oneshot.c
SRC += features_conf.c
SRC += features/odk_layer.c
INTROSPECTION_KEYMAP_C = features/combos.c
MUSIC_ENABLE = no
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no

View file

@ -30,6 +30,17 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
//apostrophe = true;
}
//if (is_caps_lock_on()) {
/* if (is_letter(*next_keycode) || is_send_string_macro(*next_keycode)) {
if (recent[RECENT_SIZE - 3] == PG_E && recent[RECENT_SIZE - 2] == PG_T && prev_keycode == KC_SPC) {
caps_word_on();
}
if (recent[RECENT_SIZE - 2] == PG_VIRG && prev_keycode == KC_SPC && is_letter(*next_keycode)) {
caps_word_on();
}
} */
//}
switch (prev_keycode) {
@ -52,9 +63,10 @@ void get_clever_keycode(uint16_t* next_keycode, keyrecord_t* record) {
case PG_POIN:
// Shift the letter at the beginning of sentences.
if (is_letter(*next_keycode) || is_send_string_macro(*next_keycode)) {
if (!is_caps_lock_on()) { add_weak_mods(MOD_BIT(KC_LSFT)); }
break;
//if (!is_caps_lock_on()) { add_weak_mods(MOD_BIT(KC_LSFT)); }
add_weak_mods(MOD_BIT(KC_LSFT));
}
break;
}
break;

View file

@ -0,0 +1,117 @@
#include "capslist.h"
static bool caps_list_active = false;
//static bool last_word = false;
static unsigned short int capslist_countdown = 0;
static unsigned short int countdown_end = 5;
bool is_caps_list_on(void) { return caps_list_active; }
void enable_caps_list(void) {
if (is_caps_lock_on()) { tap_code(KC_CAPS); }
caps_word_on();
caps_list_active = true;
//last_word = false;
capslist_countdown = 0;
countdown_end = 5;
}
void disable_caps_list(void) {
caps_word_off();
caps_list_active = false;
}
void toggle_caps_list(void) {
if (caps_list_active) {
disable_caps_list();
} else {
enable_caps_list();
}
}
bool process_caps_list(uint16_t keycode, keyrecord_t *record) {
// Handle the custom keycodes that go with this feature
if (keycode == CAPSLIST) {
if (record->event.pressed) {
toggle_caps_list();
//enable_caps_list();
}
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 (!caps_list_active) { return true; }
// No action on keyrelease
if (!record->event.pressed) { return true; }
// If Caps Word is on, Caps List stays on as well.
if (is_caps_word_on()) { return true; }
// Get the base keycode of a mod or layer tap key
switch (keycode) {
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
return true;
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
// Earlier return if this has not been considered tapped yet
if (record->tap.count == 0) { return true; }
keycode = keycode & 0xFF; // Get tapping keycode.
break;
}
if (should_continue_caps_list(keycode)) {
//if (is_caps_lock_on()) { return true; }
if (caps_word_reactivation()) {
caps_word_on(); // Reactivate Caps Word for a new word
capslist_countdown = 0;
}
if (capslist_countdown < countdown_end) { return true; }
}
disable_caps_list();
return true;
}
//bool caps_list_press_user(uint16_t keycode) {
bool should_continue_caps_list(uint16_t keycode) {
if (keycode == KC_BSPC) {
capslist_countdown--;
return true;
}
if (is_letter(keycode) || is_send_string_macro(keycode) || keycode == PG_AROB) {
capslist_countdown++;
return true;
}
if (caps_word_press_user(keycode)) {
capslist_countdown++;
return true;
}
// Keycodes that continue Caps List, but not Caps Word.
// These keycodes trigger the countdown to end Caps List.
switch (keycode) {
case PG_VIRG:
case KC_SPC:
capslist_countdown++;
return true;
}
return false; // Deactivate Caps List.
}
bool caps_word_reactivation(void) {
// Words that continue Caps List.
if (recent[RECENT_SIZE - 1] == KC_SPC) {
if (recent[RECENT_SIZE - 4] == KC_SPC && recent[RECENT_SIZE - 3] == PG_E && recent[RECENT_SIZE - 2] == PG_T) {
countdown_end = 1;
return true;
}
if (recent[RECENT_SIZE - 4] == KC_SPC && recent[RECENT_SIZE - 3] == PG_O && recent[RECENT_SIZE - 2] == PG_U) {
countdown_end = 1;
return true;
}
if (recent[RECENT_SIZE - 2] == PG_VIRG) {
return true;
}
}
return false;
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "quantum.h"
#include "keymap.h"
bool is_caps_list_on(void);
void enable_caps_list(void);
void disable_caps_list(void);
void toggle_caps_list(void);
bool process_caps_list(uint16_t keycode, keyrecord_t *record);
bool should_continue_caps_list(uint16_t keycode);
bool caps_word_reactivation(void);

View file

@ -18,7 +18,6 @@
uint16_t recent[RECENT_SIZE] = {KC_NO};
uint16_t deadline = 0;
//static unsigned short int bkspc_countdown = RECENT_SIZE + 1;
unsigned short int bkspc_countdown = RECENT_SIZE + 1;
// Copy of the record argument for the clever key.

View file

@ -52,6 +52,7 @@ bool process_macros(uint16_t keycode, keyrecord_t *record) {
layer_clear();
clear_oneshot_mods();
clear_weak_mods();
caps_word_off();
disable_num_word();
clear_recent_keys();

View file

@ -41,8 +41,7 @@ void disable_num_word(void) {
void toggle_num_word(void) {
if (is_num_word_on) {
disable_num_word();
}
else {
} else {
enable_num_word();
}
}

View file

@ -219,6 +219,7 @@ bool to_be_shifted(uint16_t keycode, keyrecord_t *record) {
is_shifted = true;
case KC_CAPS:
case CAPSWORD:
case CAPSLIST:
return false;
default:
return (os4a_layer == _R_MODS) == on_left_hand(record->event.key);

View file

@ -97,6 +97,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Custom tap-hold keys
if (!process_custom_tap_hold(keycode, record)) { return false; }
// Caps List
if (!process_caps_list(keycode, record)) { return false; }
// Macros
if (!process_macros(keycode, record)) { return false; }
@ -138,7 +141,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
KC_NO, PG_VIRG, PG_EACU, PG_U, PG_P, PG_TIRE, PG_V, PG_M, PG_C, PG_J, PG_X, KC_NO,
KC_NO, PG_O, PG_A, PG_I, PG_N, PG_POIN, PG_G, PG_T, PG_S, PG_R, PG_L, KC_NO,
KC_NO, PG_Q, PG_Z, PG_Y, PG_H, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, PG_D, PG_F, PG_W, OS_ODK, KC_NO,
KC_NO, PG_Q, PG_Z, PG_Y, PG_H, CAPSLIST, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, PG_D, PG_F, PG_W, OS_ODK, KC_NO,
KC_NO, KC_SPC, L_OS4A, LT_E, LT_MGC, LT_REPT, LT_SPC, R_OS4A, KC_RGUI, KC_NO
),
@ -157,10 +160,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `----------------------------------' `----------------------------------'
*/
[_L_MODS] = LAYOUT(
KC_NO, KC_NO, KC_NO, OS_WIN, KC_RGUI, KC_NO, _______, _______, _______, _______, _______, _______,
KC_NO, OS_RSA, 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, _______, _______
KC_NO, KC_NO, KC_NO, OS_WIN, KC_RGUI, KC_NO, _______, _______, _______, _______, _______, _______,
KC_NO, OS_RSA, 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, _______, CAPSLIST, _______, _______
),
/*
@ -181,7 +184,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, KC_NO, KC_RGUI, OS_WIN, KC_NO, KC_NO, KC_NO,
_______, _______, _______, _______, _______, _______, TT_FA, OS_SHFT, OS_CTRL, NUMWORD, NUM_ODK, KC_NO,
_______, _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, OS_FA, OS_LALT, KC_NO,
_______, _______, _______, _______, MAGIC, TG_APOS, _______, _______, KC_NO, KC_NO
_______, _______, KC_CAPS, _______, MAGIC, TG_APOS, _______, _______, KC_NO, KC_NO
),

View file

@ -24,6 +24,7 @@
#include "features/tap_hold_utilities.h"
#include "features/clever_keys_utilities.h"
#include "features/numword.h"
#include "features/capslist.h"
#include "features/macros.h"
#include "features/os4a.h"
#include "features/oneshot.h"
@ -44,6 +45,7 @@ enum layers {
enum custom_keycodes {
NUMWORD = SAFE_RANGE,
CAPSLIST,
FEN_B,
COPY,
AIDE_MEM,

View file

@ -32,6 +32,7 @@ SRC += oled.c
SRC += features/clever_keys_utilities.c
SRC += clever_keys.c
SRC += features/numword.c
SRC += features/capslist.c
SRC += features/macros.c
SRC += features/oneshot.c
SRC += features_conf.c