# 画面設計書 31-設定変更

## 概要

本ドキュメントは、Lua Language ServerのLSPコマンド「設定変更（lua.setConfig）」の画面設計書です。

### 本画面の処理概要

この画面（LSPコマンド）は、エディタからLua Language Serverの設定を動的に変更するための機能を提供します。

**業務上の目的・背景**：
開発者がエディタ上でLuaコードを編集する際、診断レベル、ワークスペース設定、補完オプションなど、Language Serverの動作を制御する様々な設定を変更する必要があります。本コマンドは、これらの設定をエディタから直接変更可能にし、ユーザーが設定ファイルを手動で編集することなく、リアルタイムで設定を反映できるようにします。特に、自動require機能の有効化/無効化、ライブラリパスの追加など、頻繁に変更される設定を効率的に管理できます。

**画面へのアクセス方法**：
本コマンドは、以下の方法でトリガーされます：
- LSPクライアント（VS Code等）からの `workspace/executeCommand` リクエストで `lua.setConfig` コマンドを実行
- 他のLSP機能（補完、コードアクション等）からの内部呼び出し
- エディタの設定変更UIからの間接的な呼び出し

**主要な操作・処理内容**：
1. クライアントの準備完了を待機（client:isReady()）
2. 設定変更要求（config.change[]）を受信
3. client.setConfig()を呼び出して設定を適用
4. メモリ上の設定を更新（config.set/add/prop）
5. 必要に応じて設定ファイル（.luarc.json等）に永続化
6. クライアントへの通知（$/command）を送信

**画面遷移**：
- 入力元：コード補完機能（自動require無効化時）、FFIメタデータ再読込機能、その他のLSP機能
- 出力先：設定変更完了後、元の処理に復帰

**権限による表示制御**：
設定変更は、ワークスペーススコープまたはグローバルスコープで適用されます。クライアントが `changeConfiguration` オプションをサポートしていない場合、ファイルベースの設定変更が試行されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 72 | 設定管理 | 主機能 | Lua設定を変更するコマンド処理 |
| 73 | 設定ローダー | 補助機能 | 設定ファイルの読み込み処理 |

## 画面種別

LSPコマンド（非同期処理）

## URL/ルーティング

- LSPコマンド名: `lua.setConfig`
- プロトコル: `workspace/executeCommand`
- ハンドラファイル: `script/core/command/setConfig.lua`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| changes | config.change[] | Yes | 設定変更の配列 |

### config.change構造

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| key | string | Yes | 設定キー（例: `Lua.completion.autoRequire`） |
| action | "add"\|"set"\|"prop" | Yes | 変更アクション種別 |
| value | any | Yes | 設定する値 |
| uri | uri | No | 対象ファイルのURI（スコープ特定用） |
| prop | string | No | プロパティ名（action="prop"時） |
| global | boolean | No | グローバル設定として適用するか |

### 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 本コマンドは戻り値を返さない |

## 表示項目

本機能はコマンド処理であり、直接的なUI表示項目はありません。ただし、設定変更失敗時にはクライアントへメッセージを送信します。

## イベント仕様

### 1-設定変更実行

1. **リクエスト受信**: クライアントから `workspace/executeCommand` でコマンドを受信
2. **準備待機**: クライアントの準備完了（client:isReady()）を待機
3. **設定適用**: client.setConfig()を呼び出し
4. **メモリ更新**: config.set/add/propでメモリ上の設定を更新
5. **永続化試行**: 以下の順序で設定ファイルへの書き込みを試行
   - 指定された設定ファイル（CONFIGPATH）
   - .luarc.jsonc / .luarc.json
   - クライアント経由での変更
6. **結果通知**: 変更完了または失敗メッセージを送信

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

### 操作別データベース影響一覧

