8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rust製ツール「Kanata」× Home Row Mods × Hyper Layer により操作性・作業効率の向上を目指すカスタムキーマップ構築録

Last updated at Posted at 2025-12-25

はじめに

エンジニアや研究者にとって、キーボードは身体の一部と言っても過言ではありません。日々タイピングする中で「このショートカットキー頻繁に使うけど押しづらいんだよな」や「もっとタイピングの効率や快適性を高められないのかな」と考えたことはないでしょうか。

本記事では、macOS の定番である Karabiner-Elements ではなく、Rust製のOSSキーマッピングツール「Kanata を選択し、理想の入力環境を構築した記録を共有します。

JIS/US 配列が混在する環境において、Home Row Mods(ホームポジション修飾キー)やレイヤー機能を駆使し、「どのキーボードでも同じ操作感」かつ「快適で効率的なキーマップ」を実現するための設計思想と実装について解説します。

今回開発した設定ファイルは GitHub リポジトリ に公開しています。

1. 開発の背景と目的

キーボード配列に対する課題意識

日々の開発や研究活動の中で常に感じていたのが、「頻繁に使う操作ほど、ホームポジションから指を大きく動かす必要がある」ということです。

例えば、以下のような操作です。

  • 文字削除: Backspace / Delete
  • カーソル移動: / / / / Home / End / Page Up / Page Down
  • キャンセル: Esc
  • タブ切り替え: Ctrl + Tab / Ctrl + Shift + Tab

これらは文章作成やコーディング等で多用するにもかかわらず、小指を大きく伸ばしたり、ホームポジションから手を離したりする必要があります。

一方で、ホームポジションの一等地(Aの隣)にありながら、ほとんど使われていないキーも存在します。その代表例が CapsLock です。
アルファベットを大文字に固定するためだけのこのキーを、日常的に活用している方はそう多くないはずです。

押しにくいキーは多用し、押しやすいキーは使われていない」。
このアンバランスさを解消することが、今回のキーマップ構築の出発点でした。

Windows 環境での成功体験と macOS での課題

私は普段、自宅では Windows デスクトップ PC を、出先では MacBook Air を使用しています。

Windows 環境では Razer 製キーボードを使用しており、専用ソフト(Razer Synapse)を用いて Hyper レイヤー(特定のキーを押している間だけ別のキーマップになる機能) を構築していました。これが非常に快適で、作業効率に大きな恩恵を受けていました。

しかし macOS 環境では、Apple 純正の JIS / US キーボードを使用しているため、ハードウェア側の機能で設定を引き継ぐことができません。

  • 「キーボード配列(JIS/US)が異なっても、同じ操作感を維持したい」
  • 「物理キーボードを買い替える(ハードウェア解決)のではなく、コストを抑えつつソフトウェアで解決したい」

こうした動機から、macOS 向けに改めて強力なキーボード環境を構築する必要性が生じました。

2. なぜ Karabiner ではなく Kanata なのか?

macOS でキーボードカスタマイズといえば Karabiner-Elements がデファクトスタンダードです。GUI で設定でき、非常に優秀なツールですが、私の環境ではいくつかの課題がありました。

  1. クロスプラットフォーム対応:
    Karabiner は macOS 専用です。将来的に他のOSでも同じ操作体系(設定ファイル)を流用したいと考えた際、OS 依存はネックになります。
  2. 設定ファイルによる管理:
    「Shiftキーを2回タップして長押ししたら Function レイヤー」といったような、文脈に依存した複雑な挙動を定義しようとした際、Kanata の方が設定ファイル(.kbd)で宣言的に記述しやすく、Git管理との相性も良いと感じました。

そこで出会ったのが Kanata です。設定ファイルがコードベースで管理でき、挙動を細かく制御できる点に惹かれました。

3. 設計思想:ホームポジションから「一歩」も動かない

今回のキーマップ構築における最大のテーマは、「思考と指の動きを一致させること」です。物理的なキー配列が JIS でも US でも、指の動きは統一します。

3-1. レイヤー構成のイメージ

論より証拠、実際に構築したレイヤーの配置をご覧ください。US配列でのイメージですが、JISでも操作感は統一しています。

Base Layer (通常時)
Home Row Mods を採用し、ホームポジションに修飾キーを埋め込んでいます。
Base Layer

