ruvim 0.4.0 → 0.6.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +53 -4
  3. data/README.md +15 -6
  4. data/Rakefile +7 -0
  5. data/benchmark/cext_compare.rb +165 -0
  6. data/benchmark/chunked_load.rb +256 -0
  7. data/benchmark/file_load.rb +140 -0
  8. data/benchmark/hotspots.rb +178 -0
  9. data/docs/binding.md +3 -2
  10. data/docs/command.md +81 -9
  11. data/docs/done.md +23 -0
  12. data/docs/spec.md +105 -19
  13. data/docs/todo.md +9 -0
  14. data/docs/tutorial.md +9 -1
  15. data/docs/vim_diff.md +13 -0
  16. data/ext/ruvim/extconf.rb +5 -0
  17. data/ext/ruvim/ruvim_ext.c +519 -0
  18. data/lib/ruvim/app.rb +217 -2778
  19. data/lib/ruvim/browser.rb +104 -0
  20. data/lib/ruvim/buffer.rb +39 -28
  21. data/lib/ruvim/command_invocation.rb +2 -2
  22. data/lib/ruvim/completion_manager.rb +708 -0
  23. data/lib/ruvim/dispatcher.rb +14 -8
  24. data/lib/ruvim/display_width.rb +91 -45
  25. data/lib/ruvim/editor.rb +64 -81
  26. data/lib/ruvim/ex_command_registry.rb +3 -1
  27. data/lib/ruvim/gh/link.rb +207 -0
  28. data/lib/ruvim/git/blame.rb +16 -6
  29. data/lib/ruvim/git/branch.rb +20 -5
  30. data/lib/ruvim/git/grep.rb +107 -0
  31. data/lib/ruvim/git/handler.rb +42 -1
  32. data/lib/ruvim/global_commands.rb +175 -35
  33. data/lib/ruvim/highlighter.rb +4 -13
  34. data/lib/ruvim/key_handler.rb +1510 -0
  35. data/lib/ruvim/keymap_manager.rb +7 -7
  36. data/lib/ruvim/lang/base.rb +5 -0
  37. data/lib/ruvim/lang/c.rb +116 -0
  38. data/lib/ruvim/lang/cpp.rb +107 -0
  39. data/lib/ruvim/lang/csv.rb +4 -1
  40. data/lib/ruvim/lang/diff.rb +2 -0
  41. data/lib/ruvim/lang/dockerfile.rb +36 -0
  42. data/lib/ruvim/lang/elixir.rb +85 -0
  43. data/lib/ruvim/lang/erb.rb +30 -0
  44. data/lib/ruvim/lang/go.rb +83 -0
  45. data/lib/ruvim/lang/html.rb +34 -0
  46. data/lib/ruvim/lang/javascript.rb +83 -0
  47. data/lib/ruvim/lang/json.rb +6 -0
  48. data/lib/ruvim/lang/lua.rb +76 -0
  49. data/lib/ruvim/lang/makefile.rb +36 -0
  50. data/lib/ruvim/lang/markdown.rb +3 -4
  51. data/lib/ruvim/lang/ocaml.rb +77 -0
  52. data/lib/ruvim/lang/perl.rb +91 -0
  53. data/lib/ruvim/lang/python.rb +85 -0
  54. data/lib/ruvim/lang/registry.rb +102 -0
  55. data/lib/ruvim/lang/ruby.rb +7 -0
  56. data/lib/ruvim/lang/rust.rb +95 -0
  57. data/lib/ruvim/lang/scheme.rb +5 -0
  58. data/lib/ruvim/lang/sh.rb +76 -0
  59. data/lib/ruvim/lang/sql.rb +52 -0
  60. data/lib/ruvim/lang/toml.rb +36 -0
  61. data/lib/ruvim/lang/tsv.rb +4 -1
  62. data/lib/ruvim/lang/typescript.rb +53 -0
  63. data/lib/ruvim/lang/yaml.rb +62 -0
  64. data/lib/ruvim/rich_view/table_renderer.rb +3 -3
  65. data/lib/ruvim/rich_view.rb +14 -7
  66. data/lib/ruvim/screen.rb +126 -72
  67. data/lib/ruvim/stream/file_load.rb +85 -0
  68. data/lib/ruvim/stream/follow.rb +40 -0
  69. data/lib/ruvim/stream/git.rb +43 -0
  70. data/lib/ruvim/stream/run.rb +74 -0
  71. data/lib/ruvim/stream/stdin.rb +55 -0
  72. data/lib/ruvim/stream.rb +35 -0
  73. data/lib/ruvim/stream_mixer.rb +394 -0
  74. data/lib/ruvim/terminal.rb +18 -4
  75. data/lib/ruvim/text_metrics.rb +84 -65
  76. data/lib/ruvim/version.rb +1 -1
  77. data/lib/ruvim/window.rb +5 -5
  78. data/lib/ruvim.rb +23 -6
  79. data/test/app_command_test.rb +382 -0
  80. data/test/app_completion_test.rb +43 -19
  81. data/test/app_dot_repeat_test.rb +27 -3
  82. data/test/app_ex_command_test.rb +154 -0
  83. data/test/app_motion_test.rb +13 -12
  84. data/test/app_register_test.rb +2 -1
  85. data/test/app_scenario_test.rb +15 -10
  86. data/test/app_startup_test.rb +70 -27
  87. data/test/app_text_object_test.rb +2 -1
  88. data/test/app_unicode_behavior_test.rb +3 -2
  89. data/test/browser_test.rb +88 -0
  90. data/test/buffer_test.rb +24 -0
  91. data/test/cli_test.rb +63 -0
  92. data/test/command_invocation_test.rb +33 -0
  93. data/test/config_dsl_test.rb +47 -0
  94. data/test/dispatcher_test.rb +74 -4
  95. data/test/ex_command_registry_test.rb +106 -0
  96. data/test/follow_test.rb +20 -21
  97. data/test/gh_link_test.rb +141 -0
  98. data/test/git_blame_test.rb +96 -17
  99. data/test/git_grep_test.rb +64 -0
  100. data/test/highlighter_test.rb +125 -0
  101. data/test/indent_test.rb +137 -0
  102. data/test/input_screen_integration_test.rb +1 -1
  103. data/test/keyword_chars_test.rb +85 -0
  104. data/test/lang_test.rb +634 -0
  105. data/test/markdown_renderer_test.rb +5 -5
  106. data/test/on_save_hook_test.rb +12 -8
  107. data/test/render_snapshot_test.rb +78 -0
  108. data/test/rich_view_test.rb +42 -42
  109. data/test/run_command_test.rb +307 -0
  110. data/test/screen_test.rb +68 -5
  111. data/test/stream_test.rb +165 -0
  112. data/test/window_test.rb +59 -0
  113. metadata +52 -2