本機能はデータベースを使用しませんが、以下のファイル/メモリへの影響があります：

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| 設定変更 | scope.config.now | UPDATE | メモリ上の現在設定を更新 |
| 設定変更 | scope.config.raw | UPDATE | メモリ上の生設定を更新 |
| 設定変更 | .luarc.json | UPDATE | ワークスペース設定ファイルを更新 |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|---------|--------------|
| CONFIG_LOAD_FAILED | Error | 設定ファイル読み込み失敗 | 設定ファイルの読み込みに失敗しました |
| CONFIG_MODIFY_FAIL_SYNTAX_ERROR | Error | JSON構文エラー | 設定ファイルの構文エラー |
| CONFIG_MODIFY_FAIL | Warning | 自動設定変更失敗 | 手動での設定変更が必要 |
| CONFIG_MODIFY_FAIL_NO_WORKSPACE | Warning | ワークスペースなし | ワークスペースが開かれていません |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| クライアント未準備 | 0.1秒間隔でリトライ |
| 設定キー不明 | assertでエラー発生 |
| 設定ファイル読み込み失敗 | エラーメッセージを表示し処理中断 |
| JSON構文エラー | エラーメッセージを表示し処理中断 |
| クライアント設定変更非対応 | ファイルベースの変更を試行 |

## 備考

- 設定変更は即座にLanguage Serverの動作に反映されます
- config.watchに登録されたコールバックが設定変更時に呼び出されます
- グローバル設定とワークスペース設定は独立して管理されます

---

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

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

### 推奨読解順序

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

まず、設定変更で使用されるデータ構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | client.lua | `script/client.lua` | config.change型の定義（202-208行目）を確認 |
| 1-2 | config.lua | `script/config/config.lua` | 設定の内部表現（scopeベースの管理）を理解 |

**読解のコツ**: `config.change`は`key`, `action`, `value`, `uri`などのフィールドを持つテーブルです。`action`は"add"/"set"/"prop"の3種類があります。

#### Step 2: エントリーポイントを理解する

コマンドの起点となるファイルを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | setConfig.lua | `script/core/command/setConfig.lua` | コマンドのメイン処理（6-11行目） |

**主要処理フロー**:
1. **7-9行目**: クライアントの準備完了を待機
2. **10行目**: client.setConfig()を呼び出し

#### Step 3: 設定変更処理を理解する

client.setConfig()の内部実装を追跡します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | client.lua | `script/client.lua` | setConfig関数（522-572行目）の実装 |

**主要処理フロー**:
- **524-540行目**: action種別に応じてconfig.add/set/propを呼び出し
- **549-571行目**: 設定ファイルへの永続化を試行

#### Step 4: 永続化処理を理解する

設定ファイルへの書き込み処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | client.lua | `script/client.lua` | tryModifyRC関数（407-445行目） |
| 4-2 | client.lua | `script/client.lua` | editConfigJson関数（337-359行目） |

**主要処理フロー**:
- **407-418行目**: .luarc.json/.luarc.jsoncファイルのパスを解決
- **337-359行目**: JSON編集ライブラリでパッチを適用

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

```
workspace/executeCommand (lua.setConfig)
    │
    └─ setConfig.lua (エントリーポイント)
           │
           ├─ await.sleep() (クライアント準備待機)
           │
           └─ client.setConfig(changes)
                  │
                  ├─ config.add() / config.set() / config.prop()
                  │      └─ config.event() (変更通知)
                  │
                  ├─ tryModifyClientGlobal()
                  │      └─ proto.notify('$/command')
                  │
                  ├─ tryModifySpecifiedConfig()
                  │      └─ editConfigJson()
                  │
                  ├─ tryModifyRC()
                  │      └─ editConfigJson()
                  │             └─ jsone.edit() (JSON編集)
                  │
                  └─ tryModifyClient()
                         └─ proto.notify('$/command')
```

### データフロー図

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

config.change[] ───▶ setConfig.lua ───▶ (なし)
                           │
                           ▼
                     client.setConfig()
                           │
                    ┌──────┴──────┐
                    ▼             ▼
             メモリ更新     ファイル更新
             (config.set)   (.luarc.json)
                    │             │
                    ▼             ▼
             config.event()  util.saveFile()
                    │
                    ▼
             watchCallback()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| setConfig.lua | `script/core/command/setConfig.lua` | ソース | コマンドエントリーポイント |
| client.lua | `script/client.lua` | ソース | 設定変更の主処理 |
| config.lua | `script/config/config.lua` | ソース | 設定管理モジュール |
| template.lua | `script/config/template.lua` | ソース | 設定項目のテンプレート定義 |
| scope.lua | `script/workspace/scope.lua` | ソース | スコープ管理 |
| json-edit.lua | `script/json-edit.lua` | ソース | JSON編集ユーティリティ |
| proto.lua | `script/proto.lua` | ソース | LSPプロトコル通信 |
