forked from mirrors/qmk_userspace
		
	[Keymap] Drashna update for post Q2 merge (#17241)
This commit is contained in:
		
					parent
					
						
							
								b554e4b612
							
						
					
				
			
			
				commit
				
					
						cda343acbe
					
				
			
		
					 59 changed files with 672 additions and 769 deletions
				
			
		| 
						 | 
				
			
			@ -23,8 +23,8 @@
 | 
			
		|||
// clang-format off
 | 
			
		||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
  [_QWERTY] = LAYOUT(
 | 
			
		||||
     KC_VOLU, KC_MPLY, KC_MPRV, RESET,
 | 
			
		||||
     KC_VOLD, KC_MUTE, KC_MNXT, RESET
 | 
			
		||||
     KC_VOLU, KC_MPLY, KC_MPRV, QK_BOOT,
 | 
			
		||||
     KC_VOLD, KC_MUTE, KC_MNXT, QK_BOOT
 | 
			
		||||
  ),
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,38 +0,0 @@
 | 
			
		|||
/* Copyright 2020 QMK
 | 
			
		||||
 *
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This file was auto-generated by:
 | 
			
		||||
 *    `qmk chibios-confmigrate -i keyboards/handwired/onekey/blackpill_f411/chconf.h -r platforms/chibios/common/configs/chconf.h`
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_ST_FREQUENCY 10000
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_SEMAPHORES TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_MAILBOXES TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_PIPES TRUE
 | 
			
		||||
 | 
			
		||||
#include_next <chconf.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +71,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define SERIAL_USART_TX_PAL_MODE 7    // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
 | 
			
		||||
#define SERIAL_USART_RX_PAL_MODE 7    // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
 | 
			
		||||
#define SERIAL_USART_TIMEOUT     100  // USART driver timeout. default 100
 | 
			
		||||
#define SERIAL_USART_SPEED       921600
 | 
			
		||||
// #define SERIAL_USART_PIN_SWAP // swap RX and TX pins on master
 | 
			
		||||
// To use the highest possible baudrate (3.75Mbit/s) uncomment the following
 | 
			
		||||
// line, this can result in dropped communications so lower the speed if there
 | 
			
		||||
| 
						 | 
				
			
			@ -102,8 +103,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define PMW3360_SPI_MODE                     3
 | 
			
		||||
#define PMW3360_SPI_DIVISOR                  64
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#        define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
 | 
			
		||||
#        define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 400
 | 
			
		||||
#        define CHARYBDIS_MINIMUM_SNIPING_DPI 200
 | 
			
		||||
#        define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 100
 | 
			
		||||
#define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
 | 
			
		||||
#define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 400
 | 
			
		||||
#define CHARYBDIS_MINIMUM_SNIPING_DPI 200
 | 
			
		||||
#define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 100
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,13 +73,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
        _________________RAISE_L1__________________,    _________________RAISE_R1__________________,
 | 
			
		||||
        _________________RAISE_L2__________________,    _________________RAISE_R2__________________,
 | 
			
		||||
        _________________RAISE_L3__________________,    _________________RAISE_R3__________________,
 | 
			
		||||
                          REBOOT,  KEYLOCK, _______,    _______, _______
 | 
			
		||||
                          QK_RBT,  _______, _______,    _______, _______
 | 
			
		||||
    ),
 | 
			
		||||
    [_ADJUST] = LAYOUT_charybdis_3x5_wrapper(
 | 
			
		||||
        _________________ADJUST_L1_________________,    _________________ADJUST_R1_________________,
 | 
			
		||||
        _________________ADJUST_L2_________________,    _________________ADJUST_R2_________________,
 | 
			
		||||
        _________________ADJUST_L3_________________,    _________________ADJUST_R3_________________,
 | 
			
		||||
                          EEP_RST, KC_NUKE, _______,    _______, RESET
 | 
			
		||||
                          EE_CLR, KC_NUKE, _______,    _______, QK_BOOT
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -98,3 +98,9 @@ bool usb_vbus_state(void) {
 | 
			
		|||
    return readPin(USB_VBUS_PIN);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
 | 
			
		||||
    for (int32_t i = 0; i < 40; i++) {
 | 
			
		||||
        __asm__ volatile("nop" ::: "memory");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,38 +0,0 @@
 | 
			
		|||
/* Copyright 2020 QMK
 | 
			
		||||
 *
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This file was auto-generated by:
 | 
			
		||||
 *    `qmk chibios-confmigrate -i keyboards/handwired/onekey/blackpill_f411/chconf.h -r platforms/chibios/common/configs/chconf.h`
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_ST_FREQUENCY 10000
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_SEMAPHORES TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_MAILBOXES TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
 | 
			
		||||
 | 
			
		||||
#define CH_CFG_FACTORY_PIPES TRUE
 | 
			
		||||
 | 
			
		||||
#include_next <chconf.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +59,7 @@
 | 
			
		|||
// // line, this can result in dropped communications so lower the speed if there
 | 
			
		||||
// // are many timeouts.
 | 
			
		||||
// // #define SERIAL_USART_SPEED (STM32_PCLK2 >> 4)
 | 
			
		||||
#define SERIAL_USART_SPEED       921600
 | 
			
		||||
 | 
			
		||||
#define CRC8_USE_TABLE
 | 
			
		||||
#define CRC8_OPTIMIZE_SPEED
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,8 +109,16 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
        _______, _________________RAISE_L3__________________,    _________________RAISE_R3__________________, _______,
 | 
			
		||||
                                   _______, _______, _______,    _______, _______,
 | 
			
		||||
                                           _______, _______,      _______
 | 
			
		||||
  )
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    [_ADJUST] = LAYOUT_charybdis_4x6_wrapper(
 | 
			
		||||
        QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE, KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
 | 
			
		||||
        VRSN,    _________________ADJUST_L1_________________,    _________________ADJUST_R1_________________, EE_CLR,
 | 
			
		||||
        KEYLOCK, _________________ADJUST_L2_________________,    _________________ADJUST_R2_________________, TG_MODS,
 | 
			
		||||
        UC_MOD,  _________________ADJUST_L3_________________,    _________________ADJUST_R3_________________, KC_MPLY,
 | 
			
		||||
                                   QK_RBT, AUTO_CTN, _______,    KC_NUKE, _______,
 | 
			
		||||
                                           _______, _______,      _______
 | 
			
		||||
    )
 | 
			
		||||
};
 | 
			
		||||
// clang-format on
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,3 +138,9 @@ bool usb_vbus_state(void) {
 | 
			
		|||
    return readPin(USB_VBUS_PIN);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
 | 
			
		||||
    for (int32_t i = 0; i < 40; i++) {
 | 
			
		||||
        __asm__ volatile("nop" ::: "memory");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,8 +78,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
        ),
 | 
			
		||||
 | 
			
		||||
    [_ADJUST] = LAYOUT_gergo_wrapper(
 | 
			
		||||
        KC_MAKE, _________________ADJUST_L1_________________,                                           _________________ADJUST_R1_________________, KC_RESET,
 | 
			
		||||
        VRSN,    _________________ADJUST_L2_________________, _______,                         KC_NUKE, _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
        QK_MAKE, _________________ADJUST_L1_________________,                                           _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
        VRSN,    _________________ADJUST_L2_________________, _______,                         KC_NUKE, _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
        _______, _________________ADJUST_L3_________________, _______, _______,       _______, _______, _________________ADJUST_R3_________________, TG_MODS,
 | 
			
		||||
                                            _______, _______, _______, _______,       _______, _______, _______, _______
 | 
			
		||||
        ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,8 +105,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
                                                     _______, _______,    _______, _______
 | 
			
		||||
    ),
 | 
			
		||||
    [_ADJUST] = LAYOUT_4x6_right_wrapper(
 | 
			
		||||
        KC_MAKE, _________________ADJUST_L1_________________,                      _________________ADJUST_R1_________________, KC_RST,
 | 
			
		||||
        VRSN,    _________________ADJUST_L2_________________,                      _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
        QK_MAKE, _________________ADJUST_L1_________________,                      _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
        VRSN,    _________________ADJUST_L2_________________,                      _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
        UC_MOD,  _________________ADJUST_L3_________________,                      _________________ADJUST_R3_________________, TG_MODS,
 | 
			
		||||
                          HPT_DWLI, HPT_DWLD,                                                        TG_GAME, TG_DBLO,
 | 
			
		||||
                                            HPT_TOG, HPT_BUZ,                               KC_NUKE,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define SERIAL_USART_TX_PAL_MODE 7    // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
 | 
			
		||||
#define SERIAL_USART_RX_PAL_MODE 7    // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
 | 
			
		||||
#define SERIAL_USART_TIMEOUT     100  // USART driver timeout. default 100
 | 
			
		||||
 | 
			
		||||
#define SERIAL_USART_SPEED       921600
 | 
			
		||||
 | 
			
		||||
#define CRC8_USE_TABLE
 | 
			
		||||
#define CRC8_OPTIMIZE_SPEED
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,3 +58,9 @@ bool usb_vbus_state(void) {
 | 
			
		|||
    return readPin(USB_VBUS_PIN);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
 | 
			
		||||
    for (int32_t i = 0; i < 40; i++) {
 | 
			
		||||
        __asm__ volatile("nop" ::: "memory");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,13 +17,19 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define DEBOUNCE 45
 | 
			
		||||
#define ENCODER_DEFAULT_POS 0x3
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_DRIVER_SH1107
 | 
			
		||||
#    undef OLED_DISPLAY_128X64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#        define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
 | 
			
		||||
#        define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 200
 | 
			
		||||
#        define CHARYBDIS_MINIMUM_SNIPING_DPI 400
 | 
			
		||||
#        define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 200
 | 
			
		||||
#define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
 | 
			
		||||
#define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 200
 | 
			
		||||
#define CHARYBDIS_MINIMUM_SNIPING_DPI 400
 | 
			
		||||
#define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 200
 | 
			
		||||
 | 
			
		||||
#define ENCODER_DEFAULT_POS 0x3
 | 
			
		||||
 | 
			
		||||
#define SECURE_UNLOCK_SEQUENCE \
 | 
			
		||||
    {                          \
 | 
			
		||||
        { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 } \
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,25 +120,24 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
                                                     _______, _______,      _______, _______
 | 
			
		||||
    ),
 | 
			
		||||
    [_ADJUST] = LAYOUT_5x6_right_wrapper(
 | 
			
		||||
        KC_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE,                 KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, KC_RST,
 | 
			
		||||
        VRSN,    _________________ADJUST_L1_________________,                        _________________ADJUST_R1_________________, EEP_RST,
 | 
			
		||||
        QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE,                 KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
 | 
			
		||||
        VRSN,    _________________ADJUST_L1_________________,                        _________________ADJUST_R1_________________, EE_CLR,
 | 
			
		||||
        KEYLOCK, _________________ADJUST_L2_________________,                        _________________ADJUST_R2_________________, TG_MODS,
 | 
			
		||||
        UC_MOD,  _________________ADJUST_L3_________________,                        _________________ADJUST_R3_________________, KC_MPLY,
 | 
			
		||||
                   TG(_DIABLOII), AUTO_CTN,                                                            TG_GAME, TG_DBLO,
 | 
			
		||||
                                            _______, REBOOT,                                  KC_NUKE,
 | 
			
		||||
                                            _______, QK_RBT,                                  KC_NUKE,
 | 
			
		||||
                                                     _______, _______,               _______,
 | 
			
		||||
                                                     _______, _______,      KC_NUKE, _______
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define BASE_ENCODERS { { KC_VOLD, KC_VOLU }, { KC_WH_D, KC_WH_U } }
 | 
			
		||||
 | 
			
		||||
#ifdef ENCODER_MAP_ENABLE
 | 
			
		||||
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
 | 
			
		||||
    [_DEFAULT_LAYER_1] = BASE_ENCODERS,
 | 
			
		||||
    [_DEFAULT_LAYER_2] = BASE_ENCODERS,
 | 
			
		||||
    [_DEFAULT_LAYER_3] = BASE_ENCODERS,
 | 
			
		||||
    [_DEFAULT_LAYER_4] = BASE_ENCODERS,
 | 
			
		||||
    [_DEFAULT_LAYER_1] = { { KC_VOLD, KC_VOLU }, { KC_WH_D, KC_WH_U } },
 | 
			
		||||
    [_DEFAULT_LAYER_2] = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_DEFAULT_LAYER_3] = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_DEFAULT_LAYER_4] = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_GAMEPAD]         = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_DIABLO]          = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_MOUSE]           = { { _______, _______ }, { KC_WH_D, KC_WH_U } },
 | 
			
		||||
| 
						 | 
				
			
			@ -188,15 +187,15 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_ENABLE
 | 
			
		||||
extern uint16_t typing_mode;
 | 
			
		||||
#    include "keyrecords/unicode.h"
 | 
			
		||||
 | 
			
		||||
oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
 | 
			
		||||
    return OLED_ROTATION_180;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oled_render_large_display(void) {
 | 
			
		||||
    if (is_keyboard_left()) {
 | 
			
		||||
        render_wpm_graph(54, 64);
 | 
			
		||||
void oled_render_large_display(bool side) {
 | 
			
		||||
    if (side) {
 | 
			
		||||
        render_wpm_graph(56, 64);
 | 
			
		||||
    } else {
 | 
			
		||||
        oled_advance_page(true);
 | 
			
		||||
        oled_advance_page(true);
 | 
			
		||||
| 
						 | 
				
			
			@ -214,25 +213,25 @@ void oled_render_large_display(void) {
 | 
			
		|||
        oled_set_cursor(1, 14);
 | 
			
		||||
        oled_write_ln_P(PSTR("Unicode:"), false);
 | 
			
		||||
        switch (typing_mode) {
 | 
			
		||||
            case KC_WIDE:
 | 
			
		||||
            case UCTM_WIDE:
 | 
			
		||||
                oled_write_P(PSTR("        Wide"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case KC_SCRIPT:
 | 
			
		||||
            case UCTM_SCRIPT:
 | 
			
		||||
                oled_write_P(PSTR("      Script"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case KC_BLOCKS:
 | 
			
		||||
            case UCTM_BLOCKS:
 | 
			
		||||
                oled_write_P(PSTR("      Blocks"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case KC_REGIONAL:
 | 
			
		||||
            case UCTM_REGIONAL:
 | 
			
		||||
                oled_write_P(PSTR("    Regional"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case KC_AUSSIE:
 | 
			
		||||
            case UCTM_AUSSIE:
 | 
			
		||||
                oled_write_P(PSTR("      Aussie"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case KC_ZALGO:
 | 
			
		||||
            case UCTM_ZALGO:
 | 
			
		||||
                oled_write_P(PSTR("       Zalgo"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            case KC_NOMODE:
 | 
			
		||||
            case UCTM_NO_MODE:
 | 
			
		||||
                oled_write_P(PSTR("      Normal"), false);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,9 @@ ifeq ($(strip $(KEYBOARD)), handwired/tractyl_manuform/5x6_right/teensy2pp)
 | 
			
		|||
    AUTOCORRECTION_ENABLE        = no
 | 
			
		||||
    CAPS_WORD_ENABLE             = yes
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(strip $(KEYBOARD)), handwired/tractyl_manuform/5x6_right/f411)
 | 
			
		||||
    BOOTLOADER = tinyuf2
 | 
			
		||||
endif
 | 
			
		||||
# DEBOUNCE_TYPE = sym_eager_pk
 | 
			
		||||
 | 
			
		||||
OLED_DRIVER = custom
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,8 +91,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
   ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_wrapper(
 | 
			
		||||
      KC_MAKE, _______, _______, _______, _______, _______,                      _________________ADJUST_R1_________________, KC_RST,
 | 
			
		||||
      VRSN,    _________________ADJUST_L1_________________,                      KC_NUKE, _______, _______, _______, _______, EEP_RST,
 | 
			
		||||
      QK_MAKE, _______, _______, _______, _______, _______,                      _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
      VRSN,    _________________ADJUST_L1_________________,                      KC_NUKE, _______, _______, _______, _______, EE_CLR,
 | 
			
		||||
      _______, _________________ADJUST_L2_________________,                      _________________ADJUST_R2_________________, TG_MODS,
 | 
			
		||||
      _______, _________________ADJUST_L3_________________, TG_GAME,    _______, _________________ADJUST_R3_________________, KC_MPLY,
 | 
			
		||||
                                        _______, _______, _______,        _______, _______, _______
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,8 +51,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_MEDIA] = LAYOUT_ortho_5x7(
 | 
			
		||||
      KC_MAKE, RESET,   MU_TOG,  AU_ON,   AU_OFF,  CK_TOGG, RGB_SAD,
 | 
			
		||||
      _______, EEP_RST, KC_RGB_T,RGB_M_P, RGB_M_B, RGB_M_R, RGB_SAI,
 | 
			
		||||
      QK_MAKE, QK_BOOT, MU_TOG,  AU_ON,   AU_OFF,  CK_TOGG, RGB_SAD,
 | 
			
		||||
      _______, EE_CLR, KC_RGB_T,RGB_M_P, RGB_M_B, RGB_M_R, RGB_SAI,
 | 
			
		||||
      RGB_TOG, RGB_MOD, RGB_RMOD,RGB_M_SW,RGB_M_SN,RGB_M_K, RGB_HUD,
 | 
			
		||||
      KC_MPLY, KC_MPRV, KC_MNXT, RGB_M_X, RGB_M_G, RGB_M_P, RGB_HUI,
 | 
			
		||||
      KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, XXXXXXX, RGB_VAD, RGB_VAI
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,8 +75,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_wrapper(
 | 
			
		||||
    KC_MAKE, _________________ADJUST_L1_________________, KC_NUKE, _________________ADJUST_R1_________________, KC_RST,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________, MG_NKRO, _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
    QK_MAKE, _________________ADJUST_L1_________________, KC_NUKE, _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________, MG_NKRO, _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
    TG_MODS, _________________ADJUST_L3_________________, KC_RGB_T,_________________ADJUST_R3_________________, RGB_IDL
 | 
			
		||||
  )
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,7 +79,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
        KC_Q,    CALTDEL, \
 | 
			
		||||
        KC_A,    TSKMGR, \
 | 
			
		||||
        KC_Z,    KC_X, \
 | 
			
		||||
        _______, RESET \
 | 
			
		||||
        _______, QK_BOOT \
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,5 +18,10 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define TAPPING_TERM_PER_KEY
 | 
			
		||||
#define WAIT_FOR_USB
 | 
			
		||||
// #define WAIT_FOR_USB
 | 
			
		||||
// #define NO_USB_STARTUP_CHECK
 | 
			
		||||
 | 
			
		||||
#define SECURE_UNLOCK_SEQUENCE \
 | 
			
		||||
    {                          \
 | 
			
		||||
        { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 } \
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,12 +106,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
    ),
 | 
			
		||||
 | 
			
		||||
    [_ADJUST] = LAYOUT_moonlander_wrapper(
 | 
			
		||||
        KC_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE,_______,   KC_NUKE,KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, KC_RST,
 | 
			
		||||
        VRSN,    _________________ADJUST_L1_________________, TG(_DIABLOII),  _______, _________________ADJUST_R1_________________, EEP_RST,
 | 
			
		||||
        QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE,_______,   KC_NUKE,KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
 | 
			
		||||
        VRSN,    _________________ADJUST_L1_________________, TG(_DIABLOII),  _______, _________________ADJUST_R1_________________, EE_CLR,
 | 
			
		||||
        KEYLOCK, _________________ADJUST_L2_________________, _______,        _______, _________________ADJUST_R2_________________, RGB_IDL,
 | 
			
		||||
        UC_MOD,  _________________ADJUST_L3_________________,                          _________________ADJUST_R3_________________, TG_MODS,
 | 
			
		||||
        _______, _______, _______, _______, _______,          _______,        _______,          _______, _______, _______, _______, AUTO_CTN,
 | 
			
		||||
                                            REBOOT,  _______, _______,        _______, _______, _______
 | 
			
		||||
                                            QK_RBT,  _______, _______,        _______, _______, _______
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,8 +61,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_wrapper(\
 | 
			
		||||
    KC_MAKE, _________________ADJUST_L1_________________,                                                               _________________ADJUST_R1_________________, KC_RESET,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________,          _______, _______,         _______, KC_NUKE,          _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
    QK_MAKE, _________________ADJUST_L1_________________,                                                               _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________,          _______, _______,         _______, KC_NUKE,          _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
    TG_MODS, _________________ADJUST_L3_________________, _______, _______, _______,         _______, _______, _______, _________________ADJUST_R3_________________, KC_MPLY
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,3 +27,5 @@
 | 
			
		|||
#define RGBLIGHT_EFFECT_KNIGHT
 | 
			
		||||
#define RGBLIGHT_EFFECT_TWINKLE
 | 
			
		||||
#define RGBLIGHT_SLEEP
 | 
			
		||||
 | 
			
		||||
#define MOUSE_EXT_REPORT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
    [0] = LAYOUT(/* Base */
 | 
			
		||||
                 C(KC_C), KC_BTN1, KC_BTN3, KC_BTN2, MO(1), KC_BTN4, KC_BTN5, DPI_CONFIG),
 | 
			
		||||
    [1] = LAYOUT(/* Base */
 | 
			
		||||
                 RGB_HUI, RGB_MOD, RGB_TOG, RGB_RMOD, MO(1), KC_VOLU, KC_VOLD, RESET)
 | 
			
		||||
                 RGB_HUI, RGB_MOD, RGB_TOG, RGB_RMOD, MO(1), KC_VOLU, KC_VOLD, QK_BOOT)
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,5 +46,4 @@
 | 
			
		|||
