読者です 読者をやめる 読者になる 読者になる

鳰のような形をした僕の迂回路

My detour/diversion like a (little) grebe.

Planckキーボードの話

 

このまえ組み立てたPlanckキーボードに指がだいぶ慣れてきたのでこのタイミングでキーマップをさらす。

f:id:CydonianBanana:20160529230345j:plain

ちなみにPlanckキーボードとは、

The Planck is a DIY compact 40% ortholinear (as opposed to staggered) keyboard kit that optimises the use of your hands in a thumb-oriented layout.

である。OLKBが設計、最近はmassdropで買える。

このPlanckキーボードは、後でレイアウトを晒すけど、EnterキーやBackSPCキーが親指で押せること、emacsで多用するLCtrlキーまでの距離が相対的に近いことなどから、指や手首への負担を大幅に軽減してくれており、今や人生に欠かせない存在となっている。

そのうえ上掲の写真のとおりキューティクルなキーキャップを装備することでたいへん可憐な見た目のキーボードとなるポテンシャルを秘めており、ぼくに至ってはエレノアという固有名詞をつけて毎日愛でているという始末である。そういうわけで皆さんにも是非おススメしたいのでこの記事を書くことにした。

キーマップ作成環境

キーレイアウトを自由に編集するために必要となるファームウェアコンパイルおよび書き換え環境を Planck Firmware Guideに沿って整える。MacOSユーザーならhomebrewでやるのが楽チン。

ファームウェアのソースは デフォルトのソース を適宜いじってやればいい。

たとえば自分のkeymap.cを

/qmk_firmware-master/keyboard/planck/keymaps/hoge/keymap.c

に作った場合は、planckキーボードの背面のボタンを押した状態で

make clean && make KEYMAP=hoge dfu 

とすればファームウェアコンパイル、書き換えができる。

キーレイアウト

ぼくがかんがえた最強のキーレイアウトは以下の通り。

/* MAC
 * ,-----------------------------------------------------------------------------------.
 * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  |  -   |
 * |------+------+------+------+------+-------------+------+------+------+------+------|
 * | Ctrl |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
 * |------+------+------+------+------+------|------+------+------+------+------+------|
 * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  | Up   |
 * |------+------+------+------+------+------+------+------+------+------+------+------|
 * | Esc  | Ctrl | Alt  | GUI  |Raise |Space |Enter |Louwer| GUI  | Left |Right | Down |
 * `-----------------------------------------------------------------------------------'
 */
[_MAC] = {
  {KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_MINS},
  {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_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_UP},
  {KC_ESC,  KC_RCTL, KC_LALT, KC_LGUI, RAISE,   KC_SPC,  KC_ENT,  LOWER,   KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT}
},

/* Lower
 * ,-----------------------------------------------------------------------------------.
 * |   ~  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  |  +   |
 * |------+------+------+------+------+-------------+------+------+------+------+------|
 * |      |      |      |      |      |      |      |      |      |   {  |   }  |  |   |
 * |------+------+------+------+------+------|------+------+------+------+------+------|
 * |      |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |  F7  |  F8  |  F9  |  F10 | Vol+ |
 * |------+------+------+------+------+------+------+------+------+------+------+------|
 * |  Del |      |      |      |LANG2 | Bksp | Bksp |      |      | Mute | Next | Vol- |
 * `-----------------------------------------------------------------------------------'
 */
[_LOWER] = {
  {S(KC_GRV), S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), S(KC_9),    S(KC_0),    S(KC_EQL)},
  {_______,   _______, _______, _______, _______, _______, _______, _______, _______, S(KC_LBRC), S(KC_RBRC), KC_PIPE},
  {_______,   KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,      KC_F10,     KC_VOLU},
  {KC_DEL,    _______, _______, _______, KC_LANG2,KC_BSPC, KC_BSPC, _______, _______, KC_MUTE,    KC_VOLD,    KC_MNXT}
},

/* Raise
 * ,-----------------------------------------------------------------------------------.
 * |   `  |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  |  =   |
 * |------+------+------+------+------+-------------+------+------+------+------+------|
 * |      |      |      |      |      |      |      |      |      |   {  |   }  |  ¥   |
 * |------+------+------+------+------+------|------+------+------+------+------+------|
 * |      |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |  F7  |  F8  |  F9  |  F10 | Vol+ |
 * |------+------+------+------+------+------+------+------+------+------+------+------|
 * |  Del |      |      |      |      | Bksp | Bksp |LANG1 |      | Mute | Next | Vol- |
 * `-----------------------------------------------------------------------------------'
 */
[_RAISE] = {
  {KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_EQL},
  {_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LBRC, KC_RBRC, KC_BSLS},
  {_______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_VOLU},
  {KC_DEL,  _______, _______, _______, _______, KC_BSPC, KC_BSPC, KC_LANG1, _______,KC_MUTE, KC_VOLD, KC_MNXT}
},

ポイントは、レイヤー1のRaiseキーとレイヤー2のLowerキーがそれぞれAppleキーボードのkanaキー(LANG1)とeisuキー(LANG2)に対応していること。これにより、日本語IMEと英数字との切り替えが、Appleワイヤレスキーボードと同じ感覚でできる1

ただ、このkanaキー(LANG1)とeisuキー(LANG2)を有効にするためにちょっとした作業が必要だった(以下)。

かなキーと英数キーを使えるようにするために

以下の経緯で改訂Rev.upされており、特に作業は発生しなくなった。

github.com

以下の議論のおかげで助かった。

