# 画面設計書 18-Terminal（ターミナル画面）

## 概要

本ドキュメントは、space-vimにおけるTerminal（ターミナル画面）の設計を記述したものである。Vim 8.1+/Neovimの内蔵ターミナルエミュレータ機能をspace-vimがラップして提供するターミナル画面について、その構成・機能・操作方法を詳細に解説する。

### 本画面の処理概要

Terminal画面は、Vimエディタ内でシェルコマンドを実行するためのターミナルエミュレータウィンドウである。エディタを離れることなくシェル操作やコマンド実行が可能となり、開発ワークフローの効率化を実現する。Vim 8.1+の`term_start()`およびNeovimの`termopen()`を使用して実装されている。

**業務上の目的・背景**：開発作業において、コード編集とシェル操作は密接に関連している。従来は、エディタとターミナルを別ウィンドウで開き、切り替えながら作業する必要があった。Terminal画面は、Vim内でターミナルを開くことで、コンテキストスイッチを最小化し、編集とコマンド実行のシームレスな統合を実現する。

**画面へのアクセス方法**：
- `SPC '` - ターミナルを起動
- `:terminal` - Vimビルトインコマンドでターミナルを起動
- `spacevim#vim#term#Open()` - プログラマブルにターミナルを開く

**主要な操作・処理内容**：
1. **ターミナル起動**：新しいターミナルバッファを開く
2. **コマンド実行**：シェルコマンドの実行
3. **入出力操作**：標準入出力のインタラクション
4. **ターミナルモード切替**：ターミナルモードとノーマルモードの切り替え
5. **ウィンドウ管理**：垂直分割でターミナルを表示

**画面遷移**：
- エディタ画面 → Terminal画面（`SPC '`）
- Terminal画面 → エディタ画面（`exit`コマンドまたは`q`キー）

**権限による表示制御**：本画面に権限による表示制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 67 | 非同期実行 | 主機能 | Vim内蔵ターミナルエミュレータによるコマンド実行 |
| 86 | Neovim API | 補助機能 | Neovim固有のtermopen APIによるターミナル制御 |

## 画面種別

ターミナルエミュレータ画面

## URL/ルーティング

Vimコマンド/キーバインドによるアクセス：
- `SPC '` - ターミナル起動（space-vim独自）
- `:terminal` - Vimビルトインターミナル
- `:call spacevim#vim#term#Open({'cmd': 'bash'})` - プログラマブル起動

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| コマンド | 入力 | 文字列 | 実行するシェルコマンド |
| カレントディレクトリ | 入力 | 文字列 | ターミナルの作業ディレクトリ |
| 標準出力 | 出力 | テキスト | コマンドの実行結果 |
| 終了コード | 出力 | 数値 | コマンドの終了ステータス |

## 表示項目

### ターミナルウィンドウ

| 表示項目 | データ型 | 説明 |
|----------|----------|------|
| プロンプト | 文字列 | シェルプロンプト |
| コマンド出力 | テキスト | 実行結果の出力 |
| カーソル | 位置 | 入力位置を示すカーソル |

### ウィンドウ設定

| 設定項目 | 値 | 説明 |
|----------|---|------|
| nonumber | true | 行番号非表示 |
| norelativenumber | true | 相対行番号非表示 |
| nowrap | true | 折り返しなし |
| nobuflisted | true | バッファリストに表示しない |
| winfixwidth | true | ウィンドウ幅固定 |
| winfixheight | true | ウィンドウ高さ固定 |

## イベント仕様

### 1-ターミナル起動

`SPC '`または`spacevim#vim#term#Open()`でターミナルを起動する。

```
[ユーザー操作] SPC ' 押下
        ↓
[spacevim] spacevim#vim#term#Open()呼び出し
        ↓
[term.vim] 終了済みターミナルバッファをクリーンアップ
        ↓
[term.vim] vertical belowright new（垂直分割で新ウィンドウ）
        ↓
[term.vim] setlocal（各種オプション設定）
        ↓
[Vim/Neovim] term_start() / termopen()
        ↓
[画面表示] ターミナルバッファが表示される
```

### 2-コマンド実行

ターミナルウィンドウでシェルコマンドを入力・実行する。

```
[ユーザー操作] コマンド入力 → Enter
        ↓
[シェル] コマンド実行
        ↓
[ターミナル] 標準出力をバッファに表示
        ↓
[画面更新] 出力結果が表示される
```

### 3-ターミナル終了

`exit`コマンドまたは`q`キーでターミナルを閉じる。

```
[ユーザー操作] exit入力 または qキー押下
        ↓
[Vim/Neovim] ジョブ終了検出（on_exit / job_status）
        ↓
[画面更新] ターミナルウィンドウが閉じる
```

### 4-システムコマンド実行

`spacevim#vim#term#System()`で一時ウィンドウにコマンド結果を表示する。

```
[呼び出し] spacevim#vim#term#System(cmd)
        ↓
[term.vim] スクラッチウィンドウをクリア
        ↓
[term.vim] system()またはredirでコマンド実行
        ↓
[term.vim] 結果を新しいスクラッチウィンドウに表示
```

