# 機能設計書 6-キーバインド管理

## 概要

本ドキュメントは、Doom Emacsのキーバインド管理システム（doom-keybinds.el）の機能設計を記述する。このシステムは、generalパッケージを基盤とした統一的なキーバインド定義システム（map!マクロ）、リーダーキー管理、which-key統合を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Doom Emacsは、Vimライクな操作性とEmacsの拡張性を両立させるために、強力なキーバインド管理システムを必要とする。generalパッケージを活用し、Evil状態対応、リーダーキー、ローカルリーダーキーなどの高度な機能を提供する。

**機能の利用シーン**：
- ユーザーによるキーバインドのカスタマイズ
- モジュールによるキーバインド定義
- リーダーキー（SPCキー）による階層的なコマンドアクセス
- which-keyによるキーバインドプレビュー

**主要な処理内容**：
1. リーダーキー管理（doom-leader-key、doom-leader-alt-key）
2. ローカルリーダーキー管理（doom-localleader-key）
3. map!マクロによるキーバインド定義
4. which-key統合
5. エスケープ処理（doom/escape）
6. 入力デコードマップ設定（C-i/C-m区別）

**関連システム・外部連携**：general.el、which-key.el、evil.el

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | キー入力全般に関連 |

## 機能種別

キーバインド管理 / 入力処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| doom-leader-key | string | No | リーダーキー（デフォルト: "SPC"） | キー文字列 |
| doom-leader-alt-key | string | No | 代替リーダーキー（デフォルト: "M-SPC"） | キー文字列 |
| doom-localleader-key | string | No | ローカルリーダーキー（デフォルト: "SPC m"） | キー文字列 |
| doom-localleader-alt-key | string | No | 代替ローカルリーダーキー | キー文字列 |

### 入力データソース

- ユーザー設定
- モジュール設定
- キーボード入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| doom-leader-map | keymap | リーダーキーマップ |
| キーバインド登録 | side-effect | 各種キーマップへの登録 |

### 出力先

Emacsのキーマップシステム

## 処理フロー

### map!マクロの処理

```
1. マクロ展開（doom--map-process）
2. プロパティ解析
   └─ :leader → doom--define-leader-key
   └─ :localleader → define-localleader-key!
   └─ :map → 指定キーマップへの登録
   └─ :mode → メジャーモードマップへの登録
3. 状態解析（:n, :v, :i等）
4. キー定義のバッチ処理
5. general-define-key呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[map!マクロ呼び出し] --> B{プロパティ解析}
    B -->|:leader| C[doom--define-leader-key]
    B -->|:localleader| D[define-localleader-key!]
    B -->|:map| E[指定キーマップ]
    B -->|状態指定| F[Evil状態解析]
    C --> G[doom-leader-map登録]
    D --> H[メジャーモードバインド]
    E --> I[general-define-key]
    F --> I
    G --> J[which-key登録]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | リーダーキー状態 | normal/visual/motionでSPC、insert/emacsでM-SPC | Evil使用時 |
| BR-02 | Evil非使用時 | doom-leader-alt-keyのみ使用 | Evil未読み込み |
| BR-03 | macOS修飾キー | command=super、option=meta | macOS |
| BR-04 | Windows修飾キー | Winキー=super | Windows |

### 状態記号マッピング

| 記号 | Evil状態 |
|-----|---------|
| :n | normal |
| :v | visual |
| :i | insert |
| :e | emacs |
| :o | operator |
| :m | motion |
| :r | replace |
| :g | global（Evil状態なし） |

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効な状態 | 未定義の状態記号 | エラーメッセージ |
| - | 無効なプロパティ | 未知のmap!プロパティ | エラーメッセージ |

### リトライ仕様

特になし

## トランザクション仕様

該当なし

## パフォーマンス要件

- doom--define-leader-keyによる20-30%の起動時間削減（define-leader-key!比較）
- general-auto-unbind-keysはdoom-after-modules-init-hook後に有効化

## セキュリティ考慮事項

特になし

## 備考

- Evil未使用でもmap!は動作する（Evil専用バインドは無視）
- C-gはdoom/escapeにリマップされる

---

## コードリーディングガイド

### 推奨読解順序

#### Step 1: 変数定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | doom-keybinds.el | `lisp/doom-keybinds.el` | 11-32行目のリーダーキー変数 |

**主要変数**:
- **11-12行目**: `doom-leader-key` = "SPC"
- **14-16行目**: `doom-leader-alt-key` = "M-SPC"
- **18-19行目**: `doom-leader-key-states` = '(normal visual motion)
- **21-22行目**: `doom-leader-alt-key-states` = '(emacs insert)
- **24-25行目**: `doom-localleader-key` = "SPC m"
- **27-29行目**: `doom-localleader-alt-key` = "M-SPC m"
- **31-32行目**: `doom-leader-map`

#### Step 2: プラットフォーム設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | doom-keybinds.el | `lisp/doom-keybinds.el` | 38-51行目のOS別設定 |

**設定内容**:
- **macOS**: command=super、option=meta、右optionは無効
- **Windows**: Winキー=super

#### Step 3: エスケープ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | doom-keybinds.el | `lisp/doom-keybinds.el` | 88-129行目のdoom/escape |

**処理フロー**:
1. ミニバッファがアクティブ → abort-recursive-edit
2. doom-escape-hookを実行
3. マクロ記録中は何もしない
4. 上記以外 → keyboard-quit

#### Step 4: map!マクロを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | doom-keybinds.el | `lisp/doom-keybinds.el` | 439-486行目のmap!マクロ |
| 4-2 | doom-keybinds.el | `lisp/doom-keybinds.el` | 294-418行目の内部関数 |

**map!プロパティ**:
- `:leader` - リーダーキー配下に定義
- `:localleader` - ローカルリーダーキー配下に定義
- `:mode` - メジャーモード固有
- `:map` - 指定キーマップに定義
- `:prefix` - プレフィックス設定
- `:after` - 機能読み込み後に定義
- `:desc` - which-key説明

### プログラム呼び出し階層図

```
map! マクロ
    │
    └─ doom--map-process
            │
            ├─ doom--map-nested (入れ子処理)
            │
            ├─ doom--map-set (状態設定)
            │
            ├─ doom--map-def (キー定義)
            │
            └─ doom--map-commit
                    │
                    ├─ doom--define-leader-key (:leader時)
                    │       └─ define-key doom-leader-map
                    │
                    ├─ define-localleader-key! (:localleader時)
                    │       └─ general-define-key
                    │
                    └─ general-define-key (通常時)

doom-init-leader-keys-h (doom-after-init-hook)
    │
    ├─ evil-define-key* (Evil使用時)
    │
    └─ define-key general-override-mode-map
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| doom-keybinds.el | `lisp/doom-keybinds.el` | ソース | キーバインド管理本体 |
| doom.el | `lisp/doom.el` | ソース | コアシステム |
| general.el | packages | 外部パッケージ | キーバインドフレームワーク |
| which-key.el | packages | 外部パッケージ | キープレビュー |