Can't use KCLANG1 & KCLANG2 key

qmkfirmwareを読み解く

具体的な作業としては、

/tmk_core/protcol/lufa/descriptor.c

に対して以下の変更を加えることで、kanaキー(LANG1)とeisuキー(LANG2)が有効になる。

HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),

->

HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
HID_RI_USAGE_MAXIMUM(8, 0x68), /* Keyboard Application */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x68),

windowsマシンでの環境

windowsマシンで使う場合、macで言う所のcommandキーをctrlキーにしたいし、あとぼくはwindowsキーをlauncher代わりに使っているので、欲しい。そこでkeyhacを使ってキースワッピングをしている。

職場では普段HHKB Japaneseを使っているが、Planckキーボードを繋いでもErgoDoxを繋いでも、編集なしですぐ使えるように、以下のconfig.pyファイルでやっている。

# -*- mode: python; coding: utf-8-dos -*-

# coding-system: utf-8-dos
# file name:     config.py 
#

from time   import sleep
from keyhac import *

def configure(keymap):

    ########################################################################
    ## keymap-replace
    ########################################################################
    # for HHKB
    keymap.replaceKey( "(242)", "RCtrl" )
    keymap.replaceKey( "LWin",  "RCtrl" )
    # RWinと半/全の入れ替え
    keymap_global = keymap.defineWindowKeymap()
    keymap_global[ "D-(243)" ] = "RWin"
    keymap_global[ "D-(244)" ] = "RWin"
    keymap_global[ "U-(243)" ] = []
    keymap_global[ "U-(244)" ] = []

    # for Planck
    keymap.replaceKey( "RCtrl", "LWin" )# PlanckのRCtrlを、L-GUIにしてしまえば、この設定はいらない
    keymap.replaceKey( "RWin",  "RCtrl" )

    ########################################################################
    ## Basis
    ########################################################################
    # editor of config.py
    keymap.editor = "emacs"

    # True: 日本語キーボード
    # False: 英語キーボード
    is_japanese_keybord = True

    # emacs のキーバインドに"したくない"アプリケーションソフトを指定する(False を返す)
    # keyhac のメニューから「内部ログ」を ON にすると processname や classname を確認することができます
    def is_emacs_target(window):
        if window.getProcessName() in ("cmd.exe",            # cmd
                                       "mintty.exe",         # mintty
                                       "emacs.exe",          # Emacs
                                       "runemacs.exe",       # Emacs
                                       "emacs-w32.exe"):     # Emacs
            return False
        return True
    keymap_emacs = keymap.defineWindowKeymap(check_func=is_emacs_target)

    # mark がセットされると True になる
    keymap_emacs.is_marked = False

    # 検索が開始されると True になる
    keymap_emacs.is_searching = False

    # キーボードマクロの play 中 は True になる
    keymap_emacs.is_playing_kmacro = False

    # universal-argument コマンドが実行されると True になる
    keymap_emacs.is_universal_argument = False

    # digit-argument コマンドが実行されると True になる
    keymap_emacs.is_digit_argument = False

    # コマンドのリピート回数を設定する
    keymap_emacs.repeat_counter = 1

    ########################################################################
    ## IMEの切替え
    ########################################################################

    # toggling
    def toggle_input_method():
        # バルーンヘルプを表示する時間(ミリ秒)
        BALLOON_TIMEOUT_MSEC = 500
        keymap.command_InputKey("A-(25)")()
        if 1:
            if not keymap_emacs.is_playing_kmacro:
                sleep(0.05) # delay

                # IME の状態を取得する
                if keymap.wnd.getImeStatus():
                    message = "[あ]"
                else:
                    message = "[A]"

                # IMEの状態をバルーンヘルプで表示する
                keymap.popBalloon("ime_status", message, BALLOON_TIMEOUT_MSEC)
            

    # Switching
    #  @param flag      切り替えフラグ(True:IME ON / False:IME OFF)
    def switch_ime(flag):
        # バルーンヘルプを表示する時間(ミリ秒)
        BALLOON_TIMEOUT_MSEC = 500
        # if not flag:
        if flag:
            ime_status = 1
            message = u"[あ]"
        else:
            ime_status = 0
            message = u"[A]"
        # IMEのON/OFFをセット
        keymap.wnd.setImeStatus(ime_status)
        # IMEの状態をバルーンヘルプで表示
        keymap.popBalloon("ime_status", message, BALLOON_TIMEOUT_MSEC)
        
    def ime_on():
        switch_ime(True)
        
    def ime_off():
        switch_ime(False)

    ## 「IMEの切替え」のキー設定
    keymap_emacs["(28)"]  = ime_on
    keymap_emacs["(29)"]  = ime_off
    keymap_global["LC-Yen"] = toggle_input_method
#    keymap_global["LC-o"]   = toggle_input_method
(後略)

まとめると、MacでもWinでも文章を書く上で僕が一番気にするのがIMEの切り替えで、windowsの全角半角キーみたいにトグル式だと無駄に脳を使ってしまうので、がんばってAppleキーボードみたいな感じにしましたということです。

Apple Magic Trackpadとの相性f:id:CydonianBanana:20160529230432j:plain

NPKC Wooden Wrist RestsのTKL Wrist Rest: 13.98 x 2.95 in (35.5 x 7.5 cm)とMagic Trackpadとの相性が非常によく、上掲の写真の通りぴったりサイズであり、気持ちがいいのでおススメです。

  1. karabinerを使ってcommandキーワンショットでIME切り替えをするのと利便性は変わらないと思う。 ↩︎