はじめに
Mac版はこちらの記事からどうぞ → 英数キーが最強レイヤーキーに変身!Karabiner-Elementsでホームポジション崩さず爆速タイピング
普段のタイピングで、矢印キーやBackspaceキーを押すたびにホームポジションから手を動かしていませんか?
また、あまり使わないCapsLockキーが重要な位置にあってもったいないと感じたことはないでしょうか。
この記事では、AutoHotKeyを使ってCapsLockキーを“レイヤーキー”として活用し、ホームポジションを崩さずに矢印キーやBackspace、Enterなどを使えるようにする方法をご紹介します。
AutoHotKey公式サイト↓
キーボード配列の問題点
- 矢印キー・Backspaceが端にある:ホームポジションから手を離さないと操作できず、タイピング中の手の移動が頻発する
- CapsLockキーが“死に”キー:あまり使わないのに重要な位置にあるため、別用途に再割り当てしたい
CapsLockレイヤー化の概要
- 
CapsLockがオンになっている間、ESDF周辺のキーを矢印キーやBackspace、Enter、Delなどに置き換える
- 必要に応じてCtrl/Altや変換/無変換キーも割り当て
- CapsLockのオン/オフ状態を視覚的にわかりやすく画面中央にオーバーレイ表示
AutoHotKeyの使い方
AutoHotKey(AHK)は、Windows上で動作するフリーのマクロ/自動化ツールです。以下の手順で導入し、スクリプトを実行することができます。
- 
インストール - 公式サイトから最新のインストーラをダウンロードし、ウィザードに従ってインストールします。
- v1系とv2系があるため、互換性のあるスクリプトを使う場合はバージョンを確認してください。(こだわりが無ければv2をダウンロードすることをおすすめします)
 
- 
スクリプトの作成 - 任意のテキストエディタで拡張子 .ahkのファイルを作成します。
- ファイル冒頭で **#Requires AutoHotkey v2.0**を記述します。(なくても良い)
 
- 任意のテキストエディタで拡張子 
- 
スクリプトの実行/再読み込み 
- 
自動起動設定(スタートアップ登録) 
これらの基本操作を押さえておくことで、CapsLockレイヤー化スクリプトのカスタマイズやトラブルシュートがスムーズになります。
1. キーマップ変更スクリプト (AutoHotKey v2)
以下のスクリプトは、CapsLockがオンになっている間だけキーの機能を入れ替える「レイヤー」動作を実現します。ホームポジションから指を大きく動かさずに、矢印移動や編集操作が可能になります。
#HotIf GetKeyState("CapsLock", "T")
  ; Esc / Tab / Backspace / Enter / Delete
  $q::Esc
  $a::Tab
  $w::Backspace
  $r::Enter
  $t::Del
  ; 矢印キー
  $e::Up
  $s::Left
  $d::Down
  $f::Right
  ; Home / Space / End
  $x::Home
  $c::Space
  $v::End
  ; Ctrl / Alt / 変換 / 無変換
  $n::Ctrl
  $m::Alt
  $u::vk1C  ; 変換キー
  $o::vk1D  ; 無変換キー
#HotIf
キーマップ一覧
| 元キー | 置換先機能 | 
|---|---|
| Q | Esc | 
| A | Tab | 
| W | Backspace | 
| R | Enter | 
| T | Del | 
| E/S/D/F | Up/Left/Down/Right | 
| X/C/V | Home/Space/End | 
| N/M | Ctrl/Alt | 
| U/O | 変換/無変換 | 
スクリプト中のキー名(例:Tab, vk1Cなど)は、公式ドキュメントで一覧化されています。ほかのキーをリマップしたい場合は以下のURLを参考に、キー名を自由に変更してください。
2. CapsLockオンオフを表示するインディケータ (AutoHotKey v2)
こちらはCapsLockの状態を中央画面にオーバーレイ表示するスクリプトです。トグルごと画像の 「NORMAL MODE」/「INSERT MODE」 を フェードイン/アウトで表示します。

#Requires AutoHotkey v2.0
; 定数定義
OVERLAY_WIDTH := 240       ; オーバーレイの幅
OVERLAY_HEIGHT := 60       ; オーバーレイの高さ
OVERLAY_BG_NORMAL := "303030"  ; 通常モード時の背景色(暗めのグレー)
OVERLAY_BG_INSERT := "304030"  ; 挿入モード時の背景色(暗めの緑グレー)
OVERLAY_OPACITY := 180      ; 透明度 (0-255, 0が完全不透明)
OVERLAY_FONT := "s16 bold" ; オーバーレイのフォントスタイル
OVERLAY_FONT_FACE := "Arial" ; オーバーレイのフォント
OVERLAY_TEXT_COLOR := "FFFFFF" ; テキストの色(白)
DISPLAY_TIME := 1000       ; オーバーレイの表示時間(ミリ秒)
FADE_STEP := 20           ; フェードアウト時の透明度減少ステップ
FADE_INTERVAL := 5       ; フェードアウトの更新間隔(ミリ秒)
INSERT_MODE_TEXT := "INSERT MODE" ; 挿入モード時の表示テキスト
NORMAL_MODE_TEXT := "NORMAL MODE" ; 通常モード時の表示テキスト
; Caps Lockの標準機能を無効化
SetCapsLockState "AlwaysOff"
; オーバーレイウィンドウの初期化
class ModeOverlay {
    static gui := ""
    static textControl := ""
    static displayTimer := 0
    static fadeTimer := 0
    static currentOpacity := OVERLAY_OPACITY
    