Hyper Layer (CapsLock 長押し)
矢印キーや削除系キーを左手側に配置し、ホームポジションから手を動かさずにカーソル操作を完結させます。
Hyper Layer

Function Layer (左 Shift 2回タップ+長押し)
ファンクションキーやテンキー操作を集約しています。
Function Layer

3-2. Home Row Mods とは?

修飾キー(Cmd, Ctrl, Shift, Alt)を打つために、小指を不自然に曲げたり、大きく手を動かしていませんか?
Home Row Mods は、ホームポジション(A, S, D, F, J, K, L, ;)に修飾キーの役割を持たせる手法です。

  • Tap(短押し): 文字入力(A, S...)
  • Hold(長押し): 修飾キー(Cmd, Shift...)

これにより、「文字を打つ指」のまま「ショートカットも打てる」ようになり、小指の負担が軽減されます。

4. 実装:配列の壁を超える .kbd 設計

Kanata の設定ファイル(.kbd)は1つにまとめることも可能ですが、私はあえて物理配列ごとに設定ファイルを分離しました。

実際のコード例 (kanata-mac-mac-JIS.kbd)
;; 0. グローバル設定
(defcfg
    process-unmapped-keys yes   ;; defsrc で定義しないキーも通す
)

;; 1. 使用キーの定義
(defsrc
    esc     f1      f2      f3      f4      f5      f6      f7      f8      f9      f10     f11     f12      
            1       2       3       4       5       6       7       8       9       0       -       =       bspc
    tab     q       w       e       r       t       y       u       i       o       p              
    lctl    a       s       d       f       g       h       j       k       l       ;       apo     \       ret
    lsft    z       x       c       v       b       n       m       ,       .       /       ro      rsft
    caps    lalt    lmet                    spc                     rmet    fn
)

;; 2. 変数の定義
(defvar
    ;; 数値(時間)の単位: ms
    tap-time    200
    hold-time   200
    double-tap-time   300
    
    left-hand-keys (
        q w e r t
        a s d f g
        z x c v b
    )
    
    right-hand-keys (
        y u i o p
        h j k l ;
        n m , . /
    )
)

;; 3. 複雑な操作の定義
(defalias
    tap (multi
        (layer-switch nomods)
        (on-idle-fakekey to-base tap 20)
    )
    a (tap-hold-release-keys $tap-time $hold-time (multi a @tap) lctl $left-hand-keys)
    s (tap-hold-release-keys $tap-time $hold-time (multi s @tap) lalt $left-hand-keys)
    d (tap-hold-release-keys $tap-time $hold-time (multi d @tap) lsft $left-hand-keys)
    f (tap-hold-release-keys $tap-time $hold-time (multi f @tap) lmet $left-hand-keys)
    j (tap-hold-release-keys $tap-time $hold-time (multi j @tap) rmet $right-hand-keys)
    k (tap-hold-release-keys $tap-time $hold-time (multi k @tap) rsft $right-hand-keys)
    l (tap-hold-release-keys $tap-time $hold-time (multi l @tap) ralt $right-hand-keys)
    ; (tap-hold-release-keys $tap-time $hold-time (multi ; @tap) rctl $right-hand-keys)
    en Lang2
    ja Lang1
    hyper (layer-while-held hyper)      ;; タップ→ esc, 長押し→Hyperレイヤー
    funct (tap-dance $double-tap-time (lsft (layer-while-held function)))   ;; タップor長押し→Left shift, 2回タップ+長押し→Functionレイヤー
    fn    (tap-hold $tap-time $hold-time fn (layer-while-held function))
)

;; 4. レイヤー定義
;; --- ベースレイヤー ---
(deflayer base
    _       _       _       _       _       _       _       _       _       _       _       _       _
            _       _       _       _       _       _       _       _       _       _       _       _       _
    _       _       _       _       _       _       _       _       _       _       _       _       _
    @hyper  @a      @s      @d      @f      _       _       @j      @k      @l      @;      _       _       _
    @funct  _       _       _       _       _       _       _       _       _       _       _       _
    lctl    _       _                       _                       @en     @fn
)

;; --- nomodsレイヤー ---
(deflayer nomods
    _       _       _       _       _       _       _       _       _       _       _       _       _
            _       _       _       _       _       _       _       _       _       _       _       _       _
    _       _       _       _       _       _       _       _       _       _       _       _       _
    @hyper  a       s       d       f       _       _       j       k       l       ;       _       _       _
    @funct  _       _       _       _       _       _       _       _       _       _       _       _
    lctl    _       _                       _                       @en     @fn
)