@@ -66,8 +66,9 @@ class OnSaveHookTest < Minitest::Test
66
66
  editor.current_buffer.replace_all_lines!(["hello"])
67
67
 
68
68
  # Execute :w command
69
+ kh = app.instance_variable_get(:@key_handler)
69
70
  keys = ":w #{path}\n".chars
70
- keys.each { |k| app.send(:handle_key, k == "\n" ? :enter : k) }
71
+ keys.each { |k| kh.handle(k == "\n" ? :enter : k) }
71
72
 
72
73
  assert called, "on_save hook should have been called"
73
74
  end
@@ -84,15 +85,16 @@ class OnSaveHookTest < Minitest::Test
84
85
  File.write(path, "x = 1\ndef foo(\n")
85
86
 
86
87
  # Open and write the file
87
- ":e #{path}\n".chars.each { |k| app.send(:handle_key, k == "\n" ? :enter : k) }
88
- ":w\n".chars.each { |k| app.send(:handle_key, k == "\n" ? :enter : k) }
88
+ kh = app.instance_variable_get(:@key_handler)
89
+ ":e #{path}\n".chars.each { |k| kh.handle(k == "\n" ? :enter : k) }
90
+ ":w\n".chars.each { |k| kh.handle(k == "\n" ? :enter : k) }
89
91
 
