今更やるHelixのキーマップカスタマイズ
Helixというキーボードキットがあるのですが、こちらを購入し作成したのが去年の2月頃。
しかし作成したはいいものの、デフォルトのキーマップに全く慣れることができずにそれから1年半ほど光る飾りと化していました。
流石に2万くらいしたし勿体ないから有効活用したいなと思い自分なりに使いやすいようにカスタマイズしてみました。本記事はその記録です。
キーマップ設定
既に情報が大量にあるので準備作業については省略しますが、やることとしては下記をforkしてkeymap.cを書き換えてビルド&書き込みという流れです。
keymap.cを書き換える前にどういうキーマップにするのか設計する必要があったので最初はKeyboard Layout Editorというツールでレイアウトを検討していました。しかしこのツール、並び替えなどもなかなかしづらく管理がなかなかに苦行だったので使うことを早々に辞めました。
そもそもQMK Configuratorというキーマップのjsonファイルを出力するところまでやってくれるツールがあるようなのでそちらを利用することに。
私が所持しているものはHelixの5行OLED, Underglowなので下記の設定をロードしキーマップを変更していきます。
キーマップは下記点を重視し検討しました。
- MBPのキーボードとの差異を少なくしラップトップ利用時の違和感を減らす
- デフォルトだと方向キーが一列になっていたり(vimライク)、Esc/Optionキーの位置だったりが既存のものとは大きく異なるので慣れたら慣れたで内蔵キーボードが使いにくくなるリスクがある
- 利用しないキーを削減し、想定外の動作を防ぐ
- 利用頻度の低いキーはAdjustレイヤーに追い出す
- フルサイズのキーボードにしかないようなやつは基本使わないので移動
具体的なキーマップは下記の通り
QWERTYレイヤー
MBPの配置に寄せれる範囲で寄せています。列が若干足りないのでスラッシュとかは別レイヤーになってしまってはいますが、ある程度違和感なく使えるようになりました。
RAISEレイヤー
利用頻度の高い記号などを配置。Raise/Lower + Shiftとかは辛いと思ったのでShift無しでも打てるように既にカバーできているキーも配置しています。
LOWERレイヤー
Raiseでほぼほぼカバーできてしまいましたが、演算系の記号はごっちゃになりやすい気がしたのでこちらにまとめています。
戯れに、P(PlayのP)には記憶させたMacroを実行できるkeycodeを割り当てています。(面白そうだったのでDynamic Macro機能有効化しました)
DYN_REC_START1 -> DYN_REC_STOP -> DYN_MACRO_PLAY1 でSTOPするまでに打ったキーを再入力させることができます。
ADJUSTレイヤー
Adjustキーは押しにくいですし、Dynamic Macroのレコードキーとか各種設定変更等の基本使わないタイプのキーを集約させています。
ファームウェアのコンパイル
QMK Configuratorでもファームウェアをコンパイルする機能はあるのですが、エラーが発生してしまいます。こちらは既知の問題らしいですが、まだ対応はされていないようです。
Linking: .build/helix_rev2_oled_under_tsts_custom.elf | | .build/obj_helix_rev2_oled_under_tsts_custom/keyboards/helix/rev2/rev2.o: In function `matrix_init_kb': | /qmk_compiler/qmk_firmware/keyboards/helix/rev2/rev2.c:25: undefined reference to `is_helix_master' | collect2: error: ld returned 1 exit status |
QMK Keymap JSONをExportしローカルでコンパイルしていきます。
% qmk json2c [exportしたjsonファイル] #include QMK_KEYBOARD_H /* THIS FILE WAS GENERATED! * * This file was generated by qmk json2c. You may or may not want to * edit it directly. */ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT(KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_NO, KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT, 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_UP, KC_RSFT, MO(5), KC_LALT, KC_GRV, KC_LGUI, KC_LANG2, MO(3), KC_SPC, KC_SPC, MO(4), KC_LANG1, KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT), ...(キーマップ設定がkeymap.cに記載できる形式で出力される) };
keymap.cを編集しキーマップを設定していきます。(既存のkeymap.cはdefaultあたりから持ってくる) このときMO(レイヤー番号)となっているものはそれぞれ既存のlayer_numberに合わせて変更しておきます。
% vi keymap.c (#if MATRIX_ROWS == 10 // HELIX_ROWS == 5の下に記載) const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT(KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_NUBS, 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_ENT, 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_UP, KC_RSFT, ADJUST, KC_LALT, KC_CAPS, KC_LGUI, KC_HANJ, LOWER, KC_SPC, KC_SPC, RAISE, KC_LANG1, KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT), [_COLEMAK] = LAYOUT(KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), [_DVORAK] = LAYOUT(KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), [_LOWER] = LAYOUT(KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, DM_PLY1, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_PAST, KC_PSLS, KC_PEQL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LPRN, KC_RPRN, KC_CIRC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), [_RAISE] = LAYOUT(KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_QUOT, KC_DQUO, KC_GRV, KC_PIPE, KC_TRNS, KC_DEL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TILD, KC_MINS, KC_EQL, KC_BSLS, KC_SLSH, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LCBR, KC_RCBR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ADJUST, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_MPLY), [_ADJUST] = LAYOUT(KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, RESET, KC_TRNS, KC_TRNS, DM_REC1, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_INS, KC_HOME, KC_PGUP, KC_NLCK, KC_TRNS, DM_RSTP, AU_ON, AU_OFF, AG_NORM, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, KC_PGDN, KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD) };
Dynamic Macroを利用するために下記設定も有効にします。
% vi rules.mk +DYNAMIC_MACRO_ENABLE = yes
後はmakeして作成されるhexをQMK ToolkitでFlashすれば完了です。
% make helix/rev2/oled/under:tsts_custom QMK Firmware 0.9.38 Making helix/rev2/oled/under with keymap tsts_custom avr-gcc (Homebrew AVR GCC 8.4.0) 8.4.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiling: keyboards/helix/local_drivers/serial.c [OK] Compiling: keyboards/helix/rev2/matrix.c [OK] Compiling: keyboards/helix/rev2/split_util.c [OK] Compiling: keyboards/helix/rev2/split_scomm.c [OK] Compiling: keyboards/helix/local_drivers/i2c.c [OK] Compiling: keyboards/helix/local_drivers/ssd1306.c [OK] Compiling: keyboards/helix/helix.c [OK] Compiling: keyboards/helix/rev2/rev2.c [OK] Compiling: keyboards/helix/rev2/keymaps/tsts_custom/keymap.c [OK] Compiling: quantum/quantum.c [OK] Compiling: quantum/keymap_common.c [OK] Compiling: quantum/keycode_config.c [OK] Compiling: quantum/debounce/sym_g.c [OK] Compiling: quantum/color.c [OK] Compiling: quantum/rgblight.c [OK] Compiling: quantum/process_keycode/process_rgb.c [OK] Compiling: drivers/avr/ws2812.c [OK] Compiling: quantum/led_tables.c [OK] Compiling: quantum/process_keycode/process_space_cadet.c [OK] Compiling: quantum/process_keycode/process_magic.c [OK] Compiling: quantum/process_keycode/process_grave_esc.c [OK] Compiling: quantum/process_keycode/process_dynamic_macro.c [OK] Archiving: .build/obj_helix_rev2_oled_under_tsts_custom/local_drivers/serial.o [OK] Compiling: tmk_core/common/host.c [OK] Compiling: tmk_core/common/keyboard.c [OK] Compiling: tmk_core/common/action.c [OK] Compiling: tmk_core/common/action_tapping.c [OK] Compiling: tmk_core/common/action_macro.c [OK] Compiling: tmk_core/common/action_layer.c [OK] Compiling: tmk_core/common/action_util.c [OK] Compiling: tmk_core/common/print.c [OK] Compiling: tmk_core/common/debug.c [OK] Compiling: tmk_core/common/sendchar_null.c [OK] Compiling: tmk_core/common/util.c [OK] Compiling: tmk_core/common/eeconfig.c [OK] Compiling: tmk_core/common/report.c [OK] Compiling: tmk_core/common/avr/suspend.c [OK] Compiling: tmk_core/common/avr/timer.c [OK] Compiling: tmk_core/common/avr/bootloader.c [OK] Assembling: tmk_core/common/avr/xprintf.S [OK] Compiling: tmk_core/common/magic.c [OK] Compiling: tmk_core/protocol/lufa/lufa.c [OK] Compiling: tmk_core/protocol/usb_descriptor.c [OK] Compiling: tmk_core/protocol/lufa/outputselect.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/ConfigDescriptors.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/DeviceStandardReq.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/Events.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/HostStandardReq.c [OK] Compiling: lib/lufa/LUFA/Drivers/USB/Core/USBTask.c [OK] Linking: .build/helix_rev2_oled_under_tsts_custom.elf [OK] Creating load file for flashing: .build/helix_rev2_oled_under_tsts_custom.hex [OK] Copying helix_rev2_oled_under_tsts_custom.hex to qmk_firmware folder [OK] Checking file size of helix_rev2_oled_under_tsts_custom.hex [OK] * The firmware size is fine - 26176/28672 (91%, 2496 bytes free)
感想
- ようやく少ない違和感で使えるようになった
- 方向キーはとりあえずMBPに合わせたけど、ホームポジションからの距離が明らかに遠くて効率が悪いのでvimの位置にもキーを持ってくるか、PCゲームっぽくWASDとかで移動できるようにしてもいいのかなと思った
- Dynamic Macro機能は汎用性高いので色々なシーンで使えそう
とりあえずしばらくお試し期間ということで使っていこうと思います。