# 機能設計書 4-設定カスタマイズ

## 概要

本ドキュメントは、space-vimの設定カスタマイズ機能の設計について記述する。この機能は、ユーザーが`~/.spacevim`ファイルを通じて独自の設定を定義できる仕組みを提供する。

### 本機能の処理概要

設定カスタマイズ機能は、ユーザーが`~/.spacevim`ファイルを編集することで、レイヤーの選択、リーダーキーの設定、プラグインの追加、Vimの設定オーバーライドなどを行える仕組みを提供する。`UserInit()`と`UserConfig()`という2つのコールバック関数により、ユーザーは適切なタイミングでカスタマイズを適用できる。

**業務上の目的・背景**：space-vimはデフォルトで多くの設定を提供するが、すべてのユーザーが同じ設定を必要とするわけではない。設定カスタマイズ機能により、ユーザーは自分のワークフローに合わせてspace-vimをカスタマイズできる。また、space-vimのアップデート時にユーザー設定が上書きされないよう、ユーザー設定は`~/.spacevim`という独立したファイルに分離されている。

**機能の利用シーン**：
- 新規ユーザーが初めてspace-vimを設定する場面
- 新しいプログラミング言語のサポートを追加したい場面
- デフォルトのキーバインドを変更したい場面
- 独自のプラグインを追加したい場面
- Vimの基本設定（インデント幅、行番号表示等）をカスタマイズしたい場面

**主要な処理内容**：
1. `~/.spacevim`ファイルの読み込みとSource実行
2. `g:spacevim_layers`変数からレイヤー一覧を取得して有効化
3. `g:spacevim_leader`からリーダーキー設定を取得（デフォルト: Space）
4. `g:spacevim_localleader`からローカルリーダー設定を取得（デフォルト: ,）
5. `UserInit()`関数の呼び出し（プラグイン追加用）
6. `UserConfig()`関数の呼び出し（設定オーバーライド用）

**関連システム・外部連携**：
- vim-plug: `UserInit()`内でPlugコマンドを使用してプラグインを追加

**権限による制御**：本機能に権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面を持たない設定機能 |

## 機能種別

設定管理 / ユーザーカスタマイズ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g:spacevim_plug_home | String | No | プラグインインストールディレクトリ | 有効なディレクトリパス |
| g:spacevim_leader | String | No | リーダーキー（デフォルト: Space） | 有効なキー文字列 |
| g:spacevim_localleader | String | No | ローカルリーダーキー（デフォルト: ,） | 有効なキー文字列 |
| g:spacevim_layers | List | No | 有効化するレイヤー名のリスト | 有効なレイヤー名 |
| g:spacevim_excluded | List | No | 除外するプラグイン名のリスト | 有効なプラグイン名 |
| g:spacevim_enable_true_color | Number | No | TrueColor有効化フラグ（0/1） | 0または1 |
| g:spacevim_nerd_fonts | Number | No | Nerdフォント使用フラグ（0/1） | 0または1 |

### 入力データソース

1. **ユーザー設定ファイル**: `~/.spacevim`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| g:mapleader | String | Vimのリーダーキー |
| g:maplocalleader | String | Vimのローカルリーダーキー |
| g:spacevim.loaded | List | 有効化されたレイヤー一覧（更新） |
| g:spacevim.excluded | List | 除外プラグイン一覧（更新） |

### 出力先

- グローバル変数
- Vim設定

## 処理フロー

### 処理シーケンス

```
1. spacevim#begin()からs:check_dot_spacevim()呼び出し
   └─ ~/.spacevimファイルの存在確認

2. ~/.spacevimファイルが存在する場合
   └─ ファイルをSource実行
   └─ g:spacevim_layersをg:spacevim.loadedに追加
   └─ g:mapleaderを設定（デフォルト: Space）
   └─ g:maplocalleaderを設定（デフォルト: ,）

3. ~/.spacevimファイルが存在しない場合
   └─ エラーメッセージを表示

4. spacevim#end()からUserInit()呼び出し
   └─ plug#begin()とplug#end()の間で実行
   └─ Plugコマンドでプラグインを追加可能

5. spacevim#end()からUserConfig()呼び出し
   └─ すべてのレイヤー設定読み込み後に実行
   └─ Vim設定をオーバーライド可能
```

