# アーキテクチャ設計書

## 概要

本ドキュメントは、space-vim（Vim/NeoVim向けのモジュラーなディストリビューション）のアーキテクチャ設計を記述したものである。space-vimはspacemacsにインスパイアされたVim設定フレームワークであり、レイヤーベースのプラグイン管理システムとニーモニックキーバインディングを特徴とする。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図.md](./アーキテクチャ構成図.md) を参照。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| vim-plug | Vimプラグインマネージャー | プラグインのインストール・管理 |
| GitHub | HTTPSダウンロード | プラグインリポジトリからの取得 |
| Vim/NeoVim | ランタイム環境 | Vimスクリプト実行環境 |
| シェル環境 | シェルスクリプト | インストール・アンインストール処理 |

## レイヤー構成

### アーキテクチャスタイル

**レイヤードアーキテクチャ + プラグインアーキテクチャ**

space-vimは、spacemacsの設計思想を踏襲したレイヤーベースのモジュラーアーキテクチャを採用している。各機能はトピック別にグループ化されたレイヤーとして構成され、ユーザーは必要なレイヤーのみを有効化できる。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Bootstrap Layer | 初期化・起動処理 | `init.vim`, `spacevim#bootstrap()` |
| Core Layer | コア機能・ユーティリティ | `core/autoload/spacevim.vim`, `core/autoload/spacevim/` |
| Plugin Layer | vim-plug連携・プラグイン管理 | `spacevim#vim#plug`, プラグイン登録・読み込み |
| Cache Layer | キャッシュ・マニフェスト管理 | `spacevim#cache`, `info.vim` |
| Feature Layers | 機能別レイヤー群 | `layers/+*` 配下の各レイヤー |
| Private Layer | ユーザーカスタマイズ | `private/`, `.spacevim` |

### レイヤー間の依存関係ルール

1. **Bootstrap → Core**: 初期化処理はコアレイヤーに依存
2. **Core → Plugin**: プラグイン管理はvim-plug連携に依存
3. **Feature → Core**: 全ての機能レイヤーはコアレイヤーに依存
4. **Private → Feature/Core**: プライベートレイヤーは全レイヤーをオーバーライド可能
5. **循環参照禁止**: レイヤー間の循環依存は禁止

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| +checkers | 構文チェック・Lint | syntax-checking |
| +completion | 自動補完 | asyncomplete, auto-completion, deoplete, unite |
| +distributions | ベースディストリビューション | better-defaults, spacevim |
| +fun | エンターテインメント | emoji, games, goyo |
| +lang | 言語別サポート | c-c++, python, javascript, go, rust等（22言語） |
| +misc | その他機能 | chinese |
| +programming | プログラミング支援 | code-snippets, editing, formatting, programming |
| +themes | テーマ・外観 | airline, lightline |
| +tools | 開発ツール | fzf, lsp, ctags, file-manager, tmux等 |
| +version-control | バージョン管理 | git, github |
| +vim | Vim拡張 | better-motion, ctrlp, text-align, which-key |

### パッケージ構造

```
space-vim/
├── init.vim                    # エントリーポイント
├── init.spacevim               # デフォルト設定テンプレート
├── install.sh                  # Bashインストーラー
├── install.cmd                 # Windowsインストーラー
├── uninstall.sh                # アンインストーラー
├── Makefile                    # Make用設定
├── core/                       # コアモジュール
│   ├── autoload/               # オートロード関数
│   │   ├── spacevim.vim        # メインエントリー
│   │   └── spacevim/           # サブモジュール
│   │       ├── api/            # API抽象化
│   │       ├── autocmd/        # Autocmd設定
│   │       ├── cache.vim       # キャッシュ管理
│   │       ├── defer.vim       # 遅延読み込み
│   │       ├── icons.vim       # アイコン定義
│   │       ├── lang/           # 言語サポート
│   │       ├── layer.vim       # レイヤー管理UI
│   │       ├── map/            # キーマッピング
│   │       ├── plug/           # プラグイン設定
│   │       ├── util.vim        # ユーティリティ
│   │       ├── vim/            # Vim固有機能
│   │       └── wrap/           # ラッパー関数
│   ├── doc/                    # ヘルプドキュメント
│   ├── ftdetect/               # ファイルタイプ検出
│   ├── ftplugin/               # ファイルタイプ別プラグイン
│   └── plugin/                 # プラグイン定義
├── layers/                     # 機能レイヤー
│   ├── LAYERS.md               # レイヤー一覧
│   ├── layers.py               # レイヤー情報生成スクリプト
│   ├── +checkers/              # 構文チェック
│   ├── +completion/            # 補完機能
│   ├── +distributions/         # ベース設定
│   ├── +fun/                   # エンターテインメント
│   ├── +lang/                  # 言語サポート
│   ├── +misc/                  # その他
│   ├── +programming/           # プログラミング支援
│   ├── +themes/                # テーマ
│   ├── +tools/                 # 開発ツール
│   ├── +version-control/       # バージョン管理
│   └── +vim/                   # Vim拡張
└── private/                    # ユーザープライベート設定
```

### コンポーネント依存関係

```
init.vim
    └── spacevim#bootstrap()
        ├── spacevim#begin()
        │   ├── s:check_vim_plug()    [vim-plug自動インストール]
        │   ├── s:define_command()    [コマンド定義]
        │   ├── s:cache()             [キャッシュ読み込み]
        │   └── s:check_dot_spacevim() [.spacevim読み込み]
        └── spacevim#end()
            ├── s:register_plugin()   [プラグイン登録]
            │   ├── plug#begin()
            │   ├── s:packages()      [レイヤーのpackages.vim]
            │   ├── UserInit()        [ユーザー初期化]
            │   └── plug#end()
            ├── s:config()            [レイヤーのconfig.vim]
            ├── UserConfig()          [ユーザー設定]
            └── spacevim#vim#plug#check() [不足プラグイン確認]
```

