# cozy

[English](README.md) | **日本語**

**nano のように打って、vim のように動く。** Rust 製のキーボード駆動ターミナルテキストエディタ（Redux 風アーキテクチャ）。

## 📋 概要

**cozy** は軽量・キーボード駆動のテキストエディタで、以下を使って構築されています:
- **ratatui** (0.29) - ターミナル UI フレームワーク
- **crossterm** (0.27) - クロスプラットフォームのターミナル操作
- **serde** - 設定のシリアライズ
- **regex** - 検索/置換のパターンマッチング

## 🏗️ アーキテクチャ

### Redux 風アーキテクチャ

関心の分離を明確にした Redux 風の構成を採用しています:

```
┌─────────────┐
│   Event     │
│   Loop      │
└──────┬──────┘
       │
       ▼
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Keymap    │────▶│   Action    │────▶│  Reducer    │
│  (Input)    │     │  (Intent)   │     │  (Logic)    │
└─────────────┘     └─────────────┘     └──────┬──────┘
                                                │
                                                ▼
                                         ┌─────────────┐
                                         │   State     │
                                         │  (Data)     │
                                         └──────┬──────┘
                                                │
                                                ▼
                                         ┌─────────────┐
                                         │     UI      │
                                         │ (Renderer)  │
                                         └─────────────┘
```

### モジュール構成

```
src/
├── main.rs              # エントリポイント、ターミナル設定
├── event_loop.rs        # メインイベントループ
├── glide.rs             # Glide モードのモーションエンジン (Motion / Operator / resolve)
├── shortcuts.rs         # キーバインド定義（正の定義元）
├── action/
│   └── action.rs        # Action enum (MoveUp, InsertChar, GlideMove, …)
├── state/               # 状態（single source of truth）
│   ├── editor.rs        # EditorState
│   ├── buffer.rs        # TextBuffer（行ベースのストレージ）
│   ├── cursor.rs        # カーソル位置＋モーション
│   └── key.rs           # 抽象 KeyCode/KeyModifiers（crossterm 非依存）
├── reducer/             # 状態リデューサー（ビジネスロジック）
│   ├── mod.rs           # メインリデューサー分配 (reduce)
│   ├── editor.rs        # モード遷移、Glide アクション
│   ├── operator.rs      # operator + motion 実行 (d/c/y)
│   ├── insert.rs / delete.rs / cursor.rs
│   ├── search.rs / replace.rs
│   ├── clipboard.rs     # 無名レジスタ＋システムクリップボード
│   └── file.rs / status.rs / helper.rs
├── ui/                  # 描画
│   ├── render/          # screen.rs / body.rs / footer.rs
│   ├── keymap.rs        # キー → Action マッピング
│   └── help.rs
└── utils/               # terminal / file / unicode / wrap / syntax / loop_guard
```

## 🎯 機能

### コア機能
- ✅ **テキスト編集**: 挿入、削除、バックスペース、改行
- ✅ **ナビゲーション**: 矢印キー、PageUp/Down、Home/End
- ✅ **ファイル操作**: 開く、保存、名前を付けて保存
- ✅ **検索**: 大文字小文字区別 / 正規表現 / 単語境界
- ✅ **置換**: 検索＆置換、正規表現モードでは `$1` キャプチャ展開対応
- ✅ **Undo/Redo**: 履歴管理 (`Ctrl+Z` / `Ctrl+Y`)
- ✅ **クリップボード貼り付け**: システムクリップボードから貼り付け（`Ctrl+V`、arboard によるクロスプラットフォーム）
- ✅ **Glide モード**: vim 風のモーダルなナビゲーション＆編集 (`Ctrl+G`)
- ✅ **シンタックスハイライト**: Rust / Python / JavaScript / JSON / TOML
- ✅ **行番号**: 行番号表示（オプション）
- ✅ **ステータスバー**: ステータスメッセージとモード表示
- ✅ **設定**: TOML ベースの設定ファイル
- ✅ **ループ保護**: 無限ループを防ぐ LoopGuard 統合

