QMK firmwareでctrl+hがbackspaceになるようにした

# 続編
https://qiita.com/toxaO/items/3f6f2a04fbc8c5cd46b9

# 前置き
メインPCはmacで、karabinerを使用してBSに変換していて特に不便はしていませんでしたが、ctrl+h でBackspaceを送信できたらいいなと思っていました。
他所のPCを自キで触る機会はないものの、ついついオタク心で実装できたら嬉しいなと考え色々といじってみました
既存の方法も見つけ実装してみましたが、キーリピートができない（単発しかBSが打てない）ものでした。
また、key overrideを使用してみましたが、qmkの古いバージョンを使用したせいかctrl+hを押すとctrl+BackSpaceになってしまい、想定した動作をしませんでした。
カスタムキーコードをリピートできるようにするコードを公開している方がいらっしゃったので、それを参考に自分なりに改良してみました。

# コード（しつこい解説付き）
```keymap.c
// 使用する変数
// ctrl_heldはctrlが押されていることを判定する変数
static bool ctrl_held = false;
// ctrl_h_heldはctrlとhが両方押されていることを判定する変数
static bool ctrl_h_held = false;
// ctrl_h_held_delayはctrlとhが両方押されてからの時間を入れる変数
static int ctrl_held_h_delay = 0;

// リピートするまでの時間(ms)の定義
#define REPEAT_TH 300

// 作成したキーボードの種類によってはkeymap.cに既にprocess_record_user関数が記載されています。
/*
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if (record->event.pressed) {
        switch(keycode) {
            //何かしらのコード
        }
    } else {
        switch(keycode){
            // 何かしらのコード
        }
    }
}
*/
// 上記のようなコードになっている場合は、何となく中に埋め込んだりせずにコードを追いながら修正してください。
// 下記をベースに既存のコードを書き直すのも良いと思います。
// 二重定義はエラーが発生しますので気をつけてください。

// キーを押した時と離した時に呼び出される関数です。
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch(keycode){
        // KC_RCTLを使用している場合はそれも下にcaseとして記載してください
        case KC_LCTL:

        // MOD_TAPを使用してctrlを設定している時は、それらのキーコードをここに列挙します
        // ex1) MT(MOD_LCTL, KC_CLN)
        case MT(MOD_LCTL, KC_CLN):

        // ex2) #define KANA_C MT(MOD_LCTL, KC_LNG1)を使用している場合
        case KANA_C:

            if (record->event.pressed){
                // ctrlが押されるとここのコードが走ります
                ctrl_held = true;
            }else{
                // ctrlが離されるとここのコードが走ります
                ctrl_held = false;
                ctrl_h_held = false;
            }
            // ここでtrueを返すと、上記のコードを処理した後に通常のキー入力処理が入ります
            return true;

        case KC_H:
            if (record->event.pressed && ctrl_held){
                // hが押されたことに加え、ctrlが押されている（ctrl_heldがtrue）の時に
                //ここのコードが走ります

                ctrl_h_held = true;
                // falseを返すと通常のキー入力処理がスキップされます
                // 今回であれば、hキーの入力がなくなります
                return false;
            }else{
                // hが離された時にここのコードが走ります

                ctrl_h_held = false;
                // ctrl+hが入力された時間をリセット
                ctrl_h_held_delay = 0;
                // 通常のキー処理(unregister_code(KC_H)?)が走ります
                // falseでもいいかもしれないが試していません
                return true;
            }
    }
    // 条件に当てはまらないものに関しては通常のキー処理
    return true;
}

// キーマトリクスを読み取る段階で呼び出される関数です
void matrix_scan_user(void) {

    if (ctrl_h_held) {
        // ctrlとhが両方押されている時にここが処理されます
        if (ctrl_h_held_delay == 0) {
            //ctrlとhが両方押された最初だけここが処理されます
            unregister_code(KC_LCTL); // ctrl+hの入力にならないようにctrlを一旦外します
            register_code(KC_BSPC); // BSを入力します
            unregister_code(KC_BSPC); // BSを離します
            register_code(KC_LCTL); // 再度ctrlを登録します
            // ここで登録したctrlはctrlを離した時にキーの通常処理で解除しています
        }
        if (ctrl_h_held_delay > REPEAT_TH) {
            // リピートまでの時間を超えたら処理されます
            unregister_code(KC_LCTL); // 上記と同様にctrlを外します
            SEND_STRING(SS_TAP(X_BSPC)SS_DELAY(20)); // BSを入力し、少し時間を置きます
            // delayを入れないとctrlかhを離したときに大量に入力されていた分が処理されるので、
            // どちらかのキーを離したタイミングでBSが止まってくれなくなります。
            register_code(KC_LCTL); // 上記と同様に再度ctrlを登録します
        }
        ctrl_h_held_delay++; // カウンターを増やします
    }

};
```

# 追記
QMKのDocを読んでいたら似たようなサンプルがありました。
こちらを参考にした実装の方がいいような気がします。

https://docs.qmk.fm/#/feature_advanced_keycodes?id=shift-backspace-for-delete

# 参考
[QMKでマクロをリピートできるようにしてみた](https://gist.github.com/ypsilon-takai/c4a249087ea19eabd1deb3f9f273de52)
[自作キーボード / QMK / etc / Ctrl + h の絶対的 Backspace](http://yakinikunotare.boo.jp/orebase2/keyboard/diy_keyboard/qmk/etc/ctrl_h_absolute_backspace)
※ctrl+hに関してもっと直接的に参考にした記事があったはずなのですが、検索し直しても見つけられませんでした......
[自作キーボード　QMKでctrl-HをBackSpaceにする](https://qiita.com/TKfumi/items/04b897ea51a295657e19)