aboutsummaryrefslogtreecommitdiff
path: root/qmk/keyboards/sofle_choc/keymaps/custom/keycodes.c
blob: 069f5e28a439427576cb1ec562632ace26544cce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include QMK_KEYBOARD_H
#include "keymap_bepo.h"
#include "keycodes.h"

/*
 * Rules and modifier to apply over the keycodes. This includes the keys
 * redefinitions and the keys to include in the caps_word mecanism.
 *
 * All thoses update are working over the custom keys declared in `keycodes.h` 
 */

/*
 * This function need to be declared after the key definition, including the
 * tapdance keys because I need to reference the keycode here if I want to
 * include them in the caps_word mecanism.
 */
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_1 ... KC_0:
        case KC_MINS:
        case KEY_C: // Add also the tapdance keys here.
        case KEY_W:
        case KEY_E:
        case BP_Z:  // Additionals keys from the bepo layout.
        case BP_M:
        case BP_G:
        case BP_H:
        case BP_N:
        case BP_F:
            add_weak_mods(MOD_BIT(KC_LSFT));  // Apply shift to next key.
            return true;

        // Keycodes that continue Caps Word, without shifting.
        case KC_BSPC:
        case KC_DEL:
            return true;
        case KC_SPACE:
            // The space key is used in order to generate the _ symbol,
            // I check which modifier is applied, it’s ok when it’s ALT
            return get_mods() & MOD_MASK_ALT;

        default:
            return false;  // Deactivate Caps Word.
    }
}

//
// Override the symbol ° and replace it by `
// The symbol is still available in the symbol layer with the key just below.
//
const key_override_t perc_key_override = 
    ko_make_basic(MOD_MASK_SHIFT, KEY_PRC, LSFT(BP_PERC));

// 
// I don’t care of the mapping CTRL+Ç and using the mod_tap does not work well
// when I type too fast because of tap-dance, so I remap the pattern here.
//
const key_override_t c_key_override = 
    ko_make_basic(MOD_MASK_CTRL, KEY_C, LCTL(BP_C));

// Same here, I want to be able to type '' without triggering the tapdance.
// And there is no such key combo for Alt+È.
const key_override_t quote_key_override =
    ko_make_basic(MOD_MASK_ALT, KEY_EE, RALT(BP_COMM));

// Same here, I override the key W with CTRL because the tapdance activate the 
// caps_word which does not make sense here.
const key_override_t w_key_override = 
    ko_make_basic(MOD_MASK_CTRL, KEY_W, LCTL(BP_W));

const key_override_t e_key_override = 
    ko_make_basic(MOD_MASK_CTRL, KEY_E, RCTL(BP_E));


// This globally defines all key overrides to be used
const key_override_t **key_overrides = (const key_override_t *[]){
    &perc_key_override,
    &c_key_override,
    &w_key_override,
    &e_key_override,
    &quote_key_override,
    NULL
};

uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case KEY_E:
            return 230;
        case LT_SFT:
            return 250;
        case KEY_EE:
            return 350;
        default:
            return TAPPING_TERM;
    }
}

static uint32_t key_timer;           // timer for last keyboard activity, use
                                     // 32bit value and function to make longer
                                     // idle time possible
static uint16_t latest_key;

bool process_record_user(uint16_t keycode, keyrecord_t *record) {


  if (!record->event.pressed) {
      // store time of last key release. This is used as a counter in order to
      // know if we are inside a typing sequence or not.
      key_timer = timer_read32();
      latest_key = keycode;
  }

  switch (keycode) {
    case AL_ENT:
      if (layer_state_is(LAYER_SYMBOLS) && !record->event.pressed) {
          // Remove the layer the key is released.
          layer_clear();
      }
      return true; // Let QMK send the enter press/release events
    // If a key where released just before, consider we are typing some text
    // and not starting a new sequence 
    case KEY_E:
      if (record->event.pressed && timer_elapsed32(key_timer) < TAPPING_TERM) {
          register_code(BP_E);
          return false;
      }
      return true;
    case KEY_T:
      if (record->event.pressed && timer_elapsed32(key_timer) < TAPPING_TERM) {
          register_code(BP_T);
          return false;
      }
      return true;
    // Here, the key KC_BSPC become È when used inside a sequence, but we still
    // allow the repetition of KC_BSPC.
    case KC_BSPC:
      if (record->event.pressed \
              && timer_elapsed32(key_timer) < TAPPING_TERM \
              && latest_key != keycode)
      {
          // I completely rewrite the key here, that’s why I’m using tap_code16
          // instead of register_code.
          tap_code16(BP_EGRV);
          return false;
      }
      return true;
    default:
      return true; // Process all other keycodes normally
  }
}