はじめてのQMKキーマップ編集

**この記事は古いものです。2020/07/30現在のQMK firmwareではOSがWindows環境の場合、MSYS2を利用したファームウェアのmake環境構築方法がQMK公式ドキュメントに記載されており、SMKj有志が随時和訳しているためそちらを参照してください。**

[QMK 環境の構築](https://github.com/shelaf/qmk_firmware/blob/f23dc6c86fea99898c97a9cad393ff342b28c86c/docs/ja/newbs_getting_started.md)
[Self-Made Keyboard in Japan discordサーバー（略してSMKj）](https://discord.com/invite/NM7XtDW)

**ドキュメントの日本語訳も随時有志によって行われてしかも充実しています。QMKは日々更新されており、ブログなどの記事では更新が追い付かないため古い可能性が高くなっています。**

**キーマップ編集の項目は今のところ「まだ」記事としては読めると思いますのでそのままとしています。**

## はじめに

　自作キーボードの醍醐味の一つである自分のためのキーマップ作り。ただそのキーマップはC言語のベタなソースコード形式で書かれているので、プログラミングの経験がないと編集に躊躇してしまうのは言うまでもありません。この記事ではqmkのmake環境を整えて自作キーボードにキーマップの書き込みが出来た人を対象に、ある程度好みのキーマップに仕上げるための編集が出来るようキーマップの編集とレイヤーの概念の理解までを書いていきます。  

　なおQMK環境の構築、エディタの使い方、makeのやり方などはカットしていますのでご了承ください。  
　[QMK configurator](https://config.qmk.fm/#/)というキーマップを作成出来る便利なツールも実用可能な域に達しているのでそちらを検索して使ってみるのもいいかと思います。（ただしこのQMK configulatorはqmk本家githubに登録されているキーボードでないと動作しないので、お使いのキーボードによっては使えないものがあります）  

## まずは自分の使っているキーマップを観てみよう

　あなたの自作キーボードのキーマップは何を使っていますか？ビルドガイドに書いてあるdefaultですか？自分が使っているキーボードにどんなキーマップが入っているか確認しましょう。  
　ファームを書き込むときにこんなコマンドを打ち込んでいると思います。  

``` bash
make helix:default:avrdude
make crkbd:default:avrdude
make lily58:default:avrdude
make zinc:default:avrdude
make treadstone48:default:avrdude
等々…
```

このコマンドは以下のようなフォーマットになっています。  
```make [①キーボードフォルダ名]:[②キーマップフォルダ名]:[③書き込み先のブートローダに合う書き込みアプリ名]```
　あなたがダウンロードしたりクローンしたqmk_firmwareにはkeyboardsフォルダがあり、そこには数多の自作キーボードの名前のフォルダが並んでいます。その中に①で指定しているキーボード名のフォルダがあります。  
　①のフォルダの中のどこかのフォルダにkeymapというフォルダがあるはずですので、そこを見てみましょう。その中にはdefaultフォルダが入っているのですが、これが②のキーマップフォルダ名になっています。
　defaultはキーボード製作者が標準で組み込む必要のある最低限のキーマップです。ほかにフォルダがあるキーボードもありますが、それらはキーボード製作者やユーザーが作成したキーマップで、自分のためだったり、ほかのユーザーでも使いやすいだろうということで公開・配布されているキーマップになります。  

　③は今回のキーマップの話から逸れるのであまり書きませんが、自作キーボードにpro microを使用しているならavrdudeだし、atmega32u4のチップ直付けならdfuだしと、キーボードのハードウェアによって変わります。QMK toolboxを使っている人はそちらで書き込むのでここでは指定しないのが普通です。  

　さて、自分が使っているキーマップフォルダの中を見てみましょう。必ずkeymap.cがあります。この中にキーマップが書かれています。基本的にこれを編集すれば自分の好きなキーマップを作成できます。  

## キーマップを見てみよう

　中を開いたらまず下の文字列を検索してください。  

```c
keymaps[][MATRIX_ROWS][MATRIX_COLS]
```

この直後の波カッコ```{}```で括られた中身がキーマップです。```KC_なんとか```が羅列されていますね。キーマップ作者にも寄りますが、キーマップをわかりやすくコメント（```//の1行```、```/*から*/```の中身はプログラムではない行）で書いてくれているものもあります（そんなのがないのもある）。例として[helixのdefaultキーマップ](https://github.com/qmk/qmk_firmware/blob/master/keyboards/helix/rev2/keymaps/default/keymap.c)の最初を引用してみます。  

```c
  /* Qwerty
   * ,-----------------------------------------.             ,-----------------------------------------.
   * |   `  |   1  |   2  |   3  |   4  |   5  |             |   6  |   7  |   8  |   9  |   0  | Del  |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * | Tab  |   Q  |   W  |   E  |   R  |   T  |             |   Y  |   U  |   I  |   O  |   P  | Bksp |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * | Ctrl |   A  |   S  |   D  |   F  |   G  |             |   H  |   J  |   K  |   L  |   ;  |  '   |
   * |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
   * | Shift|   Z  |   X  |   C  |   V  |   B  |   [  |   ]  |   N  |   M  |   ,  |   .  |   /  |Enter |
   * |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
   * |Adjust| Esc  | Alt  | GUI  | EISU |Lower |Space |Space |Raise | KANA | Left | Down |  Up  |Right |
   * `-------------------------------------------------------------------------------------------------'
   */
  [_QWERTY] = LAYOUT( \
      KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,                      KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_DEL, \
      KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,                      KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC, \
      KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,                      KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT, \
      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_LBRC, KC_RBRC, KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT , \
      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, EISU,    LOWER,   KC_SPC,  KC_SPC,  RAISE,   KANA,    KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT \
      ),
```

　上半分のエリアがコメント行で、下半分の```LAYOUT( ～ )```の中がプログラムコードです。数字の1キーはKC_1、AキーはKC_A、CtrlキーはKC_LCTL（LeftCtrl）という感じに読み取ることが出来ます。  
　このように、キーマップの中身は基本的に```KC_なんとか```で指定するのが決まりです。  
　この```KC_なんとか```は[qmk_firmware\tmk_core\common\keycode.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/keycode.h)などで決められています。([qmk_firmware\docs\keycodes_basic.md](https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes_basic.md)に説明がありますのでそちらを見た方がイイかもです)  

　キーボードによってはKC_を省略して記述出来るようにプログラムされたキーマップも存在します。[crkbdのデフォルトキーマップ](https://github.com/qmk/qmk_firmware/blob/master/keyboards/crkbd/keymaps/default/keymap.c)がそれです。  

```c
  [_QWERTY] = LAYOUT_kc( \
  //,-----------------------------------------.                ,-----------------------------------------.
        ESC,     Q,     W,     E,     R,     T,                      Y,     U,     I,     O,     P,  BSPC,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
      CTLTB,     A,     S,     D,     F,     G,                      H,     J,     K,     L,  SCLN,  QUOT,\
  //|------+------+------+------+------+------|                |------+------+------+------+------+------|
       LSFT,     Z,     X,     C,     V,     B,                      N,     M,  COMM,   DOT,  SLSH,  RSFT,\
  //|------+------+------+------+------+------+------|  |------+------+------+------+------+------+------|
                                  GUIEI, LOWER,   SPC,      ENT, RAISE, ALTKN \
                              //`--------------------'  `--------------------'
  ),
```

　```KC_```の文字を省略しているため、helixのようにコメント行が無くてもある程度理解・判別しやすいようになっています  

## キーマップを書き換えてみよう

　眺めてなんとなく理解したら書き換えてみましょう。手始めはヤバくない程度に、例えばKC_1をKC_0と書き換えていつも通りにmakeしてキーボードに書き込みます。うまく行けば書き込んだキーボードの、それまで1だったところが0に変わっているはずです。うまく行かなければmakeの対象になっているキーボードとキーマップと、編集しているソースコードに食い違いがあると思うので、手順を見直して解決しましょう。  
　ここでのルールとして,（カンマ）は消してはいけません。逆に空白は分かりやすく見せるために入れているだけで、実際にはプログラムに影響するわけではないので消しても大丈夫です。  
　あと、コメント行も同様に消しても問題ありませんが、```/*```の場合は```*/```と対になっているので注意してください。  

## JISキーボード系の記号ってどれ？

　日本ではUSキーボードとJISキーボードを観る機会が多いと思いますが、実はそれ以外に各国用向けに何種類もあったりします。細かいことは省略しますがキーコードは同じでも出てくる記号が違ったりします（USキーボードはShift+2で@と出るけどJISキーボードだと"と出るなど）  
　その影響で上記のkeycode.hに書いてある記号キーのキーコードと、実際に打鍵したときに出てくる記号とに違いが出てきます。  
　そのため、JISキーボードユーザーがキーマップを作りやすいように[```JP_なんとか```という定義が別途用意されています](https://github.com/qmk/qmk_firmware/blob/master/quantum/keymap_extras/keymap_jp.h)ので、これを使えばキーマップに入力する記号の名前と書き込んで打鍵したときの記号が一致します。  
　使用するには編集しているkeymap.cの上部にあるQMK_KEYBOARD_Hと書かれた行の下に```#include "keymap_jp.h"```を追加します。

```c
#include QMK_KEYBOARD_H
#include "keymap_jp.h"
```

追加したら```JP_なんとか```が使えるようになります。  
既に入っているよ、って場合は何もしなくても使えます。

## レイヤーという概念

　キーボードでShift押しながらaを押すとAになったり、1が!になったりしますね。  
　ノートパソコンなんかだとfnキーを押しながら特定のキーを押すと音量の上げ下げが出来たりテンキーが使えるようになっていたりが出来るようになっている機種もあります。  
　この「特定のキーを押し続けながら別のキーを押したときに、普段とは別のキーになる」というレイヤー機能をQMKでも利用出来ます。  
　たとえば自作キーボードはテンキー、ファンクションキー、PrintScrnやPagedownなどのキー、一部の記号キー、一部のモデファイアキーなどをどんどん省略しても、レイヤー機能を使って割り当てればちゃんと使えます。  

　QMKのレイヤーは最大で32個持つことが出来るのですが、大抵Lower、Raiseという2レイヤーで事足ります。有名どころのキーキャップにもLowerとRaiseという文字が書かれているのでこの2レイヤーの名称で付けられているものがほとんどです。あとはAdjustという文字を打ち込む以外のキーボード自体の設定を行うようなレイヤーが大抵ついているので、この3つくらいはあるんだなと覚えておくとイイでしょう。  
　ということで[先ほどみていたhelixのLowerレイヤー](https://github.com/qmk/qmk_firmware/blob/master/keyboards/helix/rev2/keymaps/default/keymap.c)を見てみましょう。  

```c
  /* Lower
   * ,-----------------------------------------.             ,-----------------------------------------.
   * |   ~  |   !  |   @  |   #  |   $  |   %  |             |   ^  |   &  |   *  |   (  |   )  |      |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * |   ~  |   !  |   @  |   #  |   $  |   %  |             |   ^  |   &  |   *  |   (  |   )  |      |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * |      |  F1  |  F2  |  F3  |  F4  |  F5  |             |  F6  |   _  |   +  |   {  |   }  |  |   |
   * |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
   * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  (   |   )  |  F12 |      |      | Home | End  |      |
   * |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
   * |      |      |      |      |      |      |      |      |      |      | Next | Vol- | Vol+ | Play |
   * `-------------------------------------------------------------------------------------------------'
   */
  [_LOWER] = LAYOUT( \
      KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,                   KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______, \
      KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,                   KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______, \
      _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,                     KC_F6,   KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
      _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_LPRN, KC_RPRN, KC_F12,  _______, _______, KC_HOME, KC_END,  _______, \
      _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
      ),
```

　```[_LOWER] = LAYOUT(```というのがLowerレイヤーのプログラムです。Raiseレイヤーだと```[_RAISE] = LAYOUT(```とかになっています(キーボードによって微妙に差異があるかもしれません）。  
ここで```_______```というのが出てきていますがこれは「下位の階層のキーと同じ」という意味合いを持ちます。上位か下位の序列は```_LOWER```とか```_QWERTY```の名称についた番号によって決まります。  
番号ってどこでつけられているの？というと、keymap.cの上の方にあります。

```c
// helixのdefaultキーマップの場合
// enumという命令により、暗黙のうちに_COLEMAKは1、_DVORAKは2、_LOWERは3…と数字が割り当てられる
enum layer_number {
    _QWERTY = 0,
    _COLEMAK,
    _DVORAK,
    _LOWER,
    _RAISE,
    _ADJUST
};

// crkbdのdefaultキーマップの場合
#define _QWERTY 0
#define _LOWER 1
#define _RAISE 2
#define _ADJUST 3
```

といった感じで設定されていて0が最下層となります。```_______```の役割は主にCTRLやALTなどのモデファイアキー、レイヤー移動キーを他のレイヤーにまたがっても使用できるようにするためです。例の_LOWERレイヤーにはモデファイアキーの割り当てがありませんが、Shift+F12と打鍵したい場合は、Lower+Shift(QwertyレイヤーのShift位置)+F12と打鍵することが出来るようになっています。  

またここでは出てきませんでしたが、```XXXXXXX```というのも存在します。これを設定したキーはそのレイヤーにいる限り何もしないという動作をします。  

## まとめ

　ここまででキーマップの編集のいろはのい、くらいは習得出来たかと思います。  
　QMKにはもっと魅力的で複雑な機能がありますしC言語というか書き方をちょっとづつ理解していく必要が出てきますが、これを最初の一歩としてあとは各個撃破して自分の手になじみまくるキーマップを作成してみてくださいね。  

## リンク

chromeなどで英訳してもらって読んでみましょう。
[Keymap Overview](https://github.com/qmk/qmk_firmware/blob/master/docs/keymap.md)
[keycodes Overview](https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md)

QMKのドキュメントです。mdファイルのリンクを開くとテキストが読めます。
[QMK docs](https://github.com/qmk/qmk_firmware/tree/master/docs)