90
92
  refute_empty editor.quickfix_items, "quickfix should be populated after :w with syntax error"
91
93
  assert_nil editor.quickfix_index, "quickfix index should be nil before navigation"
92
94
 
93
95
  # Press ]q — should jump to first item (index 0)
94
- app.send(:handle_key, "]")
95
- app.send(:handle_key, "q")
96
+ kh.handle("]")
97
+ kh.handle("q")
96
98
 
97
99
  assert_equal 0, editor.quickfix_index
98
100
  first_item = editor.quickfix_items.first
@@ -112,12 +114,13 @@ class OnSaveHookTest < Minitest::Test
112
114
  path = File.join(dir, "ok.rb")
113
115
  File.write(path, "puts 'hi'\n")
114
116
 
115
- ":e #{path}\n".chars.each { |k| app.send(:handle_key, k == "\n" ? :enter : k) }
117
+ kh = app.instance_variable_get(:@key_handler)
118
+ ":e #{path}\n".chars.each { |k| kh.handle(k == "\n" ? :enter : k) }
116
119
  # Set some dummy quickfix items first
117
120
  editor.set_quickfix_list([{ buffer_id: editor.current_buffer.id, row: 0, col: 0, text: "dummy" }])
118
121
  refute_empty editor.quickfix_items
119
122
 
120
- ":w\n".chars.each { |k| app.send(:handle_key, k == "\n" ? :enter : k) }
123
+ ":w\n".chars.each { |k| kh.handle(k == "\n" ? :enter : k) }
121
124
  assert_empty editor.quickfix_items, "quickfix should be cleared after :w with valid file"
122
125
  end
123
126
  end
@@ -141,8 +144,9 @@ class OnSaveHookTest < Minitest::Test
141
144
  editor.current_buffer.replace_all_lines!(["hello"])
142
145
  editor.set_option("onsavehook", false)
143
146
 
147
+ kh = app.instance_variable_get(:@key_handler)
144
148
  keys = ":w #{path}\n".chars
145
- keys.each { |k| app.send(:handle_key, k == "\n" ? :enter : k) }
149
+ keys.each { |k| kh.handle(k == "\n" ? :enter : k) }
146
150
 
147
151
  refute called, "on_save hook should NOT have been called when onsavehook is disabled"
148
152
  end
@@ -64,7 +64,85 @@ class RenderSnapshotTest < Minitest::Test
64
64
  (1..rows).map { |row| strip_ansi(frame[:lines][row].to_s) }.join("\n")
65
65
  end
66
66
 
67
+ def build_raw_frame(lines:, winsize:, number: false, rich_format: nil, cursor_y: 0, cursor_x: 0)
68
+ editor = RuVim::Editor.new
69
+ buf = editor.add_empty_buffer
70
+ win = editor.add_window(buffer_id: buf.id)
71
+ buf.replace_all_lines!(lines)
72
+ editor.set_option("number", number, scope: :window, window: win, buffer: buf)
73
+ win.cursor_y = cursor_y
74
+ win.cursor_x = cursor_x
75
+ if rich_format
76
+ editor.instance_variable_set(:@rich_state, { format: rich_format })
77
+ end
78
+
79
+ term = TerminalStub.new(winsize)
80
+ screen = RuVim::Screen.new(terminal: term)
81
+
82
+ rows, cols = term.winsize
83
+ text_rows, text_cols = editor.text_viewport_size(rows:, cols:)
84
+ rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
85
+ win.ensure_visible(buf, height: text_rows, width: text_cols, tabstop: 2)
86
+ frame = screen.send(:build_frame, editor, rows:, cols:, text_rows:, text_cols:, rects:)
87
+
88
+ (1..rows).map { |row| frame[:lines][row].to_s }.join("\n")
89
+ end
90
+
67
91
  def strip_ansi(str)
