# 機能設計書 68-ctags

## 概要

本ドキュメントは、space-vimにおけるctags機能の設計について記載する。vim-gutentagsプラグインによるタグファイルの自動生成・更新機能を提供する。

### 本機能の処理概要

ctags機能は、ソースコードからタグファイル（シンボル定義情報のインデックス）を自動的に生成・更新する機能を提供する。ファイル保存時や新規ファイル作成時に自動的にタグを更新し、コードナビゲーション（定義ジャンプ等）を高速化する。

**業務上の目的・背景**：大規模プロジェクトでは、関数やクラスの定義位置を探すのに時間がかかる。ctagsはソースコード内のシンボル（関数、クラス、変数等）の定義位置をインデックス化し、`Ctrl-]`や`:tag`コマンドで即座にジャンプできるようにする。vim-gutentagsは、このタグファイルを自動的に生成・更新することで、手動管理の手間を省く。

**機能の利用シーン**：
- 関数やクラスの定義位置にジャンプしたい場合
- 大規模プロジェクトでコードナビゲーションを効率化したい場合
- タグファイルの手動更新を省略したい場合
- C/C++プロジェクトで定義ジャンプを使用する場合

**主要な処理内容**：
1. プロジェクトルートの自動検出
2. ファイル保存時にタグファイルを自動更新
3. タグファイルをキャッシュディレクトリに保存
4. gtags-cscope連携（インストール済みの場合）

**関連システム・外部連携**：
- ludovicchabant/vim-gutentags プラグイン
- ctags/universal-ctags（外部ツール）
- gtags-cscope（オプション、インストール済みの場合）
- space-vimの+tools/ctagsレイヤーとして提供

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | Tagbar（タグバー） | 補助機能 | vim-gutentagsによる自動タグ生成との連携 |

## 機能種別

バックグラウンド処理 / インデックス生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g:gutentags_ctags_tagfile | String | No | タグファイル名（デフォルト: `.tags`） | 有効なファイル名 |
| g:gutentags_modules | List | No | 使用するモジュール（ctags, gtags_cscope等） | 有効なモジュール名 |
| g:gutentags_cache_dir | String | No | キャッシュディレクトリ | 有効なディレクトリパス |

### 入力データソース

- ソースコードファイル（C/C++ファイル）
- プロジェクトルートの検出（.git, Makefileなど）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タグファイル | ファイル | シンボル定義情報のインデックス |
| GTAGSファイル | ファイル | gtags形式のインデックス（gtags使用時） |

### 出力先

- `~/.cache/tags/` ディレクトリ
- プロジェクトルート（設定による）

## 処理フロー

### 処理シーケンス

```
1. プロジェクトルート検出
   └─ .git, Makefile等からプロジェクトルートを特定

2. ファイルイベント検出
   └─ BufWritePost, BufEnter等のイベントをトリガー

3. タグ生成処理開始
   └─ バックグラウンドでctagsを実行

4. タグファイル更新
   └─ キャッシュディレクトリにタグファイルを保存

5. タグファイル読み込み
   └─ set tags設定により自動的に読み込み
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル保存/オープン] --> B[プロジェクトルート検出]
    B --> C{プロジェクト内?}
    C -->|Yes| D[タグ更新が必要か判定]
    C -->|No| E[処理終了]
    D --> F{更新必要?}
    F -->|Yes| G[バックグラウンドでctags実行]
    F -->|No| E
    G --> H[タグファイル生成]
    H --> I[キャッシュディレクトリに保存]
    I --> J[タグファイル読み込み]
    J --> E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | タグファイル名 | デフォルトは`.tags`（ドットファイル） | g:gutentags_ctags_tagfile設定 |
| BR-02 | キャッシュディレクトリ | `~/.cache/tags/`に保存 | g:gutentags_cache_dir設定 |
| BR-03 | gtags連携 | gtags-cscopeがインストール済みの場合は自動連携 | gtags-cscopeが利用可能な場合 |
| BR-04 | C/C++ファイルで有効 | C/C++ファイルでのみ自動ロード | `{ 'for': ['c', 'cpp'] }`設定 |

### 計算ロジック

特になし（ctagsコマンドによる処理）

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

該当なし（ファイルベースのインデックス生成）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ctags未インストール | ctagsがシステムにインストールされていない | プラグインが機能しない |
| - | 権限エラー | キャッシュディレクトリに書き込み権限がない | ディレクトリを作成または権限を付与 |

### リトライ仕様

次回ファイル保存時に自動リトライ

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

該当なし（ファイル操作のみ）

## パフォーマンス要件

- バックグラウンド処理のため、Vim操作を妨げない
- 差分更新により、大規模プロジェクトでも高速

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

特になし

## 備考

- vim-gutentagsはC/C++ファイルに対してのみ自動ロードされる
- キャッシュディレクトリが存在しない場合は自動作成
- Universal Ctagsの使用が推奨される

---

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

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

### 推奨読解順序

#### Step 1: プラグイン登録を理解する

vim-gutentagsプラグインの登録を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | packages.vim | `layers/+tools/ctags/packages.vim` | vim-gutentagsの登録を確認 |

**読解のコツ**: C/C++ファイルでのみ自動ロードされる設定になっている。

**主要処理フロー**:
1. **1行目**: `MP 'ludovicchabant/vim-gutentags', { 'for': ['c', 'cpp'] }` - C/C++ファイル向け遅延ロード
2. **2行目**: `autocmd! User vim-gutentags call spacevim#autocmd#gutentags#Init()` - 初期化関数の登録