#define BOOTMAGIC_LITE_ROW_RIGHT    4
 | 
			
		||||
#define BOOTMAGIC_LITE_COLUMN_RIGHT 7
 | 
			
		||||
 | 
			
		||||
#define I2C1_CLOCK_SPEED 400000
 | 
			
		||||
#define I2C1_DUTY_CYCLE  FAST_DUTY_CYCLE_2
 | 
			
		||||
#define SERIAL_USART_SPEED       921600
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,10 +90,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
                                   _______, _______, _______, _______, _______,   _______, _______, _______, _______, _______
 | 
			
		||||
    ),
 | 
			
		||||
    [_ADJUST] = LAYOUT_wrapper(
 | 
			
		||||
        KC_MAKE, _________________ADJUST_L1_________________,                                       _________________ADJUST_R1_________________, KC_RESET,
 | 
			
		||||
        VRSN,    _________________ADJUST_L2_________________,                                       _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
        QK_MAKE, _________________ADJUST_L1_________________,                                       _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
        VRSN,    _________________ADJUST_L2_________________,                                       _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
        UC_MOD,  _________________ADJUST_L3_________________, HPT_TOG, HPT_FBK,   MG_NKRO, UC_MOD,  _________________ADJUST_R3_________________, TG_MODS,
 | 
			
		||||
                                   REBOOT,  _______, KEYLOCK, KC_NUKE, _______,   _______, _______, _______, _______, AUTO_CTN
 | 
			
		||||
                                   QK_RBT,  _______, KEYLOCK, KC_NUKE, _______,   _______, _______, _______, _______, AUTO_CTN
 | 
			
		||||
    ),
 | 
			
		||||
//     [_LAYERINDEX] = LAYOUT_wrapper(
 | 
			
		||||
//       _______, _______, _______, _______, _______, _______,                                       _______, _______, _______, _______, _______, _______,
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
 | 
			
		||||
#ifdef ENCODER_MAP_ENABLE
 | 
			
		||||
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
 | 
			
		||||
    [_DEFAULT_LAYER_1] = { { KC_DOWN, KC_UP   }, { KC_VOLD, KC_VOLU } },
 | 
			
		||||
    [_DEFAULT_LAYER_1] = { { KC_VOLD, KC_VOLU }, { KC_WH_D, KC_WH_U } },
 | 
			
		||||
    [_DEFAULT_LAYER_2] = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_DEFAULT_LAYER_3] = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
    [_DEFAULT_LAYER_4] = { { _______, _______ }, { _______, _______ } },
 | 
			
		||||
