ErgoDoxEZの量子キーコードのリーダーがリーダー

今までの派遣先では、ずっとメンバ(作業者)として作業していた。
下層派遣会社なので、リーダになれるわけがない。
しかし、ErgoDoxEZの作業ぐらいリーダー格を持ちたいと思い、[Quantum Keycodes](https://github.com/qmk/qmk_firmware/blob/ce3ccd3f4a5e8ff8ac391887f3357dd8e985a452/docs/quantum_keycodes.md#quantum-keycodes "ギットハブのQMKクォンタムキーコード")を調べはするが、それ以上に、リーダーキーをリーダー扱いして調べた。

とは言え、大トリは最後だと決まっている^^

以下、執筆順

* [RESET](#reset)
* [DEBUG](#debug)
* [KC_GESC](#kc_gesc)
* [KC_LSPO](#kc_lspo)
* [KC_RSPC](#kc_rspc)
* [FUNC(n)](#funcn)
* [M(n)](#mn)　←省略
* [MACROTAP(n)](#macrotapn)
* [KC_LOCK](#kc_lock)　←省略
* [KC_LEAD](#kc_lead)


#RESET
言わずもがな。
推して知るべし。
無意識にキー配置に設定しているキーコードと言っても過言ではないだろう。

このキーコードは、キーボード単体に付いているリセットボタンの代わりになるキーだ。
ErgoDoxEZキーボードのリセットボタンは、まち針がなければ押せないぐらい細い穴の奥にある。
しかし、そんな場所のボタンを押さなくてもこのキーがあれば解決する。

ちなみに、リセットボタンやリセットキーコードは、キーボード本体のファームウェアを更新する上で欠かせないキーコードだ。

##使い方
コンパイル結果の`〜.hex`ファイルをteensy.exeで読み込んでから威力を発揮する。

###teensy.exe起動直後
以下の状態で起動していると思われる。

![Autoボタン押下前(起動直後).png](https://qiita-image-store.s3.amazonaws.com/0/82414/5c8bcc3d-b4b7-50f3-4db2-fd5aaa5eb991.png)

アイコンボタンが4つ並んでいる状態の右端が黒ずんでいる。
左三つのボタンは押せないように見えるが、左端の`Open HEX FIle`ボタンは押下可能になっている。

###teensy.exe操作方法
左端の`Open HEX FIle`ボタンにて、読み込みたい`〜.hex`ファイルを指定する。

![Autoボタン押下後.png](https://qiita-image-store.s3.amazonaws.com/0/82414/68d5b3cd-20b9-8ba0-6c5d-c510da45446b.png)

![Hexファイル読み込み.png](https://qiita-image-store.s3.amazonaws.com/0/82414/fd515258-f043-6dae-74bf-50492076661d.png)

この後、通常であればキーボード本体のリセットボタンをまち針で押すのだが、今回のキーコードを設定していることで、ファームウェアの更新が行われる。

###Hexファイル読み込み
注意点として、読み込んでいるときは、当然のようにキーボードが使えない。

![hexファイル読込.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/5acc9110-8ef8-6239-8e6a-0ed88a550799.jpeg)

ダイアログボックス(?)が閉じれば、読み込みが終わり、キーボードが使えるようになる。

#DEBUG
トグル扱いのデバッグキーコード

押下によって、デバッグコードが動くようになり、再度の押下によって止まる(通常使用に戻る)。
しかし、使ったことがないため、どうなるのか分からない。

コードの埋め方は、AキーやShiftキーなどのように使えば良い。

```ErgoDoxEZ:keymap.c
/* Keymap XXX: keys
 *
 * ,--------------------------------------------------.
 * |        |      |      |      |      |      |      |
 * |--------+------+------+------+------+-------------|
 * |        |      |      |      |      |      |      |
 * |--------+------+------+------+------+------|      |
 * |        |  1   |  2   | DEBUG|  4   |  5   |------|
 * |--------+------+------+------+------+------|      |
 * |        |  !   |  @   |  #   |  $   |  %   |      |
 * `--------+------+------+------+------+-------------'
 *   |  　  |      |      |      |      |
 *   `----------------------------------'
 *                                        ,-------------.
 *                                        |      |      |
 *                                 ,------|------|------|
 *                                 |      |      |      |
 *                                 |      |      |------|
 *                                 |      |      |      |
 *                                 `--------------------'
 */
[XXXkeys] = LAYOUT_ergodox(
       // left hand
		KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,
		KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,	KC_NO,
		KC_NO,	KC_1,	KC_2,	DEBUG,	KC_4,	KC_5,
```


#KC_GESC
押下だけ(タップ)の場合は、Escキーになる。そして、ShiftキーやGUIキーと組みあわせた場合の挙動は異なる。

タップだけの場合：エスケープキー
Gui+KC_GESC：グレイヴ(`)記号
Shift+KC_GESC：波(~)記号(チルダキー)

上記で誤解を生む表現をしているかも知れない。
チルダ記号と波ダッシュ記号など勘違いしていたら申し訳ない。

エイリアス：GRAVE_ESC
エイリアスの方が名前的に分かりやすいが、エイリアスの癖して長い。

※[MacOS](8c236477d288988c6300#macosでのバックティック)では意図しない動きをする。

#KC_LSPO
特殊なキー割り当てをしている意味は分からないが、何かに需要があるのだろう。

タップだけの場合：(記号
押し続ける場合：左Shiftキーになる。

当然のことだが、Shiftキーを押し続けた状態で、`KC_LSPO`キーを押しても何も起こらない。

#KC_RSPC
`KC_LSPO`の対括弧になる。

タップだけの場合：)記号
押し続ける場合：右Shiftキーになる。

括弧なんて9キーや0キーをShiftとの組合せで良さそうに思うのだが、数字行がないコンパクトキーボード用なのだろうか。
通常キーボードの左右に、Shiftキーがあり、それに当てはめておけば、通常利用に便利だという・・・。

不思議なことに、Shiftキーを押し続けた状態で、`KC_RSPC`キーを押した場合、閉じ括弧)記号が入力できる。

#FUNC(n)
これもよく分からない。
独自の関数を呼び出して使うのであれば、下記のマクロ(M(x))キーとどう違うのだろうか。

[公式ページのfn_actions[]](https://github.com/qmk/qmk_firmware/blob/master/docs/keymap.md#custom-functions "ギットハブのqmkによる独自関数")

クローンしたときに、すでに実装されていたようだ。
`fn_actions`関数がそれなのだろう。


```ErgoDoxEZ:クローンディレクトリ\github_repository\qmk_firmware\keyboards\ergodox_ez\keymaps\default\keymap.c
const uint16_t PROGMEM fn_actions[] = {
    [1] = ACTION_LAYER_TAP_TOGGLE(SYMB)                // FN1 - Momentary Layer 1 (Symbols)
};
```

3行目に`[1]`とある。
要は、FUNCキーを設定するとき、この番号を設定すれば、使えるようになる。
なぜ、0から始まらないのか不思議だが・・・。

キー：`FUNC(1)`

このサンプルがなにをするキーかと言えば、`SYMB`レイヤーに移動する挙動になる。
トグルと言うからには、移動先のレイヤーにも同じキーを設定しなければならないようだ。
私はそれを忘れて、元のレイヤーに戻れず、戻すのに苦労した。

何より、気になるのは[ACTION_LAYER_TAP_TOGGLE](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_code.h#L283 "ギットハブのQMKによるアクションコードヘッダ")だろう。
これは、action_code.hに定義されている。

元の宣言は、`ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)`とのこと。
だからなんだって話だが・・・この関数名から挙動を予想するしかないようだ。

公式ページのサンプルでは、`ACTION_FUNCTION`関数を使っている。
これはこれで使い道があるようだ(GRAVEキーかEscキーを使い分けられるようだ)。
引数に0を渡せばだろうけど・・・。

エイリアス：F(n)


このキーを使いこなす人は、世の中にいないと思う。
使いこなしたいと思う人は、キーボードに何を求める人なのだろうか。
宇宙旅行？
四次元ポケット？
反重力物質？
メイド服を着た女性か？

#M(n)
これも説明不要なぐらい有名なマクロキーだろう。

大分前に、[半角／全角キー代替](https://qiita.com/chesscommands/items/4589a9453c59ef26a4bc#tap-the-last-show "ErgoDoxEZの日本語変換(英語QWERTY配列キーボード)※Windowsに限るはず")投稿をした。
そのときに使った。

ざっくり説明すれば、keymap.cに、`action_get_macro`関数部分に追加した処理を実行するときに使う(呼び出す)キーコードになる。

そして、頻繁にキー割り当てをする場合や見やすいキーコードにしたい場合は、名前付けをすれば便利だろう。
以下の通り。

```ErgoDoxEZ:keymap.c
#define HANZEN M(x)	// ←xは、(過去に説明済みの)数字を付ける。
```

既存の`define`行が存在する辺りに記載すれば良い(その後ろの行などに)。


#MACROTAP(n)
何これ？

> Macro-tap n idk FIXME

idkとは、`I don't know`の頭文字とのこと。
まさにそのとおり。
これが何か分からない。

FIXMEとは、コードが間違っており、修正が必要なことを指すようだ。
だから何!?

結論は、上記の`M(x)`と同じ動きをする。
しかし、キーコードの名前的に、タップの場合は、M(x)の動きをして、押し続ける場合は、違う動きになるとか？
それを実装できないため、こんな注釈が付くとか？


#KC_LOCK
[糞みたいなタイトル](https://qiita.com/chesscommands/items/7487b98e5c5f0344b68a#%E3%81%9D%E3%81%AE%E4%BB%96key-lock "ErgoDoxEZでキーロックをホールディングで対応")で分かりにくいが、過去に投稿した。
投稿内容は、よく分からないと言う糞内容だった・・・恥ずかしい。
見返さなければ良かった。

通常の[キーコード](https://github.com/qmk/qmk_firmware/blob/ce3ccd3f4a5e8ff8ac391887f3357dd8e985a452/docs/keycodes_basic.md#lock-keys "ギットハブのQMKによるKeyLock" )は使える。

取りあえず、[キーロック](https://github.com/qmk/qmk_firmware/blob/ce3ccd3f4a5e8ff8ac391887f3357dd8e985a452/docs/feature_key_lock.md "ギットハブのQMKによるKeyLock")出来ることは確かだ。


#KC_LEAD
今回の大トリキーコード

早速サンプル通りに、`KC_LEAD+W+C`を組みあわせたが、何も動かないため、ソースコードを眺めたら・・・。

```ErgoDoxEZ:keymap.c
void matrix_scan_user(void) {

};
```

中身無しorz
サンプルをそのまま右から左に流し込んで使う。

##リーダーキー(Leader Key)
通常のマクロキーと何が違うのか未だに区別は付かないが、リーダキーを押し続けた状態で、きっかけとなるキーを押すことで、事前登録した処理が走るようだ。

以下、サンプルコードそのもの.

```ErgoDoxEZ:keymap.c
LEADER_EXTERNS();

void matrix_scan_user(void) {
  LEADER_DICTIONARY() {
    leading = false;
    leader_end();

    SEQ_ONE_KEY(KC_F) {
      // Anything you can do in a macro.
      SEND_STRING("QMK is awesome.");
    }
    SEQ_TWO_KEYS(KC_D, KC_D) {
      SEND_STRING(SS_LCTRL("a")SS_LCTRL("c"));
    }
    SEQ_THREE_KEYS(KC_D, KC_D, KC_S) {
      SEND_STRING("https://start.duckduckgo.com"SS_TAP(X_ENTER));
    }
    SEQ_TWO_KEYS(KC_A, KC_S) {
      register_code(KC_LGUI);
      register_code(KC_S);
      unregister_code(KC_S);
      unregister_code(KC_LGUI);
    }
  }
}
```

使い方はそのまま。

`KC_LEAD`をどこかのキーに割り当てる。
そして、"QMK is awesome."の文字を唐突にテキストエディタに打ち込みたい瞬間が出てきた。
そんなとき、KC_LEADキーを押し続け、`SEQ_ONE_KEY`の引数に記載されているFキーを押下することで、先の文字列がテキストエディタに打ち込まれる。
まるで、優秀な秘書を得たように、正確無比に用意した文字列を出してくれる様は圧巻だ(自分で出しているだけだけど)。
感動すら覚えるよ。

KC_LEADキーを押し続け、Dキーを2回連打すれば、全選択後にコピーすることが可能になる。

##有効時間(LEADER_TIMEOUT)
サンプル通りに300ミリ秒を設定したが、あまりにも短い。
私のより短い(何が？)。

そのため、もう少し持続時間を延ばす。

```ErgoDoxEZ:keymap.c
#define LEADER_TIMEOUT 5000
```

先ほどは300ミリ秒位内にDキーを2回押さなければならないが、今回の設定変更にて、~~5秒以内にDキーを2回押せば、"全選択後にコピーする"処理が走る~~。
5秒以内に押したつもりだが動かない。
まさかと思って10に設定したが、ダメだった。
このタイムアウトは何？

設定した時間の前後にFキーなどを押すのではなく、設定した時間丁度に押さなければならないとか!?
500ミリ秒にしたら私に合っていたようだ。きちんと動いた。
しかし、3つのキー(D・D・S)は、設定時間でほぼ同時に押せない。
この時間設定を使いこなさなければ、便利な処理を実装したところで、使えずじまいだろう。

忙しいキー操作をするぐらいであれば、落ち着いて通常キーを組みあわせて操作した方が確実に目的に近づきそうに思う。

##ここ以降、あまりリーダーキーに関係ない
今回の投稿は、リーダーキーを主役にして解説するつもりだったが、よく分からないまま終わってしまった。
そして、ここ以降の解説は、リーダキー以外でも使える。

###SEND_STRING
これは、文字列を送信するマクロなのだが、QMKマクロではない。
SEND_STRINGマクロという。そのままの名前。仕組みは、Cプリプロセッサマクロだが、それが何か分からない。

[Github-qmk-SEND_STRING](https://github.com/qmk/qmk_firmware/blob/ee700b2e831067bdb7584425569b61bc6329247b/docs/feature_macros.md#the-new-way-send_string--process_record_user "ギットハブのQMKによる文字列送信説明")

今まで使ってきた関数(process_record_user)でも使える。


####SS_LCTRL
これは、左側のコントロールキーなのだが、引数に文字列を渡すことで、コントロールキーを押し続けた状態で、文字列を押すことになる。

たとえば、`SS_LCTRL("a")`の場合、テキストエディタがアクティブになっている場合、文字列が全選択される。
しかし、これだけではコンパイルエラーになる。

SEND_STRING(SS_LCTRL("a"))

としなければならない。
これ以降全てそうだ。
しかも、これは上記の関数内でしか使えない。

~~`KC_A, SS_LCTRL("a"), KC_B`~~
~~`KC_A, SEND_STRING(SS_LCTRL("a")), KC_B`~~

のように、通常キーコードとして設定できない。

####SS_LGUI
これは、上記と同じで、左側のGUIキーを押し続けながら別のキーを押すことが出来るキーだ。

SEND_STRING(SS_LGUI("s"))

これをすることで、WindowsOSであれば、検索(コルタナ?)画面が出てくる。

####SS_LALT
これは、上記と同じで、左側のAltキーを押し続けながら別のキーを押すことが出来るキーだ。

SEND_STRING(SS_LALT("f"))

これをすることで、WindowsOSのテキストエディタであれば、メニューバーの"ファイル(F)"が押下されたことになる。

なぜか、これには右側(`SS_RALT`)が用意されている。

####SS_LSFT
これは、上記と同じで、左側のShiftキーを押し続けながら別のキーを押すことが出来るキーだ。

SEND_STRING(SS_LSFT("f"))

これをすることで、WindowsOSのテキストエディタであれば、大文字のFキーが押されたことになる。

####日本語／英語切り替え方法
今まで、MACRO関数を使っていたが、古いやり方だったようだ。
これからは、`SEND_STRING`関数を使うのが主流になるだろう。


```ErgoDoxEZ:keymap.c
	case 2:
		if (record->event.pressed) { // 日本語入力のオン／オフ（英語配列）
//			return MACRO( D(LALT), T(GRAVE), U(LALT), END);　←古い。
			SEND_STRING( SS_RALT("`") ); // ←これからは、こっちを使う。
		}
		break;
```

####register_code・unregister_code
これもキーを押し続けることができる。
先頭にunと付いているのは、キーを離す。これをしなければ、永遠に押し続けることになる。



####SS_TAP
1回の押下(通常キー操作)をするキーコードだ。

`SEND_STRING(SS_TAP(X_HOME))`

とすることで、HOMEキーを押下したことになり、テキストエディタであれば、行頭に移動する。

####SS_DOWN
これは、`SS_TAP`と違い、キーを押し続ける。


####SS_UP
`SS_DOWN`にて押し続けているため、`SS_UP`でキーを離す。



####接頭辞の"X_"（例えばX_HOME）
いままでキーコードを設定するときは、KC_Aだったが、`SEND_STRING`で使用する場合は、使えない。
その代わり,Aキーを使う場合は、文字列を使っていた(ダブルクォーテーションで囲む)。
そして、それでは今までと勝手が違うため、見にくいと思うならば、"KC_"の接頭辞を"X_"に置き換えれば良い。

キーコード：SS_LSFT("a")
キーコード：SS_LSFT(X_A)

お察しの通り、非常にめんどくさい作業に変わる。
このままでは、小文字のaが打たれてしまい、大文字のAは打てない。

キーコード：SS_LSFT("A")
キーコード：SS_DOWN(X_LSHIFT) SS_TAP(X_A) SS_UP(X_LSHIFT)
全体：SEND_STRING(SS_DOWN(X_LSHIFT) SS_TAP(X_B) SS_UP(X_LSHIFT));

必要か!?
文字以外は使う価値があるだろう。

X_ENTER
X_ESCAPE
X_BSPACE
X_TAB
X_SPACE
X_MINUS
X_EQUAL
X_LBRACKET
X_RBRACKET
X_BSLASH
X_CAPSLOCK

などなど。
他にもスクリーンショットやスクロールロックなど、基本的には接頭辞がX_になったキーコードたちが[send_string_keycodes.h](https://github.com/qmk/qmk_firmware/blob/6590f3c81155f5d5cfb59c5b8a28610d6f3207d0/quantum/send_string_keycodes.h "ギットハブのQMKによるキーコード一覧")に存在する。

ちなみに、`X_HOME`は、KC_HOMEのこと。





#感想
使いこなせば、コンパクトキーボードのみで十分になるだろう。
逆に、割り当てたいキーが増えて、フルキーボードのほうが良くなるかも知れない。
一応は、HHKBで満足しているが・・・未だに、本格的にErgoDoxEZに乗り換えられないでいる。

そもそもErgoDoxEZというか、QMKがややこしくて、使いこなせる気がしない。
未だに、全てに目を通していない。
理解できるとは思っていないが、目を通すことすら出来ていない。
う〜ん・・・既製品万歳。

##ちなみに
`Quantum`とは、[量子](https://github.com/qmk/qmk_firmware/blob/fe8c2209ca9172352cb46cc6cf7800e4998849ea/docs/keycodes.md#quantum-keycodes)のことらしいが、何がどう量子なのだろうか・・・。
映画『アントマン&ワスプ』にも量子うんぬん出てきたが、結局量子とは何ぞや!?

以上だ。