diff options
Diffstat (limited to 'users/ericgebhart/extensions')
36 files changed, 2929 insertions, 0 deletions
diff --git a/users/ericgebhart/extensions/accented_keys.c b/users/ericgebhart/extensions/accented_keys.c new file mode 100644 index 0000000000..2569bffea8 --- /dev/null +++ b/users/ericgebhart/extensions/accented_keys.c @@ -0,0 +1,50 @@ +/* + Copyright 2022 Eric Gebhart <e.a.gebhart@gmail.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 USERSPACE_H +#include "accented_keys.h" +#include <stdint.h> +#include <stdbool.h> + +static inline void tap_accented_letter(uint16_t letter, uint16_t dead_key) { + uint8_t mod_state = get_mods(); + uint8_t oneshot_mod_state = get_oneshot_mods(); + del_mods(MOD_MASK_SHIFT); + del_oneshot_mods(MOD_MASK_SHIFT); + tap_code16(dead_key); + set_mods(mod_state); + set_oneshot_mods(oneshot_mod_state); + tap_code(letter); +} + +#undef ACCENTED +#define ACCENTED(KC, K1, DEAD_KEY) \ + case KC: \ + if (record->event.pressed) { \ + tap_accented_letter(K1, DEAD_KEY); \ + } \ + return false; + + +bool process_accent_keys(uint16_t keycode, keyrecord_t* record) { + switch(keycode){ +#ifdef ACCENTED_KEYS_ENABLE +#include "accented_keys.def" +#endif + } + return true; +} diff --git a/users/ericgebhart/extensions/accented_keys.h b/users/ericgebhart/extensions/accented_keys.h new file mode 100644 index 0000000000..017c6fa312 --- /dev/null +++ b/users/ericgebhart/extensions/accented_keys.h @@ -0,0 +1,19 @@ +#pragma once +/* + Copyright 2018 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ + +bool process_accent_keys(uint16_t keycode, keyrecord_t* record); diff --git a/users/ericgebhart/extensions/alt_shift.c b/users/ericgebhart/extensions/alt_shift.c new file mode 100644 index 0000000000..002adec230 --- /dev/null +++ b/users/ericgebhart/extensions/alt_shift.c @@ -0,0 +1,99 @@ +#include USERSPACE_H +#include <stdbool.h> +#include <stdint.h> + +bool shift_for_two(uint16_t keycode, keyrecord_t *record){ + uint16_t mod_state = get_mods(); + + bool is_shifted = (get_mods() & MOD_MASK_SHIFT) || + (get_oneshot_mods() & MOD_MASK_SHIFT); + + if(record ->event.pressed) { + // If shifted, double these common punctuation marks. + if(is_shifted){ + // clear shift temporarily + del_mods(MOD_MASK_SHIFT); + del_oneshot_mods(MOD_MASK_SHIFT); + + tap_code16(keycode); + tap_code16(keycode); + + // restore previous shift state + set_mods(mod_state); + return false; + } + } + return true; +} + +bool shift_for_three(uint16_t keycode, keyrecord_t *record){ + uint16_t mod_state = get_mods(); + + bool is_shifted = (get_mods() & MOD_MASK_SHIFT) || + (get_oneshot_mods() & MOD_MASK_SHIFT); + + if(record ->event.pressed) { + // If shifted, double these common punctuation marks. + if(is_shifted){ + // clear shift temporarily + del_mods(MOD_MASK_SHIFT); + del_oneshot_mods(MOD_MASK_SHIFT); + + tap_code16(keycode); + tap_code16(keycode); + tap_code16(keycode); + + // restore previous shift state + set_mods(mod_state); + return false; + } + } + return true; + } + +bool override_shift(uint16_t keycode, + uint16_t shift_keycode, + keyrecord_t *record + ) { + + bool is_shifted = (get_mods() & MOD_MASK_SHIFT) || + (get_oneshot_mods() & MOD_MASK_SHIFT); + + if (record->event.pressed) { + if (is_shifted) { + uint8_t mod_state = get_mods(); + del_mods(MOD_MASK_SHIFT); + del_oneshot_mods(MOD_MASK_SHIFT); + + tap_code16(shift_keycode); + + set_mods(mod_state); + } else { + //tap_code16(keycode); + } + } + return false; +} + +// macros for use in alt_shift.defs. +#define ALT_SHIFT(KCKEY, KC01) \ + case KCKEY: \ + return override_shift(KCKEY, KC01, record); \ + break; + +#define SHIFT_FOR_2(KCKEY) \ + case KCKEY: \ + return shift_for_two(KCKEY, record); \ + break; + +#define SHIFT_FOR_3(KCKEY) \ + case KCKEY: \ + return shift_for_three(KCKEY, record); \ + break; + +bool process_alt_shift_user(uint16_t keycode, keyrecord_t *record) { + switch(keycode){ +#include "alt_shift.def" + } + return true; +} diff --git a/users/ericgebhart/extensions/altlocal_keys.c b/users/ericgebhart/extensions/altlocal_keys.c new file mode 100644 index 0000000000..569a2076b5 --- /dev/null +++ b/users/ericgebhart/extensions/altlocal_keys.c @@ -0,0 +1,82 @@ +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ + +// Create custom keycodes with arbitrary shifted and unshifted keys. +// originally for dvorak on bepo. But used by beakl on qwerty now too. + +// Why?: Because the keycodes are actually defined on the computer. So +// if you are trying to have dvorak, or beakl on bepo-fr, the shifted keys +// are wrong. But, I want my dvorak, so this allows the pairing of keys into +// a keycode that has shifted and non shifted behavior, outside of what the +// locale map says on the computer. +// +// These are the keys for dvorak on bepo. column one is the keycode and mods for +// the unshifted key, the second column is the keycode and mods for the shifted key. +// GR is Good Range. It subtracts SAFE_RANGE from the keycode so we can make a +// reasonably sized array without difficulties. The macro is for the constant declarations +// the function is for when we use it. + +//make an alt_local_keys.def - see the example. +// Include this file where you have your process_record_user function, +// call process_alt_local_key inside your process_record_user. + +#include USERSPACE_H +#include "altlocal_keys.h" + +const uint16_t key_translations[][2][2] = { +#include "altlocal_keys.def" +}; + +uint8_t gr(uint16_t kc){ + return (kc - SAFE_RANGE); +} + +// send the right keycode for the right mod. +// remove the mods we are taking care of, +// send our keycodes then restore them. +// all so we can make dvorak keys from bepo keycodes. +void send_keycode(uint16_t kc){ + uint8_t tmp_mods = get_mods(); + bool is_shifted = ( tmp_mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) ); + + // need to turn of the shift if it is on. + unregister_mods((MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT))); + if(is_shifted){ + register_mods(SHIFTED_MODS(kc)); + register_code16(SHIFTED_KEY(kc)); + unregister_code16(SHIFTED_KEY(kc)); + unregister_mods(SHIFTED_MODS(kc)); + } else{ + register_mods(UNSHIFTED_MODS(kc)); + register_code16(UNSHIFTED_KEY(kc)); + unregister_code16(UNSHIFTED_KEY(kc)); + unregister_mods(UNSHIFTED_MODS(kc)); + } + clear_mods(); + register_mods(tmp_mods); +} + +bool process_alt_local_key(uint16_t keycode, keyrecord_t* record) { + switch(keycode){ + case ALT_LOCAL_KEYS_START ... ALT_LOCAL_KEYS_END: + if(record->event.pressed) + send_keycode(keycode); + unregister_code(keycode); + break; + } + return (true); +} diff --git a/users/ericgebhart/extensions/altlocal_keys.h b/users/ericgebhart/extensions/altlocal_keys.h new file mode 100644 index 0000000000..8e30472081 --- /dev/null +++ b/users/ericgebhart/extensions/altlocal_keys.h @@ -0,0 +1,56 @@ +#pragma once +/* + Copyright 2018 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ + +// Create custom keycodes with arbitrary shifted and unshifted keys. +// originally for dvorak on bepo. But used by beakl on qwerty now too. + +// Why?: Because the keycodes are actually defined on the computer. So +// if you are trying to have dvorak, or beakl on bepo-fr, the shifted keys +// are wrong. But, I want my dvorak, so this allows the pairing of keys into +// a keycode that has shifted and non shifted behavior, outside of what the +// locale map says on the computer. +// +// These are the keys for dvorak on bepo. column one is the keycode and mods for +// the unshifted key, the second column is the keycode and mods for the shifted key. +// GR is Good Range. It subtracts SAFE_RANGE from the keycode so we can make a +// reasonably sized array without difficulties. The macro is for the constant declarations +// the function is for when we use it. + +//make an alt_local_keys.def - see the example. +// Include this file where you have your process_record_user function, +// call process_alt_local_key inside your process_record_user. + +uint8_t gr(uint16_t); +void send_keycode(uint16_t); +bool process_alt_local_key(uint16_t keycode, keyrecord_t* record); + +#define MOD_NONE 0x00 + +#define GR(x) (x-SAFE_RANGE) +// indexs for the keycode translation table. + +#define MK_KEY(KCNAME, KC1, MOD1, KC2, MOD2) \ + [GR(KCNAME)] = {{KC1, MOD1}, {KC2, MOD2}}, + +#define MK_SKEY(KCNAME, KC1, KC2) \ + [GR(KCNAME)] = {{KC1, MOD_NONE}, {KC2, MOD_NONE}}, + +#define UNSHIFTED_KEY(key) key_translations[gr(key)][0][0] +#define UNSHIFTED_MODS(key) key_translations[gr(key)][0][1] +#define SHIFTED_KEY(key) key_translations[gr(key)][1][0] +#define SHIFTED_MODS(key) key_translations[gr(key)][1][1] diff --git a/users/ericgebhart/extensions/console_key_logger.c b/users/ericgebhart/extensions/console_key_logger.c new file mode 100644 index 0000000000..074673bd06 --- /dev/null +++ b/users/ericgebhart/extensions/console_key_logger.c @@ -0,0 +1,38 @@ +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ + +#if defined( CONSOLE_ENABLE) && defined(CONSOLE_KEY_LOGGER_ENABLE) + +#include USERSPACE_H +#include "print.h" +#include "console_key_logger.h" + +void process_console_key_logger(uint16_t keycode, keyrecord_t *record) { + if (record->event.pressed) { + uprintf("0x%04X,%u,%u,%u,%b,0x%02X,0x%02X,%u\n", + keycode, + record->event.key.row, + record->event.key.col, + get_highest_layer(layer_state), + record->event.pressed, + get_mods(), + get_oneshot_mods(), + record->tap.count + ); + } +} +#endif diff --git a/users/ericgebhart/extensions/console_key_logger.h b/users/ericgebhart/extensions/console_key_logger.h new file mode 100644 index 0000000000..5e7e2d5bc0 --- /dev/null +++ b/users/ericgebhart/extensions/console_key_logger.h @@ -0,0 +1,19 @@ +#pragma once +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ + +void process_console_key_logger(uint16_t keycode, keyrecord_t *record); diff --git a/users/ericgebhart/extensions/encoders.c b/users/ericgebhart/extensions/encoders.c new file mode 100644 index 0000000000..9a3d90b82f --- /dev/null +++ b/users/ericgebhart/extensions/encoders.c @@ -0,0 +1,83 @@ +/* + Copyright 2022 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ +#ifdef ENCODER_ENABLE +#include "encoders.h" +#include USERSPACE_H + +encoder_action_t encoder_actions[] = { +#include "encoders.def" +}; +uint8_t NUM_ENCODER_ACTIONS = sizeof(encoder_actions) / sizeof(encoder_action_t); + + +bool encoder_update_user(uint8_t index, bool clockwise) { + // do it twice, once for layer actions, once for non layer specific actions. + if (!do_encoder_action(index, clockwise, true)){ + do_encoder_action(index, clockwise, false); + } + return false; +} + +bool do_encoder_action(uint8_t index, bool clockwise, bool layer_actions) { + uint8_t mods = get_mods(); + encoder_action_t *action; + + // look for a match. + // on the layer, not on any layer. + // with the mods, or no mods. + for (int i = 0; i < NUM_ENCODER_ACTIONS; ++i) { + action = &encoder_actions[i]; + + // this encoder, or another. + if (action->index != index) + continue; + + // skip non layer specific actions and visa versa + // two pass system, once for layers, again for + // actions without layers. + if (layer_actions){ + if (action->layer == LAYER_NONE || + action->layer != biton32(layer_state)){ + continue; + } + }else if (action->layer != LAYER_NONE) + continue; + + // no mods, or these mods. + if ((mods && (action->mods == MOD_NONE)) || + (mods && (mods != action->mods))) + continue; + + // found one. + if (clockwise) { + if (action->clockwise != 0) { + tap_code16(action->clockwise); + } else if (action->cw_func != NULL) { + action->cw_func(); + } + } else { + if (action->counter_clockwise != 0) { + tap_code16(action->counter_clockwise); + } else if (action->ccw_func != NULL) { + action->ccw_func(); + } + } + } + return false; +} + +#endif diff --git a/users/ericgebhart/extensions/encoders.h b/users/ericgebhart/extensions/encoders.h new file mode 100644 index 0000000000..458c5c541d --- /dev/null +++ b/users/ericgebhart/extensions/encoders.h @@ -0,0 +1,46 @@ +#pragma once +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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 + +typedef struct { + uint16_t layer; + uint16_t index; // 0 or 1, left/right. + uint16_t clockwise; + uint16_t counter_clockwise; + uint16_t mods; + void (*cw_func)(void); + void (*ccw_func)(void); +} encoder_action_t; +extern encoder_action_t encoder_actions[]; +extern uint8_t NUM_ENCODER_ACTIONS; + +// haven't looked at the real values for index, but I know +// 0 and 1 are left and right on my kyria. +#define LEFT 0 +#define RIGHT 1 +#define LAYER_NONE -1 +#define MOD_NONE 0x00 + +#define ENCODER_ACTION(LAYER, INDEX, CW_KC, CCW_KC, MOD) \ + {LAYER, INDEX, CW_KC, CCW_KC, MOD, NULL, NULL}, + +#define ENCODER_FUNCTION(LAYER, INDEX, CW_FUNC, CCW_FUNC, MOD) \ + {LAYER, INDEX, 0, 0, MOD, CW_FUNC, CCW_FUNC}, + +bool do_encoder_action(uint8_t index, bool clockwise, bool layer_actions); diff --git a/users/ericgebhart/extensions/extensions.c b/users/ericgebhart/extensions/extensions.c new file mode 100644 index 0000000000..f71e615a00 --- /dev/null +++ b/users/ericgebhart/extensions/extensions.c @@ -0,0 +1,91 @@ +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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 USERSPACE_H + +#include "extensions.h" +#include "keymap_combo.h" +#include "altlocal_keys.h" +#include "tap_hold.h" +#include "accented_keys.h" +#include "process_smart_lock.h" +#include "mod_lock.h" +#include "oneshot.h" +#include "process_nshot.h" +#include "process_locales.h" +#include "unicode.h" +#include "key_overrides.h" +#include "console_key_logger.h" + +// should make header files maybe. being lazy. +void process_not_dead(uint16_t keycode, keyrecord_t *record); +bool process_alt_shift_user(uint16_t keycode, keyrecord_t *record); +void process_send_strs(uint16_t keycode, keyrecord_t *record); +//bool process_alt_local_key(uint16_t keycode, keyrecord_t* record); +bool process_global_quick_tap(uint16_t keycode, keyrecord_t *record); + +// call this from the top of process records before the switch. + +bool process_extensions(uint16_t keycode, keyrecord_t *record){ + if (!process_locales(keycode, record)) { return false; } + +#ifdef GLOBAL_QUICK_TAP_ENABLE + if (!process_global_quick_tap(keycode, record)) {return false; } +#endif +#ifdef CAPS_WORD_ENABLE + if (!process_caps_word(keycode, record)) { return false; } +#endif +#ifdef ALT_LOCAL_ENABLE + if (!process_alt_local_key(keycode, record)) { return false; } +#endif +#ifdef ACCENTED_KEYS_ENABLE + if (!process_accent_keys(keycode, record)) { return false; } +#endif +#ifdef TAP_HOLD_ENABLE + process_tap_hold_user(keycode, record); +#endif +#ifdef SMART_LOCK_ENABLE + process_smart_lock(keycode, record); +#endif +#ifdef MOD_LOCK_ENABLE + process_mod_lock(keycode, record); +#endif +#ifdef NSHOT_ENABLE + if(!process_nshot_state(keycode, record)) {return false;} +#endif +#ifdef SEND_UNICODE_ENABLE + process_unicode_strs(keycode, record); +#endif +#ifdef SEND_STRING_ENABLE + process_send_strs(keycode, record); +#endif +#ifdef NOT_DEAD_ENABLE + process_not_dead(keycode, record); +#endif +#ifdef ALT_SHIFT_ENABLE + if(!process_alt_shift_user(keycode, record)) {return false;} +#endif +#if defined( CONSOLE_ENABLE) && defined(CONSOLE_KEY_LOGGER_ENABLE) + process_console_key_logger(keycode, record); +#endif +#ifdef ONESHOT_MOD_ENABLE + int8_t keycode_consumed = 0; + keycode_consumed += update_oneshot_modifiers(keycode, record, keycode_consumed); +#endif + return true; + +} diff --git a/users/ericgebhart/extensions/extensions.h b/users/ericgebhart/extensions/extensions.h new file mode 100644 index 0000000000..899dbdd3d6 --- /dev/null +++ b/users/ericgebhart/extensions/extensions.h @@ -0,0 +1,22 @@ +#pragma once +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ + +bool process_extensions(uint16_t keycode, keyrecord_t *record); + +#define PROCESS_EXTENSIONS \ + if (!process_extensions(keycode, record)) {return false;} diff --git a/users/ericgebhart/extensions/key_overrides.h b/users/ericgebhart/extensions/key_overrides.h new file mode 100644 index 0000000000..3fb0c9a5bb --- /dev/null +++ b/users/ericgebhart/extensions/key_overrides.h @@ -0,0 +1,53 @@ +#pragma once +/* + Copyright 2018-2022 Eric Gebhart <e.a.gebhart@gmail.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/>. +*/ +#ifdef KEY_OVERRIDE_ENABLE + +#define KO_NAME(name, ...) &name, +#define KO_T(name) const key_override_t name + +#undef KOL +#define KOL(name, mods, modded_key, replacement, layer) \ + KO_T(name) = ko_make_with_layers(mods, modded_key, replacement, (1 << layer)); + +#define KO(name, mods, key, replacement) \ + KO_T(name) = ko_make_basic(mods, key, replacement) + +#define KOLN(name, mods, key, replacement, layers, neg_mods) \ + KO_T(name) = ko_make_with_layers_and_negmods(mods, key, replacement, layers, neg_mods) + +#define KOLNO(name, mods, key, replacement, layers, neg_mods, options) \ + KO_T(name) = ko_make_with_layers_negmods_and_options \ + (mods, key, replacement, layers, neg_mods, options) + +#include "key_overrides.def" + +#undef KO |