36 lines
2.4 KiB
Markdown
36 lines
2.4 KiB
Markdown
# TUI: 入力欄の単語単位カーソル移動
|
||
|
||
## 背景
|
||
|
||
TUI の入力欄では現在、`Left/Right` で1文字単位の移動、`Home/End` で行端への移動ができるが、単語単位で飛ぶ手段がない。長めの行を編集するときに左右キーを押し続けることになりテンポが悪い。
|
||
|
||
シェルやエディタで広く使われている `Ctrl+Left` / `Ctrl+Right` での単語単位移動を提供したい。
|
||
|
||
## 要件
|
||
|
||
- `Ctrl+Left` で1単語ぶん後ろ(左)にカーソルが飛ぶ。
|
||
- `Ctrl+Right` で1単語ぶん前(右)にカーソルが飛ぶ。
|
||
- 「単語」の境界は文字種ベースで判定する:
|
||
- **ASCII**: 英数字とアンダースコア (`_`)
|
||
- **ひらがな** (U+3040..U+309F)
|
||
- **カタカナ** (U+30A0..U+30FF, U+31F0..U+31FF)
|
||
- **漢字** (CJK Unified Ideographs: U+3400..U+4DBF, U+4E00..U+9FFF, U+F900..U+FAFF, U+20000..U+2FFFF)
|
||
- **その他の単語文字**: 上記に該当せず `char::is_alphanumeric()` が true(アクセント付きラテン、キリル、ハングル等をひとまとめ)
|
||
- 上記以外(空白・句読点・改行)は区切り。
|
||
- 同じ種別の連続は1単語、種別が切り替わる位置で境界となる。形態素解析は使わない(送り仮名の途中で切れることは許容、VSCode/emacs と同等の挙動)。
|
||
- ペースト atom (`Atom::Paste`) は不可分な1単語として扱う(カーソルが内部に入らない既存の不変条件を維持する)。
|
||
- 既存の `Ctrl+Home/End` (履歴のスクロール)や `Ctrl+[` / `Ctrl+]` (ターンジャンプ)と衝突しないこと。
|
||
- 既存の `Left/Right`(1文字移動)の挙動は変えない。
|
||
|
||
## 完了条件
|
||
|
||
- `crates/tui` で `Ctrl+Left` / `Ctrl+Right` が単語単位移動として動作する。
|
||
- 単語境界の判定にユニットテストが付いている(空・連続スペース・`\n` をまたぐ・Paste をまたぐ・ひらがな/カタカナ/漢字/ASCII の混在)。
|
||
- 既存テストが通る。
|
||
|
||
## 範囲外
|
||
|
||
- `Ctrl+Backspace` / `Alt+Backspace` などによる単語単位削除(別チケット候補)。
|
||
- `Alt+Left/Right` など他の単語移動キーバインドの追加。
|
||
- 形態素解析による日本語の単語分割(辞書サイズ・起動コストの観点で TUI には過剰)。送り仮名や複合語の途中で切れる挙動は許容する。
|