# 機能設計書 54-行幅（printWidth）

## 概要

本ドキュメントは、Prettierの`printWidth`オプションに関する機能設計書である。このオプションは、Prettierがコードを折り返す際の目標行長を指定する。Prettierはこの値を超えないように行を折り返そうとするが、必ずしも保証されるものではない。

### 本機能の処理概要

**業務上の目的・背景**：コードの可読性を維持するために、行長を一定に保つことは重要である。多くのプロジェクトでは80文字や100文字を標準として採用している。このオプションにより、プロジェクトのスタイルガイドに合わせた行長制御が可能になる。エディタの表示幅やターミナル幅に合わせた設定も可能。

**機能の利用シーン**：すべてのコードフォーマット時に使用される。特に、コードレビュー、CIパイプライン、エディタ統合において一貫した行長を維持するために重要である。

**主要な処理内容**：
1. オプション値（整数）の読み込み
2. Docプリンター処理でremainingWidthを計算
3. fits関数で現在の出力がprintWidth内に収まるかを判定
4. 収まらない場合はグループを展開（改行）

**関連システム・外部連携**：すべての言語パーサー・プリンターと連携して動作する。

**権限による制御**：権限による制御は存在しない。設定ファイルまたはCLIオプションで指定する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 補助機能 | サイドバーから行幅オプションを設定 |
| 19 | Configuration - Options | 主機能 | printWidthオプションの詳細説明 |

## 機能種別

設定オプション / フォーマット制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| printWidth | int | No | 目標行長（文字数） | 0以上の整数、デフォルト: 80 |

### 入力データソース

- 設定ファイル（.prettierrc、prettier.config.js等）
- CLIオプション（--print-width）
- プログラマティックAPI呼び出し時のオプションオブジェクト
- EditorConfigファイル（max_line_length）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| formattedCode | string | 行長制御が適用されたフォーマット済みコード |

### 出力先

フォーマット結果は呼び出し元に返却される（標準出力、ファイル、API戻り値）。

## 処理フロー

### 処理シーケンス

```
1. オプション解析
   └─ printWidthオプションの値を取得（デフォルト: 80）
2. Docツリー生成
   └─ ASTからDocツリーを生成
3. プリンター処理
   └─ printDocToString関数でDocを文字列に変換
4. fits判定
   └─ 各グループでremainingWidth（残り幅）を計算し、収まるか判定
5. 折り返し決定
   └─ 収まらない場合はMODE_BREAKを適用
6. 文字列出力
   └─ 最終的なフォーマット済み文字列を生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Docツリーを生成]
    B --> C[printDocToString開始]
    C --> D[グループを処理]
    D --> E{remainingWidth = printWidth - position}
    E --> F{fits判定}
    F -->|収まる| G[MODE_FLATで出力]
    F -->|収まらない| H[MODE_BREAKで出力]
    G --> I{次のグループあり?}
    H --> I
    I -->|Yes| D
    I -->|No| J[フォーマット済み文字列を返却]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-1 | デフォルト値 | 80文字を目標行長とする | printWidth未指定 |
| BR-54-2 | 目標値 | Prettierは厳密な最大値としてではなく目標として扱う | 常時 |
| BR-54-3 | 文字幅計算 | getStringWidthでUnicode対応の文字幅を計算 | 常時 |
| BR-54-4 | 無制限設定 | Number.POSITIVE_INFINITYで無制限に設定可能 | EditorConfig: max_line_length = off |
| BR-54-5 | 範囲 | 0から無限大まで設定可能 | 常時 |

### 計算ロジック

```
remainingWidth = options.printWidth - position
fits = fits(command, restCommands, remainingWidth, hasLineSuffix, groupModeMap)
```

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

データベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 型エラー | 整数以外の値が指定された場合 | Prettierのオプション検証でエラーが発生 |

### リトライ仕様

リトライは不要（同期的な設定適用処理）。

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

トランザクション管理は不要。

## パフォーマンス要件

fits判定は再帰的に行われるため、深くネストしたコードではパフォーマンスに影響する可能性がある。

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

セキュリティに関する特別な考慮事項は存在しない。

## 備考

- printWidthは厳密な最大値ではなく、目標値として扱われる。
- 文字列リテラルなど、分割できない要素はprintWidthを超える場合がある。
- EditorConfigのmax_line_lengthから自動的に設定される場合がある。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | core-options.evaluate.js | `src/main/core-options.evaluate.js` | printWidthオプションの定義 |

**読解のコツ**: このファイルでは、printWidthがint型でデフォルト80、範囲が0〜無限大であることを確認する。

#### Step 2: プリンターでの使用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | printer.js | `src/document/printer/printer.js` | printDocToString関数でのprintWidth使用 |

**主要処理フロー**:
1. **183行目**: `const width = options.printWidth;`でprintWidthを取得
2. **258行目**: `const remainingWidth = width - position;`で残り幅を計算
3. **265-271行目**: fits関数でremainingWidth内に収まるか判定
4. **53-60行目**: fits関数の定義、remainingWidthを使用して判定

#### Step 3: fits関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | printer.js | `src/document/printer/printer.js` | fits関数の実装詳細 |

**主要処理フロー**:
- **61-63行目**: remainingWidthがNumber.POSITIVE_INFINITYの場合は常にtrue
- **72行目**: `while (remainingWidth >= 0)`で残り幅がある間処理
- **94行目**: `remainingWidth -= getStringWidth(doc);`で文字幅を減算

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

```
printDocToString (printer.js)
    │
    ├─ options.printWidth 取得 (183行目)
    │
    ├─ remainingWidth 計算 (258行目)
    │      └─ width - position
    │
    └─ fits 判定 (265-271行目)
           ├─ remainingWidth をパラメータとして渡す
           ├─ getStringWidth で文字幅を計算
           └─ remainingWidth >= 0 で判定
```

### データフロー図

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

オプション設定 ───▶ printDocToString関数 ───▶ フォーマット済み文字列
(printWidth)           (printer.js)
        │
        ▼
        width ───▶ remainingWidth計算 ───▶ fits判定
               └─ width - position      └─ MODE_FLAT / MODE_BREAK
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| core-options.evaluate.js | `src/main/core-options.evaluate.js` | ソース | オプション定義（154-160行目） |
| printer.js | `src/document/printer/printer.js` | ソース | Doc出力処理、fits判定 |
| get-string-width.js | `src/utilities/get-string-width.js` | ソース | Unicode文字幅計算 |
| editorconfig-to-prettier.js | `src/config/editorconfig/editorconfig-to-prettier.js` | ソース | EditorConfig変換（33-35行目） |
| public.d.ts | `src/document/public.d.ts` | 型定義 | Doc printer型定義（214行目） |
| is-lone-short-argument.js | `src/language-js/utilities/is-lone-short-argument.js` | ソース | printWidth参照（20, 26行目） |
