ruvim 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +4 -0
  3. data/AGENTS.md +84 -0
  4. data/CLAUDE.md +1 -0
  5. data/docs/binding.md +29 -0
  6. data/docs/command.md +101 -0
  7. data/docs/config.md +203 -84
  8. data/docs/done.md +21 -0
  9. data/docs/lib_cleanup_report.md +79 -0
  10. data/docs/plugin.md +13 -15
  11. data/docs/spec.md +195 -33
  12. data/docs/todo.md +183 -10
  13. data/docs/tutorial.md +1 -1
  14. data/docs/vim_diff.md +94 -171
  15. data/lib/ruvim/app.rb +1543 -172
  16. data/lib/ruvim/buffer.rb +35 -1
  17. data/lib/ruvim/cli.rb +12 -3
  18. data/lib/ruvim/clipboard.rb +2 -0
  19. data/lib/ruvim/command_invocation.rb +3 -1
  20. data/lib/ruvim/command_line.rb +2 -0
  21. data/lib/ruvim/command_registry.rb +2 -0
  22. data/lib/ruvim/config_dsl.rb +2 -0
  23. data/lib/ruvim/config_loader.rb +21 -5
  24. data/lib/ruvim/context.rb +2 -7
  25. data/lib/ruvim/dispatcher.rb +153 -13
  26. data/lib/ruvim/display_width.rb +28 -2
  27. data/lib/ruvim/editor.rb +622 -69
  28. data/lib/ruvim/ex_command_registry.rb +2 -0
  29. data/lib/ruvim/global_commands.rb +1386 -114
  30. data/lib/ruvim/highlighter.rb +16 -21
  31. data/lib/ruvim/input.rb +52 -29
  32. data/lib/ruvim/keymap_manager.rb +83 -0
  33. data/lib/ruvim/keyword_chars.rb +48 -0
  34. data/lib/ruvim/lang/base.rb +25 -0
  35. data/lib/ruvim/lang/csv.rb +18 -0
  36. data/lib/ruvim/lang/json.rb +18 -0
  37. data/lib/ruvim/lang/markdown.rb +170 -0
  38. data/lib/ruvim/lang/ruby.rb +236 -0
  39. data/lib/ruvim/lang/scheme.rb +44 -0
  40. data/lib/ruvim/lang/tsv.rb +19 -0
  41. data/lib/ruvim/rich_view/markdown_renderer.rb +248 -0
  42. data/lib/ruvim/rich_view/table_renderer.rb +176 -0
  43. data/lib/ruvim/rich_view.rb +93 -0
  44. data/lib/ruvim/screen.rb +851 -119
  45. data/lib/ruvim/terminal.rb +18 -1
  46. data/lib/ruvim/text_metrics.rb +28 -0
  47. data/lib/ruvim/version.rb +2 -2
  48. data/lib/ruvim/window.rb +37 -10
  49. data/lib/ruvim.rb +15 -0
  50. data/test/app_completion_test.rb +174 -0
  51. data/test/app_dot_repeat_test.rb +13 -0
  52. data/test/app_motion_test.rb +110 -2
  53. data/test/app_scenario_test.rb +998 -0
  54. data/test/app_startup_test.rb +197 -0
  55. data/test/arglist_test.rb +113 -0
  56. data/test/buffer_test.rb +49 -30
  57. data/test/config_loader_test.rb +37 -0
  58. data/test/dispatcher_test.rb +438 -0
  59. data/test/display_width_test.rb +18 -0
  60. data/test/editor_register_test.rb +23 -0
  61. data/test/fixtures/render_basic_snapshot.txt +7 -8
  62. data/test/fixtures/render_basic_snapshot_nonumber.txt +1 -2
  63. data/test/fixtures/render_unicode_scrolled_snapshot.txt +6 -7
  64. data/test/highlighter_test.rb +121 -0
  65. data/test/indent_test.rb +201 -0
  66. data/test/input_screen_integration_test.rb +65 -14
  67. data/test/markdown_renderer_test.rb +279 -0
  68. data/test/on_save_hook_test.rb +150 -0
  69. data/test/rich_view_test.rb +478 -0
  70. data/test/screen_test.rb +470 -0
  71. data/test/window_test.rb +26 -0
  72. metadata +37 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d2d270426e0c654c22de404d8745368dbc7a5eb98fc91eecad94624a3b91b6c