### エディタモード
- **Edit**: 既定の編集モード — nano のようにそのまま打てる
- **Glide**: vim 風のモーダルナビ／編集 (`Ctrl+G`)
- **Search**: インクリメンタル検索 (`Ctrl+F`)
- **Replace**: 検索＆置換 (`Ctrl+R`)
- **Goto**: 行番号へジャンプ (`Ctrl+J`)
- **Save**: 保存ダイアログ (`Ctrl+S`)
- **Open**: ファイルを開くダイアログ (`Ctrl+O`)
- **Help**: ヘルプ画面 (`Ctrl+H`)

## 🚀 使い方

### ビルド

```bash
cargo build --release
```

### 実行

```bash
# 新規ファイル
cargo run

# 既存ファイルを開く
cargo run <filename>
```

### 設定

設定は以下の優先順で読み込まれます:
1. `./config.toml`（カレントディレクトリ）
2. `~/.config/cozy/config.toml`
3. `~/.cozy/config.toml`

いずれも無ければ組み込みデフォルトを使用します。

`config.toml` の例:
```toml
page_size = 20
theme = "dark"
show_line_numbers = true
status_duration = 3
line_number_bg = "darkgray"
line_number_fg = "white"
cursor_blink = true
```

## ⌨️ キーバインド

> キーバインドの正は `src/shortcuts.rs`（`get_shortcuts()`）。ここでは既定値を示します。
> `config.toml` の `[keys]` セクションでアクション単位の上書きが可能です。

### ファイル
- `Ctrl+S`: 保存（保存ダイアログ）
- `Ctrl+Shift+S`: 名前を付けて保存
- `Ctrl+O`: ファイルを開く
- `Ctrl+X`: 終了（変更があれば保存を確認）
- `Ctrl+Q`: 保存せず即終了

### ナビゲーション
- `↑` `↓` `←` `→`: カーソル移動
- `Ctrl+A`: 行頭 / `Ctrl+E`: 行末
- `PageUp` / `PageDown`: ページスクロール
- `Ctrl+J`: 行番号へジャンプ（Goto モード）
- `Ctrl+G`: Glide（モーダル）モードへ

### 編集
- `Enter`: 改行
- `Backspace` / `Delete`: カーソル前 / カーソル位置を削除
- `Ctrl+K`: 現在行を削除（カット）
- `Ctrl+V`: システムクリップボードから貼り付け
- `Ctrl+Z`: 元に戻す / `Ctrl+Y`: やり直し

### 検索 & 置換
- `Ctrl+F`: 検索モードへ
- `Ctrl+N`: 次を検索 / `Ctrl+P`: 前を検索
- `Ctrl+T`: 検索オプション切替（正規表現 / 大小区別 / 単語）
- `Ctrl+R`: 置換モードへ。もう一度押すと全置換
- `Tab`（置換中）: 検索／置換フィールドの切替
- `Enter`（置換中）: 現在のマッチを置換

### 表示 / その他
- `Ctrl+H` / `F1`: ヘルプ表示（`F1` は確実に効くフォールバック）
- `Ctrl+L`: 行番号の表示切替
- `Ctrl+W`: 行折り返しの切替
- `Esc` / `Ctrl+[`: 現在の操作をキャンセル / モードを抜ける

### Glide モード (`Ctrl+G`)
vim 風のモーダル編集。数字を前置すると回数指定（count）になります。
- 移動: `h` `j` `k` `l`、`w`/`b`/`e` 単語（記号で止まる）、`W`/`B`/`E` WORD（空白区切り）、`0`/`^`/`$` 行頭／最初の非空白／行末、`>`/`<` 次／前の文字へジャンプ・`t`/`T` 文字の手前／直後へ（till）、`.`/`,` 直前のジャンプを前方／後方に繰り返し、`gg`/`G` ファイル先頭／末尾、`H`/`M`/`L` 画面上／中／下
- オペレータ: `d`/`c`/`y`（削除／変更／ヤンク）＋モーション — `dw`, `de`, `d$`, `dj`, `cw`, `yw`, `d3w`、to-char operand `d>)`/`d<(`（文字の上まで）と `dt,`/`dT_`（文字の手前まで）
- 行単位: `dd`/`cc`/`yy` 行まるごと（`3dd` = 3行）、`D`/`C`/`Y` = `d$`/`c$`/`yy`
- 編集: `x` 文字削除、`X` バックスペース、`~` 大小文字トグル、`J` 行連結
- 貼り付け: `p`/`P` 直前のカットを下／上（行）または後／前（インライン）に
- 挿入: `i`/`I` 挿入、`a`/`A` 追記、`o`/`O` 行を開く
- `f` 検索、`r` 置換、`Esc` Edit へ戻る