(deffakekeys
    to-base (layer-switch base)
)

;; --- Hyperレイヤー ---
(deflayer hyper
    _       _       _       _       _       _       _       _       _       _       _       _       _
            _       _       _       _       _       _       _       _       _       _       _       _       _
    esc     C-tab   bspc    up      del     C-S-tab _       _       _       _       _       _       _
    @hyper  home    lft     down    rght    end     _       @j      @k      @l      @;      _       _       _
    @funct  pgup    M-z     M-S-z   pgdn    _       _       _       _       _       _       _       _
    lctl    _       _                       ret                     @ja     @fn
)

;; --- Functionレイヤー ---
(deflayer function
    _       brdn    brup    mctl    sls     dtn     dnd     prev    pp      next    mute    voldwn  volu
            f1      f2      f3      f4      f5      f6      f7      f8      f9      f10     f11     f12     del
    _       C-tab   bspc    up      del     C-S-tab kp,     kp7     kp8     kp9     S--     ret     _
    @hyper  home    lft     down    rght    end     kp.     kp4     kp5     kp6     kp+     kp*     _       _
    @funct  pgup    M-z     M-S-z   pgdn    kp0     kp1     kp2     kp3     -       kp/     _       _
    lctl    _       _                       _                       @ja     @fn
)

こだわりの設定ポイント

実際の .kbd ファイルから、特にこだわった部分を抜粋して解説します。

① Home Row Mods の定義 (defalias)

誤入力を防ぐため、tap-hold-release-keys を使用しています。これは「他のキーが押されたタイミング」なども考慮して Tap/Hold を判定してくれる高度な設定です。

kanata-mac-mac-US.kbd
(defvar
    ;; 数値(時間)の単位: ms
    tap-time    200
    hold-time   200
    
    left-hand-keys ( q w e r t a s d f g z x c v b )
    right-hand-keys ( y u i o p h j k l ; n m , . / )
)

(defalias
    ;; 左手:Aキーを長押しでCtrl、短押しでa
    a (tap-hold-release-keys $tap-time $hold-time (multi a @tap) lctl $left-hand-keys)
    s (tap-hold-release-keys $tap-time $hold-time (multi s @tap) lalt $left-hand-keys)
    d (tap-hold-release-keys $tap-time $hold-time (multi d @tap) lsft $left-hand-keys)
    f (tap-hold-release-keys $tap-time $hold-time (multi f @tap) lmet $left-hand-keys)
    
    ;; 右手も同様に対称配置
    j (tap-hold-release-keys $tap-time $hold-time (multi j @tap) rmet $right-hand-keys)
    k (tap-hold-release-keys $tap-time $hold-time (multi k @tap) rsft $right-hand-keys)
    l (tap-hold-release-keys $tap-time $hold-time (multi l @tap) ralt $right-hand-keys)
)

調整の柔軟性
defvar で定義した tap-time, hold-time 変数は、キーボードの物理的な特性(キーストロークの深さやスイッチの重さ)に合わせて自由に調整できます。誤爆が発生しないよう試行錯誤した結果、現在は JIS/US ともに 200ms で運用しています。環境や好みに応じてミリ秒単位でチューニングできるのは Kanata の大きな魅力です。

② Hyper レイヤーの活用(入力切替とナビゲーション)

Hyper レイヤー(Capslock長押し)には、カーソル移動だけでなく「入力ソースの切り替え」という重要な役割も持たせています。

日本語 / 英語入力の切り替え
US配列などでは「入力切替」のキー確保に悩みますが、右 Cmd キー(rmet)を活用して解決しました。

  • Base レイヤー(通常時): 英語入力(Lang2 / 英数)
  • Hyper & Function レイヤー(長押し時): 日本語入力(Lang1 / かな)

これにより、同じキーでも「そのまま押せば英語」「Hyperキーと一緒に押せば日本語」という直感的な切り替えが可能になり、今どちらの入力なのか確認する手間がなくなります。

kanata-mac-mac-us.kbd
(defalias
    ...
    en Lang2
    ja Lang1
    ...
)

;; --- Baseレイヤー ---
(deflayer base
    ...
    _       _       _       _               _                       @en     fn
)

;; --- Hyperレイヤー ---
(deflayer hyper
    ...
    _       _       _       _               ret                     @ja     fn
)