    ; オーバーレイウィンドウの初期化
    static Init() {
        this.gui := Gui("+AlwaysOnTop -Caption +ToolWindow +E0x20")
        this.gui.BackColor := OVERLAY_BG_NORMAL
        ; フォントのパディングを設定(垂直方向のオフセットを追加)
        this.gui.SetFont(OVERLAY_FONT " c" OVERLAY_TEXT_COLOR, OVERLAY_FONT_FACE)
        ; テキストコントロールをGUI全体に広げて中央揃えにする
        ; 0x1: SS_CENTER - テキストを水平方向に中央揃え
        ; 0x200: SS_CENTERIMAGE - テキストを垂直方向に中央揃え
        ; 合計: 0x201 - 完全に中央揃え
        ; y2に設定して少し下方向に調整
        this.textControl := this.gui.Add("Text", "x0 y2 w" OVERLAY_WIDTH " h" OVERLAY_HEIGHT-4 " +0x201 Center", "")
        
        ; ウィンドウの透明度を設定
        WinSetTransparent(OVERLAY_OPACITY, this.gui)
    }
    
    ; オーバーレイを表示
    static Show(text, isInsertMode := false) {
        ; 透明度を初期値に戻す
        this.currentOpacity := OVERLAY_OPACITY
        
        ; フェードタイマーが動いていれば停止
        if this.fadeTimer
            SetTimer(this.fadeTimer, 0)
            
        ; 既存の表示タイマーをクリア
        if this.displayTimer
            SetTimer(this.displayTimer, 0)
        
        ; モードに応じて背景色を変更
        this.gui.BackColor := isInsertMode ? OVERLAY_BG_INSERT : OVERLAY_BG_NORMAL
        
        ; アクティブなウィンドウが属するモニターの中央に表示
        monitorRect := this.GetActiveMonitorRect()
        
        ; モニターの中央座標を計算
        x := monitorRect.left + (monitorRect.right - monitorRect.left) // 2 - OVERLAY_WIDTH // 2
        y := monitorRect.top + (monitorRect.bottom - monitorRect.top) // 2 - OVERLAY_HEIGHT // 2
        
        ; テキスト設定(上下中央に表示されるように垂直センタリングを追加)
        this.textControl.Value := text
        
        ; オーバーレイを表示
        this.gui.Show("x" x " y" y " w" OVERLAY_WIDTH " h" OVERLAY_HEIGHT " NoActivate")
        
        ; 透明度を再設定(色が変わった後にも透明度を維持するため)
        WinSetTransparent(OVERLAY_OPACITY, this.gui)
        
        ; 指定時間後にフェードアウト開始
        this.displayTimer := ObjBindMethod(this, "StartFadeOut")
        SetTimer(this.displayTimer, -DISPLAY_TIME)
    }
    
    ; フェードアウト開始
    static StartFadeOut() {
        this.fadeTimer := ObjBindMethod(this, "FadeStep")
        SetTimer(this.fadeTimer, FADE_INTERVAL)
    }
    
    ; フェードアウトのステップ処理
    static FadeStep() {
        ; 透明度を減少
        this.currentOpacity -= FADE_STEP
        
        ; 透明度が0以下になったら非表示にして終了
        if (this.currentOpacity <= 0) {
            SetTimer(this.fadeTimer, 0)
            this.gui.Hide()
            this.currentOpacity := OVERLAY_OPACITY
            return
        }
        
        ; 透明度を適用
        WinSetTransparent(this.currentOpacity, this.gui)
    }
    
    ; オーバーレイを即時非表示(フェードなし)
    static Hide() {
        ; フェードタイマーが動いていれば停止
        if this.fadeTimer
            SetTimer(this.fadeTimer, 0)
            
        this.gui.Hide()
        this.currentOpacity := OVERLAY_OPACITY
    }
    
