From 82422ab1ec7f8949ca6e6be097a11e6d9bd52665 Mon Sep 17 00:00:00 2001 From: sajenim Date: Sun, 19 Feb 2023 17:51:22 +0800 Subject: [PATCH] idk --- keyboards/crkbd/keymaps/sajenim/combos.def | 23 + keyboards/crkbd/keymaps/sajenim/config.h | 31 +- .../autocorrect_dictionary.txt | 0 keyboards/crkbd/keymaps/sajenim/keycodes.h | 48 -- keyboards/crkbd/keymaps/sajenim/keymap.c | 409 ++---------------- keyboards/crkbd/keymaps/sajenim/layers.h | 31 ++ keyboards/crkbd/keymaps/sajenim/leader.c | 61 +++ keyboards/crkbd/keymaps/sajenim/leader.h | 26 ++ keyboards/crkbd/keymaps/sajenim/oled.c | 152 +++++++ keyboards/crkbd/keymaps/sajenim/oled.h | 0 .../crkbd/keymaps/sajenim/process_record.c | 52 +++ .../crkbd/keymaps/sajenim/process_record.h | 76 ++++ keyboards/crkbd/keymaps/sajenim/rules.mk | 38 +- keyboards/crkbd/keymaps/sajenim/tapdance.c | 350 +++++++++++++++ keyboards/crkbd/keymaps/sajenim/tapdance.h | 70 +++ 15 files changed, 937 insertions(+), 430 deletions(-) create mode 100644 keyboards/crkbd/keymaps/sajenim/combos.def rename keyboards/crkbd/keymaps/sajenim/{ => dictionaries}/autocorrect_dictionary.txt (100%) delete mode 100644 keyboards/crkbd/keymaps/sajenim/keycodes.h create mode 100644 keyboards/crkbd/keymaps/sajenim/layers.h create mode 100644 keyboards/crkbd/keymaps/sajenim/leader.c create mode 100644 keyboards/crkbd/keymaps/sajenim/leader.h create mode 100644 keyboards/crkbd/keymaps/sajenim/oled.c create mode 100644 keyboards/crkbd/keymaps/sajenim/oled.h create mode 100644 keyboards/crkbd/keymaps/sajenim/process_record.c create mode 100644 keyboards/crkbd/keymaps/sajenim/process_record.h create mode 100644 keyboards/crkbd/keymaps/sajenim/tapdance.c create mode 100644 keyboards/crkbd/keymaps/sajenim/tapdance.h diff --git a/keyboards/crkbd/keymaps/sajenim/combos.def b/keyboards/crkbd/keymaps/sajenim/combos.def new file mode 100644 index 0000000..50e3506 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/combos.def @@ -0,0 +1,23 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +//#include "dictionaries/emerge.def" + +// name result chord keys +COMB(NE_ESCAPE, KC_ESC, HOME_N, HOME_E) +COMB(SE_CAPSWRD, CW_TOGG, HOME_S, HOME_E) + +/* vim: set filetype=c : */ diff --git a/keyboards/crkbd/keymaps/sajenim/config.h b/keyboards/crkbd/keymaps/sajenim/config.h index 77ac164..3b865f8 100644 --- a/keyboards/crkbd/keymaps/sajenim/config.h +++ b/keyboards/crkbd/keymaps/sajenim/config.h @@ -1,3 +1,19 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + #pragma once // By default, the firmware does not know which side is which; it needs some help to determine that. @@ -9,15 +25,15 @@ #define OLED_FONT_H "keyboards/crkbd/lib/glcdfont.c" +// Tap-Hold Configuration Options // Configure the global tapping term (default: 200ms) #define TAPPING_TERM 200 - // Activate the modifier when another key is pressed and released while the mod-tap is held. #define PERMISSIVE_HOLD - +// Makes tap and hold keys (like Layer Tap) work better for fast typists +#define HOLD_ON_OTHER_KEY_PRESS // Prevent normal rollover on alphas from accidentally triggering mods. #define IGNORE_MOD_TAP_INTERRUPT - // Enable rapid switch from tap to hold, disables double tap hold auto-repeat. #define TAPPING_FORCE_HOLD @@ -29,9 +45,16 @@ #define AUTO_SHIFT_TIMEOUT 175 #define AUTO_SHIFT_REPEAT #define AUTO_SHIFT_MODIFIERS - // Retro Shift #define RETRO_SHIFT 500 // Caps Word #define CAPS_WORD_IDLE_TIMEOUT 2000 + +// Leader Key +#define LEADER_TIMEOUT 300 +#define LEADER_PER_KEY_TIMING + +// Combos +#define COMBO_TERM 50 + diff --git a/keyboards/crkbd/keymaps/sajenim/autocorrect_dictionary.txt b/keyboards/crkbd/keymaps/sajenim/dictionaries/autocorrect_dictionary.txt similarity index 100% rename from keyboards/crkbd/keymaps/sajenim/autocorrect_dictionary.txt rename to keyboards/crkbd/keymaps/sajenim/dictionaries/autocorrect_dictionary.txt diff --git a/keyboards/crkbd/keymaps/sajenim/keycodes.h b/keyboards/crkbd/keymaps/sajenim/keycodes.h deleted file mode 100644 index cdf3aff..0000000 --- a/keyboards/crkbd/keymaps/sajenim/keycodes.h +++ /dev/null @@ -1,48 +0,0 @@ -// This file contains user defined aliases - -// Layers -#define SPACEFN LT(L_NAVIGATION, KC_SPC) -#define ENTERFN LT(L_MACRO, KC_ENT) - -#define NUMBERS MO(L_NUMBERS) -#define SYMBOLS MO(L_SYMBOLS) - -#define LOWER MO(L_LOWER) -#define RAISE MO(L_RAISE) - -// One Shot Keys -#define OS_OPRS OSL(L_OPERATORS) -#define OS_MEH OSM(MOD_MEH) -#define OS_SUPR OSM(MOD_LGUI) -#define OS_HYPR OSM(MOD_HYPR) - -#define OS_LCTL OSM(MOD_LCTL) -#define OS_LSFT OSM(MOD_LSFT) -#define OS_LALT OSM(MOD_LALT) -#define OS_LGUI OSM(MOD_LGUI) - -#define OS_RCTL OSM(MOD_RCTL) -#define OS_RSFT OSM(MOD_RSFT) -#define OS_RALT OSM(MOD_RALT) -#define OS_RGUI OSM(MOD_RGUI) - -// Tap Dance -#define TD_YANK TD(YANK) -#define TD_PSTE TD(PSTE) - -// Left-hand home row mods -#define HOME_C LGUI_T(KC_C) -#define HOME_R LALT_T(KC_R) -#define HOME_S LSFT_T(KC_S) -#define HOME_T LCTL_T(KC_T) - -// Right-hand home row mods -#define HOME_N RCTL_T(KC_N) -#define HOME_E RSFT_T(KC_E) -#define HOME_I RALT_T(KC_I) -#define HOME_A RGUI_T(KC_A) - -// Shortcuts -#define PREFIX LCTL(KC_B) -#define DELWORD LCTL(KC_W) -#define ST_PSTE LSFT(KC_INSERT) diff --git a/keyboards/crkbd/keymaps/sajenim/keymap.c b/keyboards/crkbd/keymaps/sajenim/keymap.c index 1dfc8fb..1fdb5f8 100644 --- a/keyboards/crkbd/keymaps/sajenim/keymap.c +++ b/keyboards/crkbd/keymaps/sajenim/keymap.c @@ -16,110 +16,34 @@ #include QMK_KEYBOARD_H #include - #include "config.h" -#include "keycodes.h" - -/* Enumeration */ - -enum layers { - L_CANARY, - L_LOWER, - L_RAISE, - L_ADJUST, - L_NAVIGATION, - L_SYMBOLS, - L_NUMBERS, - L_OPERATORS, - L_MACRO -}; - -enum custom_keycodes { - VI_SAVE = SAFE_RANGE, - VI_EXIT, - HOME, - UPDIR -}; - -enum td_keycodes { - YANK, - PSTE -}; - -enum combos { - NE_ESCAPE, - SE_CAPWRD, - COMBO_LENGTH -}; - - -/* Tapdance */ - -// Define a type containing as many tapdance states as you need -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_TAP, - TD_DOUBLE_HOLD -} td_state_t; - -// Create a global instance of the tapdance state type -static td_state_t td_state; - -// Declare your tapdance functions: - -// Function to determine the current tapdance state -td_state_t cur_dance(qk_tap_dance_state_t *state); - -// `finished` and `reset` functions for each tapdance keycode -void yank_finished(qk_tap_dance_state_t *state, void *user_data); -void yank_reset(qk_tap_dance_state_t *state, void *user_data); - -void pste_finished(qk_tap_dance_state_t *state, void *user_data); -void pste_reset(qk_tap_dance_state_t *state, void *user_data); - - -/* Combos */ - -// Programmatically declare the size of the Combo data structure -uint16_t COMBO_LEN = COMBO_LENGTH; - -// Define key sequences -const uint16_t PROGMEM ne_combo[] = {HOME_N, HOME_E, COMBO_END}; -const uint16_t PROGMEM se_combo[] = {HOME_S, HOME_E, COMBO_END}; - -// List the combination of keys and there resulting action -combo_t key_combos[] = { - [NE_ESCAPE] = COMBO(ne_combo, KC_ESC), - [SE_CAPWRD] = COMBO(se_combo, CW_TOGG), -}; - +#include "layers.h" +#include "process_record.h" +#include "g/keymap_combo.h" /* Keymaps */ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [L_CANARY] = LAYOUT_split_3x6_3( //,-----------------------------------------------------. ,-----------------------------------------------------. - PREFIX, KC_W, KC_L, KC_Y, KC_P, KC_B, KC_Z, KC_F, KC_O, KC_U, KC_QUOT, XXXXXXX, + KC_GRV, KC_W, KC_L, KC_Y, KC_P, KC_B, KC_Z, KC_F, KC_O, KC_U, KC_QUOT, XXXXXXX, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - KC_BSPC, HOME_C, HOME_R, HOME_S, HOME_T, KC_G, KC_M, HOME_N, HOME_E, HOME_I, HOME_A, KC_DEL, + BAKWORD, HOME_C, HOME_R, HOME_S, HOME_T, KC_G, KC_M, HOME_N, HOME_E, HOME_I, HOME_A, DELWORD, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - OS_MEH, KC_Q, KC_J, KC_V, KC_D, KC_K, KC_X, KC_H, KC_SLSH, KC_COMM, KC_DOT, OS_HYPR, + XXXXXXX, KC_Q, KC_J, KC_V, KC_D, KC_K, KC_X, KC_H, KC_SLSH, KC_COMM, KC_DOT, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| - LOWER, NUMBERS, SPACEFN, ENTERFN, SYMBOLS, RAISE + LOWER, FN_PFX, FN_SPC, FN_ENT, FN_LDR, RAISE //`--------------------------' `--------------------------' ), [L_NAVIGATION] = LAYOUT_split_3x6_3( //,-----------------------------------------------------. ,-----------------------------------------------------. - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + _______, XXXXXXX, XXXXXXX, KC_PGUP, KC_PGDN, XXXXXXX, XXXXXXX, KC_HOME, KC_END, XXXXXXX, XXXXXXX, _______, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| _______, OS_LGUI, OS_LALT, OS_LSFT, OS_LCTL, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_PGDN, KC_PGUP, KC_END, _______, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| _______, _______, _______, KC_TAB, _______, _______ //`--------------------------' `--------------------------' @@ -137,35 +61,23 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { //`--------------------------' `--------------------------' ), - [L_OPERATORS] = LAYOUT_split_3x6_3( - //,-----------------------------------------------------. ,-----------------------------------------------------. - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| - _______, _______, _______, _______, _______, _______ - //`--------------------------' `--------------------------' - ), - [L_NUMBERS] = LAYOUT_split_3x6_3( //,-----------------------------------------------------. ,-----------------------------------------------------. - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_SLSH, KC_7, KC_8, KC_9, KC_MINS, XXXXXXX, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_SLSH, KC_7, KC_8, KC_9, KC_MINS, _______, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| _______, OS_LGUI, OS_LALT, OS_LSFT, OS_LCTL, XXXXXXX, KC_ASTR, KC_4, KC_5, KC_6, KC_PLUS, _______, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_1, KC_2, KC_3, KC_DOT, _______, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_DOT, KC_1, KC_2, KC_3, KC_EQL, _______, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| - _______, _______, _______, KC_0, _______, _______ + _______, _______, _______, _______, KC_0, _______ //`--------------------------' `--------------------------' ), [L_MACRO] = LAYOUT_split_3x6_3( //,-----------------------------------------------------. ,-----------------------------------------------------. - HOME, XXXXXXX, XXXXXXX, TD_YANK, TD_PSTE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, UPDIR, + HOME, XXXXXXX, XXXXXXX, YANK, PSTE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, UPDIR, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| - DELWORD, XXXXXXX, XXXXXXX, VI_SAVE, VI_EXIT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, VI_SAVE, VI_EXIT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| @@ -211,273 +123,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { }; -/* OLED */ - -#ifdef OLED_ENABLE -oled_rotation_t oled_init_user(oled_rotation_t rotation) { - if (is_keyboard_master()) { - return OLED_ROTATION_270; - } else { - return OLED_ROTATION_180; - } - return rotation; -} - -void oled_render_master(void) { - // Layer Status - switch (get_highest_layer(layer_state)) { - case L_CANARY: - oled_write("CANRY", false); - break; - case L_LOWER: - oled_write("LOWER", false); - break; - case L_RAISE: - oled_write("RAISE", false); - break; - case L_ADJUST: - oled_write("ADJST", false); - break; - case L_NAVIGATION: - oled_write_ln(" NAV", false); - break; - case L_SYMBOLS: - oled_write_ln(" SYM", false); - break; - case L_NUMBERS: - oled_write_ln(" NUM", false); - break; - case L_OPERATORS: - oled_write("OPER8", false); - break; - case L_MACRO: - oled_write("MACRO", false); - break; - default: - oled_write_ln(" UND", false); - } - - // Mod Status - uint8_t this_mod = get_mods(); - uint8_t this_osm = get_oneshot_mods(); - - oled_write("-----", false); - - if ((this_mod | this_osm) & MOD_MASK_GUI) { - oled_write("gui:*", false); - } else { - oled_write("gui:.", false); - } - - if ((this_mod | this_osm) & MOD_MASK_ALT) { - oled_write("alt:*", false); - } else { - oled_write("alt:.", false); - } - - if ((this_mod | this_osm) & MOD_MASK_SHIFT) { - oled_write("sft:*", false); - } else { - oled_write("sft:.", false); - } - - if ((this_mod | this_osm) & MOD_MASK_CTRL) { - oled_write("ctl:*", false); - } else { - oled_write("ctl:.", false); - } - - // Feature Status - oled_write("-----", false); - - bool is_autoshift_enabled = get_autoshift_state(); - if (is_autoshift_enabled) { - oled_write("as: *", false); - } else { - oled_write("as: .", false); - } - - bool is_autocorrect_enabled = autocorrect_is_enabled(); - if (is_autocorrect_enabled) { - oled_write("ac: *", false); - } else { - oled_write("ac: .", false); - } - - if (is_combo_enabled()) { - oled_write("cm: *", false); - } else { - oled_write("cm: .", false); - } - - // Caps Word - oled_write("-----", false); - - if (is_caps_word_on()) { - oled_write("cap:*", false); - } else { - oled_write("cap:.", false); - } - - // WPM Status - char wpm_str [4]; - sprintf(wpm_str, "%03d", get_current_wpm()); - oled_set_cursor(1, 14); - oled_write_ln(wpm_str, false); - oled_write(" wpm", false); -} - -void oled_render_slave(void) { - static const char PROGMEM crkbd_logo[] = { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, - 0}; - oled_write_P(crkbd_logo, false); -} - -bool oled_task_user(void) { - if (is_keyboard_master()) { - oled_render_master(); - } else { - oled_render_slave(); - } - return false; -} -#endif // OLED_ENABLE - - -/* Custom Keycodes */ - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case VI_SAVE: - if (record->event.pressed) { - tap_code(KC_ESC); - SEND_STRING(":w"); - tap_code(KC_ENT); - } - break; - - case VI_EXIT: - if (record->event.pressed) { - tap_code(KC_ESC); - SEND_STRING(":q!"); - tap_code(KC_ENT); - } - break; - - case HOME: - if (record->event.pressed) { - SEND_STRING("cd ~/"); - tap_code(KC_ENT); - } - break; - - case UPDIR: - if (record->event.pressed) { - SEND_STRING("cd ../"); - tap_code(KC_ENT); - } - break; - - } - return true; -}; - - -/* Tapdance Functions */ - -// Determine the tapdance state to return -td_state_t cur_dance(qk_tap_dance_state_t *state) { - if (state->count == 1) { - if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; - else return TD_SINGLE_HOLD; - } - - if (state->count == 2) { - if (state->interrupted || !state->pressed) return TD_DOUBLE_TAP; - else return TD_DOUBLE_HOLD; - } - - else return TD_UNKNOWN; // Any number higher than the maximum state value you return above -} - -// Handle the possible states for each tapdance keycode you define: - -void yank_finished(qk_tap_dance_state_t *state, void *user_data) { - td_state = cur_dance(state); - switch (td_state) { - case TD_SINGLE_TAP: - register_mods(MOD_BIT(KC_LCTL)); - register_code(KC_C); - break; - case TD_DOUBLE_TAP: - register_mods(MOD_BIT(KC_LCTL)); - register_mods(MOD_BIT(KC_LSFT)); - register_code(KC_C); - break; - default: - break; - } -} - -void yank_reset(qk_tap_dance_state_t *state, void *user_data) { - switch (td_state) { - case TD_SINGLE_TAP: - unregister_mods(MOD_BIT(KC_LCTL)); - unregister_code(KC_C); - break; - case TD_DOUBLE_TAP: - unregister_mods(MOD_BIT(KC_LCTL)); - unregister_mods(MOD_BIT(KC_LSFT)); - unregister_code(KC_C); - break; - default: - break; - } -} - -void pste_finished(qk_tap_dance_state_t *state, void *user_data) { - td_state = cur_dance(state); - switch (td_state) { - case TD_SINGLE_TAP: - register_mods(MOD_BIT(KC_LCTL)); - register_code(KC_V); - break; - case TD_DOUBLE_TAP: - register_mods(MOD_BIT(KC_LCTL)); - register_mods(MOD_BIT(KC_LSFT)); - register_code(KC_V); - break; - default: - break; - } -} - -void pste_reset(qk_tap_dance_state_t *state, void *user_data) { - switch (td_state) { - case TD_SINGLE_TAP: - unregister_mods(MOD_BIT(KC_LCTL)); - unregister_code(KC_V); - break; - case TD_DOUBLE_TAP: - unregister_mods(MOD_BIT(KC_LCTL)); - unregister_mods(MOD_BIT(KC_LSFT)); - unregister_code(KC_V); - break; - default: - break; - } -} - -// Define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions -qk_tap_dance_action_t tap_dance_actions[] = { - [YANK] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, yank_finished, yank_reset), - [PSTE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, pste_finished, pste_reset) -}; - - /* Add Home Row Mods to Auto Shift */ bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { @@ -508,10 +153,34 @@ bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { } +/* Configure which words are word breaking */ +bool caps_word_press_user(uint16_t keycode) { + switch (keycode) { + // Keycodes that continue Caps Word, with shift applied. + case KC_A ... KC_Z: + case KC_MINS: + add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key. + return true; + + // Keycodes that continue Caps Word, without shifting. + case KC_1 ... KC_0: + case KC_BSPC: + case KC_DEL: + case KC_UNDS: + // Our custom keys + case BAKWORD: + case DELWORD: + return true; + + default: + return false; // Deactivate Caps Word. + } +} + + /* Layer Change */ layer_state_t layer_state_set_user(layer_state_t state) { - state = update_tri_layer_state(state, L_NUMBERS, L_SYMBOLS, L_OPERATORS); state = update_tri_layer_state(state, L_LOWER, L_RAISE, L_ADJUST); return state; } diff --git a/keyboards/crkbd/keymaps/sajenim/layers.h b/keyboards/crkbd/keymaps/sajenim/layers.h new file mode 100644 index 0000000..85bb610 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/layers.h @@ -0,0 +1,31 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#pragma once + +// Our layers +enum layers { + L_CANARY, + L_LOWER, + L_RAISE, + L_ADJUST, + L_NAVIGATION, + L_SYMBOLS, + L_NUMBERS, + L_OPERATORS, + L_MACRO, +}; + diff --git a/keyboards/crkbd/keymaps/sajenim/leader.c b/keyboards/crkbd/keymaps/sajenim/leader.c new file mode 100644 index 0000000..1d5fa33 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/leader.c @@ -0,0 +1,61 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ +#include QMK_KEYBOARD_H +#include "leader.h" +#include "secrets.h" + +LEADER_EXTERNS(); + +void matrix_scan_user(void) { + LEADER_DICTIONARY() { + leading = false; + leader_end(); + + /* Emerge */ + SEQ_TWO_KEYS(KC_E, KC_S) { + SEND_STRING(SEARCH); + } + SEQ_TWO_KEYS(KC_E, KC_I) { + SEND_STRING(INSTALL); + } + SEQ_TWO_KEYS(KC_E, KC_R) { + SEND_STRING(REMOVE); + } + SEQ_TWO_KEYS(KC_E, KC_U) { + SEND_STRING(UPDATE); + } + SEQ_TWO_KEYS(KC_E, KC_D) { + SEND_STRING(DEPCLEAN); + } + SEQ_THREE_KEYS(KC_E, KC_U, KC_U) { + SEND_STRING(UPGRADE); + } + + /* Secrets */ + SEQ_TWO_KEYS(KC_A, KC_H) { + SEND_STRING(ADDRESS); + } + SEQ_TWO_KEYS(KC_P, KC_M) { + SEND_STRING(PHONE); + } + SEQ_TWO_KEYS(KC_E, KC_O) { + SEND_STRING(OUTLOOK); + } + SEQ_TWO_KEYS(KC_E, KC_P) { + SEND_STRING(PROTON); + } + } +} diff --git a/keyboards/crkbd/keymaps/sajenim/leader.h b/keyboards/crkbd/keymaps/sajenim/leader.h new file mode 100644 index 0000000..223296a --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/leader.h @@ -0,0 +1,26 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#pragma once + +/* Emerge */ +#define SEARCH "sudo emerge --search " +#define INSTALL "sudo emerge --ask " +#define REMOVE "sudo emerge --ask --deselect " +#define UPDATE "sudo emerge --sync" +#define DEPCLEAN "sudo emerge --ask --depclean" +#define UPGRADE "sudo emerge --ask --update --deep --newuse --with-bdeps=y @world" + diff --git a/keyboards/crkbd/keymaps/sajenim/oled.c b/keyboards/crkbd/keymaps/sajenim/oled.c new file mode 100644 index 0000000..8641126 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/oled.c @@ -0,0 +1,152 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#include QMK_KEYBOARD_H +#include +#include "oled.h" +#include "layers.h" + +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + if (is_keyboard_master()) { + return OLED_ROTATION_270; + } else { + return OLED_ROTATION_180; + } + return rotation; +} + +void oled_render_master(void) { + // Layer Status + switch (get_highest_layer(layer_state)) { + case L_CANARY: + oled_write("CANRY", false); + break; + case L_LOWER: + oled_write("LOWER", false); + break; + case L_RAISE: + oled_write("RAISE", false); + break; + case L_ADJUST: + oled_write("ADJST", false); + break; + case L_NAVIGATION: + oled_write_ln(" NAV", false); + break; + case L_SYMBOLS: + oled_write_ln(" SYM", false); + break; + case L_NUMBERS: + oled_write_ln(" NUM", false); + break; + case L_OPERATORS: + oled_write("OPER8", false); + break; + case L_MACRO: + oled_write("MACRO", false); + break; + default: + oled_write_ln(" UND", false); + } + + // Mod Status + uint8_t this_mod = get_mods(); + uint8_t this_osm = get_oneshot_mods(); + + oled_write("-----", false); + + if ((this_mod | this_osm) & MOD_MASK_GUI) { + oled_write("gui:*", false); + } else { + oled_write("gui:.", false); + } + + if ((this_mod | this_osm) & MOD_MASK_ALT) { + oled_write("alt:*", false); + } else { + oled_write("alt:.", false); + } + + if ((this_mod | this_osm) & MOD_MASK_SHIFT) { + oled_write("sft:*", false); + } else { + oled_write("sft:.", false); + } + + if ((this_mod | this_osm) & MOD_MASK_CTRL) { + oled_write("ctl:*", false); + } else { + oled_write("ctl:.", false); + } + + // Feature Status + oled_write("-----", false); + + bool is_autoshift_enabled = get_autoshift_state(); + if (is_autoshift_enabled) { + oled_write("as: *", false); + } else { + oled_write("as: .", false); + } + + bool is_autocorrect_enabled = autocorrect_is_enabled(); + if (is_autocorrect_enabled) { + oled_write("ac: *", false); + } else { + oled_write("ac: .", false); + } + + if (is_combo_enabled()) { + oled_write("cm: *", false); + } else { + oled_write("cm: .", false); + } + + // Caps Word + oled_write("-----", false); + + if (is_caps_word_on()) { + oled_write("cap:*", false); + } else { + oled_write("cap:.", false); + } + + // WPM Status + char wpm_str [4]; + sprintf(wpm_str, "%03d", get_current_wpm()); + oled_set_cursor(1, 14); + oled_write_ln(wpm_str, false); + oled_write(" wpm", false); +} + +void oled_render_slave(void) { + static const char PROGMEM crkbd_logo[] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, + 0}; + oled_write_P(crkbd_logo, false); +} + +bool oled_task_user(void) { + if (is_keyboard_master()) { + oled_render_master(); + } else { + oled_render_slave(); + } + return false; +} + diff --git a/keyboards/crkbd/keymaps/sajenim/oled.h b/keyboards/crkbd/keymaps/sajenim/oled.h new file mode 100644 index 0000000..e69de29 diff --git a/keyboards/crkbd/keymaps/sajenim/process_record.c b/keyboards/crkbd/keymaps/sajenim/process_record.c new file mode 100644 index 0000000..aa3ea75 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/process_record.c @@ -0,0 +1,52 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#include "process_record.h" + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case VI_SAVE: + if (record->event.pressed) { + tap_code(KC_ESC); + SEND_STRING(":w"); + tap_code(KC_ENT); + } + break; + + case VI_EXIT: + if (record->event.pressed) { + tap_code(KC_ESC); + SEND_STRING(":q!"); + tap_code(KC_ENT); + } + break; + + case HOME: + if (record->event.pressed) { + SEND_STRING("~/"); + } + break; + + case UPDIR: + if (record->event.pressed) { + SEND_STRING("../"); + } + break; + + } + return true; +}; + diff --git a/keyboards/crkbd/keymaps/sajenim/process_record.h b/keyboards/crkbd/keymaps/sajenim/process_record.h new file mode 100644 index 0000000..243f074 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/process_record.h @@ -0,0 +1,76 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#pragma once + +#include "quantum.h" +#include "tapdance.h" + +// Our custom keycodes +enum custom_keycodes { + VI_SAVE = SAFE_RANGE, + VI_EXIT, + HOME, + UPDIR +}; + +// Left-hand thumb key layers +#define LOWER MO(L_LOWER) +#define FN_PFX TD(TD_FNPFX) +#define FN_SPC LT(L_NAVIGATION, KC_SPC) + +// Right-hand thumb key layers +#define FN_ENT LT(L_MACRO, KC_ENT) +#define FN_LDR TD(TD_FNLDR) +#define RAISE MO(L_RAISE) + +// Left-hand home row mods +#define HOME_C LGUI_T(KC_C) +#define HOME_R LALT_T(KC_R) +#define HOME_S LSFT_T(KC_S) +#define HOME_T LCTL_T(KC_T) + +// Right-hand home row mods +#define HOME_N RCTL_T(KC_N) +#define HOME_E RSFT_T(KC_E) +#define HOME_I RALT_T(KC_I) +#define HOME_A RGUI_T(KC_A) + +// One Shot Keys +#define OS_MEH OSM(MOD_MEH) +#define OS_SUPR OSM(MOD_LGUI) +#define OS_HYPR OSM(MOD_HYPR) + +#define OS_LCTL OSM(MOD_LCTL) +#define OS_LSFT OSM(MOD_LSFT) +#define OS_LALT OSM(MOD_LALT) +#define OS_LGUI OSM(MOD_LGUI) + +#define OS_RCTL OSM(MOD_RCTL) +#define OS_RSFT OSM(MOD_RSFT) +#define OS_RALT OSM(MOD_RALT) +#define OS_RGUI OSM(MOD_RGUI) + +// Tap Dance +#define YANK TD(TD_YANK) +#define PSTE TD(TD_PSTE) +#define BAKWORD TD(TD_BAKWORD) +#define DELWORD TD(TD_DELWORD) + +// Shortcuts +#define PREFIX LCTL(KC_B) +#define ST_PSTE LSFT(KC_INSERT) + diff --git a/keyboards/crkbd/keymaps/sajenim/rules.mk b/keyboards/crkbd/keymaps/sajenim/rules.mk index 931e7fd..a5aab55 100644 --- a/keyboards/crkbd/keymaps/sajenim/rules.mk +++ b/keyboards/crkbd/keymaps/sajenim/rules.mk @@ -4,17 +4,39 @@ CONVERT_TO = promicro_rp2040 # Bootloader selection BOOTLOADER = rp2040 -# Defaults +# Default features LTO_ENABLE = yes -OLED_ENABLE = yes OLED_DRIVER = SSD1306 -# Enable some features -CAPS_WORD_ENABLE = yes -COMBO_ENABLE = yes -LEADER_ENABLE = yes -WPM_ENABLE = yes +# Toggleable through keymap AUTO_SHIFT_ENABLE = yes -TAP_DANCE_ENABLE = yes AUTOCORRECT_ENABLE = yes +CAPS_WORD_ENABLE = yes +# Optional features +OLED_ENABLE = yes +COMBO_ENABLE = yes +TAP_DANCE_ENABLE = yes +LEADER_ENABLE = yes +# Only required if OLED_ENABLE = yes +WPM_ENABLE = yes + +# Source required c files +SRC += ./process_record.c + +# Contitionally source optional c files +ifeq ($(OLED_ENABLE),yes) + SRC += ./oled.c +endif + +ifeq ($(COMBO_ENABLE),yes) + VPATH += keyboards/gboards +endif + +ifeq ($(TAP_DANCE_ENABLE),yes) + SRC += ./tapdance.c +endif + +ifeq ($(LEADER_ENABLE),yes) + SRC += ./leader.c +endif diff --git a/keyboards/crkbd/keymaps/sajenim/tapdance.c b/keyboards/crkbd/keymaps/sajenim/tapdance.c new file mode 100644 index 0000000..9fd3e32 --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/tapdance.c @@ -0,0 +1,350 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#include QMK_KEYBOARD_H +#include "layers.h" +#include "tapdance.h" + +/* Return an integer that corresponds to what kind of tap dance should be executed. + * + * How to figure out tap dance state: interrupted and pressed. + * + * Interrupted: If the state of a dance is "interrupted", that means that another key has been hit + * under the tapping term. This is typically indicitive that you are trying to "tap" the key. + * + * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term + * has ended, but the key is still being pressed down. This generally means the key is being "held". + * + * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold" + * feature. In general, advanced tap dances do not work well if they are used with commonly typed letters. + * For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters. + * + * Good places to put an advanced tap dance: + * z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon + * + * Criteria for "good placement" of a tap dance key: + * Not a key that is hit frequently in a sentence + * Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or + * in a web form. So 'tab' would be a poor choice for a tap dance. + * Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the + * letter 'p', the word 'pepper' would be quite frustating to type. + * + * For the third point, there does exist the 'TD_DOUBLE_SINGLE_TAP', however this is not fully tested + * + */ + +td_state_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; + // Key has not been interrupted, but the key is still held. Means you want to send a 'HOLD'. + else return TD_SINGLE_HOLD; + } else if (state->count == 2) { + // TD_DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap + // action when hitting 'pp'. Suggested use case for this return value is when you want to send two + // keystrokes of the key, and not the 'double tap' action/macro. + if (state->interrupted) return TD_DOUBLE_SINGLE_TAP; + else if (state->pressed) return TD_DOUBLE_HOLD; + else return TD_DOUBLE_TAP; + } + + // Assumes no one is trying to type the same letter three times (at least not quickly). + // If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add + // an exception here to return a 'TD_TRIPLE_SINGLE_TAP', and define that enum just like 'TD_DOUBLE_SINGLE_TAP' + if (state->count == 3) { + if (state->interrupted || !state->pressed) return TD_TRIPLE_TAP; + else return TD_TRIPLE_HOLD; + } else return TD_UNKNOWN; +} + + +/* Yank: + * + * Sends + on single tap + * Sends + + on double tap (Commonly used in UNIX terminals) + * + */ + +static td_tap_t yank_tap_state = { + .is_press_action = true, + .state = TD_NONE +}; + +void yank_finished(qk_tap_dance_state_t *state, void *user_data) { + yank_tap_state.state = cur_dance(state); + switch (yank_tap_state.state) { + case TD_SINGLE_TAP: + register_code(KC_LCTL); + register_code(KC_C); + break; + case TD_DOUBLE_TAP: + register_code(KC_LCTL); + register_code(KC_LSFT); + register_code(KC_C); + break; + default: + break; + } +} + +void yank_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (yank_tap_state.state) { + case TD_SINGLE_TAP: + unregister_code(KC_LCTL); + unregister_code(KC_C); + break; + case TD_DOUBLE_TAP: + unregister_code(KC_LCTL); + unregister_code(KC_LSFT); + unregister_code(KC_C); + break; + default: + break; + } + yank_tap_state.state = TD_NONE; +} + + +/* Paste: + * + * Sends + on single tap + * Sends + + on double tap (Commonly used in UNIX terminals) + * + */ + +static td_tap_t pste_tap_state = { + .is_press_action = true, + .state = TD_NONE +}; + +void pste_finished(qk_tap_dance_state_t *state, void *user_data) { + pste_tap_state.state = cur_dance(state); + switch (pste_tap_state.state) { + case TD_SINGLE_TAP: + register_code(KC_LCTL); + register_code(KC_V); + break; + case TD_DOUBLE_TAP: + register_code(KC_LCTL); + register_code(KC_LSFT); + register_code(KC_V); + break; + default: + break; + } +} + +void pste_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (pste_tap_state.state) { + case TD_SINGLE_TAP: + unregister_code(KC_LCTL); + unregister_code(KC_V); + break; + case TD_DOUBLE_TAP: + unregister_code(KC_LCTL); + unregister_code(KC_LSFT); + unregister_code(KC_V); + break; + default: + break; + } + pste_tap_state.state = TD_NONE; +} + + +/* Delete word: + * + * Sends delete on single tap or hold + * Sends + "daw" on double tap (Vim: delete the word under the cursor) + * + */ + +static td_tap_t delword_tap_state = { + .is_press_action = true, + .state = TD_NONE +}; + +void delword_finished(qk_tap_dance_state_t *state, void *user_data) { + delword_tap_state.state = cur_dance(state); + switch (delword_tap_state.state) { + case TD_SINGLE_TAP: + register_code(KC_DEL); + break; + case TD_SINGLE_HOLD: + register_code(KC_DEL); + break; + case TD_DOUBLE_TAP: + tap_code(KC_ESC); + SEND_STRING("daw"); + break; + default: + break; + } +} + +void delword_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (delword_tap_state.state) { + case TD_SINGLE_TAP: + unregister_code(KC_DEL); + break; + case TD_SINGLE_HOLD: + unregister_code(KC_DEL); + break; + default: + break; + } + delword_tap_state.state = TD_NONE; +} + + +/* Back word: + * + * Sends bacspace on single tap or hold + * Sends + on double tap (Bash: remove the command/argument before the cursor) + * + */ + +static td_tap_t backword_tap_state = { + .is_press_action = true, + .state = TD_NONE +}; + +void bakword_finished(qk_tap_dance_state_t *state, void *user_data) { + backword_tap_state.state = cur_dance(state); + switch (backword_tap_state.state) { + case TD_SINGLE_TAP: + register_code(KC_BSPC); + break; + case TD_SINGLE_HOLD: + register_code(KC_BSPC); + break; + case TD_DOUBLE_TAP: + register_code(KC_LCTL); + register_code(KC_W); + break; + default: + break; + } +} + +void bakword_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (backword_tap_state.state) { + case TD_SINGLE_TAP: + unregister_code(KC_BSPC); + break; + case TD_SINGLE_HOLD: + unregister_code(KC_BSPC); + break; + case TD_DOUBLE_TAP: + unregister_code(KC_LCTL); + unregister_code(KC_W); + break; + default: + break; + } + backword_tap_state.state = TD_NONE; +} + + +/* Function prefix: + * + * Send tmux prefix on tap + . + * Enable function layer on hold. + * + */ + +static td_tap_t fnpfx_tap_state = { + .is_press_action = true, + .state = TD_NONE +}; + +void fnpfx_finished(qk_tap_dance_state_t *state, void *user_data) { + fnpfx_tap_state.state = cur_dance(state); + switch (fnpfx_tap_state.state) { + case TD_SINGLE_TAP: + register_code(KC_LCTL); + register_code(KC_B); + break; + case TD_SINGLE_HOLD: + layer_on(L_NUMBERS); + break; + default: + break; + } +} + +void fnpfx_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (fnpfx_tap_state.state) { + case TD_SINGLE_TAP: + unregister_code(KC_LCTL); + unregister_code(KC_B); + break; + case TD_SINGLE_HOLD: + layer_off(L_NUMBERS); + break; + default: + break; + } + fnpfx_tap_state.state = TD_NONE; +} + + +/* Function leader: + * + * Send leader key on tap. + * Enable function layer on hold. + * + */ + +static td_tap_t fnldr_tap_state = { + .is_press_action = true, + .state = TD_NONE +}; + +void fnldr_finished(qk_tap_dance_state_t *state, void *user_data) { + fnldr_tap_state.state = cur_dance(state); + switch (fnldr_tap_state.state) { + case TD_SINGLE_TAP: + qk_leader_start(); + break; + case TD_SINGLE_HOLD: + layer_on(L_SYMBOLS); + break; + default: + break; + } +} + +void fnldr_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (fnldr_tap_state.state) { + case TD_SINGLE_HOLD: + layer_off(L_SYMBOLS); + break; + default: + break; + } + fnldr_tap_state.state = TD_NONE; +} + +// Define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions +qk_tap_dance_action_t tap_dance_actions[] = { + [TD_YANK] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, yank_finished, yank_reset), + [TD_PSTE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, pste_finished, pste_reset), + [TD_DELWORD] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, delword_finished, delword_reset), + [TD_BAKWORD] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, bakword_finished, bakword_reset), + [TD_FNPFX] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, fnpfx_finished, fnpfx_reset), + [TD_FNLDR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, fnldr_finished, fnldr_reset) +}; + diff --git a/keyboards/crkbd/keymaps/sajenim/tapdance.h b/keyboards/crkbd/keymaps/sajenim/tapdance.h new file mode 100644 index 0000000..88c630b --- /dev/null +++ b/keyboards/crkbd/keymaps/sajenim/tapdance.h @@ -0,0 +1,70 @@ +/* Copyright 2022 @ sajenim (https://github.com/sajenim) + * + * 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 . + */ + +#pragma once + +// Our tapdance keycodes +enum td_keycodes { + TD_YANK, + TD_PSTE, + TD_BAKWORD, + TD_DELWORD, + TD_FNPFX, + TD_FNLDR +}; + +// Define a type containing as many tapdance states as we need +typedef enum { + TD_NONE, + TD_UNKNOWN, + TD_SINGLE_TAP, + TD_SINGLE_HOLD, + TD_DOUBLE_TAP, + TD_DOUBLE_HOLD, + TD_DOUBLE_SINGLE_TAP, // Send two single taps + TD_TRIPLE_TAP, + TD_TRIPLE_HOLD +} td_state_t; + +typedef struct { + bool is_press_action; + td_state_t state; +} td_tap_t; + +// Declare our tapdance functions: + +// Function to determine the current tapdance state +td_state_t cur_dance(qk_tap_dance_state_t *state); + +// `finished` and `reset` functions for each tapdance keycode +void yank_finished(qk_tap_dance_state_t *state, void *user_data); +void yank_reset(qk_tap_dance_state_t *state, void *user_data); + +void pste_finished(qk_tap_dance_state_t *state, void *user_data); +void pste_reset(qk_tap_dance_state_t *state, void *user_data); + +void delword_finished(qk_tap_dance_state_t *state, void *user_data); +void delword_reset(qk_tap_dance_state_t *state, void *user_data); + +void bakword_finished(qk_tap_dance_state_t *state, void *user_data); +void bakword_reset(qk_tap_dance_state_t *state, void *user_data); + +void fnpfx_finished(qk_tap_dance_state_t *state, void *user_data); +void fnpfx_reset(qk_tap_dance_state_t *state, void *user_data); + +void fnldr_finished(qk_tap_dance_state_t *state, void *user_data); +void fnldr_reset(qk_tap_dance_state_t *state, void *user_data); +