QMK薙刀式の進化

これまでの薙刀式キーマップは、入力したキーをバッファに保管し、キーを離し始めたタイミングでバッファの先頭から辞書にしたがって変換していくものでした。

しかし、少しでもキープレスが重なっていたら同時押しと判定していたので、高速打鍵での意図しない変換が多かったり、長い連続シフトの判定を誤ったりしていました。

今でも日常使いでそれほど問題はないのですが、Mac用の薙刀式変換ソフトBenkeiはもっと高度な判定をしたいと考えていたので、一旦まずはrubyで新しいロジックを書いてみて、うまくいけばBenkeiやQMKに書き換えようと思っていました。

なかなか手がつかなかったのですが、かな漢字変換のロジックを読んだ時に、薙刀式変換でも同じことだと思い、rubyで書いて試してみたところ、いくつかの例でうまく動作し、また先に挙げた問題点も解決できそうなので、QMKでの実装を開始しました。

基本的なロジックは
1. キー入力をバッファにためていく
2. 全てのキーを離したら変換開始する。それまでは何も出力しない。
3. バッファの中のキーがとりえる組み合わせ(各キーが単独押しか、同時押しか、連続シフトなのかなど)を全部列挙する。この組み合わせは事前に定義されたテーブルに従っている。
4. まず、この組み合わせから辞書にない同時押しを含む組み合わせは削除する。
5. 次に残った組み合わせを評価関数に通して点数付けし、一番点が高い組み合わせを採用する。

評価関数として、キーを押してる時間に対する、他のキーとの重なり時間の割合、としてみた。評価関数はいろいろ考えられるし、キーの組み合わせごとに変えるとかもできるはず。

これまで考慮していなかった時間を導入したので、ちょっとくらい重なっていても、2つの単独押しとするなどができる。

また、最初に全部の組み合わせを列挙するので、考慮しないパターンというのはないはず。現時点で4キーまでの組み合わせテーブルを持っている。5キーになると組み合わせが爆発してくるので、まだ作っていないが、5キーまでは実用的に必要だと思っている。

反面、全てのキーを離すまで何も表示されないというのはデメリットである。
全ての組み合わせを網羅したいというコンセプトとの背反である。

とりあえず編集モードなしのQMK実装を書いてみて、変換できることを確認した。2キー同士押しはいい感じだが、3キー同時だと2+1や1+2キーの同時押しになりやすい。これは評価関数によるもので、チューニングが必要である。
また、かなり実行時にメモリをつかうらしく(ファームウェアは小さい)、AVRではハングアップした。RP2040なら動作する。これは配列をPROGMEMでファームウェア上に確保することで解決できるだろう。

書き殴ったコードなので整理が必要だし、編集モードは実装してないし、実用的に動作するレベルではないが、今後の進化余地はありそう。評価関数で挙動が変えられるので、いろいろ試せるだろう。

汎用キーマップ変換ソフトの、DvorakJや紅皿とは違うアプローチであるのも面白い。

薙刀式の進化に合わせて、こちらも進化を見せることができそうです。