4
- data.tar.gz: 75ad40c44e89934ab1746d43aee2ac09c695513d6edb6f7e71d0b888126931a8
3
+ metadata.gz: c463658b0badbad140842446b82818bb797930372d4ccb8ff5e4275fbe627904
4
+ data.tar.gz: 92b3c9f004f8b075f603d4b8f2e4c48255ac0ef3eea768dd3e290495ab661033
5
5
  SHA512:
6
- metadata.gz: 938e1eb393efd57f97260526fc40f375d27ca0aecf9b370d0b0b41b7c3f535026b1c8be82588a2713025c615e4e5222abe871f46918fbc08f3fef9b35347e023
7
- data.tar.gz: f0a3fb80d5f3e2395daf0c689fd4129bfd6ff026e3184eb8f0e58ffc68f19ede36be7ac6c914fa3a2a70bd9b7c9bb95ae60bf292f760ce7691b498a0b12d66a7
6
+ metadata.gz: 46ec215ad18a1e72a62d54e0a95b24d87b7ee5b9093300a4597c8d96754ef4a1ce30f964101e1f2cd3dda8ecefcc74d7565602bb80f0eba6ce28cd2fb835a9ad
7
+ data.tar.gz: 49827d053ac4b9c827b0cbe86ebb00ff8a6609af4998ef5060a2407d0022f33b47327c11eaef4efc75aca03e0ddc07660a8bf12214db28e8c98f58c83c705b60
@@ -7,9 +7,13 @@ on:
7
7
  jobs:
8
8
  test:
9
9
  runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby: ["3.2", "3.3", "3.4", "4.0"]
10
13
  steps:
11
14
  - uses: actions/checkout@v4
12
15
  - uses: ruby/setup-ruby@v1
13
16
  with:
17
+ ruby-version: ${{ matrix.ruby }}
14
18
  bundler-cache: true
15
19
  - run: bundle exec rake ci