#### Step 2: 初期化処理を理解する

vim-gutentagsの初期化設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gutentags.vim | `core/autoload/spacevim/autocmd/gutentags.vim` | 設定の詳細を確認 |

**主要処理フロー**:
- **1行目**: `let s:modules = ['ctags']` - デフォルトモジュール
- **3-5行目**: gtags-cscope利用可能時のモジュール追加
  - **3行目**: `if executable('gtags-cscope') && executable('gtags')` - gtagsの存在確認
  - **4行目**: `let s:modules += ['gtags_cscope']` - モジュール追加
- **7-11行目**: キャッシュディレクトリ設定
  - **7行目**: `let s:vim_tags = expand('~/.cache/tags')` - キャッシュパス
  - **9-11行目**: ディレクトリ自動作成
- **13行目**: `let g:spacevim#vim#ctags#cache_dir = s:vim_tags` - 変数エクスポート
- **15-30行目**: `spacevim#autocmd#gutentags#Init()`関数
  - **16行目**: `let g:gutentags_ctags_tagfile = '.tags'` - タグファイル名
  - **18行目**: `set tags=./.tags;,.tags` - tagsファイルの検索パス
  - **20-22行目**: ctagsの追加オプション設定
  - **24行目**: `let g:gutentags_modules = s:modules` - モジュール設定
  - **27行目**: `let g:gutentags_cache_dir = s:vim_tags` - キャッシュディレクトリ
  - **29行目**: `let g:gutentags_auto_add_gtags_cscope = 0` - gtags自動追加無効

#### Step 3: レイヤー構成を確認する

ctagsレイヤーの全体構成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.vim | `layers/+tools/ctags/config.vim` | 追加設定の有無を確認 |

**主要処理フロー**:
- ファイルが空であり、追加設定は存在しない

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

```
C/C++ファイルオープン
    │
    └─ vim-plug による遅延ロード
           │
           └─ vim-gutentags ロード
                  │
                  └─ autocmd User vim-gutentags
                         │
                         └─ spacevim#autocmd#gutentags#Init()
                                │
                                ├─ g:gutentags_ctags_tagfile = '.tags'
                                │
                                ├─ set tags=./.tags;,.tags
                                │
                                ├─ g:gutentags_ctags_extra_args 設定
                                │      ├─ --fields=+niazS
                                │      ├─ --extra=+q
                                │      ├─ --c++-kinds=+px
                                │      └─ --c-kinds=+px
                                │
                                ├─ g:gutentags_modules 設定
                                │      ├─ ctags
                                │      └─ gtags_cscope (利用可能時)
                                │
                                └─ g:gutentags_cache_dir = ~/.cache/tags
```

### データフロー図

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

ソースコード             vim-gutentags                  タグファイル
(C/C++)           ───▶   プラグイン処理    ───▶         (.tags)
    +                          │
ファイル保存                   ▼
                         ctags コマンド
                         (バックグラウンド)
                              │
                              ▼
                         ~/.cache/tags/
                         ディレクトリに保存

タグファイル             Vim                            定義ジャンプ
(.tags)           ───▶   Ctrl-] / :tag     ───▶         シンボル定義位置
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| packages.vim | `layers/+tools/ctags/packages.vim` | 設定 | プラグイン登録 |
| config.vim | `layers/+tools/ctags/config.vim` | 設定 | 追加設定（空） |
| gutentags.vim | `core/autoload/spacevim/autocmd/gutentags.vim` | ソース | 初期化設定 |
| LAYERS.md | `layers/LAYERS.md` | ドキュメント | レイヤー一覧 |
| vim-gutentags | 外部プラグイン（ludovicchabant/vim-gutentags） | プラグイン | タグ自動生成機能 |