### フローチャート

```mermaid
flowchart TD
    A[spacevim#begin] --> B[s:check_dot_spacevim]
    B --> C{~/.spacevim存在?}
    C -->|No| D[エラー表示]
    C -->|Yes| E[Source ~/.spacevim]
    E --> F[g:spacevim_layers取得]
    F --> G[g:spacevim.loadedに追加]
    G --> H[g:mapleader設定]
    H --> I[g:maplocalleader設定]
    I --> J[spacevim#end]
    J --> K[plug#begin]
    K --> L[レイヤーpackages.vim読み込み]
    L --> M{UserInit存在?}
    M -->|Yes| N[UserInit呼び出し]
    M -->|No| O[plug#end]
    N --> O
    O --> P[レイヤーconfig.vim読み込み]
    P --> Q{UserConfig存在?}
    Q -->|Yes| R[UserConfig呼び出し]
    Q -->|No| S[完了]
    R --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | .spacevim必須 | ~/.spacevimファイルが存在しない場合はエラー | 常時 |
| BR-02 | デフォルトリーダー | g:spacevim_leader未設定時はSpaceキー | 常時 |
| BR-03 | デフォルトローカルリーダー | g:spacevim_localleader未設定時はカンマ | 常時 |
| BR-04 | UserInit実行タイミング | plug#begin()とplug#end()の間で実行 | UserInit関数が定義されている場合 |
| BR-05 | UserConfig実行タイミング | レイヤーconfig.vim読み込み後に実行 | UserConfig関数が定義されている場合 |
| BR-06 | Layers後方互換性 | Layers()関数も呼び出される（存在する場合） | 後方互換性維持 |

### 計算ロジック

該当なし

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 設定エラー | ~/.spacevimファイルが存在しない | エラーメッセージ表示 |
| - | Sourceエラー | ~/.spacevimファイルの構文エラー | Vim標準のエラーハンドリング |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ~/.spacevimファイルの読み込みは高速（通常は数ミリ秒）
- UserInit()/UserConfig()の実行時間はユーザー定義の処理に依存

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

- ~/.spacevimファイルは任意のVimScriptを実行可能
- 信頼できる内容のみ記述すること
- 第三者が提供する.spacevimファイルは使用前に内容を確認すること

## 備考

- init.spacevimが~/.spacevimのテンプレートとして提供される
- space-vimのアップデート時に~/.spacevimは上書きされない

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

設定カスタマイズで使用されるグローバル変数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | init.spacevim | `init.spacevim` | ユーザー設定可能な変数とその形式 |

**読解のコツ**: init.spacevimはテンプレートファイルで、以下の設定項目を含む:
- `g:spacevim_plug_home`: プラグインインストールディレクトリ
- `g:spacevim_leader`: リーダーキー
- `g:spacevim_localleader`: ローカルリーダーキー
- `g:spacevim_layers`: 有効化するレイヤーのリスト
- `g:spacevim_enable_true_color`: TrueColor有効化
- `g:spacevim_nerd_fonts`: Nerdフォント使用

#### Step 2: 設定ファイル読み込み処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | spacevim.vim | `core/autoload/spacevim.vim` | s:check_dot_spacevim()の処理 |

**主要処理フロー**:
- **17行目**: s:dot_spacevimを$HOME.'/.spacevim'と定義
- **56-65行目**: s:check_dot_spacevim()
  - **57行目**: ファイル存在確認
  - **58行目**: ファイルをSource実行
  - **59行目**: g:spacevim_layersをg:spacevim.loadedに追加
  - **60行目**: g:spacevim_leaderからg:mapleader設定（デフォルト: Space）
  - **61行目**: g:spacevim_localleaderからg:maplocalleader設定（デフォルト: ,）
  - **63行目**: ファイル不存在時はエラー表示

#### Step 3: UserInit/UserConfig呼び出しを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | spacevim.vim | `core/autoload/spacevim.vim` | spacevim#end()内のUserInit/UserConfig呼び出し |

**主要処理フロー**:
- **155-174行目**: s:register_plugin()
  - **172行目**: UserInit()呼び出し（存在する場合）- plug#begin()とplug#end()の間
- **137-152行目**: spacevim#end()
  - **139行目**: Layers()呼び出し（後方互換性）
  - **146行目**: UserConfig()呼び出し（存在する場合）- config.vim読み込み後

#### Step 4: テンプレートファイルの構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | init.spacevim | `init.spacevim` | .spacevimファイルの標準構造 |

**主要処理フロー**:
- **3行目**: g:spacevim_plug_home設定
- **6行目**: g:spacevim_leader設定（コメントアウト）
- **9行目**: g:spacevim_localleader設定（コメントアウト）
- **13-15行目**: g:spacevim_layers設定
- **18行目**: g:spacevim_enable_true_color設定（コメントアウト）
- **21行目**: g:spacevim_nerd_fonts設定（コメントアウト）
- **30-35行目**: UserInit()関数定義（プラグイン追加用）
- **38-49行目**: UserConfig()関数定義（設定オーバーライド用）

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

```
spacevim#begin()  [core/autoload/spacevim.vim:32]
    │
    └─ s:check_dot_spacevim()  [core/autoload/spacevim.vim:56]
           │
           ├─ s:Source(~/.spacevim)
           │      └─ ~/.spacevimファイルを実行
           │             ├─ g:spacevim_layers 定義
           │             ├─ g:spacevim_leader 定義（オプション）
           │             ├─ g:spacevim_localleader 定義（オプション）
           │             ├─ UserInit() 定義
           │             └─ UserConfig() 定義
           │
           ├─ extend(g:spacevim.loaded, g:spacevim_layers)
           │
           ├─ g:mapleader 設定
           │
           └─ g:maplocalleader 設定

