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.
- checksums.yaml +4 -4
- data/AGENTS.md +53 -4
- data/README.md +15 -6
- data/Rakefile +7 -0
- data/benchmark/cext_compare.rb +165 -0
- data/benchmark/chunked_load.rb +256 -0
- data/benchmark/file_load.rb +140 -0
- data/benchmark/hotspots.rb +178 -0
- data/docs/binding.md +3 -2
- data/docs/command.md +81 -9
- data/docs/done.md +23 -0
- data/docs/spec.md +105 -19
- data/docs/todo.md +9 -0
- data/docs/tutorial.md +9 -1
- data/docs/vim_diff.md +13 -0
- data/ext/ruvim/extconf.rb +5 -0
- data/ext/ruvim/ruvim_ext.c +519 -0
- data/lib/ruvim/app.rb +217 -2778
- data/lib/ruvim/browser.rb +104 -0
- data/lib/ruvim/buffer.rb +39 -28
- data/lib/ruvim/command_invocation.rb +2 -2
- data/lib/ruvim/completion_manager.rb +708 -0
- data/lib/ruvim/dispatcher.rb +14 -8
- data/lib/ruvim/display_width.rb +91 -45
- data/lib/ruvim/editor.rb +64 -81
- data/lib/ruvim/ex_command_registry.rb +3 -1
- data/lib/ruvim/gh/link.rb +207 -0
- data/lib/ruvim/git/blame.rb +16 -6
- data/lib/ruvim/git/branch.rb +20 -5
- data/lib/ruvim/git/grep.rb +107 -0
- data/lib/ruvim/git/handler.rb +42 -1
- data/lib/ruvim/global_commands.rb +175 -35
- data/lib/ruvim/highlighter.rb +4 -13
- data/lib/ruvim/key_handler.rb +1510 -0
- data/lib/ruvim/keymap_manager.rb +7 -7
- data/lib/ruvim/lang/base.rb +5 -0
- data/lib/ruvim/lang/c.rb +116 -0
- data/lib/ruvim/lang/cpp.rb +107 -0
- data/lib/ruvim/lang/csv.rb +4 -1
- data/lib/ruvim/lang/diff.rb +2 -0
- data/lib/ruvim/lang/dockerfile.rb +36 -0
- data/lib/ruvim/lang/elixir.rb +85 -0
- data/lib/ruvim/lang/erb.rb +30 -0
- data/lib/ruvim/lang/go.rb +83 -0
- data/lib/ruvim/lang/html.rb +34 -0
- data/lib/ruvim/lang/javascript.rb +83 -0
- data/lib/ruvim/lang/json.rb +6 -0
- data/lib/ruvim/lang/lua.rb +76 -0
- data/lib/ruvim/lang/makefile.rb +36 -0
- data/lib/ruvim/lang/markdown.rb +3 -4
- data/lib/ruvim/lang/ocaml.rb +77 -0
- data/lib/ruvim/lang/perl.rb +91 -0
- data/lib/ruvim/lang/python.rb +85 -0
- data/lib/ruvim/lang/registry.rb +102 -0
- data/lib/ruvim/lang/ruby.rb +7 -0
- data/lib/ruvim/lang/rust.rb +95 -0
- data/lib/ruvim/lang/scheme.rb +5 -0
- data/lib/ruvim/lang/sh.rb +76 -0
- data/lib/ruvim/lang/sql.rb +52 -0
- data/lib/ruvim/lang/toml.rb +36 -0
- data/lib/ruvim/lang/tsv.rb +4 -1
- data/lib/ruvim/lang/typescript.rb +53 -0
- data/lib/ruvim/lang/yaml.rb +62 -0
- data/lib/ruvim/rich_view/table_renderer.rb +3 -3
- data/lib/ruvim/rich_view.rb +14 -7
- data/lib/ruvim/screen.rb +126 -72
- data/lib/ruvim/stream/file_load.rb +85 -0
- data/lib/ruvim/stream/follow.rb +40 -0
- data/lib/ruvim/stream/git.rb +43 -0
- data/lib/ruvim/stream/run.rb +74 -0
- data/lib/ruvim/stream/stdin.rb +55 -0
- data/lib/ruvim/stream.rb +35 -0
- data/lib/ruvim/stream_mixer.rb +394 -0
- data/lib/ruvim/terminal.rb +18 -4
- data/lib/ruvim/text_metrics.rb +84 -65
- data/lib/ruvim/version.rb +1 -1
- data/lib/ruvim/window.rb +5 -5
- data/lib/ruvim.rb +23 -6
- data/test/app_command_test.rb +382 -0
- data/test/app_completion_test.rb +43 -19
- data/test/app_dot_repeat_test.rb +27 -3
- data/test/app_ex_command_test.rb +154 -0
- data/test/app_motion_test.rb +13 -12
- data/test/app_register_test.rb +2 -1
- data/test/app_scenario_test.rb +15 -10
- data/test/app_startup_test.rb +70 -27
- data/test/app_text_object_test.rb +2 -1
- data/test/app_unicode_behavior_test.rb +3 -2
- data/test/browser_test.rb +88 -0
- data/test/buffer_test.rb +24 -0
- data/test/cli_test.rb +63 -0
- data/test/command_invocation_test.rb +33 -0
- data/test/config_dsl_test.rb +47 -0
- data/test/dispatcher_test.rb +74 -4
- data/test/ex_command_registry_test.rb +106 -0
- data/test/follow_test.rb +20 -21
- data/test/gh_link_test.rb +141 -0
- data/test/git_blame_test.rb +96 -17
- data/test/git_grep_test.rb +64 -0
- data/test/highlighter_test.rb +125 -0
- data/test/indent_test.rb +137 -0
- data/test/input_screen_integration_test.rb +1 -1
- data/test/keyword_chars_test.rb +85 -0
- data/test/lang_test.rb +634 -0
- data/test/markdown_renderer_test.rb +5 -5
- data/test/on_save_hook_test.rb +12 -8
- data/test/render_snapshot_test.rb +78 -0
- data/test/rich_view_test.rb +42 -42
- data/test/run_command_test.rb +307 -0
- data/test/screen_test.rb +68 -5
- data/test/stream_test.rb +165 -0
- data/test/window_test.rb +59 -0
- metadata +52 -2
data/test/on_save_hook_test.rb
CHANGED
|
@@ -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|
|
|
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
|
-
|
|
88
|
-
":
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
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|
|
|
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|
|
|
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
|
data/test/rich_view_test.rb
CHANGED
|
@@ -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(
|
|
8
|
-
assert RuVim::RichView.renderer_for(
|
|
9
|
-
assert_nil RuVim::RichView.renderer_for(
|
|
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,
|
|
15
|
-
assert_includes fts,
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
127
|
+
RuVim::RichView.open!(editor, format: :tsv)
|
|
128
128
|
state = editor.rich_state
|
|
129
|
-
assert_equal
|
|
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:
|
|
139
|
+
RuVim::RichView.open!(editor, format: :csv)
|
|
140
140
|
state = editor.rich_state
|
|
141
|
-
assert_equal
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
732
|
+
assert_equal :jsonl, RuVim::RichView.detect_format(buf)
|
|
733
733
|
end
|
|
734
734
|
end
|