たねやつの木

Photographs, Keyboards and Programming

QMKで、1キーでIMEの入力モードを切り替える (ひらがな <-> 半角英数)

IMG_20180903_011916

こんばんは、たねやつです。 前回のQMKビルド環境構築に続いて第二弾です。マクロ作成について書きます('ω')

US配列のキーボードでは、IMEの入力モードを切り替えるためには、Alt + Graveだったりを割り当てて切り替えるのが よくあるパターンだと思いますが、2キー押すのが結構面倒なので、1キーに割り当ててみました。

KC_LANG5にいわゆる半角/全角キーが割り当てられているようなのですが、うまく動作しないためマクロで2キー同時押しを 再現させてみます。

私の場合は、右Alt(スペースバーの右横)に割り当てたのでずいぶんと切り替え時の手の動きが減少しました。 まだ完全に離れていないのでちょっと戸惑いますがなかなかいい感じです('ω')

前の記事

QMKのビルド環境構築についてはこちら

設定

マクロの設定

以下の記事を参考にしながら進めていきます。

https://beta.docs.qmk.fm/features/feature_macros

前の記事で作成した自分用のキーマップのソースコードを開き、追記・修正していきます。

手順としてはこんな感じになります。

  1. マクロ用のキーコード名の宣言
  2. マクロの実装
  3. キーマップに宣言したキーコードを指定


とりあえず追加して完成形となったのソースがこちらです。

#include QMK_KEYBOARD_H
#define _BL 0 // Default layer
#define _FL 1 // Function layer
#define _______ KC_TRNS

// 1. マクロ用のキーコード名の宣言
enum custom_keycodes {
    M_HNZN_TGL = SAFE_RANGE;    // IMEトグル用
};

// 2. マクロの実装
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if (record->event.pressed) {
        switch(keycode) {
            case M_HNZN_TGL:
                    SEND_STRING(SS_LALT("`"));
                return false;
        }
    }
    return true;
};

// 3. キーマップに宣言したキーコードを指定
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BL] = LAYOUT_ansi(
  ...
  KC_LCTL, KC_LGUI, KC_LALT,                KC_SPC,                       M_HNZN_TGL, MO(_FL), KC_RCTRL, KC_LEFT,KC_DOWN, KC_RGHT),

[_FL] = LAYOUT_ansi(...)
};

一つずつ見ていきましょう。



// 1. マクロ用のキーコード名の宣言
enum custom_keycodes {
    M_HNZN_TGL = SAFE_RANGE;    // IMEトグル用
};

前回の記事でC言語かなと言っていましたが、C#でしたね( ;∀;)失礼いたしました。

ここでキーコード名を宣言します。SAFE_RANGEとすることでほかのキーのキーコードと衝突しない値で宣言できます。

キーコード名は一発でわかる、かつ短い名前にしたほうが良いです。 あまり長いとキーマップに組み込んだ時にソースコード上のレイアウトが崩れて可読性が落ちます。(性能に変わりはありませんが) かといって短くしすぎるとあとで見たときにぱっと何のキーなのか、処理なのかがわからなくなります。

私の場合はとりあえずマクロ用のキーにはM_の接頭辞を付けるようにしました。HNZNは半角全角で、TGLはトグルです。 これでもちょっと長いですね。変数などのネーミングはセンスが問われます。。。orz



bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if (record->event.pressed) {
        switch(keycode) {
            case M_HNZN_TGL:
                    SEND_STRING(SS_LALT("`"));
                return false;
        }
    }
    return true;
};

メインとなるマクロ内容です。ひな形は公式からのコピペです。if部分はキーが押されたか否かの判定でswitchでなんのキーが押されたかの判定となっています。

今見て思ったんですが、breakがかけていない(笑) 公式のほうにもbreakがないのですが、C#では不要なんですかね?( ;∀;)

case内で実行したい処理を書くのですが、SEND_STRING(SS_LALT(""));`としています。

SEND_STRING()でキー押下を再現しているようで、引数には押下するキーもしくは文字列を指定します。SEND_STRING("Hello World!")とすれば一発でハローワールドを入力することができるようになります。キーボードのマクロに定型文やスニペットを追加する人はかなりの変態だと思いますが可能です。

SS_LALT()は、左Altを押しながら引数のキーを押す、そのあとに左Altを離すというようなキー入力を再現してくれます。 Alt, Ctrl, Shiftには特殊なSS_という関数が用意されているので簡単です。

私の場合は[Alt + Grave]にIME切り替えを割り当てているので、SEND_STRING(SS_LALT("(バッククォート)"));とすると切り替えを行ってくれます。(MacOSでは当然動かないでしょうね。。。( ;∀;))

[Shift + Space]に切り替えを割り当てている場合は、SS_LSFT(" ")で実現可能と思います。

理論的には関数を入れ子にしてSS_LCTRL(SS_LALT("1"))[Ctrl + Alt + 1]を再現できそうですがこれも試していません。実現できればIDEや各種編集ソフトでのワークスペースの切り替えなんかも1キーで対応できてしまいそうですね。



あとはビルドしてキーボード本体に書き込めば完了です。無事IMEを切り替えることできれば成功です! ^^) _旦~~

参考

使用できるキーコード一覧

マクロ https://beta.docs.qmk.fm/features/feature_macros