;; --- Functionレイヤー ---
(deflayer function
    ...
    _       _       _       _               _                       @ja     fn
)

範囲選択の最適化
プログラミングや文書作成において頻発する「Shift + ナビゲーションキー」による範囲選択も、ホームポジションを崩さずに行えます。

  • 右手: 中指で K をホールド(Shift)
  • 左手: 小指で Capslock をホールド(Hyper) + E/S/D/F(矢印)
    ※ Home Row Mods → Hyper Layer という手順でないと上手く機能しない可能性があります。
kanata-mac-mac-us.kbd
(deflayer hyper
    _       _       _       _       _       _       _       _       _       _       _       _       _
            _       _       _       _       _       _       _       _       _       _       _       _       _
    esc     C-tab   bspc    up      del     C-S-tab _       _       _       _       _       _       _
    @hyper  home    lft     down    rght    end     _       @j      @k      @l      @;      _       _
    @funct  pgup    M-z     M-S-z   pgdn    _       _       _       _       _       _       _      
    _       _       _       _               ret                     @ja     fn
)

修飾キー(Shift)とナビゲーションキー(矢印キー, Home, End など)の役割を左右の手で分担することで、指を不自然に捻ることなく、流れるようにコードの範囲選択が可能です。

③ 特殊なレイヤー呼び出し (tap-dance)

Function レイヤーは常時使うものではないため、誤爆を防ぐために少し特殊な呼び出し方を採用しました。「左 Shift を2回タップし、そのまま押しっぱなしにした時だけ」レイヤーが有効になります。

(defalias
    ;; タップor長押し→Left shift
    ;; 2回タップ+長押し→Functionレイヤー
    funct (tap-dance $double-tap-time (lsft (layer-while-held function)))
)

この tap-dance 機能のおかげで、普段の Shift キー入力(大文字入力など)を邪魔することなく、特殊機能を追加できています。

5. 導入方法とトラブルシューティング

インストール

macOS では Homebrew を利用してインストールしました。

brew install kanata

※ 権限周りの設定やドライバ(Karabiner-VirtualHIDDevice)の導入が必要です。詳細は公式ドキュメントまたは私のリポジトリの README を参照してください。

ハマりどころ:スタートアップ時の挙動

MacBook Air の方では問題ないのですが、Mac mini で導入した際に起動直後のログイン画面において、「約5秒経過すると『i』などの定義されているキーが反応しなくなり、その後ログインしても Kanata は起動していない状態になる」 という現象に遭遇しました。原因は不明ですが、機種の問題というより、導入手順や設定に問題があるとみています。

現状の回避策としては、「ログイン画面が表示されたら即座にパスワードを入力する(Kanataが干渉する前にログインを完了させる)」ことで対応しています。根本的な解決には至っていませんが、運用でのカバーは可能です。

ハマりどころ:Home Row Mods の「誤爆」

「普通に文字を打ったつもりが、Cmdキーとして認識された」
これは Home Row Mods 導入時の最大の壁です。前述の defvar で定義した tap-timehold-time を自分のタイピング速度に合わせて 10ms 単位で調整しました。最初は長めの設定(200ms〜)から始め、慣れに合わせて短くしていくのがおすすめです。

6. 結論

慣れるまでの「1週間」を乗り越える

正直に言うと、導入直後は違和感しかありませんでした。特に Home Row Mods は、タイピングのリズムを変える必要があるため、無意識に使えるようになるまで約1週間かかりました。

しかし、一度慣れてしまうと世界が変わります。

  • カーソル移動がスムーズ: ホームポジションから手を動かさずに、矢印キーや PageUp/Down が打てる。
  • 手首の疲れが軽減: 手首を左右に振る動作が減った。
  • 配列を選ばない: 設定ファイルを切り替えるだけで、どんなキーボードでも「いつもの操作感」になる。

今回の構築を通じて、キーボード配列は「与えられるもの」ではなく「自分の使い方に合わせて育てていくもの」だと実感しました。

本記事の設定は macOS 向けですが、Kanata 自体は Windows にも対応しています(※私はWindows版を作成する予定はありませんが、興味のある方はぜひ挑戦してみてください!)。

もし今のキーボード操作に少しでも違和感があるなら、ぜひ Kanata で「自分だけの快適なキーマップ」を作り上げてみてください。

7. 参考資料・リンク集

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?