## データベース更新仕様

本画面は表示・コマンド実行専用であり、直接的なデータベース更新は行わない。実行されるシェルコマンドに依存する。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| TERM001 | 情報 | [Process exited N] | ジョブ終了時（Neovim） |
| TERM002 | 情報 | [終了] | ジョブ終了時（Vim） |

## 例外処理

| 例外状態 | 対処 | ユーザーへの通知 |
|---------|------|-----------------|
| 空のコマンド | ターミナル起動をスキップ | return（静かに終了） |
| ジョブ終了 | バッファをwipeout | 自動クリーンアップ |
| シェル未設定 | デフォルトシェルを使用 | 特になし |

## 備考

- Vim 8.1+の`:terminal`機能およびNeovimの`termopen()`を使用
- space-vimでは`spacevim#vim#term#Open()`関数でラップして提供
- VimとNeovimで異なるAPI（term_start vs termopen）を内部で切り替え
- 終了済みターミナルバッファは次回起動時に自動クリーンアップ
- 垂直分割（vertical belowright）でターミナルウィンドウを開く

---

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

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

### 推奨読解順序

#### Step 1: ターミナル関数の実装を理解する

まず、space-vimのターミナル機能の中核である関数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | term.vim | `core/autoload/spacevim/vim/term.vim` | ターミナル操作関数群 |

**読解のコツ**: Vim 8.xとNeovimで異なるAPIを使用しているため、`has('nvim')`による分岐に注目する。

**主要処理フロー**:
1. **1-5行目**: スクリプト変数の初期化（termbuf管理、jobs辞書）
2. **8-85行目**: `spacevim#vim#term#Open(opts)`関数
   - **10-38行目**: 終了済みターミナルバッファのクリーンアップ
   - **40-57行目**: 新ウィンドウ作成とオプション設定
   - **66-79行目**: Neovim: `termopen()`、Vim: `term_start()`の分岐
   - **81行目**: `nnoremap <silent> q :q<CR>` - qキーで閉じる
3. **89-92行目**: `spacevim#vim#term#Run(...)`関数 - コマンド実行ラッパー
4. **96-113行目**: `spacevim#vim#term#System(cmd)`関数 - システムコマンド実行

#### Step 2: ウィンドウ設定を理解する

ターミナルウィンドウに適用される各種設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | term.vim | `core/autoload/spacevim/vim/term.vim` | setlocal設定（41-57行目） |

**主要処理フロー**:
1. **41-57行目**: ターミナルバッファ用のローカル設定
   - `nonumber` / `norelativenumber` - 行番号非表示
   - `nolist` / `nowrap` - リスト表示なし、折り返しなし
   - `winfixwidth` / `winfixheight` - サイズ固定
   - `nobuflisted` - バッファリストから除外

#### Step 3: Neovim/Vim APIの違いを理解する

Neovimとvim 8.xで異なるターミナルAPIを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | term.vim | `core/autoload/spacevim/vim/term.vim` | API分岐（66-79行目） |

**主要処理フロー**:
- **66-72行目（Neovim）**: `termopen(cmd, {'cwd': cwd, 'on_exit': ...})`
- **74-78行目（Vim）**: `term_start(cmd, {'curwin': 1})`

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

```
SPC ' 押下
    │
    └─ spacevim#vim#term#Open({'cmd': 'bash'})
           │
           ├─ 終了済みバッファのクリーンアップ
           │      ├─ Neovim: s:closed リストを処理
           │      └─ Vim: term_list()で終了チェック
           │
           ├─ vertical belowright new
           │
           ├─ setlocal（各種オプション）
           │
           └─ ターミナル起動
                  ├─ Neovim: termopen()
                  │      └─ on_exit コールバック登録
                  │
                  └─ Vim: term_start()

spacevim#vim#term#Run('git', 'status')
    │
    └─ spacevim#vim#term#Open({'cmd': ['git', 'status']})

spacevim#vim#term#System('ls -la')
    │
    ├─ スクラッチウィンドウをクローズ
    ├─ system() または redir で実行
    └─ vnew でスクラッチウィンドウに出力
```

### データフロー図

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

SPC ' ───────────▶ term.vim ────────────▶ ターミナルウィンドウ
                          │
                          ├─▶ term_start() / termopen()
                          │
                          └─▶ シェルプロセス起動

コマンド入力 ───▶ シェル ─────────────▶ 標準出力表示
                          │
                          └─▶ バッファに書き込み

exit ───────────▶ シェル ─────────────▶ ジョブ終了
                          │
                          └─▶ on_exit / job_status
                                 └─▶ バッファクリーンアップ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| term.vim | `core/autoload/spacevim/vim/term.vim` | ソース | ターミナル操作関数群 |
| 画面一覧.csv | `docs/code-to-docs/画面一覧/画面一覧.csv` | データ | 画面No.18の定義 |
| 画面遷移図.md | `docs/code-to-docs/画面一覧/画面遷移図.md` | ドキュメント | 画面遷移の定義（33,40行目） |