68
92
  str.gsub(/\e\[[0-9;?]*[A-Za-z]/, "")
69
93
  end
70
94
  end
95
+
96
+ class RenderSanitizeTest < Minitest::Test
97
+ TerminalStub = Struct.new(:winsize) do
98
+ def write(_data); end
99
+ end
100
+
101
+ def test_normal_buffer_sanitizes_escape_sequences
102
+ # ESC (0x1B) should be replaced with "?" in normal rendering
103
+ lines = ["hello\x1b]52;c;dGVzdA==\x07world"]
104
+ snapshot = build_raw_frame(lines: lines, winsize: [5, 40])
105
+ refute_includes snapshot, "\x1b]52"
106
+ refute_includes snapshot, "\x07"
107
+ end
108
+
109
+ def test_rich_view_sanitizes_escape_sequences_in_tsv
110
+ lines = ["col1\tcol2", "val1\t\x1b]52;c;dGVzdA==\x07evil"]
111
+ snapshot = build_raw_frame(lines: lines, winsize: [6, 40], rich_format: :tsv)
112
+ refute_includes snapshot, "\x1b]52"
113
+ refute_includes snapshot, "\x07"
114
+ end
115
+
116
+ def test_rich_view_sanitizes_escape_sequences_in_markdown
117
+ lines = ["# heading", "\x1b]52;c;dGVzdA==\x07evil text"]
118
+ snapshot = build_raw_frame(lines: lines, winsize: [6, 40], rich_format: :markdown)
119
+ refute_includes snapshot, "\x1b]52"
120
+ refute_includes snapshot, "\x07"
121
+ end
122
+
123
+ private
124
+
125
+ def build_raw_frame(lines:, winsize:, number: false, rich_format: nil, cursor_y: 0, cursor_x: 0)
126
+ editor = RuVim::Editor.new
127
+ buf = editor.add_empty_buffer
128
+ win = editor.add_window(buffer_id: buf.id)
129
+ buf.replace_all_lines!(lines)
130
+ editor.set_option("number", number, scope: :window, window: win, buffer: buf)
131
+ win.cursor_y = cursor_y
132
+ win.cursor_x = cursor_x
133
+ if rich_format
134
+ editor.instance_variable_set(:@rich_state, { format: rich_format })
135
+ end
136
+
137
+ term = TerminalStub.new(winsize)
138
+ screen = RuVim::Screen.new(terminal: term)
139
+
140
+ rows, cols = term.winsize
141
+ text_rows, text_cols = editor.text_viewport_size(rows:, cols:)
142
+ rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
143
+ win.ensure_visible(buf, height: text_rows, width: text_cols, tabstop: 2)
144
+ frame = screen.send(:build_frame, editor, rows:, cols:, text_rows:, text_cols:, rects:)
145
+
146
+ (1..rows).map { |row| frame[:lines][row].to_s }.join("\n")
147
+ end
148
+ end
@@ -4,36 +4,36 @@ class RichViewTest < Minitest::Test
4
4
  # --- Framework tests ---
5
5
 
6
6
  def test_register_and_renderer_for
7
- assert RuVim::RichView.renderer_for("tsv")
8
- assert RuVim::RichView.renderer_for("csv")
9
- assert_nil RuVim::RichView.renderer_for("unknown")
7
+ assert RuVim::RichView.renderer_for(:tsv)
8
+ assert RuVim::RichView.renderer_for(:csv)
9
+ assert_nil RuVim::RichView.renderer_for(:unknown)
10
10
  end
11
11
 
12
12
  def test_registered_filetypes
13
13
  fts = RuVim::RichView.registered_filetypes
14
- assert_includes fts, "tsv"
15
- assert_includes fts, "csv"
14
+ assert_includes fts, :tsv
15
+ assert_includes fts, :csv
16
16
  end
17
17
 
18
18
  def test_detect_format_from_filetype
19
19
  editor = fresh_editor
20
20
  buf = editor.current_buffer
21
21
  buf.options["filetype"] = "csv"
22
- assert_equal "csv", RuVim::RichView.detect_format(buf)
22
+ assert_equal :csv, RuVim::RichView.detect_format(buf)
23
23
  end
24
24
 
25
25
  def test_detect_format_auto_tsv
26
26
  editor = fresh_editor
27
27
  buf = editor.current_buffer
28
28
  buf.replace_all_lines!(["a\tb\tc", "d\te\tf"])
29
- assert_equal "tsv", RuVim::RichView.detect_format(buf)
29
+ assert_equal :tsv, RuVim::RichView.detect_format(buf)
30
30
  end
31
31
 
32
32
  def test_detect_format_auto_csv
33
33
  editor = fresh_editor
34
34
  buf = editor.current_buffer
35
35
  buf.replace_all_lines!(["a,b,c", "d,e,f"])
36
- assert_equal "csv", RuVim::RichView.detect_format(buf)
36
+ assert_equal :csv, RuVim::RichView.detect_format(buf)
37
37
  end
38
38
 
39
39
  def test_detect_format_returns_nil_for_plain_text
@@ -63,7 +63,7 @@ class RichViewTest < Minitest::Test
63
63
  buf.replace_all_lines!(["a\tb", "c\td"])
64
64
  buf.options["filetype"] = "tsv"
65
65
 
66
- RuVim::RichView.open!(editor, format: "tsv")
66
+ RuVim::RichView.open!(editor, format: :tsv)
67
67
  assert_equal :rich, editor.mode
68
68
  assert RuVim::RichView.active?(editor)
69
69
  end
@@ -75,7 +75,7 @@ class RichViewTest < Minitest::Test
75
75
  buf.options["filetype"] = "tsv"
76
76
  original_id = buf.id
77
77
 
78
- RuVim::RichView.open!(editor, format: "tsv")
78
+ RuVim::RichView.open!(editor, format: :tsv)
79
79
  assert_equal original_id, editor.current_buffer.id
80
80
  end
81
81
 
@@ -85,7 +85,7 @@ class RichViewTest < Minitest::Test
85
85
  buf.replace_all_lines!(["x\ty"])
86
86
  buf.options["filetype"] = "tsv"
87
87
 
88
- RuVim::RichView.open!(editor, format: "tsv")
88
+ RuVim::RichView.open!(editor, format: :tsv)
89
89
  assert_equal :rich, editor.mode
90
90
 
91
91
  RuVim::RichView.close!(editor)
@@ -100,7 +100,7 @@ class RichViewTest < Minitest::Test
100
100
  buf.options["filetype"] = "tsv"
101
101
  original_id = buf.id
102
102
 
103
- RuVim::RichView.open!(editor, format: "tsv")
103
+ RuVim::RichView.open!(editor, format: :tsv)
104
104
  RuVim::RichView.close!(editor)
105
105
  assert_equal original_id, editor.current_buffer.id
106
106
  end
@@ -124,9 +124,9 @@ class RichViewTest < Minitest::Test
124
124
  buf.replace_all_lines!(["a\tb"])
125
125
  buf.options["filetype"] = "tsv"
126
126
 
127
- RuVim::RichView.open!(editor, format: "tsv")
127
+ RuVim::RichView.open!(editor, format: :tsv)
128
128
  state = editor.rich_state
129
- assert_equal "tsv", state[:format]
129
+ assert_equal :tsv, state[:format]
130
130
  assert_equal "\t", state[:delimiter]
131
131
  end
132
132
 
@@ -136,9 +136,9 @@ class RichViewTest < Minitest::Test
136
136
  buf.replace_all_lines!(["a,b"])
137
137
  buf.options["filetype"] = "csv"
138
138
 
139
- RuVim::RichView.open!(editor, format: "csv")
139
+ RuVim::RichView.open!(editor, format: :csv)
140
140
  state = editor.rich_state
141
- assert_equal "csv", state[:format]
141
+ assert_equal :csv, state[:format]
142
142
  assert_equal ",", state[:delimiter]
143
143
  end
144
144
 
@@ -148,7 +148,7 @@ class RichViewTest < Minitest::Test
148
148
  buf.replace_all_lines!(["a\tb"])
149
149
  buf.options["filetype"] = "tsv"
150
150
 
151
- RuVim::RichView.open!(editor, format: "tsv")
151
+ RuVim::RichView.open!(editor, format: :tsv)
152
152
  RuVim::RichView.close!(editor)
153
153
  assert_nil editor.rich_state
154
154
  end
@@ -159,7 +159,7 @@ class RichViewTest < Minitest::Test
159
159
  buf.replace_all_lines!(["a\tb"])
160
160
  buf.options["filetype"] = "tsv"
161
161
 
162
- RuVim::RichView.open!(editor, format: "tsv")
162
+ RuVim::RichView.open!(editor, format: :tsv)
163
163
  editor.enter_command_line_mode(":")
164
164
  assert_equal :command_line, editor.mode
165
165
  assert RuVim::RichView.active?(editor)
@@ -171,7 +171,7 @@ class RichViewTest < Minitest::Test
171
171
  buf.replace_all_lines!(["a\tb"])
172
172
  buf.options["filetype"] = "tsv"
173
173
 
174
- RuVim::RichView.open!(editor, format: "tsv")
174
+ RuVim::RichView.open!(editor, format: :tsv)
175
175
  assert_equal :rich, editor.mode
176
176
 
177
177
  editor.enter_command_line_mode(":")
@@ -189,7 +189,7 @@ class RichViewTest < Minitest::Test
189
189
  buf.replace_all_lines!(["a\tb"])
190
190
  buf.options["filetype"] = "tsv"
191
191
 
192
- RuVim::RichView.open!(editor, format: "tsv")
192
+ RuVim::RichView.open!(editor, format: :tsv)
193
193
  editor.enter_command_line_mode(":")
194
194
  editor.leave_command_line
195
195
  assert_equal :rich, editor.mode
@@ -210,7 +210,7 @@ class RichViewTest < Minitest::Test
210
210
  buf.replace_all_lines!(["a\tb"])
211
211
  buf.options["filetype"] = "tsv"
212
212
 
213
- RuVim::RichView.open!(editor, format: "tsv")
213
+ RuVim::RichView.open!(editor, format: :tsv)
214
214
  editor.enter_normal_mode
215
215
  assert_nil editor.rich_state
216
216
  assert_equal :normal, editor.mode
@@ -222,7 +222,7 @@ class RichViewTest < Minitest::Test
222
222
  buf.replace_all_lines!(["a\tbb", "ccc\td"])
223
223
  buf.options["filetype"] = "tsv"
224
224
 
225
- RuVim::RichView.open!(editor, format: "tsv")
225
+ RuVim::RichView.open!(editor, format: :tsv)
226
226
  lines = [buf.line_at(0), buf.line_at(1)]
227
227
  rendered = RuVim::RichView.render_visible_lines(editor, lines)
228
228
  assert_equal 2, rendered.length
@@ -236,7 +236,7 @@ class RichViewTest < Minitest::Test
236
236
  buf.options["filetype"] = "tsv"
237
237
  count_before = editor.buffers.length
238
238
 
239
- RuVim::RichView.open!(editor, format: "tsv")
239
+ RuVim::RichView.open!(editor, format: :tsv)
240
240
  assert_equal count_before, editor.buffers.length
241
241
  end
242
242
 
@@ -462,7 +462,7 @@ class RichViewTest < Minitest::Test
462
462
  # --- JSON Rich View tests ---
463
463
 
464
464
  def test_json_registered
465
- assert RuVim::RichView.renderer_for("json")
465
+ assert RuVim::RichView.renderer_for(:json)
466
466
  end
467
467
 
468
468
  def test_json_open_creates_virtual_buffer
@@ -472,7 +472,7 @@ class RichViewTest < Minitest::Test
472
472
  buf.options["filetype"] = "json"
473
473
  count_before = editor.buffers.length
474
474
 
475
- RuVim::RichView.open!(editor, format: "json")
475
+ RuVim::RichView.open!(editor, format: :json)
476
476
  assert_equal count_before + 1, editor.buffers.length
477
477
  new_buf = editor.current_buffer
478
478
  refute_equal buf.id, new_buf.id
@@ -487,7 +487,7 @@ class RichViewTest < Minitest::Test
487
487
  buf.replace_all_lines!(['{"a":1}'])
488
488
  buf.options["filetype"] = "json"
489
489
 
490
- RuVim::RichView.open!(editor, format: "json")
490
+ RuVim::RichView.open!(editor, format: :json)
491
491
  result = editor.keymap_manager.resolve_with_context(:normal, ["\e"], editor: editor)
492
492
  assert_equal "rich.close_buffer", result.invocation.id
493
493
  end
@@ -498,7 +498,7 @@ class RichViewTest < Minitest::Test
498
498
  buf.replace_all_lines!(['{"a":1,"b":[2,3]}'])
499
499
  buf.options["filetype"] = "json"
500
500
 
501
- RuVim::RichView.open!(editor, format: "json")
501
+ RuVim::RichView.open!(editor, format: :json)
502
502
  new_buf = editor.current_buffer
503
503
  lines = new_buf.lines
504
504
  assert lines.length > 1, "Minified JSON should be expanded to multiple lines"
@@ -512,7 +512,7 @@ class RichViewTest < Minitest::Test
512
512
  buf.replace_all_lines!(['{', '"key": "value"', '}'])
513
513
  buf.options["filetype"] = "json"
514
514
 
515
- RuVim::RichView.open!(editor, format: "json")
515
+ RuVim::RichView.open!(editor, format: :json)
516
516
  new_buf = editor.current_buffer
517
517
  lines = new_buf.lines
518
518
  assert lines.length >= 3
@@ -524,7 +524,7 @@ class RichViewTest < Minitest::Test
524
524
  buf.replace_all_lines!(['{"invalid json'])
525
525
  buf.options["filetype"] = "json"
526
526
 
527
- RuVim::RichView.open!(editor, format: "json")
527
+ RuVim::RichView.open!(editor, format: :json)
528
528
  # Should stay on original buffer
529
529
  assert_equal buf.id, editor.current_buffer.id
530
530
  assert_match(/JSON/, editor.message.to_s)
@@ -536,7 +536,7 @@ class RichViewTest < Minitest::Test
536
536
  buf.replace_all_lines!(['{"a":1}'])
537
537
  buf.options["filetype"] = "json"
538
538
 
539
- RuVim::RichView.open!(editor, format: "json")
539
+ RuVim::RichView.open!(editor, format: :json)
540
540
  # Virtual buffer approach — no rich mode
541
541
  assert_equal :normal, editor.mode
542
542
  assert_nil editor.rich_state
@@ -554,7 +554,7 @@ class RichViewTest < Minitest::Test
554
554
  idx = line.index('"c"')
555
555
  editor.current_window.cursor_x = idx
556
556
 
557
- RuVim::RichView.open!(editor, format: "json")
557
+ RuVim::RichView.open!(editor, format: :json)
558
558
  new_buf = editor.current_buffer
559
559
  # Cursor should be on the line containing "c"
560
560
  cursor_line = new_buf.line_at(editor.current_window.cursor_y)
@@ -571,7 +571,7 @@ class RichViewTest < Minitest::Test
571
571
  editor.current_window.cursor_y = 1
572
572
  editor.current_window.cursor_x = 2
573
573
 
574
- RuVim::RichView.open!(editor, format: "json")
574
+ RuVim::RichView.open!(editor, format: :json)
575
575
  new_buf = editor.current_buffer
576
576
  cursor_line = new_buf.line_at(editor.current_window.cursor_y)
577
577
  assert_match(/"x"/, cursor_line, "Cursor should be on the line with \"x\" key")
@@ -584,7 +584,7 @@ class RichViewTest < Minitest::Test
584
584
  buf.options["filetype"] = "json"
585
585
  editor.current_window.cursor_x = 0
586
586
 
587
- RuVim::RichView.open!(editor, format: "json")
587
+ RuVim::RichView.open!(editor, format: :json)
588
588
  assert_equal 0, editor.current_window.cursor_y
589
589
  end
590
590
 
@@ -611,7 +611,7 @@ class RichViewTest < Minitest::Test
611
611
  editor = fresh_editor
612
612
  buf = editor.current_buffer
613
613
  buf.options["filetype"] = "json"
614
- assert_equal "json", RuVim::RichView.detect_format(buf)
614
+ assert_equal :json, RuVim::RichView.detect_format(buf)
615
615
  end
616
616
 
617
617
  # --- Filetype detection tests ---
@@ -639,7 +639,7 @@ class RichViewTest < Minitest::Test
639
639
  # --- JSONL Rich View tests ---
640
640
 
641
641
  def test_jsonl_registered
642
- assert RuVim::RichView.renderer_for("jsonl")
642
+ assert RuVim::RichView.renderer_for(:jsonl)
643
643
  end
644
644
 
645
645
  def test_jsonl_open_creates_virtual_buffer
@@ -649,7 +649,7 @@ class RichViewTest < Minitest::Test
649
649
  buf.options["filetype"] = "jsonl"
650
650
  count_before = editor.buffers.length
651
651
 
652
- RuVim::RichView.open!(editor, format: "jsonl")
652
+ RuVim::RichView.open!(editor, format: :jsonl)
653
653
  assert_equal count_before + 1, editor.buffers.length
654
654
  new_buf = editor.current_buffer
655
655
  refute_equal buf.id, new_buf.id
@@ -664,7 +664,7 @@ class RichViewTest < Minitest::Test
664
664
  buf.replace_all_lines!(['{"a":1}', '{"b":2}'])
665
665
  buf.options["filetype"] = "jsonl"
666
666
 
667
- RuVim::RichView.open!(editor, format: "jsonl")
667
+ RuVim::RichView.open!(editor, format: :jsonl)
668
668
  result = editor.keymap_manager.resolve_with_context(:normal, ["\e"], editor: editor)
669
669
  assert_equal "rich.close_buffer", result.invocation.id
670
670
  end
@@ -675,7 +675,7 @@ class RichViewTest < Minitest::Test
675
675
  buf.replace_all_lines!(['{"a":1,"b":[2,3]}', '{"c":4}'])
676
676
  buf.options["filetype"] = "jsonl"
677
677
 
678
- RuVim::RichView.open!(editor, format: "jsonl")
678
+ RuVim::RichView.open!(editor, format: :jsonl)
679
679
  new_buf = editor.current_buffer
680
680
  lines = new_buf.lines
681
681
  # Each JSON object should be expanded; separated by "---"
@@ -690,7 +690,7 @@ class RichViewTest < Minitest::Test
690
690
  buf.options["filetype"] = "jsonl"
691
691
  editor.current_window.cursor_y = 1 # on second entry
692
692
 
693
- RuVim::RichView.open!(editor, format: "jsonl")
693
+ RuVim::RichView.open!(editor, format: :jsonl)
694
694
  new_buf = editor.current_buffer
695
695
  cy = editor.current_window.cursor_y
696
696
  # Cursor should be within the second entry's formatted block
@@ -704,7 +704,7 @@ class RichViewTest < Minitest::Test
704
704
  buf.replace_all_lines!(['{"a":1}', '', '{"b":2}'])
705
705
  buf.options["filetype"] = "jsonl"
706
706
 
707
- RuVim::RichView.open!(editor, format: "jsonl")
707
+ RuVim::RichView.open!(editor, format: :jsonl)
708
708
  new_buf = editor.current_buffer
709
709
  lines = new_buf.lines
710
710
  # Should contain both entries
@@ -718,7 +718,7 @@ class RichViewTest < Minitest::Test
718
718
  buf.replace_all_lines!(['{"a":1}', 'bad json', '{"b":2}'])
719
719
  buf.options["filetype"] = "jsonl"
720
720
 
721
- RuVim::RichView.open!(editor, format: "jsonl")
721
+ RuVim::RichView.open!(editor, format: :jsonl)
722
722
  new_buf = editor.current_buffer
723
723
  lines = new_buf.lines
724
724
  # Invalid line should show an error marker
@@ -729,6 +729,6 @@ class RichViewTest < Minitest::Test
729
729
  editor = fresh_editor
730
730
  buf = editor.current_buffer
731
731
  buf.options["filetype"] = "jsonl"
732
- assert_equal "jsonl", RuVim::RichView.detect_format(buf)
732
+ assert_equal :jsonl, RuVim::RichView.detect_format(buf)
733
733
  end
734
734
  end