data/AGENTS.md ADDED
@@ -0,0 +1,84 @@
1
+ This project is RuVim, a Vim-like editor written in Ruby. Always run the full test suite (`rake test` or equivalent) after making code changes and confirm all tests pass before committing.
2
+
3
+ * check docs/ to understand the specification
4
+ * docs/spec.md
5
+ * docs/todo.md
6
+ * When modifying the source code
7
+ * write tests first, then implement (test-first)
8
+ * update docs/
9
+ * catch up changes
10
+ * move completed tasks to done.md
11
+ * update CLAUDE.md Source Tree section if files were added, removed, or renamed
12
+ * commit it
13
+ * After committing, show the commit message
14
+
15
+ ## Source Tree
16
+
17
+ ### Architecture
18
+
19
+ ```
20
+ CLI (exe/ruvim) → CLI.parse() → App.new() → App.run_ui_loop()
21
+ Input.read_key() → KeymapManager.resolve() → Dispatcher.dispatch()
22
+ → GlobalCommands.<method>() → Editor state update → Screen.render() → Terminal.write()
23
+ ```
24
+
25
+ ### Core (lib/ruvim/)
26
+
27
+ | File | Description |
28
+ |------|-------------|
29
+ | `app.rb` | Main application loop, input handling, startup |
30
+ | `editor.rb` | Editor state: buffers, windows, options, registers, marks, modes |
31
+ | `buffer.rb` | Text buffer (lines, file I/O, encoding) |
32
+ | `window.rb` | View of a buffer (cursor, scroll, grapheme-aware movement) |
33
+ | `global_commands.rb` | All built-in command implementations (cursor, edit, search, visual, etc.) |
34
+ | `screen.rb` | Rendering: window layout, syntax highlight, line numbers, status line, wrap |
35
+ | `dispatcher.rb` | Routes commands; parses Ex ranges/substitute; shell execution |
36
+ | `keymap_manager.rb` | Key-to-command mapping with layers (filetype > buffer > mode > global) |
37
+ | `input.rb` | Raw keyboard input, ANSI escape sequence parsing |
38
+ | `terminal.rb` | Terminal I/O: raw mode, alternate screen, winsize |
39
+ | `command_line.rb` | Command-line text/cursor state |
40
+ | `command_registry.rb` | Normal/insert mode command registry (singleton) |
41
+ | `ex_command_registry.rb` | Ex command registry (singleton) |
42
+ | `cli.rb` | CLI argument parsing, `--help`, `--version` |
43
+ | `config_loader.rb` | Load `~/.config/ruvim/init.rb` and ftplugin |
44
+ | `config_dsl.rb` | User config DSL: `nmap`, `imap`, `set`, `command`, `colorscheme` |
45
+ | `display_width.rb` | Character display width (CJK, emoji, combining marks) |
46
+ | `text_metrics.rb` | Grapheme-aware text measurement and navigation |
47
+ | `keyword_chars.rb` | Word character definition (iskeyword) |
48
+ | `highlighter.rb` | Syntax highlighting dispatcher (delegates to lang modules) |
49
+ | `lang/base.rb` | Default lang module (no-op fallback for indent/dedent) |
50
+ | `lang/markdown.rb` | Markdown parsing, detection helpers, and syntax highlight colors |
51
+ | `lang/ruby.rb` | Ruby syntax highlighting via Prism lexer; auto-indent calculation |
52
+ | `lang/json.rb` | JSON syntax highlighting via regex |
53
+ | `lang/scheme.rb` | Scheme syntax highlighting via regex |
54
+ | `lang/tsv.rb` | TSV detection and RichView renderer registration |
55
+ | `lang/csv.rb` | CSV detection and RichView renderer registration |
56
+ | `clipboard.rb` | System clipboard access (xclip, pbpaste, etc.) |
57
+ | `context.rb` | Command handler context (editor, window, buffer, invocation) |
58
+ | `command_invocation.rb` | Single command invocation (id, argv, count, bang) |
59
+ | `rich_view.rb` | Rich view mode (TSV/CSV/Markdown rendering) |
60
+ | `rich_view/table_renderer.rb` | Table formatting with display-width-aware column alignment |
61
+ | `rich_view/markdown_renderer.rb` | Markdown rendering (headings, inline, tables, code blocks, HR) |
62
+
63
+ ### Tests (test/)
64
+
65
+ - Unit: `buffer_test`, `window_test`, `editor_test`, `screen_test`, `display_width_test`, `text_metrics_test`, `keymap_manager_test`, `highlighter_test`, `dispatcher_test`, `config_*_test`, `indent_test`
66
+ - Integration: `app_scenario_test`, `app_motion_test`, `app_text_object_test`, `app_register_test`, `app_dot_repeat_test`, `app_completion_test`, `app_unicode_behavior_test`, `render_snapshot_test`, `on_save_hook_test`
67
+ - Helper: `test_helper.rb` (fresh_editor, Minitest)
68
+
69
+ ### Docs (docs/)
70
+
71
+ `spec.md` (feature spec), `command.md`, `binding.md`, `config.md`, `tutorial.md`, `vim_diff.md`, `plugin.md`, `todo.md`, `done.md`
72
+
73
+ ## Debugging (Lumitrace)
74
+
75
+ lumitrace is a tool that records runtime values of each Ruby expression.
76
+ When a test fails, read `lumitrace help` first, then use it.
77
+ Basic: `lumitrace -t exec rake test`
78
+
79
+ When fixing bugs, do NOT assume the first fix attempt is correct. After applying a fix, re-read the relevant code paths to verify the fix addresses the actual root cause, not a symptom. If the user says 'it hasn't changed' or equivalent, start fresh analysis from the failing behavior.
80
+
81
+ ## misc
82
+
83
+ The user communicates in both English and Japanese. Respond in the same language the user uses. When the user gives feedback like 変わってないですよ ('it hasn't changed'), treat it as a bug report requiring re-analysis.
84
+
data/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ AGENTS.md
data/docs/binding.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # RuVim キーバインディング一覧
2
2
 
3
+ 実行時の現在有効な binding 一覧は `:bindings` で表示できます(layer: `buffer` / `filetype` / `app`)。
4
+
3
5
  ## Normal mode
4
6
 
5
7
  - `h` : 左へ移動
@@ -47,6 +49,7 @@
47
49
  - `'{mark}` / `` `{mark} `` : mark へ jump(行頭寄せ / 正確位置)
48
50
  - `''` / `` `` `` : jumplist で前の位置へ jump(行頭寄せ / 正確位置)
49
51
  - `r<char>` : 1文字置換
52
+ - `=` + motion / `==` : auto-indent(Ruby filetype 対応)
50
53
  - `c` + motion / `cc` : change(削除して Insert mode)
51
54
  - `ciw` / `caw` : 単語 text object change(簡易)
52
55
  - `ci"` / `ca"` : quote text object change(簡易)
@@ -56,20 +59,32 @@
56
59
  - `V` : Visual (linewise)
57
60
  - `Ctrl-w w` : 次の window へ移動
58
61
  - `Ctrl-w h/j/k/l` : window 間移動(split UI)
62
+ - `Shift+矢印キー` : window 間移動 or 分割(1ウィンドウ時は分割、2個以上なら移動)
59
63
  - `u` : Undo
60
64
  - `Ctrl-r` : Redo
61
65
  - `.` : 直前変更の repeat(現状: `x`, `dd`, `d{motion}`, `p/P`, `r<char>`)
62
66
  - `Ctrl-o` : jumplist の古い位置へ
63
67
  - `Ctrl-i` : jumplist の新しい位置へ(端末では Tab と同じコード)
68
+ - `Ctrl-d` / `Ctrl-u` : 半ページ下/上へ移動(概ね表示高さの半分)
69
+ - `Ctrl-f` / `Ctrl-b` : 1ページ下/上へ移動(`PageDown` / `PageUp` 相当)
70
+ - `Ctrl-e` / `Ctrl-y` : カーソル位置をなるべく保ったまま画面を1行下/上へスクロール(最小実装)
64
71
  - `q{reg}` : macro 記録開始/終了(再度 `q` で停止)
65
72
  - `@{reg}` / `@@` : macro 再生 / 直前 macro 再生
66
73
  - `n` : 直前検索を次へ
67
74
  - `N` : 直前検索を前へ(逆方向)
68
75
  - `*` / `#` : カーソル下の単語検索(前/後)
69
76
  - `g*` / `g#` : カーソル下の単語を部分一致検索(前/後)
77
+ - `gf` : カーソル下のファイル名を開く(最小。`path` / `suffixesadd` を参照)
78
+ - `file:line` 形式なら開いた後に `line` 行目へ移動
79
+ - `gr` : Rich mode をトグル(TSV/CSV をテーブル整形表示、同一バッファ上で動作)
70
80
  - `Esc` : メッセージ/保留入力のクリア
81
+ - `Ctrl-z` : shell へ suspend(`fg` で復帰)
71
82
  - `矢印キー` : 移動
72
83
  - `PageUp` / `PageDown` : 画面単位で移動(概ね表示高さ - 1 行)
84
+ - `Q` : quickfix list を開く(`:copen` 相当)
85
+ - `]q` : 次の quickfix item へジャンプ(`:cnext` 相当)
86
+ - `[q` : 前の quickfix item へジャンプ(`:cprev` 相当)
87
+ - `Enter` : quickfix / location list バッファ上では選択項目へジャンプ(一覧ウィンドウから元の編集ウィンドウへ戻る)
73
88
 
74
89
  ### count 対応(現状)
75
90
 
@@ -85,6 +100,7 @@
85
100
  - `Ctrl-p` : buffer words 補完(前候補)
86
101
  - `Esc` : Normal mode に戻る
87
102
  - `Ctrl-c` : Normal mode に戻る
103
+ - `Ctrl-z` : shell へ suspend(`fg` で復帰)
88
104
  - `矢印キー` : 移動
89
105
  - `PageUp` / `PageDown` : 画面単位で移動
90
106
 
@@ -96,8 +112,18 @@
96
112
  - `V` : linewise Visual の開始/切替
97
113
  - `y` : 選択範囲を yank
98
114
  - `d` : 選択範囲を delete
115
+ - `=` : 選択範囲を auto-indent
99
116
  - `i` / `a` + object : text object を選択(`iw`, `aw`, `ip`, `ap`, `i"`, `a"`, ``i` ``, ``a` ``, `i)`, `a)`, `i]`, `a]`, `i}`, `a}`)
100
117
  - `Esc` / `Ctrl-c` : Normal mode に戻る
118
+ - `Ctrl-z` : shell へ suspend(`fg` で復帰)
119
+
120
+ ## Rich mode
121
+
122
+ - Normal mode のキーバインドをほぼそのまま使える(移動・検索・yank 等)
123
+ - バッファを変更する操作(insert/delete/change/paste/replace)はブロック
124
+ - `Esc` : Normal mode に戻る
125
+ - `Ctrl-c` : Normal mode に戻る
126
+ - `Ctrl-z` : shell へ suspend(`fg` で復帰)
101
127
 
102
128
  ## Command-line mode
103
129
 
@@ -109,6 +135,7 @@
109
135
  - `Tab` (`Ctrl-i`) : Ex 補完(`:` prefix 時、コマンド名/一部引数の文脈対応)
110
136
  - `Esc` : キャンセル
111
137
  - `Ctrl-c` : キャンセル
138
+ - `Ctrl-z` : shell へ suspend(`fg` で復帰)
112
139
 
113
140
  ### prefix 別の Enter 動作
114
141
 
@@ -122,4 +149,6 @@
122
149
  - `d` は keymap の固定列ではなく operator-pending 状態機械で解釈
123
150
  - keymap 解決順(現状実装): `filetype-local -> buffer-local -> mode-local -> global`
124
151
  - `~/.config/ruvim/init.rb`(または `$XDG_CONFIG_HOME/ruvim/init.rb`)の `nmap` / `imap` / `map_global` で上書き・追加可能
152
+ - `Ctrl-d/u/f/b/e/y` に加えて、`矢印キー` / `PageUp` / `PageDown` も「既定挙動の前に keymap override を試す」ため `nmap "<PageDown>", ...` のように上書き可能
153
+ - `Ctrl-z` は keymap ではなく app レベルの suspend 処理として扱う(全モード共通)
125
154
  - `~/.config/ruvim/ftplugin/<filetype>.rb`(または `$XDG_CONFIG_HOME/ruvim/ftplugin/<filetype>.rb`)では `nmap` / `imap` が filetype-local として登録される
data/docs/command.md CHANGED
@@ -19,6 +19,16 @@
19
19
  - `-c {cmd}`
20
20
  - `+{cmd}`, `+{line}`, `+`
21
21
 
22
+ 補足(現状挙動):
23
+
24
+ - `cmd | ruvim`
25
+ - `stdin` を follow stream として開く(`[stdin]` バッファ)
26
+ - Normal mode の `Ctrl-c` で stream 停止(上流プロセスには直接 `SIGINT` は送らない)
27
+ - `Ctrl-z`
28
+ - 全モード共通で shell へ suspend(`SIGTSTP`)
29
+ - suspend 前に terminal を cooked + main screen へ戻す
30
+ - `fg` 復帰後は alt screen を再有効化し、画面を全面再描画する
31
+
22
32
  ## Ex コマンド(builtin)
23
33
 
24
34
  ### `:w` / `:write`
@@ -36,11 +46,22 @@
36
46
  - 最後の window / tab のとき: エディタ終了
37
47
  - 最後の window / tab で未保存変更がある場合、`!` なしでは拒否
38
48
 
49
+ ### `:qa` / `:qall`
50
+
51
+ - 形式: `:qa`, `:qa!`
52
+ - 全ウィンドウ/タブを無視して一括終了
53
+ - 未保存変更があるファイルバッファが存在する場合、`!` なしでは拒否
54
+
39
55
  ### `:wq`
40
56
 
41
57
  - 形式: `:wq`, `:wq!`, `:wq [path]`
42
58
  - 保存して `:q` 相当(window / tab / app を閉じる)
43
59
 
60
+ ### `:wqa` / `:wqall` / `:xa` / `:xall`
61
+
62
+ - 形式: `:wqa`, `:wqa!`
63
+ - 変更のある全ファイルバッファを保存して一括終了
64
+
44
65
  ### `:e` / `:edit`
45
66
 
46
67
  - 形式: `:e[!] [path]`
@@ -48,6 +69,11 @@
48
69
  - 引数なし: 現在ファイルを再読込
49
70
  - 未保存変更がある場合は `!` なしで拒否
50
71
  - `:e!` は未保存変更を破棄して開き直す(undo/redo もクリア)
72
+ - 大きいファイル(閾値以上)は段階読み込みになる場合がある
73
+ - 読み込み中は status line に `[load/live]`
74
+ - デフォルトでは先頭 `8MB` を先に表示して、残りを後から追加
75
+ - 閾値: `RUVIM_ASYNC_FILE_THRESHOLD_BYTES`
76
+ - 先読みサイズ: `RUVIM_ASYNC_FILE_PREFIX_BYTES`
51
77
 
52
78
  ### `:help`
53
79
 
@@ -64,6 +90,16 @@
64
90
  - 形式: `:commands`
65
91
  - Ex コマンド一覧(alias 含む)を read-only バッファに表示
66
92
 
93
+ ### `:bindings`
94
+
95
+ - 形式: `:bindings [mode]`
96
+ - 現在バッファに対して有効な key binding 一覧を read-only バッファに表示
97
+ - layer ごとに表示:
98
+ - `buffer`
99
+ - `filetype`
100
+ - `app`
101
+ - `mode` は任意(例: `normal`, `insert`, `visual_line`, `command_line`。短縮形 `n`, `i`, `v`, `c` なども可)
102
+
67
103
  ### quickfix / location list(最小)
68
104
 
69
105
  - `:vimgrep /pattern/`
@@ -82,6 +118,17 @@
82
118
  - `:grep`, `:make`, `:cfile`, `:lgrep` は未実装
83
119
  - 一覧バッファ上で `Enter` からのジャンプは未実装
84
120
 
121
+ ### `:rich`
122
+
123
+ - 形式: `:rich [format]`
124
+ - Rich mode を開始 / 終了する(トグル)
125
+ - `format` に `tsv` または `csv` を指定可能(省略時は filetype / 内容から自動判定)
126
+ - 同一バッファ上で動作し、描画時にテーブル整形を適用する
127
+ - Rich mode では移動・検索・yank 等は使えるが、バッファ変更操作はブロックされる
128
+ - 区切り文字は ` | `(スペース+パイプ+スペース)
129
+ - 列幅は画面に見えている行だけから計算(大規模ファイルでも高速)
130
+ - `Esc` / `Ctrl-C` で Normal mode に戻る
131
+
85
132
  ### `:command`
86
133
 
87
134
  - 形式: `:command Name ex_body`
@@ -94,8 +141,17 @@
94
141
  - 形式: `:ruby <code>`
95
142
  - 形式: `:rb <code>`
96
143
  - Ruby コードを評価し、返り値をステータスに表示
144
+ - `stdout` / `stderr` に出力があった場合は `[Ruby Output]` 仮想バッファに表示(返り値も末尾に表示)
97
145
  - 利用可能: `ctx`, `editor`, `buffer`, `window`
98
146
 
147
+ ### `:!`(shell 実行, 最小)
148
+
149
+ - 形式: `:!<command>`
150
+ - shell コマンドを同期実行します
151
+ - `stdout` / `stderr` に出力があった場合は `[Shell Output]` 仮想バッファに表示(終了ステータスも表示)
152
+ - 出力がない場合は `shell exit N` をステータス表示
153
+ - `-Z`(restricted mode)では無効
154
+
99
155
  ### `:ls` / `:buffers`
100
156
 
101
157
  - 形式: `:ls`
@@ -121,6 +177,41 @@
121
177
  - バッファ ID / 名前 / `#`(alternate)で切替
122
178
  - `!` 対応(未保存変更を無視して切替)
123
179
 
180
+ ### `:bdelete` / `:bd`
181
+
182
+ - 形式: `:bdelete [id|name|#]`
183
+ - 現在バッファ(または指定バッファ)を一覧から削除
184
+ - 表示中 window は別バッファへ切り替えられる
185
+ - `!` 対応(未保存変更バッファを破棄)
186
+
187
+ ### `:args`
188
+
189
+ - 形式: `:args`
190
+ - 引数リスト(arglist)を表示
191
+ - 現在の引数は `[filename]` 形式で表示される
192
+
193
+ ### `:next`
194
+
195
+ - 形式: `:next`
196
+ - arglist の次の引数ファイルを開く
197
+ - エラー: 最後の引数で実行時
198
+
199
+ ### `:prev`
200
+
201
+ - 形式: `:prev`
202
+ - arglist の前の引数ファイルを開く
203
+ - エラー: 最初の引数で実行時
204
+
205
+ ### `:first`
206
+
207
+ - 形式: `:first`
208
+ - arglist の最初の引数ファイルを開く
209
+
210
+ ### `:last`
211
+
212
+ - 形式: `:last`
213
+ - arglist の最後の引数ファイルを開く
214
+
124
215
  ### `:split`
125
216
 
126
217
  - 形式: `:split`
@@ -149,6 +240,13 @@
149
240
  - 形式: `:tabprev`
150
241
  - 前のタブへ移動
151
242
 
243
+ ### `:tabs`
244
+
245
+ - 形式: `:tabs`
246
+ - 全タブページの一覧を表示
247
+ - 各タブに含まれるウィンドウとバッファ名を表示
248
+ - 現在のタブ / ウィンドウは `>` マーカーで示す
249
+
152
250
  ## 内部コマンド(主なもの)
153
251
 
154
252
  内部コマンドは主に key binding から使われ、`RuVim::CommandRegistry` に登録されます。
@@ -205,6 +303,7 @@
205
303
  - `editor.buffer_prev`
206
304
  - `buffer.replace_char`
207
305
  - `ui.clear_message`
306
+ - `rich.toggle`
208
307
 
209
308
  ## 検索コマンド(Normal mode)
210
309
 
@@ -249,6 +348,7 @@
249
348
  - `buffer.visual_delete`
250
349
  - blockwise は最小実装(矩形選択 + `y/d`)
251
350
  - blockwise の text object 選択 / paste の Vim 互換挙動は未対応
351
+ - `Ctrl-z` で shell へ suspend(`fg` で復帰)
252
352
 
253
353
  ## repeat(Normal mode)
254
354
 
@@ -294,6 +394,7 @@
294
394
 
295
395
  - `Screen` は行キャッシュを使った簡易差分描画を行う
296
396
  - `SIGWINCH` + self-pipe + `IO.select` で入力待機中でもリサイズに即追従
397
+ - `Ctrl-z` suspend/`fg` 復帰後は `Screen` キャッシュを破棄し、全面再描画する
297
398
  - command-line は履歴と Ex 補完(コマンド名 + 一部引数の文脈補完)を持つ
298
399
  - Insert mode は `Ctrl-n` / `Ctrl-p` の buffer words 補完を持つ
299
400
  - 文字幅は `DisplayWidth` の近似実装(tab 展開 + 一部全角幅2)