    ; アクティブなモニターの領域を取得
    static GetActiveMonitorRect() {
        ; アクティブなウィンドウの情報を取得
        activeWin := WinGetID("A")
        
        ; アクティブなウィンドウが属するモニターのハンドルを取得
        ; MONITOR_DEFAULTTONEAREST = 2
        activeMonitor := DllCall("MonitorFromWindow", "Ptr", activeWin, "UInt", 2)
        
        ; MONITORINFO構造体を作成(40バイト: サイズ(4) + RECT(16) + RECT(16) + フラグ(4))
        monitorInfo := Buffer(40, 0)
        NumPut("UInt", 40, monitorInfo, 0)  ; 構造体のサイズを設定
        
        ; モニター情報を取得
        DllCall("GetMonitorInfo", "Ptr", activeMonitor, "Ptr", monitorInfo)
        
        ; モニターの作業領域(タスクバーを除いた領域)を取得
        return {
            left: NumGet(monitorInfo, 20, "Int"),
            top: NumGet(monitorInfo, 24, "Int"),
            right: NumGet(monitorInfo, 28, "Int"),
            bottom: NumGet(monitorInfo, 32, "Int")
        }
    }
}
; オーバーレイを初期化
ModeOverlay.Init()
; モード管理クラス
class InputModeManager {
    static isInsertMode := true
    
    ; モードを切り替え
    static ToggleMode() {
        this.isInsertMode := !this.isInsertMode
        
        if this.isInsertMode {
            ModeOverlay.Show(INSERT_MODE_TEXT, false)
            SetCapsLockState "off"
        } else {
            ModeOverlay.Show(NORMAL_MODE_TEXT, true)
            SetCapsLockState "on"
        }
    }
}
; Caps Lockキーのホットキー設定
CapsLock::InputModeManager.ToggleMode()
インディケータの主要パラメーター説明
| 変数名 | 用途 | デフォルト値 | 調整例 | 
|---|---|---|---|
| OVERLAY_WIDTH | オーバーレイウィンドウの横幅 (px) | 240 | 300にすれば横長にできます | 
| OVERLAY_HEIGHT | オーバーレイウィンドウの高さ (px) | 60 | 80にすれば縦に大きく表示 | 
| OVERLAY_FONT | フォントサイズとスタイル設定 | "s16 bold" | "s20 bold"→ 文字をさらに大きく、"s14"→ 少し小さめに | 
| OVERLAY_FONT_FACE | フォントフェミリー名 | "Arial" | "Meiryo UI"に変更して和文フォントに | 
| OVERLAY_TEXT_COLOR | 表示文字の色 (16進RGB) | "FFFFFF"(白) | "FF0000"→ 赤文字に、"00FF00"→ 緑文字に | 
| OVERLAY_BG_NORMAL | 通常モード時の背景色 (16進RGB) | "303030"(グレー) | "202020"→ さらに暗いグレー、"505050"→ 明るめのグレー | 
| OVERLAY_BG_INSERT | 挿入モード時の背景色 (16進RGB) | "304030"(緑寄り) | "203020"→ 暗い緑、"407040"→ 明るい緑 | 
| OVERLAY_OPACITY | ウィンドウの不透明度 (0~255, 高いほど不透明) | 180 | 200にすればより不透明に、120にすればより透けて見えます | 
| DISPLAY_TIME | オーバーレイを表示する時間 (ミリ秒) | 1000 | 2000にすると2秒間表示され、500にすると半秒でフェードアウト開始 | 
| FADE_STEP | フェードアウト時に一度に減少する透明度 | 20 | 10にするとゆっくりフェードアウト、30にすると速くフェードアウト | 
| FADE_INTERVAL | フェードアウト更新間隔 (ミリ秒) | 5 | 10にするとフェードの刻みが粗く、2にするとより滑らか | 
| INSERT_MODE_TEXT | 文字入力モード表示文字 | "INSERT MODE" | "Vim Off"などお好みの文言に変更可能 | 
| NORMAL_MODE_TEXT | 装飾モード表示文字 | "NORMAL MODE" | "Vim On"などお好みの文言に変更可能 | 
Tip 1:
これらの変数はスクリプト冒頭で定義しています。自分の環境や好みに合わせて数値やカラーコード、テキストを自由に変更してください。
Tip 2:
Vimのモード名似合わせているため、通常モードを”INSERT”に、特殊モードを”NORMAL”に命名しています。
3. 日本語/英語入力切替キーの設定方法
Windows標準キーボードには、Macのような専用のかな/英数キーがありません。以下の方法で切り替えを割り当てておくと便利です。
- Google 日本語入力(Mozc)用のかなキー設定
- Windows IME用のかな入力切替キー設定
これらのURLを参考に、 vk15 (無変換)や vk1C (変換)などをAutoHotKeyで再マップしましょう。
まとめ
- CapsLockをレイヤーキー化することで、ホームポジションを崩さずに矢印キーやBackspace、Enterなどを操作可能に
- AutoHotKey v1/v2それぞれのスクリプト例を掲載
- オーバーレイ表示でCapsLockの状態が一目瞭然に
- 日本語/英語入力切替キーも併せて設定すれば、Windowsでのタイピングがさらに快適に!
ぜひご自身のキーボードでも試してみてください!