## ミドルウェア構成

### データベース

本プロジェクトはVim設定フレームワークであり、データベースは使用していない。

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| RDB | - | - | 該当なし |
| NoSQL | - | - | 該当なし |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| Vimスクリプトファイル | - | レイヤーマニフェストキャッシュ(`info.vim`) | 手動更新(`LayerCache`コマンド) |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| - | - | 該当なし |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| - | - | 該当なし |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| vim-plug | 最新版 | Vimプラグインマネージャー |
| Python (オプション) | 2.x/3.x | キャッシュ高速化 |
| curl | - | プラグインダウンロード |
| git | - | リポジトリ管理・プラグイン取得 |

## データフロー

### リクエスト処理の流れ

**Vim/NeoVim起動時のブートストラップシーケンス:**

1. `init.vim` が読み込まれる
2. `g:spacevim` グローバル変数の初期化（OS判定、バージョン情報等）
3. `runtimepath` に `core/` を追加
4. `spacevim#bootstrap()` を呼び出し
5. `spacevim#begin()`:
   - vim-plugの存在確認・自動ダウンロード
   - コマンド定義（`Layer`, `MP`, `LayerStatus`等）
   - キャッシュ読み込み（`info.vim`）
   - `.spacevim` 設定ファイル読み込み
6. `spacevim#end()`:
   - プラグイン登録（`plug#begin/end`）
   - 各レイヤーの`packages.vim`読み込み
   - `UserInit()` 実行（ユーザー定義プラグイン）
   - 各レイヤーの`config.vim`読み込み
   - `UserConfig()` 実行（ユーザー設定）
   - 不足プラグインの確認・インストール促進

### 非同期処理の流れ

**遅延プラグイン読み込み（タイマー/Autocmd）:**

1. `g:spacevim.timer` が有効な場合（Vim 8+/NeoVim）
2. `timer_start()` で1500ms後に不足プラグイン確認を実行
3. プラグインの`on_event`オプションによるイベント駆動読み込み
4. `augroup` を使用したAutocmdベースの遅延ロード

### データ永続化の流れ

**キャッシュの永続化:**

1. `LayerCache` コマンドまたは自動実行で`spacevim#cache#init()` が呼び出される
2. `layers/` ディレクトリをスキャンしてトピック・レイヤー構造を解析
3. Pythonが利用可能な場合はPythonで高速処理、そうでなければVimスクリプトで処理
4. `g:spacevim.manifest` と `g:spacevim.topics` をVimスクリプトとして `info.vim` に書き出し
5. 次回起動時はキャッシュから読み込むことで高速化

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| - | - | 該当なし（ローカルVim設定のため認証不要） |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| デバッグログ | `spacevim#debugging#Info()` | Vimバッファ出力 |
| プロファイリング | `spacevim#util#ProfileStart/Stop()` | `profile.log`, `verbose.log` |
| エラーメッセージ | `spacevim#util#err()` | Vim echoエリア |
| 警告メッセージ | `spacevim#util#warn()` | Vim echoエリア |

### エラーハンドリング

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| .spacevimファイル不在 | `spacevim#util#err()` | エラーメッセージ表示、処理中断 |
| キャッシュ読み込み失敗 | `try-catch` + 再生成 | キャッシュ自動再生成 |
| プラグイン不足 | ダイアログ/プロンプト | `PlugInstall`実行の確認 |
| レイヤー設定エラー | `try-catch` | エラーメッセージ表示、キャッシュ再生成 |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| - | - | 該当なし（データベース不使用） |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 関心の分離 | レイヤー構造 | 各レイヤーが `packages.vim` と `config.vim` で分離 |
| 単一責任原則 | モジュール分割 | `cache.vim`, `layer.vim`, `util.vim` 等の機能別分割 |
| 開放閉鎖原則 | プラグインシステム | 新レイヤー追加が既存コードに影響しない |
| 依存性逆転原則 | 抽象化層 | `spacevim#map#manager` による検索ツール抽象化 |
| Don't Repeat Yourself | ユーティリティ | `spacevim#util` に共通関数を集約 |

### コーディング規約

1. **Vimスクリプトコーディング規約**
   - スクリプト先頭に `scriptencoding utf-8` を記述
   - ローカル変数は `l:` プレフィックスを使用
   - スクリプトローカル変数は `s:` プレフィックスを使用
   - グローバル変数は `g:spacevim` オブジェクト配下に集約
   - 関数名は `spacevim#モジュール名#関数名` のネームスペース規約に従う

2. **レイヤー構成規約**
   - 各レイヤーは `packages.vim`（プラグイン定義）と `config.vim`（設定）を含む
   - レイヤーディレクトリ名がレイヤー名となる
   - トピック（`+`プレフィックス）でカテゴリ分類

3. **キーバインディング規約**
   - `<Space>` をリーダーキーとして使用
   - `,` をローカルリーダーキーとして使用
   - ニーモニックプレフィックス: `b`=buffer, `f`=file, `g`=git, `w`=window等

## 備考

- space-vimはVim 8.0以降またはNeoVimでの使用を推奨
- GUI環境とターミナル環境の両方をサポート
- Windows, macOS, Linuxのクロスプラットフォーム対応
- spacemacsのキーバインディング・UIを踏襲しつつ、Vimエコシステムとの親和性を重視
- 現在のバージョン: 0.9.0