## 📊 コード統計

- **総ファイル数**: 41 Rust ファイル
- **総行数**: 約 5,200 行
- **依存クレート**: 8 個（ratatui, crossterm, serde, toml, dirs, regex, unicode-width, arboard）

## 🔧 技術詳細

### 状態管理

中央集権的な `EditorState` が以下を保持します:
- `buffer: TextBuffer` - 行ベースのテキストストレージ
- `cursor: Cursor` - カーソル位置（行, 列）
- `mode: EditorMode` - 現在のエディタモード
- `filename: Option<PathBuf>` - 現在のファイルパス
- `modified: bool` - 未保存フラグ
- `status_message: Option<String>` - ステータスバーのメッセージ
- `config: Config` - 設定

### テキストバッファ

テキストは `Vec<String>`（行ベース）で保持し、以下の利点があります:
- 効率的な行操作
- スクロール／描画が容易
- シンプルな undo/redo 実装

### イベント処理

イベントループ (`event_loop.rs`) は以下を扱います:
- キーボード入力 → `Keymap::map_key_to_action()`
- ペーストイベント → `Action::InsertString`
- ターミナルのリサイズ
- カーソル点滅アニメーション（500ms タイムアウト）

### 描画

ratatui による描画:
- **Body**: 行番号付きの本文
- **Footer**: モードとメッセージを表示するステータスバー
- レイアウトは描画ごとに再計算

## 🛡️ ループ保護

イベントループの無限ループを防ぐ **LoopGuard** を統合しています:

- **最大反復数**: 10,000,000（Relaxed レベル）
- **タイムアウト**: 30 秒
- **ソフト警告**: 90%（9,000,000 反復）時点
- **統計**: 終了時に自動ログ出力

詳細は `docs/integration/LOOP_GUARD_INTEGRATION.md` を参照してください。

## 🐛 既知の問題 / TODO

- [ ] Unicode 取り扱いの改善
- [ ] 複数ファイル編集
- [ ] プラグインシステム
- [ ] エラーメッセージの改善

## 📝 開発メモ

### 設計判断

1. **Redux 風**: action / reducer / state を明確に分離し、保守性を高める
2. **行ベースバッファ**: この用途ではギャップバッファより簡潔
3. **モードベース UI**: 同じ入力をモードごとに別扱い（検索 vs テキスト入力など）
4. **設定**: 複数の探索パスを持つ TOML ベース設定

### テスト

ユニットテストは `src/reducer/editor_test.rs` などにあります:
```bash
cargo test
```

## 📚 ドキュメント

詳細なドキュメントはリポジトリの `docs/` ディレクトリにあります:

- **アーキテクチャ**: `docs/architecture/ARCHITECTURE.md`
- **LoopGuard 統合**: `docs/integration/LOOP_GUARD_INTEGRATION.md`
- **バグレポート**: `docs/development/BUGS.md`

索引は `docs/README.md` を参照してください。

## 📄 ライセンス

以下のいずれか好きな方を選択できます:

- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) または <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) または <http://opensource.org/licenses/MIT>)

## 🤝 コントリビューション

明示的に別途定めない限り、あなたが本作品への取り込みを意図して提出した貢献は、Apache-2.0 ライセンスの定義に従い、上記のデュアルライセンスで提供されるものとします（追加の条項なしに）。