spacevim#end()  [core/autoload/spacevim.vim:137]
    │
    ├─ Layers()  [~/.spacevim（オプション、後方互換性）]
    │
    ├─ s:register_plugin()  [core/autoload/spacevim.vim:155]
    │      │
    │      ├─ plug#begin()
    │      ├─ レイヤーpackages.vim読み込み
    │      ├─ UserInit()  [~/.spacevim]  ←ここでプラグイン追加
    │      └─ plug#end()
    │
    ├─ s:config()  [レイヤーconfig.vim読み込み]
    │
    └─ UserConfig()  [~/.spacevim]  ←ここで設定オーバーライド
```

### データフロー図

```
[入力]                          [処理]                         [出力]

~/.spacevim
  │
  ├─ g:spacevim_layers ──────▶ s:check_dot_spacevim() ──────▶ g:spacevim.loaded
  │                                   │
  ├─ g:spacevim_leader ──────────────▶│──────────────────────▶ g:mapleader
  │                                   │
  ├─ g:spacevim_localleader ─────────▶│──────────────────────▶ g:maplocalleader
  │                                   │
  ├─ g:spacevim_excluded ────────────▶│──────────────────────▶ g:spacevim.excluded
  │
  ├─ UserInit() ──────────────────────────────────────────────▶ 追加プラグイン登録
  │    └─ Plug 'user/plugin'                                    （vim-plug経由）
  │
  └─ UserConfig() ────────────────────────────────────────────▶ Vim設定オーバーライド
       └─ set xxx=yyy
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| spacevim.vim | `core/autoload/spacevim.vim` | ソース | 設定読み込み・コールバック呼び出し |
| init.spacevim | `init.spacevim` | テンプレート | ~/.spacevimのテンプレート |
| util.vim | `core/autoload/spacevim/util.vim` | ソース | エラーメッセージ表示（spacevim#util#err） |
| .spacevim | `~/.spacevim` | ユーザー設定 | ユーザー独自の設定ファイル |