| 
						 | 
				
			
			@ -129,9 +129,9 @@ oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oled_render_large_display(void) {
 | 
			
		||||
    if (is_keyboard_left()) {
 | 
			
		||||
        render_wpm_graph(54, 64);
 | 
			
		||||
void oled_render_large_display(bool side) {
 | 
			
		||||
    if (side) {
 | 
			
		||||
        render_wpm_graph(56, 64);
 | 
			
		||||
    } else {
 | 
			
		||||
        static const char PROGMEM kyria_logo[] = {
 | 
			
		||||
            0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128,128,192,224,240,112,120, 56, 60, 28, 30, 14, 14, 14,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 14, 14, 14, 30, 28, 60, 56,120,112,240,224,192,128,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
| 
						 | 
				
			
			@ -149,27 +149,6 @@ void oled_render_large_display(void) {
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENCODER_ENABLE
 | 
			
		||||
bool encoder_update_user(uint8_t index, bool clockwise) {
 | 
			
		||||
    if (index == 0) {
 | 
			
		||||
        // Volume control
 | 
			
		||||
        if (clockwise) {
 | 
			
		||||
            tap_code(KC_VOLU);
 | 
			
		||||
        } else {
 | 
			
		||||
            tap_code(KC_VOLD);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (index == 1) {
 | 
			
		||||
        // Page up/Page down
 | 
			
		||||
        if (clockwise) {
 | 
			
		||||
            tap_code(KC_PGDN);
 | 
			
		||||
        } else {
 | 
			
		||||
            tap_code(KC_PGUP);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RGBLIGHT_LAYERS
 | 
			
		||||
const rgblight_segment_t PROGMEM shift_layers[]   = RGBLIGHT_LAYER_SEGMENTS({8, 1, 120, 255, 255}, {18, 1, 120, 255, 255});
 | 
			
		||||
const rgblight_segment_t PROGMEM control_layers[] = RGBLIGHT_LAYER_SEGMENTS({6, 1, 0, 255, 255}, {16, 1, 0, 255, 255});
 | 
			
		||||
| 
						 | 
				
			
			@ -188,3 +167,12 @@ void matrix_scan_keymap(void) {
 | 
			
		|||
    rgblight_set_layer_state(3, mods & MOD_MASK_GUI);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef KEYBOARD_splitkb_kyria_rev1_proton_c
 | 
			
		||||
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
 | 
			
		||||
    for (int32_t i = 0; i < 40; i++) {
 | 
			
		||||
        __asm__ volatile("nop" ::: "memory");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,11 +17,10 @@ ifeq ($(strip $(KEYBOARD)), splitkb/kyria/rev1/proton_c)
 | 
			
		|||
    TAP_DANCE_ENABLE       = yes
 | 
			
		||||
    SWAP_HANDS_ENABLE      = yes
 | 
			
		||||
    LTO_ENABLE             = no
 | 
			
		||||
    CTPC                   = yes
 | 
			
		||||
    ENCODER_MAP_ENABLE     = yes
 | 
			
		||||
    AUTOCORRECTION_ENABLE  = yes
 | 
			
		||||
    CAPS_WORD_ENABLE       = yes
 | 
			
		||||
    OLED_DRIVER            = custom
 | 
			
		||||
    DEBUG_MATRIX_SCAN_RATE_ENABLE = api
 | 
			
		||||
else
 | 
			
		||||
    LTO_ENABLE             = yes
 | 
			
		||||
    BOOTLOADER             = qmk-hid
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
        KC_P1,   KC_P2,   KC_P3
 | 
			
		||||
    ),
 | 
			
		||||
    [1] = LAYOUT_ortho_4x3( /* Layer 1 */
 | 
			
		||||
        RESET,   _______, XXXXXXX,
 | 
			
		||||
        QK_BOOT, _______, XXXXXXX,
 | 
			
		||||
        AU_ON,   AU_OFF,  XXXXXXX,
 | 
			
		||||
        CK_TOGG, XXXXXXX, CK_UP,
 | 
			
		||||
        CK_RST,  XXXXXXX, CK_DOWN
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,8 +83,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_wrapper(
 | 
			
		||||
    KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RST, _______,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
    QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT, _______,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
    _______, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL,
 | 
			
		||||
    KEYLOCK, _______, _______, _______, _______, KC_NUKE, _______, _______, _______, _______, _______, TG_MODS
 | 
			
		||||
  )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -167,8 +167,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
            ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_ergodox_pretty_wrapper(
 | 
			
		||||
             KC_MAKE, _______, _______, _______, _______, _______, UC_MOD,                  KC_NUKE, _________________ADJUST_R1_________________, KC_RST,
 | 
			
		||||
             VRSN,    _________________ADJUST_L1_________________, _______,                 _______, _________________ADJUST_R1_________________, EEP_RST,
 | 
			
		||||
             QK_MAKE, _______, _______, _______, _______, _______, UC_MOD,                  KC_NUKE, _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
             VRSN,    _________________ADJUST_L1_________________, _______,                 _______, _________________ADJUST_R1_________________, EE_CLR,
 | 
			
		||||
             _______, _________________ADJUST_L2_________________,                                   _________________ADJUST_R2_________________, RGB_IDL,
 | 
			
		||||
             KEYLOCK, _________________ADJUST_L3_________________, _______,                 _______, _________________ADJUST_R3_________________, TG_MODS,
 | 
			
		||||
             _______, _______, _______, _______, _______,                                                     _______, _______, _______, _______, _______,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_GAMEPAD] = LAYOUT_numpad_5x6(
 | 
			
		||||
		RGB_TOG, _______,  _______, EEP_RST, KC_MAKE, RESET,
 | 
			
		||||
		RGB_TOG, _______,  _______, EE_CLR, QK_MAKE, QK_BOOT,
 | 
			
		||||
		RGB_MOD, RGB_RMOD, _______, _______, _______,
 | 
			
		||||
		RGB_HUI, RGB_HUD,  _______, _______, _______, _______,
 | 
			
		||||
		RGB_SAI, RGB_SAD,  _______, _______, _______,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,10 +103,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_ortho_4x12_wrapper(
 | 
			
		||||
    KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RST,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
    QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
    TH_LVL,  _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL,
 | 
			
		||||
    KEYLOCK, _______, _______, REBOOT,  _______, KC_NUKE, _______, _______, AUTO_CTN,_______, _______, TG_MODS
 | 
			
		||||
    KEYLOCK, _______, _______, QK_RBT,  _______, KC_NUKE, _______, _______, AUTO_CTN,_______, _______, TG_MODS
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,8 +121,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
 * `-----------------------------------------------------------------------------------'
 | 
			
		||||
 */
 | 
			
		||||
[_ADJUST] = LAYOUT_ortho_5x12_wrapper( \
 | 
			
		||||
  KC_MAKE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RST,
 | 
			
		||||
  VRSN,    _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EEP_RST,
 | 
			
		||||
  QK_MAKE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, QK_BOOT,
 | 
			
		||||
  VRSN,    _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EE_CLR,
 | 
			
		||||
  _______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, RGB_IDL,
 | 
			
		||||
  KEYLOCK, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS,
 | 
			
		||||
  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,10 +87,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
  ),
 | 
			
		||||
 | 
			
		||||
  [_ADJUST] = LAYOUT_split_3x6_3_wrapper( \
 | 
			
		||||
    KC_MAKE, _________________ADJUST_L1_________________,                    _________________ADJUST_R1_________________, KC_RESET,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________,                    _________________ADJUST_R2_________________, EEP_RST,
 | 
			
		||||
    QK_MAKE, _________________ADJUST_L1_________________,                    _________________ADJUST_R1_________________, QK_BOOT,
 | 
			
		||||
    VRSN,    _________________ADJUST_L2_________________,                    _________________ADJUST_R2_________________, EE_CLR,
 | 
			
		||||
    KEYLOCK, _________________ADJUST_L3_________________,                    _________________ADJUST_R3_________________, RGB_IDL,
 | 
			
		||||
                                     REBOOT, KC_NUKE, _______,        _______, TG_MODS, AUTO_CTN
 | 
			
		||||
                                     QK_RBT, KC_NUKE, _______,        _______, TG_MODS, AUTO_CTN
 | 
			
		||||
  )
 | 
			
		||||
};
 | 
			
		||||
// clang-format on
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +120,9 @@ uint32_t anim_frame_duration = 500;
 | 
			
		|||
uint8_t  current_sleep_frame = 0;
 | 
			
		||||
uint8_t  current_wake_frame  = 0;  // uncomment if WAKE_FRAMES >1
 | 
			
		||||
uint8_t  current_kaki_frame  = 0;
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
uint8_t  current_rtogi_frame = 0;
 | 
			
		||||
#endif
 | 
			
		||||
// uint8_t current_ltogi_frame = 0;
 | 
			
		||||
// clang-format off
 | 
			
		||||
void render_small_kitty(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -171,6 +173,7 @@ void render_small_kitty(void) {
 | 
			
		|||
                                                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x0a, 0x0e, 0x1d, 0x95, 0x24, 0x24, 0x27, 0x13, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00,
 | 
			
		||||
                                                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x14, 0x08,
 | 
			
		||||
                                                                }};
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
    static const char PROGMEM rtogi[KAKI_FRAMES][ANIM_SIZE]  = {{
 | 
			
		||||
                                                                    // 'rtogi1', 32x32px
 | 
			
		||||
                                                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x90, 0x10, 0x20, 0xf0, 0xf8, 0xf8,
 | 
			
		||||
| 
						 | 
				
			
			@ -184,15 +187,20 @@ void render_small_kitty(void) {
 | 
			
		|||
                                                                    0x0f, 0x11, 0x22, 0x44, 0x48, 0x4c, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x06, 0x01,
 | 
			
		||||
                                                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 | 
			
		||||
                                                                }};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    // assumes 1 frame prep stage
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
    extern bool swap_hands;
 | 
			
		||||
#endif
 | 
			
		||||
    void        animation_phase(void) {
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
        if (swap_hands) {
 | 
			
		||||
            anim_frame_duration = 300;
 | 
			
		||||
            current_rtogi_frame = (current_rtogi_frame + 1) % RTOGI_FRAMES;
 | 
			
		||||
            oled_write_raw_P(rtogi[abs((RTOGI_FRAMES - 1) - current_rtogi_frame)], ANIM_SIZE);
 | 
			
		||||
        } else {
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
        {
 | 
			
		||||
            if (get_current_wpm() <= SLEEP_SPEED) {
 | 
			
		||||
                anim_frame_duration = 500;
 | 
			
		||||
                current_sleep_frame = (current_sleep_frame + 1) % SLEEP_FRAMES;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,13 +14,21 @@ UNICODE_ENABLE             = no  # Unicode
 | 
			
		|||
RGBLIGHT_ENABLE            = no  # Enable WS2812 RGB underlight.
 | 
			
		||||
SWAP_HANDS_ENABLE          = no  # Enable one-hand typing
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(KEYBOARD)), crkbd/rev1)
 | 
			
		||||
    OLED_ENABLE            = yes
 | 
			
		||||
    RGB_MATRIX_ENABLE      = yes
 | 
			
		||||
    HAPTIC_ENABLE          = no
 | 
			
		||||
USE_ARM_CONFIG ?= no
 | 
			
		||||
ifeq ($(strip $(CONVERT_TO)), proton_c)
 | 
			
		||||
    USE_ARM_CONFIG = yes
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(strip $(CTPC)), yes)
 | 
			
		||||
    USE_ARM_CONFIG = yes
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(strip $(MCU)), STM32F303)
 | 
			
		||||
    USE_ARM_CONFIG = yes
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(strip $(MCU)), STM32F401)
 | 
			
		||||
    USE_ARM_CONFIG = yes
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(CTPC)), yes)
 | 
			
		||||
ifeq ($(strip $(USE_ARM_CONFIG)), yes)
 | 
			
		||||
    HAPTIC_ENABLE          = no
 | 
			
		||||
    WS2812_DRIVER          = pwm # won't work without a patch to the ctpc mk file
 | 
			
		||||
    SERIAL_DRIVER          = usart
 | 
			
		||||
| 
						 | 
				
			
			@ -33,3 +41,13 @@ else
 | 
			
		|||
    BOOTLOADER             = qmk-hid
 | 
			
		||||
    BOOTLOADER_SIZE        = 512
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(KEYBOARD)), crkbd/rev1)
 | 
			
		||||
    OLED_ENABLE            = yes
 | 
			
		||||
    RGB_MATRIX_ENABLE      = yes
 | 
			
		||||
    HAPTIC_ENABLE          = no
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(KEYBOARD)), cantor)
 | 
			
		||||
    SWAP_HANDS_ENABLE      = no
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								users/drashna/autocorrect_data.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								users/drashna/autocorrect_data.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
#if __has_include("../qmk_secrets/autocorrection_data.h")
 | 
			
		||||
#    include "../qmk_secrets/autocorrection_data.h"
 | 
			
		||||
#else
 | 
			
		||||
#    include "autocorrect_data_default.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +87,9 @@ void suspend_power_down_user(void) {
 | 
			
		|||
 | 
			
		||||
__attribute__((weak)) void suspend_wakeup_init_keymap(void) {}
 | 
			
		||||
void                       suspend_wakeup_init_user(void) {
 | 
			
		||||
#ifdef OLED_ENABLE
 | 
			
		||||
        oled_timer_reset();
 | 
			
		||||
#endif
 | 
			
		||||
    suspend_wakeup_init_keymap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,3 @@ void matrix_init_unicode(void);
 | 
			
		|||
#ifdef SPLIT_KEYBOARD
 | 
			
		||||
void matrix_slave_scan_keymap(void);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CAPS_WORD_ENABLE
 | 
			
		||||
#    include "keyrecords/caps_word.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,9 +37,9 @@
 | 
			
		|||
// #    define WPM_LAUNCH_CONTROL
 | 
			
		||||
// #    define WPM_ALLOW_COUNT_REGRESSOIN
 | 
			
		||||
// #    define WPM_UNFILTERED
 | 
			
		||||
#    define WPM_SAMPLE_SECONDS      6
 | 
			
		||||
#    define WPM_SAMPLE_SECONDS      10
 | 
			
		||||
#    define WPM_SAMPLE_PERIODS      50
 | 
			
		||||
#    define WPM_ESTIMATED_WORD_SIZE 6
 | 
			
		||||
#    define WPM_ESTIMATED_WORD_SIZE 5
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef AUDIO_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -291,6 +291,12 @@
 | 
			
		|||
#    ifndef OLED_BRIGHTNESS
 | 
			
		||||
#        define OLED_BRIGHTNESS 50
 | 
			
		||||
#    endif
 | 
			
		||||
#    if !defined(STM32F4XX)
 | 
			
		||||
#        undef OLED_UPDATE_INTERVAL
 | 
			
		||||
#    define OLED_UPDATE_INTERVAL 100
 | 
			
		||||
#        define OLED_UPDATE_INTERVAL 75
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define ENABLE_COMPILE_KEYCODE
 | 
			
		||||
 | 
			
		||||
#define BOTH_SHIFTS_TURNS_ON_CAPS_WORD
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,13 @@
 | 
			
		|||
#    pragma GCC push_options
 | 
			
		||||
#    pragma GCC optimize("O0")
 | 
			
		||||
#    include "autocorrection_data.h"
 | 
			
		||||
#    ifndef AUTOCORRECTION_MIN_LENGTH
 | 
			
		||||
#        define AUTOCORRECTION_MIN_LENGTH AUTOCORRECT_MIN_LENGTH
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef AUTOCORRECTION_MAX_LENGTH
 | 
			
		||||
#        define AUTOCORRECTION_MAX_LENGTH AUTOCORRECT_MAX_LENGTH
 | 
			
		||||
#    endif
 | 
			
		||||
#    define autocorrection_data autocorrect_data
 | 
			
		||||
#    if AUTOCORRECTION_MIN_LENGTH < 4
 | 
			
		||||
#        error Minimum Length is too short and may cause overflows
 | 
			
		||||
#    endif
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +24,138 @@
 | 
			
		|||
#        error Dictionary size excees maximum size permitted
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
static uint8_t typo_buffer[AUTOCORRECT_MAX_LENGTH] = {KC_SPC};
 | 
			
		||||
static uint8_t typo_buffer_size                    = 1;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief function for querying the enabled state of autocorrect
 | 
			
		||||
 *
 | 
			
		||||
 * @return true if enabled
 | 
			
		||||
 * @return false if disabled
 | 
			
		||||
 */
 | 
			
		||||
bool autocorrect_is_enabled(void) {
 | 
			
		||||
    return userspace_config.autocorrection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Enables autocorrect and saves state to eeprom
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void autocorrect_enable(void) {
 | 
			
		||||
    userspace_config.autocorrection = true;
 | 
			
		||||
    eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Disables autocorrect and saves state to eeprom
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void autocorrect_disable(void) {
 | 
			
		||||
    userspace_config.autocorrection = false;
 | 
			
		||||
    typo_buffer_size                 = 0;
 | 
			
		||||
    eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Toggles autocorrect's status and save state to eeprom
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void autocorrect_toggle(void) {
 | 
			
		||||
    userspace_config.autocorrection = !userspace_config.autocorrection;
 | 
			
		||||
    typo_buffer_size                 = 0;
 | 
			
		||||
    eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief handler for determining if autocorrect should process keypress
 | 
			
		||||
 *
 | 
			
		||||
 * @param keycode Keycode registered by matrix press, per keymap
 | 
			
		||||
 * @param record keyrecord_t structure
 | 
			
		||||
 * @param typo_buffer_size passed along to allow resetting of autocorrect buffer
 | 
			
		||||
 * @param mods allow processing of mod status
 | 
			
		||||
 * @return true Allow autocorection
 | 
			
		||||
 * @return false Stop processing and escape from autocorrect.
 | 
			
		||||
 */
 | 
			
		||||
__attribute__((weak)) bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) {
 | 
			
		||||
    // See quantum_keycodes.h for reference on these matched ranges.
 | 
			
		||||
    switch (*keycode) {
 | 
			
		||||
        // Exclude these keycodes from processing.
 | 
			
		||||
        case KC_LSFT:
 | 
			
		||||
        case KC_RSFT:
 | 
			
		||||
        case KC_CAPS:
 | 
			
		||||
        case QK_TO ... QK_ONE_SHOT_LAYER_MAX:
 | 
			
		||||
        case QK_LAYER_TAP_TOGGLE ... QK_LAYER_MOD_MAX:
 | 
			
		||||
        case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        // Mask for base keycode from shifted keys.
 | 
			
		||||
        case QK_LSFT ... QK_LSFT + 255:
 | 
			
		||||
        case QK_RSFT ... QK_RSFT + 255:
 | 
			
		||||
            if (*keycode >= QK_LSFT && *keycode <= (QK_LSFT + 255)) {
 | 
			
		||||
                *mods |= MOD_LSFT;
 | 
			
		||||
            } else {
 | 
			
		||||
                *mods |= MOD_RSFT;
 | 
			
		||||
            }
 | 
			
		||||
            *keycode &= 0xFF; // Get the basic keycode.
 | 
			
		||||
            return true;
 | 
			
		||||
#ifndef NO_ACTION_TAPPING
 | 
			
		||||
        // Exclude tap-hold keys when they are held down
 | 
			
		||||
        // and mask for base keycode when they are tapped.
 | 
			
		||||
        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
 | 
			
		||||
#    ifdef NO_ACTION_LAYER
 | 
			
		||||
            // Exclude Layer Tap, if layers are disabled
 | 
			
		||||
            // but action tapping is still enabled.
 | 
			
		||||
            return false;
 | 
			
		||||
#    endif
 | 
			
		||||
        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
 | 
			
		||||
            // Exclude hold keycode
 | 
			
		||||
            if (!record->tap.count) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            *keycode &= 0xFF;
 | 
			
		||||
            break;
 | 
			
		||||
#else
 | 
			
		||||
        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
 | 
			
		||||
        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
 | 
			
		||||
            // Exclude if disabled
 | 
			
		||||
            return false;
 | 
			
		||||
#endif
 | 
			
		||||
        // Exclude swap hands keys when they are held down
 | 
			
		||||
        // and mask for base keycode when they are tapped.
 | 
			
		||||
        case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
            if (*keycode >= 0x56F0 || !record->tap.count) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            *keycode &= 0xFF;
 | 
			
		||||
            break;
 | 
			
		||||
#else
 | 
			
		||||
            // Exclude if disabled
 | 
			
		||||
            return false;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Disable autocorrect while a mod other than shift is active.
 | 
			
		||||
    if ((*mods & ~MOD_MASK_SHIFT) != 0) {
 | 
			
		||||
        *typo_buffer_size = 0;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief handling for when autocorrection has been triggered
 | 
			
		||||
 *
 | 
			
		||||
 * @param backspaces number of characters to remove
 | 
			
		||||
 * @param str pointer to PROGMEM string to replace mistyped seletion with
 | 
			
		||||
 * @return true apply correction
 | 
			
		||||
 * @return false user handled replacement
 | 
			
		||||
 */
 | 
			
		||||
__attribute__((weak)) bool apply_autocorrect(uint8_t backspaces, const char *str) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Process handler for autocorrect feature
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -25,131 +164,124 @@
 | 
			
		|||
 * @return true Continue processing keycodes, and send to host
 | 
			
		||||
 * @return false Stop processing keycodes, and don't send to host
 | 
			
		||||
 */
 | 
			
		||||
bool process_autocorrection(uint16_t keycode, keyrecord_t* record) {
 | 
			
		||||
    static uint8_t typo_buffer[AUTOCORRECTION_MAX_LENGTH] = {KC_SPC};
 | 
			
		||||
    static uint8_t typo_buffer_size                       = 1;
 | 
			
		||||
bool process_autocorrection(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    uint8_t mods = get_mods();
 | 
			
		||||
#ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    mods |= get_oneshot_mods();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (keycode == AUTO_CTN) {
 | 
			
		||||
        if (record->event.pressed) {
 | 
			
		||||
            typo_buffer_size = 0;
 | 
			
		||||
            userspace_config.autocorrection ^= 1;
 | 
			
		||||
            eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
    if ((keycode >= AUTOCORRECT_ON && keycode <= AUTOCORRECT_TOGGLE) && record->event.pressed) {
 | 
			
		||||
        if (keycode == AUTOCORRECT_ON) {
 | 
			
		||||
            autocorrect_enable();
 | 
			
		||||
        } else if (keycode == AUTOCORRECT_OFF) {
 | 
			
		||||
            autocorrect_disable();
 | 
			
		||||
        } else if (keycode == AUTOCORRECT_TOGGLE) {
 | 
			
		||||
            autocorrect_toggle();
 | 
			
		||||
        } else {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!userspace_config.autocorrection) {
 | 
			
		||||
    if (!autocorrect_is_enabled()) {
 | 
			
		||||
        typo_buffer_size = 0;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        case KC_LSFT:
 | 
			
		||||
        case KC_RSFT:
 | 
			
		||||
            return true;
 | 
			
		||||
#    ifndef NO_ACTION_TAPPING
 | 
			
		||||
        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
 | 
			
		||||
            if (((keycode >> 8) & 0xF) == MOD_LSFT) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
#        ifndef NO_ACTION_LAYER
 | 
			
		||||
        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
 | 
			
		||||
#        endif
 | 
			
		||||
            if (record->event.pressed || !record->tap.count) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            keycode &= 0xFF;
 | 
			
		||||
            break;
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
        case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
 | 
			
		||||
            if (keycode >= 0x56F0 || record->event.pressed || !record->tap.count) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            keycode &= 0xFF;
 | 
			
		||||
            break;
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef NO_ACTION_ONESHOT
 | 
			
		||||
        case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
 | 
			
		||||
            if ((keycode & 0xF) == MOD_LSFT) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
#    endif
 | 
			
		||||
        default:
 | 
			
		||||
            // Disable autocorrection while a mod other than shift is active.
 | 
			
		||||
            if (((get_mods() | get_oneshot_mods()) & ~MOD_MASK_SHIFT) != 0) {
 | 
			
		||||
                typo_buffer_size = 0;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
    if (!record->event.pressed) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // autocorrect keycode verification and extraction
 | 
			
		||||
    if (!process_autocorrect_user(&keycode, record, &typo_buffer_size, &mods)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Subtract buffer for Backspace key, reset for other non-alpha.
 | 
			
		||||
    if (!(KC_A <= keycode && keycode <= KC_Z)) {
 | 
			
		||||
        if (keycode == KC_BSPC) {
 | 
			
		||||
    // keycode buffer check
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        case KC_A ... KC_Z:
 | 
			
		||||
            // process normally
 | 
			
		||||
            break;
 | 
			
		||||
        case KC_1 ... KC_0:
 | 
			
		||||
        case KC_TAB ... KC_SEMICOLON:
 | 
			
		||||
        case KC_GRAVE ... KC_SLASH:
 | 
			
		||||
            // Set a word boundary if space, period, digit, etc. is pressed.
 | 
			
		||||
            keycode = KC_SPC;
 | 
			
		||||
            break;
 | 
			
		||||
        case KC_ENTER:
 | 
			
		||||
            // Behave more conservatively for the enter key. Reset, so that enter
 | 
			
		||||
            // can't be used on a word ending.
 | 
			
		||||
            typo_buffer_size = 0;
 | 
			
		||||
            keycode          = KC_SPC;
 | 
			
		||||
            break;
 | 
			
		||||
        case KC_BSPC:
 | 
			
		||||
            // Remove last character from the buffer.
 | 
			
		||||
            if (typo_buffer_size > 0) {
 | 
			
		||||
                --typo_buffer_size;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (KC_1 <= keycode && keycode <= KC_SLSH && keycode != KC_ESC) {
 | 
			
		||||
            // Set a word boundary if space, period, digit, etc. is pressed.
 | 
			
		||||
            // Behave more conservatively for the enter key. Reset, so that enter
 | 
			
		||||
            // can't be used on a word ending.
 | 
			
		||||
            if (keycode == KC_ENT || (keycode == KC_MINUS && (get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT)) {
 | 
			
		||||
                typo_buffer_size = 0;
 | 
			
		||||
            }
 | 
			
		||||
        case KC_QUOTE:
 | 
			
		||||
            // Treat " (shifted ') as a word boundary.
 | 
			
		||||
            if ((mods & MOD_MASK_SHIFT) != 0) {
 | 
			
		||||
                keycode = KC_SPC;
 | 
			
		||||
        } else {
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            // Clear state if some other non-alpha key is pressed.
 | 
			
		||||
            typo_buffer_size = 0;
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Rotate oldest character if buffer is full.
 | 
			
		||||
    if (typo_buffer_size >= AUTOCORRECTION_MAX_LENGTH) {
 | 
			
		||||
        memmove(typo_buffer, typo_buffer + 1, AUTOCORRECTION_MAX_LENGTH - 1);
 | 
			
		||||
        typo_buffer_size = AUTOCORRECTION_MAX_LENGTH - 1;
 | 
			
		||||
    if (typo_buffer_size >= AUTOCORRECT_MAX_LENGTH) {
 | 
			
		||||
        memmove(typo_buffer, typo_buffer + 1, AUTOCORRECT_MAX_LENGTH - 1);
 | 
			
		||||
        typo_buffer_size = AUTOCORRECT_MAX_LENGTH - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Append `keycode` to buffer.
 | 
			
		||||
    typo_buffer[typo_buffer_size++] = keycode;
 | 
			
		||||
    // Return if buffer is smaller than the shortest word.
 | 
			
		||||
    if (typo_buffer_size < AUTOCORRECTION_MIN_LENGTH) {
 | 
			
		||||
    if (typo_buffer_size < AUTOCORRECT_MIN_LENGTH) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check for typo in buffer using a trie stored in `autocorrection_data`.
 | 
			
		||||
    // Check for typo in buffer using a trie stored in `autocorrect_data`.
 | 
			
		||||
    uint16_t state = 0;
 | 
			
		||||
    uint8_t  code  = pgm_read_byte(autocorrection_data + state);
 | 
			
		||||
    for (uint8_t i = typo_buffer_size - 1; i >= 0; --i) {
 | 
			
		||||
    uint8_t  code  = pgm_read_byte(autocorrect_data + state);
 | 
			
		||||
    for (int8_t i = typo_buffer_size - 1; i >= 0; --i) {
 | 
			
		||||
        uint8_t const key_i = typo_buffer[i];
 | 
			
		||||
 | 
			
		||||
        if (code & 64) { // Check for match in node with multiple children.
 | 
			
		||||
            code &= 63;
 | 
			
		||||
            for (; code != key_i; code = pgm_read_byte(autocorrection_data + (state += 3))) {
 | 
			
		||||
            for (; code != key_i; code = pgm_read_byte(autocorrect_data + (state += 3))) {
 | 
			
		||||
                if (!code) return true;
 | 
			
		||||
            }
 | 
			
		||||
            // Follow link to child node.
 | 
			
		||||
            state = (pgm_read_byte(autocorrection_data + state + 1) | pgm_read_byte(autocorrection_data + state + 2) << 8);
 | 
			
		||||
            state = (pgm_read_byte(autocorrect_data + state + 1) | pgm_read_byte(autocorrect_data + state + 2) << 8);
 | 
			
		||||
            // Check for match in node with single child.
 | 
			
		||||
        } else if (code != key_i) {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (!(code = pgm_read_byte(autocorrection_data + (++state)))) {
 | 
			
		||||
        } else if (!(code = pgm_read_byte(autocorrect_data + (++state)))) {
 | 
			
		||||
            ++state;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        code = pgm_read_byte(autocorrection_data + state);
 | 
			
		||||
        // Stop if `state` becomes an invalid index. This should not normally
 | 
			
		||||
        // happen, it is a safeguard in case of a bug, data corruption, etc.
 | 
			
		||||
        if (state >= DICTIONARY_SIZE) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (code & 128) {  // A typo was found! Apply autocorrection.
 | 
			
		||||
            const uint8_t backspaces = code & 63;
 | 
			
		||||
        code = pgm_read_byte(autocorrect_data + state);
 | 
			
		||||
 | 
			
		||||
        if (code & 128) { // A typo was found! Apply autocorrect.
 | 
			
		||||
            const uint8_t backspaces = (code & 63) + !record->event.pressed;
 | 
			
		||||
            if (apply_autocorrect(backspaces, (char const *)(autocorrect_data + state + 1))) {
 | 
			
		||||
                for (uint8_t i = 0; i < backspaces; ++i) {
 | 
			
		||||
                    tap_code(KC_BSPC);
 | 
			
		||||
                }
 | 
			
		||||
            send_string_P((char const*)(autocorrection_data + state + 1));
 | 
			
		||||
                send_string_P((char const *)(autocorrect_data + state + 1));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (keycode == KC_SPC) {
 | 
			
		||||
                typo_buffer[0]   = KC_SPC;
 | 
			
		||||
| 
						 | 
				
			
			@ -166,5 +298,7 @@ bool process_autocorrection(uint16_t keycode, keyrecord_t* record) {
 | 
			
		|||
#    pragma GCC pop_options
 | 
			
		||||
#else
 | 
			
		||||
#    pragma message "Warning!!! Autocorrect is not corretly setup!"
 | 
			
		||||
bool process_autocorrection(uint16_t keycode, keyrecord_t* record) { return true; }
 | 
			
		||||
bool process_autocorrection(uint16_t keycode, keyrecord_t* record) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,4 +7,11 @@
 | 
			
		|||
 | 
			
		||||
#include "drashna.h"
 | 
			
		||||
 | 
			
		||||
bool process_autocorrection(uint16_t keycode, keyrecord_t* record);
 | 
			
		||||
bool process_autocorrection(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods);
 | 
			
		||||
bool apply_autocorrect(uint8_t backspaces, const char *str);
 | 
			
		||||
 | 
			
		||||
bool autocorrect_is_enabled(void);
 | 
			
		||||
void autocorrect_enable(void);
 | 
			
		||||
void autocorrect_disable(void);
 | 
			
		||||
void autocorrect_toggle(void);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
# Copyright 2021 Google LLC
 | 
			
		||||
# 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ Each line of the dict file defines one typo and its correction with the syntax
 | 
			
		|||
Example:
 | 
			
		||||
 | 
			
		||||
  :thier        -> their
 | 
			
		||||
  dosen't       -> doesn't
 | 
			
		||||
  fitler        -> filter
 | 
			
		||||
  lenght        -> length
 | 
			
		||||
  ouput         -> output
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +43,7 @@ https://getreuer.info/posts/keyboards/autocorrection
 | 
			
		|||
 | 
			
		||||
import sys
 | 
			
		||||
import textwrap
 | 
			
		||||
from typing import Any, Dict, List, Tuple
 | 
			
		||||
from typing import Any, Dict, Iterator, List, Tuple
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
  from english_words import english_words_lower_alpha_set as CORRECT_WORDS
 | 
			
		||||
| 
						 | 
				
			
			@ -51,52 +52,52 @@ except ImportError:
 | 
			
		|||
        'correctly spelled word. To check for this, install the english_words '
 | 
			
		||||
        'package and rerun this script:\n\n  pip install english_words\n')
 | 
			
		||||
  # Use a minimal word list as a fallback.
 | 
			
		||||
  CORRECT_WORDS = ('information', 'available', 'international', 'language',
 | 
			
		||||
                   'loosest', 'reference', 'wealthier', 'entertainment',
 | 
			
		||||
                   'association', 'provides', 'technology', 'statehood')
 | 
			
		||||
  CORRECT_WORDS = ('apparent', 'association', 'available', 'classification',
 | 
			
		||||
                   'effect', 'entertainment', 'fantastic', 'information',
 | 
			
		||||
                   'integrate', 'international', 'language', 'loosest',
 | 
			
		||||
                   'manual', 'nothing', 'provides', 'reference', 'statehood',
 | 
			
		||||
                   'technology', 'virtually', 'wealthier', 'wonderful')
 | 
			
		||||
 | 
			
		||||
KC_A = 4
 | 
			
		||||
KC_SPC = 0x2c
 | 
			
		||||
KC_QUOT = 0x34
 | 
			
		||||
 | 
			
		||||
TYPO_CHARS = dict(
 | 
			
		||||
  [
 | 
			
		||||
    ("'", KC_QUOT),
 | 
			
		||||
    (':', KC_SPC),  # "Word break" character.
 | 
			
		||||
  ] +
 | 
			
		||||
  # Characters a-z.
 | 
			
		||||
  [(chr(c), c + KC_A - ord('a')) for c in range(ord('a'), ord('z') + 1)]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def parse_file(file_name: str) -> List[Tuple[str, str]]:
 | 
			
		||||
  """Parses autocorrections dictionary file.
 | 
			
		||||
 | 
			
		||||
  Each line of the file defines one typo and its correction with the syntax
 | 
			
		||||
  "typo -> correction". Blank lines or lines starting with '#' are ignored. The
 | 
			
		||||
  function validates that typos only have characters a-z and that typos are not
 | 
			
		||||
  substrings of other typos, otherwise the longer typo would never trigger.
 | 
			
		||||
  function validates that typos only have characters in TYPO_CHARS, that
 | 
			
		||||
  typos are not substrings of other typos, and checking that typos don't trigger
 | 
			
		||||
  on CORRECT_WORDS.
 | 
			
		||||
 | 
			
		||||
  Args:
 | 
			
		||||
    file_name: String, path of the autocorrections dictionary.
 | 
			
		||||
  Returns:
 | 
			
		||||
    List of (typo, correction) tuples.
 | 
			
		||||
  """
 | 
			
		||||
 | 
			
		||||
  correct_words = ('information', 'available', 'international', 'language', 'loosest', 'reference', 'wealthier', 'entertainment', 'association', 'provides', 'technology', 'statehood')
 | 
			
		||||
  autocorrections = []
 | 
			
		||||
  typos = set()
 | 
			
		||||
  line_number = 0
 | 
			
		||||
  for line in open(file_name, 'rt'):
 | 
			
		||||
    line_number += 1
 | 
			
		||||
    line = line.strip()
 | 
			
		||||
    if line and line[0] != '#':
 | 
			
		||||
      # Parse syntax "typo -> correction", using strip to ignore indenting.
 | 
			
		||||
      tokens = [token.strip() for token in line.split('->', 1)]
 | 
			
		||||
      if len(tokens) != 2 or not tokens[0]:
 | 
			
		||||
        print(f'Error:{line_number}: Invalid syntax: "{line}"')
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
      typo, correction = tokens
 | 
			
		||||
      typo = typo.lower()  # Force typos to lowercase.
 | 
			
		||||
      typo = typo.replace(' ', ':')
 | 
			
		||||
 | 
			
		||||
  for line_number, typo, correction in parse_file_lines(file_name):
 | 
			
		||||
    if typo in typos:
 | 
			
		||||
      print(f'Warning:{line_number}: Ignoring duplicate typo: "{typo}"')
 | 
			
		||||
      continue
 | 
			
		||||
 | 
			
		||||
    # Check that `typo` is valid.
 | 
			
		||||
      if not(all([ord('a') <= ord(c) <= ord('z') or c == ':' for c in typo])):
 | 
			
		||||
    if not(all([c in TYPO_CHARS for c in typo])):
 | 
			
		||||
      print(f'Error:{line_number}: Typo "{typo}" has '
 | 
			
		||||
              'characters other than a-z and :.')
 | 
			
		||||
            'characters other than ' + ''.join(TYPO_CHARS.keys()))
 | 
			
		||||
      sys.exit(1)
 | 
			
		||||
    for other_typo in typos:
 | 
			
		||||
      if typo in other_typo or other_typo in typo:
 | 
			
		||||
| 
						 | 
				
			
			@ -108,25 +109,7 @@ def parse_file(file_name: str) -> List[Tuple[str, str]]:
 | 
			
		|||
      print(f'Warning:{line_number}: It is suggested that typos are at '
 | 
			
		||||
            f'least 5 characters long to avoid false triggers: "{typo}"')
 | 
			
		||||
 | 
			
		||||
      if typo.startswith(':') and typo.endswith(':'):
 | 
			
		||||
        if typo[1:-1] in CORRECT_WORDS:
 | 
			
		||||
          print(f'Warning:{line_number}: Typo "{typo}" is a correctly spelled '
 | 
			
		||||
                'dictionary word.')
 | 
			
		||||
      elif typo.startswith(':') and not typo.endswith(':'):
 | 
			
		||||
        for word in CORRECT_WORDS:
 | 
			
		||||
          if word.startswith(typo[1:]):
 | 
			
		||||
            print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger '
 | 
			
		||||
                  f'on correctly spelled word "{word}".')
 | 
			
		||||
      elif not typo.startswith(':') and typo.endswith(':'):
 | 
			
		||||
        for word in CORRECT_WORDS:
 | 
			
		||||
          if word.endswith(typo[:-1]):
 | 
			
		||||
            print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger '
 | 
			
		||||
                  f'on correctly spelled word "{word}".')
 | 
			
		||||
      elif not typo.startswith(':') and not typo.endswith(':'):
 | 
			
		||||
        for word in CORRECT_WORDS:
 | 
			
		||||
          if typo in word:
 | 
			
		||||
            print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger '
 | 
			
		||||
                  f'on correctly spelled word "{word}".')
 | 
			
		||||
    check_typo_against_dictionary(typo, line_number, correct_words)
 | 
			
		||||
 | 
			
		||||
    autocorrections.append((typo, correction))
 | 
			
		||||
    typos.add(typo)
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +135,47 @@ def make_trie(autocorrections: List[Tuple[str, str]]) -> Dict[str, Any]:
 | 
			
		|||
  return trie
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def parse_file_lines(file_name: str) -> Iterator[Tuple[int, str, str]]:
 | 
			
		||||
  """Parses lines read from `file_name` into typo-correction pairs."""
 | 
			
		||||
 | 
			
		||||
  line_number = 0
 | 
			
		||||
  for line in open(file_name, 'rt'):
 | 
			
		||||
    line_number += 1
 | 
			
		||||
    line = line.strip()
 | 
			
		||||
    if line and line[0] != '#':
 | 
			
		||||
      # Parse syntax "typo -> correction", using strip to ignore indenting.
 | 
			
		||||
      tokens = [token.strip() for token in line.split('->', 1)]
 | 
			
		||||
      if len(tokens) != 2 or not tokens[0]:
 | 
			
		||||
        print(f'Error:{line_number}: Invalid syntax: "{line}"')
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
      typo, correction = tokens
 | 
			
		||||
      typo = typo.lower()  # Force typos to lowercase.
 | 
			
		||||
      typo = typo.replace(' ', ':')
 | 
			
		||||
 | 
			
		||||
      yield line_number, typo, correction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def check_typo_against_dictionary(typo: str, line_number: int, correct_words) -> None:
 | 
			
		||||
  """Checks `typo` against English dictionary words."""
 | 
			
		||||
 | 
			
		||||
  if typo.startswith(':') and typo.endswith(':'):
 | 
			
		||||
    if typo[1:-1] in correct_words:
 | 
			
		||||
      print(f'Warning:{line_number}: Typo "{typo}" is a correctly spelled dictionary word.')
 | 
			
		||||
  elif typo.startswith(':') and not typo.endswith(':'):
 | 
			
		||||
    for word in correct_words:
 | 
			
		||||
      if word.startswith(typo[1:]):
 | 
			
		||||
            print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger on correctly spelled word "{word}".')
 | 
			
		||||
  elif not typo.startswith(':') and typo.endswith(':'):
 | 
			
		||||
    for word in correct_words:
 | 
			
		||||
      if word.endswith(typo[:-1]):
 | 
			
		||||
            print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger on correctly spelled word "{word}".')
 | 
			
		||||
  elif not typo.startswith(':') and not typo.endswith(':'):
 | 
			
		||||
    for word in correct_words:
 | 
			
		||||
      if typo in word:
 | 
			
		||||
        print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger on correctly spelled word "{word}".')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def serialize_trie(autocorrections: List[Tuple[str, str]],
 | 
			
		||||
                   trie: Dict[str, Any]) -> List[int]:
 | 
			
		||||
  """Serializes trie and correction data in a form readable by the C code.
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +189,7 @@ def serialize_trie(autocorrections: List[Tuple[str, str]],
 | 
			
		|||
  table = []
 | 
			
		||||
 | 
			
		||||
  # Traverse trie in depth first order.
 | 
			
		||||
  def traverse(trie_node):
 | 
			
		||||
  def traverse(trie_node: Dict[str, Any]) -> Dict[str, Any]:
 | 
			
		||||
    if 'LEAF' in trie_node:  # Handle a leaf trie node.
 | 
			
		||||
      typo, correction = trie_node['LEAF']
 | 
			
		||||
      word_boundary_ending = typo[-1] == ':'
 | 
			
		||||
| 
						 | 
				
			
			@ -200,37 +224,35 @@ def serialize_trie(autocorrections: List[Tuple[str, str]],
 | 
			
		|||
 | 
			
		||||
  traverse(trie)
 | 
			
		||||
 | 
			
		||||
  def serialize(e):
 | 
			
		||||
    def kc_code(c):
 | 
			
		||||
      if ord('a') <= ord(c) <= ord('z'):
 | 
			
		||||
        return ord(c) - ord('a') + KC_A
 | 
			
		||||
      elif c == ':':
 | 
			
		||||
        return KC_SPC
 | 
			
		||||
      else:
 | 
			
		||||
        raise ValueError(f'Invalid character: {c}')
 | 
			
		||||
 | 
			
		||||
    encode_link = lambda link: [link['byte_offset'] & 255,
 | 
			
		||||
                                link['byte_offset'] >> 8]
 | 
			
		||||
 | 
			
		||||
  def serialize(e: Dict[str, Any]) -> List[int]:
 | 
			
		||||
    if not e['links']:  # Handle a leaf table entry.
 | 
			
		||||
      return e['data']
 | 
			
		||||
    elif len(e['links']) == 1:  # Handle a chain table entry.
 | 
			
		||||
      return list(map(kc_code, e['chars'])) + [0] #+ encode_link(e['links'][0]))
 | 
			
		||||
      return [TYPO_CHARS[c] for c in e['chars']] + [0]
 | 
			
		||||
    else:  # Handle a branch table entry.
 | 
			
		||||
      data = []
 | 
			
		||||
      for c, link in zip(e['chars'], e['links']):
 | 
			
		||||
        data += [kc_code(c) | (0 if data else 64)] + encode_link(link)
 | 
			
		||||
        data += [TYPO_CHARS[c] | (0 if data else 64)] + encode_link(link)
 | 
			
		||||
      return data + [0]
 | 
			
		||||
 | 
			
		||||
  byte_offset = 0
 | 
			
		||||
  for e in table:  # To encode links, first compute byte offset of each entry.
 | 
			
		||||
    e['byte_offset'] = byte_offset
 | 
			
		||||
    byte_offset += len(serialize(e))
 | 
			
		||||
    assert 0 <= byte_offset <= 0xffff
 | 
			
		||||
 | 
			
		||||
  return [b for e in table for b in serialize(e)]  # Serialize final table.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def encode_link(link: Dict[str, Any]) -> List[int]:
 | 
			
		||||
  """Encodes a node link as two bytes."""
 | 
			
		||||
  byte_offset = link['byte_offset']
 | 
			
		||||
  if not (0 <= byte_offset <= 0xffff):
 | 
			
		||||
    print('Error: The autocorrection table is too large, a node link exceeds '
 | 
			
		||||
          '64KB limit. Try reducing the autocorrection dict to fewer entries.')
 | 
			
		||||
    sys.exit(1)
 | 
			
		||||
  return [byte_offset & 255, byte_offset >> 8]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def write_generated_code(autocorrections: List[Tuple[str, str]],
 | 
			
		||||
                         data: List[int],
 | 
			
		||||
                         file_name: str) -> None:
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +264,10 @@ def write_generated_code(autocorrections: List[Tuple[str, str]],
 | 
			
		|||
    file_name: String, path of the output C file.
 | 
			
		||||
  """
 | 
			
		||||
  assert all(0 <= b <= 255 for b in data)
 | 
			
		||||
  typo_len = lambda e: len(e[0])
 | 
			
		||||
 | 
			
		||||
  def typo_len(e: Tuple[str, str]) -> int:
 | 
			
		||||
    return len(e[0])
 | 
			
		||||
 | 
			
		||||
  min_typo = min(autocorrections, key=typo_len)[0]
 | 
			
		||||
  max_typo = max(autocorrections, key=typo_len)[0]
 | 
			
		||||
  generated_code = ''.join([
 | 
			
		||||
| 
						 | 
				
			
			@ -252,9 +277,8 @@ def write_generated_code(autocorrections: List[Tuple[str, str]],
 | 
			
		|||
                   for typo, correction in autocorrections)),
 | 
			
		||||
    f'\n#define AUTOCORRECTION_MIN_LENGTH {len(min_typo)}  // "{min_typo}"\n',
 | 
			
		||||
    f'#define AUTOCORRECTION_MAX_LENGTH {len(max_typo)}  // "{max_typo}"\n\n',
 | 
			
		||||
    f'#define DICTIONARY_SIZE {len(data)}\n\n',
 | 
			
		||||
    textwrap.fill('static const uint8_t autocorrection_data[DICTIONARY_SIZE] PROGMEM = {%s};' % (
 | 
			
		||||
      ', '.join(map(str, data))), width=120, subsequent_indent='    '),
 | 
			
		||||
    textwrap.fill('static const uint8_t autocorrection_data[%d] PROGMEM = {%s};' % (
 | 
			
		||||
      len(data), ', '.join(map(str, data))), width=80, subsequent_indent='  '),
 | 
			
		||||
    '\n\n'])
 | 
			
		||||
 | 
			
		||||
  with open(file_name, 'wt') as f:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,139 +0,0 @@
 | 
			
		|||
#include "caps_word.h"
 | 
			
		||||
 | 
			
		||||
static bool caps_word_active = false;
 | 
			
		||||
 | 
			
		||||
#if CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
#    if CAPS_WORD_IDLE_TIMEOUT < 100 || CAPS_WORD_IDLE_TIMEOUT > 30000
 | 
			
		||||
// Constrain timeout to a sensible range. With the 16-bit timer, the longest
 | 
			
		||||
// representable timeout is 32768 ms, rounded here to 30000 ms = half a minute.
 | 
			
		||||
#        error "caps_word: CAPS_WORD_IDLE_TIMEOUT must be between 100 and 30000 ms"
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
static uint16_t idle_timer = 0;
 | 
			
		||||
 | 
			
		||||
void caps_word_task(void) {
 | 
			
		||||
    if (caps_word_active && timer_expired(timer_read(), idle_timer)) {
 | 
			
		||||
        caps_word_set(false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif // CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
 | 
			
		||||
bool process_caps_word(uint16_t keycode, keyrecord_t* record) {
 | 
			
		||||
#ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    const uint8_t mods = get_mods() | get_oneshot_mods();
 | 
			
		||||
#else
 | 
			
		||||
    const uint8_t mods = get_mods();
 | 
			
		||||
#endif // NO_ACTION_ONESHOT
 | 
			
		||||
 | 
			
		||||
    if (!caps_word_active) {
 | 
			
		||||
        // Pressing both shift keys at the same time enables caps word.
 | 
			
		||||
        if ((mods & MOD_MASK_SHIFT) == MOD_MASK_SHIFT) {
 | 
			
		||||
            caps_word_set(true); // Activate Caps Word.
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    } else {
 | 
			
		||||
#if CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
        idle_timer = record->event.time + CAPS_WORD_IDLE_TIMEOUT;
 | 
			
		||||
#endif // CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!record->event.pressed) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(mods & ~MOD_MASK_SHIFT)) {
 | 
			
		||||
        switch (keycode) {
 | 
			
		||||
            // Ignore MO, TO, TG, TT, and OSL layer switch keys.
 | 
			
		||||
            case QK_MOMENTARY ... QK_MOMENTARY_MAX:
 | 
			
		||||
            case QK_TO ... QK_TO_MAX:
 | 
			
		||||
            case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
 | 
			
		||||
            case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
 | 
			
		||||
            case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
#ifndef NO_ACTION_TAPPING
 | 
			
		||||
            case QK_MOD_TAP ... QK_MOD_TAP_MAX:
 | 
			
		||||
                if (record->tap.count == 0) {
 | 
			
		||||
                    // Deactivate if a mod becomes active through holding a mod-tap key.
 | 
			
		||||
                    caps_word_set(false);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                keycode &= 0xff;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
#    ifndef NO_ACTION_LAYER
 | 
			
		||||
            case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
 | 
			
		||||
#    endif // NO_ACTION_LAYER
 | 
			
		||||
                if (record->tap.count == 0) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                keycode &= 0xff;
 | 
			
		||||
                break;
 | 
			
		||||
#endif // NO_ACTION_TAPPING
 | 
			
		||||
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
            case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
 | 
			
		||||
                if (keycode > 0x56F0 || record->tap.count == 0) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                keycode &= 0xff;
 | 
			
		||||
                break;
 | 
			
		||||
#endif // SWAP_HANDS_ENABLE
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (caps_word_press_user(keycode)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    caps_word_set(false); // Deactivate Caps Word.
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void caps_word_set(bool active) {
 | 
			
		||||
    if (active != caps_word_active) {
 | 
			
		||||
        if (active) {
 | 
			
		||||
            clear_mods();
 | 
			
		||||
#ifndef NO_ACTION_ONESHOT
 | 
			
		||||
            clear_oneshot_mods();
 | 
			
		||||
#endif // NO_ACTION_ONESHOT
 | 
			
		||||
#if CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
            idle_timer = timer_read() + CAPS_WORD_IDLE_TIMEOUT;
 | 
			
		||||
#endif // CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
        } else if ((get_weak_mods() & MOD_BIT(KC_LSFT)) != 0) {
 | 
			
		||||
            // If the weak shift mod is still on, turn it off and send an update to
 | 
			
		||||
            // the host computer.
 | 
			
		||||
            del_weak_mods(MOD_BIT(KC_LSFT));
 | 
			
		||||
            send_keyboard_report();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        caps_word_active = active;
 | 
			
		||||
        caps_word_set_user(active);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool caps_word_get(void) {
 | 
			
		||||
    return caps_word_active;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void caps_word_set_user(bool active) {}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) bool caps_word_press_user(uint16_t keycode) {
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        // Keycodes that continue Caps Word, with shift applied.
 | 
			
		||||
        case KC_A ... KC_Z:
 | 
			
		||||
            add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key.
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        // Keycodes that continue Caps Word, without shifting.
 | 
			
		||||
        case KC_1 ... KC_0:
 | 
			
		||||
        case KC_BSPC:
 | 
			
		||||
        case KC_MINS:
 | 
			
		||||
        case KC_UNDS:
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return false; // Deactivate Caps Word.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,85 +0,0 @@
 | 
			
		|||
// Copyright 2021 Google LLC.
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "drashna.h"
 | 
			
		||||
 | 
			
		||||
// Call this function from `process_record_user()` to implement Caps Word.
 | 
			
		||||
bool process_caps_word(uint16_t keycode, keyrecord_t* record);
 | 
			
		||||
 | 
			
		||||
// If CAPS_WORD_IDLE_TIMEOUT is set, call `caps_word_task()` from
 | 
			
		||||
// `matrix_scan_user()` as described above.
 | 
			
		||||
//
 | 
			
		||||
// If CAPS_WORD_IDLE_TIMEOUT isn't set, calling this function has no effect (but
 | 
			
		||||
// will still compile).
 | 
			
		||||
#if CAPS_WORD_IDLE_TIMEOUT > 0
 | 
			
		||||
void caps_word_task(void);
 | 
			
		||||
#else
 | 
			
		||||
static inline void caps_word_task(void) {}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Activates or deactivates Caps Word. For instance activate Caps Word with a
 | 
			
		||||
// combo by defining a `COMBO_ACTION` that calls `caps_word_set(true)`:
 | 
			
		||||
//
 | 
			
		||||
// void process_combo_event(uint16_t combo_index, bool pressed) {
 | 
			
		||||
//   switch(combo_index) {
 | 
			
		||||
//     case CAPS_COMBO:
 | 
			
		||||
//       if (pressed) {
 | 
			
		||||
//         caps_word_set(true);  // Activate Caps Word.
 | 
			
		||||
//       }
 | 
			
		||||
//       break;
 | 
			
		||||
//
 | 
			
		||||
//     // Other combos...
 | 
			
		||||
//   }
 | 
			
		||||
// }
 | 
			
		||||
void caps_word_set(bool active);
 | 
			
		||||
 | 
			
		||||
// Returns whether Caps Word is currently active.
 | 
			
		||||
bool caps_word_get(void);
 | 
			
		||||
 | 
			
		||||
// An optional callback that gets called when Caps Word turns on or off. This is
 | 
			
		||||
// useful to represent the current Caps Word state, e.g. by setting an LED or
 | 
			
		||||
// playing a sound. In your keymap, define
 | 
			
		||||
//
 | 
			
		||||
//   void caps_word_set_user(bool active) {
 | 
			
		||||
//     if (active) {
 | 
			
		||||
//       // Do something when Caps Word activates.
 | 
			
		||||
//     } else {
 | 
			
		||||
//       // Do something when Caps Word deactivates.
 | 
			
		||||
//     }
 | 
			
		||||
//   }
 | 
			
		||||
void caps_word_set_user(bool active);
 | 
			
		||||
 | 
			
		||||
// An optional callback which is called on every key press while Caps Word is
 | 
			
		||||
// active. When the key should be shifted (that is, a letter key), the callback
 | 
			
		||||
// should call `add_weak_mods(MOD_BIT(KC_LSFT))` to shift the key. The callback
 | 
			
		||||
// also determines whether the key should continue Caps Word. Returning true
 | 
			
		||||
// continues the current "word", while returning false is "word breaking" and
 | 
			
		||||
// deactivates Caps Word. The default callback is
 | 
			
		||||
//
 | 
			
		||||
//   bool caps_word_press_user(uint16_t keycode) {
 | 
			
		||||
//     switch (keycode) {
 | 
			
		||||
//       // Keycodes that continue Caps Word, with shift applied.
 | 
			
		||||
//       case KC_A ... KC_Z:
 | 
			
		||||
//         add_weak_mods(MOD_BIT(KC_LSFT));  // Apply shift to the next key.
 | 
			
		||||
//         return true;
 | 
			
		||||
//
 | 
			
		||||
//       // Keycodes that continue Caps Word, without shifting.
 | 
			
		||||
//       case KC_1 ... KC_0:
 | 
			
		||||
//       case KC_BSPC:
 | 
			
		||||
//       case KC_MINS:
 | 
			
		||||
//       case KC_UNDS:
 | 
			
		||||
//         return true;
 | 
			
		||||
//
 | 
			
		||||
//       default:
 | 
			
		||||
//         return false;  // Deactivate Caps Word.
 | 
			
		||||
//     }
 | 
			
		||||
//   }
 | 
			
		||||
//
 | 
			
		||||
// To customize, copy the above function into your keymap and add/remove
 | 
			
		||||
// keycodes to the above cases.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Outside of this callback, you can use `caps_word_set(false)` to
 | 
			
		||||
// deactivate Caps Word.
 | 
			
		||||
bool caps_word_press_user(uint16_t keycode);
 | 
			
		||||
| 
						 | 
				
			
			@ -5,14 +5,9 @@ Keycodes are defined in the `process_record.h` file and need to be included in t
 | 
			
		|||
 | 
			
		||||
A bunch of macros are present and are only included on boards that are not the Ergodox EZ or Orthodox, as they are not needed for those boards. 
 | 
			
		||||
 | 
			
		||||
* `KC_MAKE` - outputs `qmk compile -kb (keyboard) -km (keymap)` and enter, to start compiling the currenct keyboard.  This uses generated variables to always use the current keyboard and keymap.  Will work with any keyboard and any keymap.
 | 
			
		||||
  * If you are holding shift, it will use `qmk flash` instead of `qmk compile`.
 | 
			
		||||
  * If `MAKE_BOOTLOADER` is defined, it will always use `qmk flash` instead of `qmk compile`.
 | 
			
		||||
* `DEFAULT_LAYER_1` ... `DEFAULT_LAYER_4` - This sets layer 0-3 as the default layer, and writes that to eeprom, and plays a chime. 
 | 
			
		||||
* `VRSN`, outputs the keyboard, keymap, commit and date info.  Eg:
 | 
			
		||||
  * `handwired/tractyl_manuform/5x6_right/f411/drashna @ 0.15.9-162-g087d08, Built on: 2021-12-19-21:10:26`
 | 
			
		||||
*  `KC_DIABLO_CLEAR` - clears the diablo tapdance status.
 | 
			
		||||
* `KC_CCCV` - Copy on hold, paste on tap.
 | 
			
		||||
* `KEYLOCK` - This unloads the host driver, and prevents any data from being sent to the host. Hitting it again loads the driver, back. 
 | 
			
		||||
* `REBOOT` - Uses watchdog timer on AVR, and `NVIC_SystemReset()` on ChibiOS to reset the board, without jumping to the bootloader.
 | 
			
		||||
* `EEP_RST` - Overrides the default behavior, disables EEPROM (which will trigger a reset on init), and reboots the keyboard as per `REBOOT` keycode. 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,9 +3,6 @@
 | 
			
		|||
 | 
			
		||||
#include "drashna.h"
 | 
			
		||||
#include "version.h"
 | 
			
		||||
#ifdef CAPS_WORD_ENABLE
 | 
			
		||||
#    include "caps_word.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef AUTOCORRECTION_ENABLE
 | 
			
		||||
#    include "autocorrection/autocorrection.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +34,15 @@ __attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t
 | 
			
		|||
 * @return false Stop process keycode and do not send to host
 | 
			
		||||
 */
 | 
			
		||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
#ifdef ENCODER_ENABLE // some debouncing for weird issues
 | 
			
		||||
    if (IS_ENCODEREVENT(record->event)) {
 | 
			
		||||
        static bool ignore_first = true;
 | 
			
		||||
        if (ignore_first) {
 | 
			
		||||
            ignore_first = false;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    // If console is enabled, it will print the matrix position and status of each key pressed
 | 
			
		||||
#ifdef KEYLOGGER_ENABLE
 | 
			
		||||
    uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
 | 
			
		||||
| 
						 | 
				
			
			@ -58,9 +64,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
#if defined(CUSTOM_POINTING_DEVICE)
 | 
			
		||||
          && process_record_pointing(keycode, record)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CAPS_WORD_ENABLE
 | 
			
		||||
          && process_caps_word(keycode, record)
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef AUTOCORRECTION_ENABLE
 | 
			
		||||
          && process_autocorrection(keycode, record)
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -87,33 +90,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case KC_MAKE:  // Compiles the firmware, and adds the flash command based on keyboard bootloader
 | 
			
		||||
            if (!record->event.pressed) {
 | 
			
		||||
#ifndef MAKE_BOOTLOADER
 | 
			
		||||
                uint8_t temp_mod = mod_config(get_mods());
 | 
			
		||||
                uint8_t temp_osm = mod_config(get_oneshot_mods());
 | 
			
		||||
                clear_mods();
 | 
			
		||||
                clear_oneshot_mods();
 | 
			
		||||
#endif
 | 
			
		||||
                send_string_with_delay_P(PSTR("qmk"), TAP_CODE_DELAY);
 | 
			
		||||
#ifndef MAKE_BOOTLOADER
 | 
			
		||||
                if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
 | 
			
		||||
#endif
 | 
			
		||||
                {
 | 
			
		||||
                    send_string_with_delay_P(PSTR(" flash "), TAP_CODE_DELAY);
 | 
			
		||||
#ifndef MAKE_BOOTLOADER
 | 
			
		||||
                } else {
 | 
			
		||||
                    send_string_with_delay_P(PSTR(" compile "), TAP_CODE_DELAY);
 | 
			
		||||
#endif
 | 
			
		||||
                }
 | 
			
		||||
                send_string_with_delay_P(PSTR("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP), TAP_CODE_DELAY);
 | 
			
		||||
#ifdef CONVERT_TO_PROTON_C
 | 
			
		||||
                send_string_with_delay_P(PSTR(" -e CTPC=yes"), TAP_CODE_DELAY);
 | 
			
		||||
#endif
 | 
			
		||||
                send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case VRSN:  // Prints firmware version
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
 | 
			
		||||
| 
						 | 
				
			
			@ -148,13 +124,19 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
                dprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
 | 
			
		||||
                eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
                if (userspace_config.rgb_layer_change) {
 | 
			
		||||
#    if defined(CUSTOM_RGBLIGHT) && defined(CUSTOM_RGB_MATRIX)
 | 
			
		||||
#    if defined(CUSTOM_RGB_MATRIX)
 | 
			
		||||
                    rgb_matrix_set_flags(LED_FLAG_UNDERGLOW | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR);
 | 
			
		||||
#        if defined(CUSTOM_RGBLIGHT)
 | 
			
		||||
                    rgblight_enable_noeeprom();
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
                    layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
 | 
			
		||||
#    if defined(CUSTOM_RGBLIGHT) && defined(CUSTOM_RGB_MATRIX)
 | 
			
		||||
#    if defined(CUSTOM_RGB_MATRIX)
 | 
			
		||||
                } else {
 | 
			
		||||
                    rgb_matrix_set_flags(LED_FLAG_ALL);
 | 
			
		||||
#        if defined(CUSTOM_RGBLIGHT)
 | 
			
		||||
                    rgblight_disable_noeeprom();
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -218,22 +200,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case EEP_RST:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                eeconfig_disable();
 | 
			
		||||
                shutdown_user();
 | 
			
		||||
#ifdef __AVR__
 | 
			
		||||
                wdt_enable(WDTO_250MS);
 | 
			
		||||
#else
 | 
			
		||||
                NVIC_SystemReset();
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        case REBOOT:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                software_reset();
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
     }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,6 @@ enum userspace_custom_keycodes {
 | 
			
		|||
    KC_DVORAK,                                // Sets default layer to DVORAK
 | 
			
		||||
    LAST_DEFAULT_LAYER_KEYCODE = KC_DVORAK,   // Sets default layer to WORKMAN
 | 
			
		||||
    KC_DIABLO_CLEAR,                          // Clears all Diablo Timers
 | 
			
		||||
    KC_MAKE,                                  // Run keyboard's customized make command
 | 
			
		||||
    KC_RGB_T,                                 // Toggles RGB Layer Indication mode
 | 
			
		||||
    RGB_IDL,                                  // RGB Idling animations
 | 
			
		||||
    KC_SECRET_1,                              // test1
 | 
			
		||||
| 
						 | 
				
			
			@ -46,8 +45,9 @@ enum userspace_custom_keycodes {
 | 
			
		|||
    KC_AUSSIE,
 | 
			
		||||
    KC_ZALGO,
 | 
			
		||||
    KC_ACCEL,
 | 
			
		||||
    AUTO_CTN,                                 // Toggle Autocorrect status
 | 
			
		||||
    REBOOT,
 | 
			
		||||
    AUTOCORRECT_ON,
 | 
			
		||||
    AUTOCORRECT_OFF,
 | 
			
		||||
    AUTOCORRECT_TOGGLE,
 | 
			
		||||
    NEW_SAFE_RANGE                            // use "NEWPLACEHOLDER for keymap specific codes
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,9 +95,6 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
 | 
			
		|||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define KC_RESET RESET
 | 
			
		||||
#define KC_RST   KC_RESET
 | 
			
		||||
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
#    define KC_C1R3 SH_T(KC_TAB)
 | 
			
		||||
#elif defined(DRASHNA_LP)
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +127,7 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
 | 
			
		|||
 | 
			
		||||
#define MG_NKRO MAGIC_TOGGLE_NKRO
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define AUTO_CTN AUTOCORRECT_TOGGLE
 | 
			
		||||
/*
 | 
			
		||||
Custom Keycodes for Diablo 3 layer
 | 
			
		||||
But since TD() doesn't work when tap dance is disabled
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,14 +24,12 @@ secrets.h
 | 
			
		|||
Here is the magic. This handles including the "secrets", and adding the custom macros to send them. 
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#include "drashna.h"  // replace with your keymap's "h" file, or whatever file stores the keycodes
 | 
			
		||||
#include QMK_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#if (__has_include("secrets.h") && !defined(NO_SECRETS))
 | 
			
		||||
#include "secrets.h"
 | 
			
		||||
#else
 | 
			
		||||
// `PROGMEM const char secret[][x]` may work better, but it takes up more space in the firmware
 | 
			
		||||
// And I'm not familiar enough to know which is better or why...
 | 
			
		||||
static const char * const secret[] = {
 | 
			
		||||
static const char * const secrets[] = {
 | 
			
		||||
  "test1",
 | 
			
		||||
  "test2",
 | 
			
		||||
  "test3",
 | 
			
		||||
| 
						 | 
				
			
			@ -43,9 +41,10 @@ static const char * const secret[] = {
 | 
			
		|||
bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
  switch (keycode) {
 | 
			
		||||
    case KC_SECRET_1 ... KC_SECRET_5: // Secrets!  Externally defined strings, not stored in repo
 | 
			
		||||
      if (!record->event.pressed) {
 | 
			
		||||
        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
 | 
			
		||||
        send_string_with_delay(secret[keycode - KC_SECRET_1], MACRO_TIMER);
 | 
			
		||||
      if (record->event.pressed) {
 | 
			
		||||
        clear_mods();
 | 
			
		||||
        clear_oneshot_mods();
 | 
			
		||||
        send_string_with_delay(secrets[keycode - KC_SECRET_1], MACRO_TIMER);
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
      break;
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +95,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
 | 
			
		||||
Here, you want your `/users/<name>/rules.mk` file to "detect" the existence of the `secrets.c` file, and only add it if the file exists.  
 | 
			
		||||
 | 
			
		||||
Additionally, to ensure that it's not added or processed in any way, it checks to see if `NO_SECRETS` is set. This way, if you run `make keyboard:name NO_SECRETS=yes`, it will remove the feature altogether. 
 | 
			
		||||
Additionally, to ensure that it's not added or processed in any way, it checks to see if `NO_SECRETS` is set. This way, if you run `qmk compile -kb keyboard -km name -e NO_SECRETS=yes`, it will remove the feature altogether. 
 | 
			
		||||
 | 
			
		||||
```make
 | 
			
		||||
ifneq ($(strip $(NO_SECRETS)), yes)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,10 @@
 | 
			
		|||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "drashna.h"
 | 
			
		||||
#include "unicode.h"
 | 
			
		||||
#include "process_unicode_common.h"
 | 
			
		||||
 | 
			
		||||
uint16_t typing_mode = KC_NOMODE;
 | 
			
		||||
uint8_t typing_mode = UCTM_NO_MODE;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Registers the unicode keystrokes based on desired unicode
 | 
			
		||||
| 
						 | 
				
			
			@ -242,10 +243,10 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
            break;
 | 
			
		||||
        case KC_NOMODE ... KC_ZALGO:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                if (typing_mode != keycode) {
 | 
			
		||||
                    typing_mode = keycode;
 | 
			
		||||
                if (typing_mode != keycode - KC_NOMODE) {
 | 
			
		||||
                    typing_mode = keycode - KC_NOMODE;
 | 
			
		||||
                } else {
 | 
			
		||||
                    typing_mode = KC_NOMODE;
 | 
			
		||||
                    typing_mode = UCTM_NO_MODE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
| 
						 | 
				
			
			@ -259,19 +260,19 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
        keycode &= 0xFF;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (typing_mode == KC_WIDE) {
 | 
			
		||||
    if (typing_mode == UCTM_WIDE) {
 | 
			
		||||
        if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
 | 
			
		||||
            return process_record_glyph_replacement(keycode, record, unicode_range_translator_wide);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (typing_mode == KC_SCRIPT) {
 | 
			
		||||
    } else if (typing_mode == UCTM_SCRIPT) {
 | 
			
		||||
        if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
 | 
			
		||||
            return process_record_glyph_replacement(keycode, record, unicode_range_translator_script);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (typing_mode == KC_BLOCKS) {
 | 
			
		||||
    } else if (typing_mode == UCTM_BLOCKS) {
 | 
			
		||||
        if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
 | 
			
		||||
            return process_record_glyph_replacement(keycode, record, unicode_range_translator_boxes);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (typing_mode == KC_REGIONAL) {
 | 
			
		||||
    } else if (typing_mode == UCTM_REGIONAL) {
 | 
			
		||||
        if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
 | 
			
		||||
            if (!process_record_glyph_replacement(keycode, record, unicode_range_translator_regional)) {
 | 
			
		||||
                wait_us(500);
 | 
			
		||||
| 
						 | 
				
			
			@ -279,9 +280,9 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (typing_mode == KC_AUSSIE) {
 | 
			
		||||
    } else if (typing_mode == UCTM_AUSSIE) {
 | 
			
		||||
        return process_record_aussie(keycode, record);
 | 
			
		||||
    } else if (typing_mode == KC_ZALGO) {
 | 
			
		||||
    } else if (typing_mode == UCTM_ZALGO) {
 | 
			
		||||
        return process_record_zalgo(keycode, record);
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								users/drashna/keyrecords/unicode.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								users/drashna/keyrecords/unicode.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
// Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
enum unicode_typing_mode {
 | 
			
		||||
    UCTM_NO_MODE,
 | 
			
		||||
    UCTM_WIDE,
 | 
			
		||||
    UCTM_SCRIPT,
 | 
			
		||||
    UCTM_BLOCKS,
 | 
			
		||||
    UCTM_REGIONAL,
 | 
			
		||||
    UCTM_AUSSIE,
 | 
			
		||||
    UCTM_ZALGO,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern uint8_t typing_mode;
 | 
			
		||||
| 
						 | 
				
			
			@ -18,10 +18,14 @@
 | 
			
		|||
#include "drashna.h"
 | 
			
		||||
#ifdef UNICODE_COMMON_ENABLE
 | 
			
		||||
#    include "process_unicode_common.h"
 | 
			
		||||
#    include "keyrecords/unicode.h"
 | 
			
		||||
#endif
 | 
			
		||||
#    ifdef AUDIO_CLICKY
 | 
			
		||||
#ifdef AUDIO_CLICKY
 | 
			
		||||
#    include "process_clicky.h"
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(AUTOCORRECTION_ENABLE)
 | 
			
		||||
#    include "keyrecords/autocorrection/autocorrection.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
extern bool host_driver_disabled;
 | 
			
		||||
| 
						 | 
				
			
			@ -100,12 +104,15 @@ void add_keylog(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
 */
 | 
			
		||||
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    if (record->event.pressed) {
 | 
			
		||||
        oled_timer = timer_read32();
 | 
			
		||||
        oled_timer_reset();
 | 
			
		||||
        add_keylog(keycode, record);
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oled_timer_reset(void) {
 | 
			
		||||
    oled_timer = timer_read32();
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Renders keylogger buffer to oled
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -262,9 +269,8 @@ void render_layer_state(void) {
 | 
			
		|||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // clang-format on
 | 
			
		||||
    uint8_t layer_is[4] = { 0, 4, 4, 4};
 | 
			
		||||
    uint8_t layer_is[4] = {0, 4, 4, 4};
 | 
			
		||||
    if (layer_state_is(_ADJUST)) {
 | 
			
		||||
        layer_is[0] = 3;
 | 
			
		||||
    } else if (layer_state_is(_RAISE)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -280,7 +286,6 @@ void render_layer_state(void) {
 | 
			
		|||
        layer_is[2] = 5;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    oled_set_cursor(1, 2);
 | 
			
		||||
    oled_write_raw_P(tri_layer_image[layer_is[0]][0], sizeof(tri_layer_image[0][0]));
 | 
			
		||||
    oled_set_cursor(5, 2);
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +327,7 @@ void render_layer_state(void) {
 | 
			
		|||
 *
 | 
			
		||||
 * @param led_usb_state Current keyboard led state
 | 
			
		||||
 */
 | 
			
		||||
void render_keylock_status(uint8_t led_usb_state) {
 | 
			
		||||
void render_keylock_status(led_t led_usb_state) {
 | 
			
		||||
#if defined(OLED_DISPLAY_VERBOSE)
 | 
			
		||||
    oled_set_cursor(1, 6);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -330,12 +335,12 @@ void render_keylock_status(uint8_t led_usb_state) {
 | 
			
		|||
#if !defined(OLED_DISPLAY_VERBOSE)
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
#endif
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LOCK_NUML), led_usb_state & (1 << USB_LED_NUM_LOCK));
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LOCK_NUML), led_usb_state.num_lock);
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LOCK_CAPS), led_usb_state & (1 << USB_LED_CAPS_LOCK));
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LOCK_CAPS), led_usb_state.caps_lock);
 | 
			
		||||
#if defined(OLED_DISPLAY_VERBOSE)
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LOCK_SCLK), led_usb_state & (1 << USB_LED_SCROLL_LOCK));
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LOCK_SCLK), led_usb_state.scroll_lock);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -417,15 +422,14 @@ void render_bootmagic_status(void) {
 | 
			
		|||
        oled_write_P(logo[0][0], !is_bootmagic_on);
 | 
			
		||||
    }
 | 
			
		||||
#ifndef OLED_DISPLAY_VERBOSE
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
    oled_write_P(logo[1][1], is_bootmagic_on);
 | 
			
		||||
    oled_write_P(logo[0][1], !is_bootmagic_on);
 | 
			
		||||
#endif
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NKRO), keymap_config.nkro);
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
#ifdef AUTOCORRECTION_ENABLE
 | 
			
		||||
    oled_write_P(PSTR("CRCT"), userspace_config.autocorrection);
 | 
			
		||||
#if defined(AUTOCORRECTION_ENABLE) || defined(AUTOCORRECT_ENABLE)
 | 
			
		||||
    oled_write_P(PSTR("CRCT"), autocorrect_is_enabled());
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
#else
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NOGUI), keymap_config.no_gui);
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +443,7 @@ void render_bootmagic_status(void) {
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_ONESHOT), !is_oneshot_enabled());
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_ONESHOT), is_oneshot_enabled());
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
    oled_write_P(PSTR(" "), false);
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_SWAP), swap_hands);
 | 
			
		||||
| 
						 | 
				
			
			@ -577,19 +581,10 @@ void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset) {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
#    endif
 | 
			
		||||
        oled_pan(false);  // then move the entire graph one pixel to the right
 | 
			
		||||
        static const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0};
 | 
			
		||||
        for (uint8_t i = 0; i < 7; i++) {
 | 
			
		||||
            oled_set_cursor(0, i + 8);
 | 
			
		||||
            oled_write_raw_P(display_border, sizeof(display_border));
 | 
			
		||||
            oled_set_cursor(21, i + 8);
 | 
			
		||||
            oled_write_raw_P(display_border, sizeof(display_border));
 | 
			
		||||
        }
 | 
			
		||||
        static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
 | 
			
		||||
        oled_set_cursor(0, 15);
 | 
			
		||||
 | 
			
		||||
        oled_write_raw_P(footer_image, sizeof(footer_image));
 | 
			
		||||
 | 
			
		||||
#    include <math.h>
 | 
			
		||||
        uint8_t y_start  = ceil(vertical_offset / 8);
 | 
			
		||||
        uint8_t y_length = y_start + ceil(max_lines_graph / 8);
 | 
			
		||||
        oled_pan_section(false, y_start, y_length, 3, 125); // then move the entire graph one pixel to the right
 | 
			
		||||
        timer = timer_read();                               // refresh the timer for the next iteration
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -781,25 +776,13 @@ void oled_driver_render_logo_left(void) {
 | 
			
		|||
#    if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE)
 | 
			
		||||
    render_pointing_dpi_status(charybdis_get_pointer_sniping_enabled() ? charybdis_get_pointer_sniping_dpi() : charybdis_get_pointer_default_dpi(), 1);
 | 
			
		||||
 | 
			
		||||
// credit and thanks to jaspertandy on discord for these images
 | 
			
		||||
    static const char PROGMEM mouse_logo[3][2][16] = {
 | 
			
		||||
        // mouse icon
 | 
			
		||||
        {
 | 
			
		||||
            {   0,   0,   0, 252,   2,   2,   2,  58,   2,   2,   2, 252,   0,   0,   0,   0 },
 | 
			
		||||
            {   0,   0,  63,  96,  64,  64,  64,  64,  64,  64,  64,  96,  63,   0,   0,   0 }
 | 
			
		||||
        },
 | 
			
		||||
    // credit and thanks to jaspertandy on discord for these images
 | 
			
		||||
    static const char PROGMEM mouse_logo[3][2][16] = {// mouse icon
 | 
			
		||||
                                                      {{0, 0, 0, 252, 2, 2, 2, 58, 2, 2, 2, 252, 0, 0, 0, 0}, {0, 0, 63, 96, 64, 64, 64, 64, 64, 64, 64, 96, 63, 0, 0, 0}},
 | 
			
		||||
                                                      // crosshair icon
 | 
			
		||||
        {
 | 
			
		||||
            { 128, 240, 136, 228, 146, 138, 202, 127, 202, 138, 146, 228, 136, 240, 128,   0 },
 | 
			
		||||
            {   0,   7,   8,  19,  36,  40,  41, 127,  41,  40,  36,  19,   8,   7,   0,   0 }
 | 
			
		||||
        },
 | 
			
		||||
                                                      {{128, 240, 136, 228, 146, 138, 202, 127, 202, 138, 146, 228, 136, 240, 128, 0}, {0, 7, 8, 19, 36, 40, 41, 127, 41, 40, 36, 19, 8, 7, 0, 0}},
 | 
			
		||||
                                                      // dragscroll icon
 | 
			
		||||
        {
 | 
			
		||||
            {   0,   0, 112, 136, 156,   2,  15,   1,  15,   2, 140,  68,  56,   0,   0,   0 },
 | 
			
		||||
            {   0,   0,   2,   6,  15,  28,  60, 124,  60,  28,  15,   6,   2,   0,   0,   0 }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
                                                      {{0, 0, 112, 136, 156, 2, 15, 1, 15, 2, 140, 68, 56, 0, 0, 0}, {0, 0, 2, 6, 15, 28, 60, 124, 60, 28, 15, 6, 2, 0, 0, 0}}};
 | 
			
		||||
 | 
			
		||||
    uint8_t image_index = 0;
 | 
			
		||||
#        ifdef OLED_DISPLAY_TEST
 | 
			
		||||
| 
						 | 
				
			
			@ -847,7 +830,7 @@ void render_status_right(void) {
 | 
			
		|||
#if !defined(OLED_DISPLAY_VERBOSE) && defined(WPM_ENABLE) && !defined(CONVERT_TO_PROTON_C)
 | 
			
		||||
    render_wpm(2);
 | 
			
		||||
#endif
 | 
			
		||||
    render_keylock_status(host_keyboard_leds());
 | 
			
		||||
    render_keylock_status(host_keyboard_led_state());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void render_status_left(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -860,9 +843,11 @@ void render_status_left(void) {
 | 
			
		|||
    render_keylogger_status();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void oled_render_large_display(void) {}
 | 
			
		||||
__attribute__((weak)) void oled_render_large_display(bool side) {}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) { return rotation; }
 | 
			
		||||
__attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
 | 
			
		||||
    return rotation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
 | 
			
		||||
    if (is_keyboard_master()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -876,10 +861,11 @@ oled_rotation_t oled_init_user(oled_rotation_t rotation) {
 | 
			
		|||
    return oled_init_keymap(rotation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) bool oled_task_keymap(void) { return true; }
 | 
			
		||||
__attribute__((weak)) bool oled_task_keymap(void) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool oled_task_user(void) {
 | 
			
		||||
 | 
			
		||||
    if (is_keyboard_master()) {
 | 
			
		||||
#ifndef OLED_DISPLAY_TEST
 | 
			
		||||
        if (timer_elapsed32(oled_timer) > 60000) {
 | 
			
		||||
| 
						 | 
				
			
			@ -896,29 +882,29 @@ bool oled_task_user(void) {
 | 
			
		|||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(OLED_DISPLAY_128X128)
 | 
			
		||||
    oled_set_cursor(0, 7);
 | 
			
		||||
    oled_render_large_display();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(OLED_DISPLAY_VERBOSE)
 | 
			
		||||
    static const char PROGMEM header_image[] = {
 | 
			
		||||
        0, 192, 32, 16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 7, 15, 31, 63, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 63, 31, 15, 7, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 192, 0,
 | 
			
		||||
        //         0,255,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  3,  7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  7,  3,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,  0
 | 
			
		||||
    };
 | 
			
		||||
    static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
 | 
			
		||||
    oled_set_cursor(0, 0);
 | 
			
		||||
    oled_write_raw_P(header_image, sizeof(header_image));
 | 
			
		||||
    oled_set_cursor(0, 1);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef OLED_DISPLAY_TEST
 | 
			
		||||
    if (is_keyboard_left()) {
 | 
			
		||||
#endif
 | 
			
		||||
        render_status_left();
 | 
			
		||||
#if defined(OLED_DISPLAY_128X128)
 | 
			
		||||
        oled_set_cursor(0, 7);
 | 
			
		||||
        oled_render_large_display(true);
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef OLED_DISPLAY_TEST
 | 
			
		||||
    } else {
 | 
			
		||||
        render_status_right();
 | 
			
		||||
#    if defined(OLED_DISPLAY_128X128)
 | 
			
		||||
        oled_set_cursor(0, 7);
 | 
			
		||||
        oled_render_large_display(false);
 | 
			
		||||
#    endif
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -936,6 +922,7 @@ bool oled_task_user(void) {
 | 
			
		|||
        oled_write_raw_P(display_border, sizeof(display_border));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
 | 
			
		||||
    oled_set_cursor(0, num_of_rows);
 | 
			
		||||
    oled_write_raw_P(footer_image, sizeof(footer_image));
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,11 +23,11 @@ extern deferred_token kittoken;
 | 
			
		|||
void            oled_driver_render_logo(void);
 | 
			
		||||
bool            process_record_user_oled(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
oled_rotation_t oled_init_keymap(oled_rotation_t rotation);
 | 
			
		||||
extern uint32_t oled_timer;
 | 
			
		||||
void            oled_timer_reset(void);
 | 
			
		||||
void            render_keylogger_status(void);
 | 
			
		||||
void            render_default_layer_state(void);
 | 
			
		||||
void            render_layer_state(void);
 | 
			
		||||
void            render_keylock_status(uint8_t led_usb_state);
 | 
			
		||||
void            render_keylock_status(led_t led_usb_state);
 | 
			
		||||
void            render_matrix_scan_rate(uint8_t padding);
 | 
			
		||||
void            render_mod_status(uint8_t modifiers);
 | 
			
		||||
void            render_bootmagic_status(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -37,9 +37,12 @@ void            render_wpm(uint8_t padding);
 | 
			
		|||
void            render_pointing_dpi_status(uint16_t cpi, uint8_t padding);
 | 
			
		||||
void            oled_driver_render_logo_left(void);
 | 
			
		||||
void            oled_driver_render_logo_right(void);
 | 
			
		||||
void            oled_render_large_display(void);
 | 
			
		||||
void            oled_render_large_display(bool side);
 | 
			
		||||
void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset);
 | 
			
		||||
 | 
			
		||||
void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(OLED_DISPLAY_128X128) || defined(OLED_DISPLAY_128X64)
 | 
			
		||||
#    define OLED_DISPLAY_VERBOSE
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -521,6 +521,25 @@ void oled_pan(bool left) {
 | 
			
		|||
    oled_dirty = OLED_ALL_BLOCKS_MASK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end) {
 | 
			
		||||
    uint16_t i = 0;
 | 
			
		||||
    for (uint16_t y = y_start; y < y_end; y++) {
 | 
			
		||||
        if (left) {
 | 
			
		||||
            for (uint16_t x = x_start; x < x_end - 1; x++) {
 | 
			
		||||
                i              = y * OLED_DISPLAY_WIDTH + x;
 | 
			
		||||
                oled_buffer[i] = oled_buffer[i + 1];
 | 
			
		||||
                oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            for (uint16_t x = x_end - 1; x > 0; x--) {
 | 
			
		||||
                i              = y * OLED_DISPLAY_WIDTH + x;
 | 
			
		||||
                oled_buffer[i] = oled_buffer[i - 1];
 | 
			
		||||
                oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
oled_buffer_reader_t oled_read_raw(uint16_t start_index) {
 | 
			
		||||
    if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE;
 | 
			
		||||
    oled_buffer_reader_t ret_reader;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
 | 
			
		|||
    if (x != 0 && y != 0) {
 | 
			
		||||
        mouse_timer = timer_read();
 | 
			
		||||
#ifdef OLED_ENABLE
 | 
			
		||||
        oled_timer = timer_read32();
 | 
			
		||||
        oled_timer_reset();
 | 
			
		||||
#endif
 | 
			
		||||
        if (timer_elapsed(mouse_debounce_timer) > TAP_CHECK) {
 | 
			
		||||
            if (enable_acceleration) {
 | 
			
		||||
| 
						 | 
				
			
			@ -94,8 +94,10 @@ bool process_record_pointing(uint16_t keycode, keyrecord_t* record) {
 | 
			
		|||
            record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
 | 
			
		||||
            mouse_timer = timer_read();
 | 
			
		||||
            break;
 | 
			
		||||
#if 0
 | 
			
		||||
        case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
 | 
			
		||||
            if (record->event.pressed || !record->tap.count) {
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,9 @@ void keyboard_post_init_rgb_matrix(void) {
 | 
			
		|||
        rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    if (userspace_config.rgb_layer_change) {
 | 
			
		||||
        rgb_matrix_set_flags(LED_FLAG_UNDERGLOW | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,8 +13,9 @@ GRAVE_ESC_ENABLE      = no
 | 
			
		|||
# DEBUG_MATRIX_SCAN_RATE_ENABLE = api
 | 
			
		||||
 | 
			
		||||
ifneq ($(strip $(NO_SECRETS)), yes)
 | 
			
		||||
    ifneq ("$(wildcard $(USER_PATH)/keyrecords/secrets.c)","")
 | 
			
		||||
        SRC += $(USER_PATH)/keyrecords/secrets.c
 | 
			
		||||
    ifneq ("$(wildcard $(USER_PATH)/../../../qmk_secrets/secrets.c)","")
 | 
			
		||||
        SRC += $(USER_PATH)/../../../qmk_secrets/secrets.c
 | 
			
		||||
        SECURE_ENABLE = yes
 | 
			
		||||
    endif
 | 
			
		||||
    ifeq ($(strip $(NO_SECRETS)), lite)
 | 
			
		||||
        OPT_DEFS += -DNO_SECRETS
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +103,7 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
 | 
			
		|||
    ifeq ($(strip $(CUSTOM_POINTING_DEVICE)), yes)
 | 
			
		||||
        SRC += $(USER_PATH)/pointing/pointing.c
 | 
			
		||||
        OPT_DEFS += -DCUSTOM_POINTING_DEVICE
 | 
			
		||||
        OPT_DEFS += -DMOUSE_EXT_REPORT
 | 
			
		||||
    endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -119,9 +121,3 @@ ifeq ($(strip $(AUTOCORRECTION_ENABLE)), yes)
 | 
			
		|||
    SRC += $(USER_PATH)/keyrecords/autocorrection/autocorrection.c
 | 
			
		||||
    OPT_DEFS += -DAUTOCORRECTION_ENABLE
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
CAPS_WORD_ENABLE ?= no
 | 
			
		||||
ifeq ($(strip $(CAPS_WORD_ENABLE)), yes)
 | 
			
		||||
    SRC += $(USER_PATH)/keyrecords/caps_word.c
 | 
			
		||||
    OPT_DEFS += -DCAPS_WORD_ENABLE
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
#ifdef UNICODE_COMMON_ENABLE
 | 
			
		||||
#    include "process_unicode_common.h"
 | 
			
		||||
extern unicode_config_t unicode_config;
 | 
			
		||||
#    include "keyrecords/unicode.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef AUDIO_ENABLE
 | 
			
		||||
#    include "audio.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +98,7 @@ void user_transport_update(void) {
 | 
			
		|||
#endif
 | 
			
		||||
#ifdef UNICODE_COMMON_ENABLE
 | 
			
		||||
        user_state.unicode_mode = unicode_config.input_mode;
 | 
			
		||||
        user_state.unicode_typing_mode = typing_mode;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SWAP_HANDS_ENABLE
 | 
			
		||||
        user_state.swap_hands = swap_hands;
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +112,7 @@ void user_transport_update(void) {
 | 
			
		|||
        user_state.raw       = transport_user_state;
 | 
			
		||||
#ifdef UNICODE_COMMON_ENABLE
 | 
			
		||||
        unicode_config.input_mode = user_state.unicode_mode;
 | 
			
		||||
        typing_mode = user_state.unicode_typing_mode;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(CUSTOM_POINTING_DEVICE)
 | 
			
		||||
        tap_toggling = user_state.tap_toggling;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ typedef union {
 | 
			
		|||
        uint8_t unicode_mode        :3;
 | 
			
		||||
        bool swap_hands             :1;
 | 
			
		||||
        bool host_driver_disabled   :1;
 | 
			
		||||
        uint8_t unicode_typing_mode :3;
 | 
			
		||||
    };
 | 
			
		||||
} user_runtime_config_t;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,21 +25,6 @@ __attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *
 | 
			
		|||
// And use "NEWPLACEHOLDER" for new safe range
 | 
			
		||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        case KC_MAKE:
 | 
			
		||||
            if (!record->event.pressed) {
 | 
			
		||||
                SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
 | 
			
		||||
#if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
 | 
			
		||||
                            ":dfu"
 | 
			
		||||
#elif defined(BOOTLOADER_HALFKAY)
 | 
			
		||||
                            ":teensy"
 | 
			
		||||
#elif defined(BOOTLOADER_CATERINA)
 | 
			
		||||
                            ":avrdude"
 | 
			
		||||
#endif
 | 
			
		||||
                            SS_TAP(X_ENTER));
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case VRSN:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@
 | 
			
		|||
 | 
			
		||||
enum custom_keycodes {
 | 
			
		||||
    VRSN = SAFE_RANGE,  // can always be here
 | 
			
		||||
    KC_MAKE,
 | 
			
		||||
    KC_RESET,
 | 
			
		||||
    QK_MAKE,
 | 
			
		||||
    QK_BOOT,
 | 
			
		||||
    NEWPLACEHOLDER  // use "NEWPLACEHOLDER for keymap specific codes
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue