ruvim 0.2.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +4 -0
- data/AGENTS.md +84 -0
- data/CLAUDE.md +1 -0
- data/docs/binding.md +23 -0
- data/docs/command.md +85 -0
- data/docs/config.md +2 -2
- data/docs/done.md +21 -0
- data/docs/spec.md +157 -12
- data/docs/todo.md +1 -5
- data/docs/vim_diff.md +94 -172
- data/lib/ruvim/app.rb +882 -69
- data/lib/ruvim/buffer.rb +35 -1
- data/lib/ruvim/cli.rb +12 -3
- data/lib/ruvim/clipboard.rb +2 -0
- data/lib/ruvim/command_invocation.rb +3 -1
- data/lib/ruvim/command_line.rb +2 -0
- data/lib/ruvim/command_registry.rb +2 -0
- data/lib/ruvim/config_dsl.rb +2 -0
- data/lib/ruvim/config_loader.rb +2 -0
- data/lib/ruvim/context.rb +2 -0
- data/lib/ruvim/dispatcher.rb +143 -13
- data/lib/ruvim/display_width.rb +3 -0
- data/lib/ruvim/editor.rb +455 -71
- data/lib/ruvim/ex_command_registry.rb +2 -0
- data/lib/ruvim/global_commands.rb +890 -63
- data/lib/ruvim/highlighter.rb +16 -21
- data/lib/ruvim/input.rb +39 -28
- data/lib/ruvim/keymap_manager.rb +83 -0
- data/lib/ruvim/keyword_chars.rb +2 -0
- data/lib/ruvim/lang/base.rb +25 -0
- data/lib/ruvim/lang/csv.rb +18 -0
- data/lib/ruvim/lang/json.rb +18 -0
- data/lib/ruvim/lang/markdown.rb +170 -0
- data/lib/ruvim/lang/ruby.rb +236 -0
- data/lib/ruvim/lang/scheme.rb +44 -0
- data/lib/ruvim/lang/tsv.rb +19 -0
- data/lib/ruvim/rich_view/markdown_renderer.rb +248 -0
- data/lib/ruvim/rich_view/table_renderer.rb +176 -0
- data/lib/ruvim/rich_view.rb +93 -0
- data/lib/ruvim/screen.rb +503 -106
- data/lib/ruvim/terminal.rb +18 -1
- data/lib/ruvim/text_metrics.rb +2 -0
- data/lib/ruvim/version.rb +1 -1
- data/lib/ruvim/window.rb +2 -0
- data/lib/ruvim.rb +14 -0
- data/test/app_completion_test.rb +73 -0
- data/test/app_dot_repeat_test.rb +13 -0
- data/test/app_motion_test.rb +13 -0
- data/test/app_scenario_test.rb +729 -1
- data/test/app_startup_test.rb +187 -0
- data/test/arglist_test.rb +113 -0
- data/test/buffer_test.rb +49 -30
- data/test/dispatcher_test.rb +322 -0
- data/test/editor_register_test.rb +23 -0
- data/test/highlighter_test.rb +121 -0
- data/test/indent_test.rb +201 -0
- data/test/input_screen_integration_test.rb +40 -2
- data/test/markdown_renderer_test.rb +279 -0
- data/test/on_save_hook_test.rb +150 -0
- data/test/rich_view_test.rb +478 -0
- data/test/screen_test.rb +304 -0
- metadata +33 -2
data/test/screen_test.rb
CHANGED
|
@@ -101,6 +101,36 @@ class ScreenTest < Minitest::Test
|
|
|
101
101
|
assert_includes out, "boom"
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
+
def test_status_line_shows_stream_state_for_stdin_buffer
|
|
105
|
+
editor = RuVim::Editor.new
|
|
106
|
+
buf = editor.add_virtual_buffer(kind: :stream, name: "[stdin]", lines: [""], readonly: true, modifiable: false)
|
|
107
|
+
buf.stream_state = :closed
|
|
108
|
+
editor.add_window(buffer_id: buf.id)
|
|
109
|
+
|
|
110
|
+
term = TerminalStub.new([6, 60])
|
|
111
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
112
|
+
line = screen.send(:status_line, editor, 60)
|
|
113
|
+
|
|
114
|
+
assert_includes line, "[stdin/closed]"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_render_uses_dim_and_brighter_line_number_gutter_colors
|
|
118
|
+
editor = RuVim::Editor.new
|
|
119
|
+
buf = editor.add_empty_buffer
|
|
120
|
+
win = editor.add_window(buffer_id: buf.id)
|
|
121
|
+
buf.replace_all_lines!(["foo", "bar"])
|
|
122
|
+
editor.set_option("number", true, scope: :window, window: win, buffer: buf)
|
|
123
|
+
win.cursor_y = 1
|
|
124
|
+
|
|
125
|
+
term = TerminalStub.new([6, 20])
|
|
126
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
127
|
+
screen.render(editor)
|
|
128
|
+
out = term.writes.last
|
|
129
|
+
|
|
130
|
+
assert_includes out, "\e[90m"
|
|
131
|
+
assert_includes out, "\e[37m"
|
|
132
|
+
end
|
|
133
|
+
|
|
104
134
|
def test_render_reuses_syntax_highlight_cache_for_same_line
|
|
105
135
|
editor = RuVim::Editor.new
|
|
106
136
|
buf = editor.add_empty_buffer
|
|
@@ -132,6 +162,40 @@ class ScreenTest < Minitest::Test
|
|
|
132
162
|
assert_equal 1, calls
|
|
133
163
|
end
|
|
134
164
|
|
|
165
|
+
def test_render_reuses_wrap_segment_cache_for_same_line
|
|
166
|
+
editor = RuVim::Editor.new
|
|
167
|
+
buf = editor.add_empty_buffer
|
|
168
|
+
win = editor.add_window(buffer_id: buf.id)
|
|
169
|
+
buf.replace_all_lines!(["x" * 400])
|
|
170
|
+
editor.set_option("wrap", true, scope: :window, window: win, buffer: buf)
|
|
171
|
+
|
|
172
|
+
term = TerminalStub.new([8, 20])
|
|
173
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
174
|
+
|
|
175
|
+
calls = [0, 0]
|
|
176
|
+
render_index = 0
|
|
177
|
+
mod = RuVim::TextMetrics.singleton_class
|
|
178
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
|
179
|
+
mod.alias_method(:__orig_clip_cells_for_width_for_screen_test, :clip_cells_for_width)
|
|
180
|
+
mod.define_method(:clip_cells_for_width) do |*args, **kwargs|
|
|
181
|
+
calls[render_index] += 1
|
|
182
|
+
__orig_clip_cells_for_width_for_screen_test(*args, **kwargs)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
begin
|
|
186
|
+
render_index = 0
|
|
187
|
+
screen.render(editor)
|
|
188
|
+
render_index = 1
|
|
189
|
+
screen.render(editor)
|
|
190
|
+
ensure
|
|
191
|
+
mod.alias_method(:clip_cells_for_width, :__orig_clip_cells_for_width_for_screen_test)
|
|
192
|
+
mod.remove_method(:__orig_clip_cells_for_width_for_screen_test) rescue nil
|
|
193
|
+
$VERBOSE = verbose
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
assert_operator calls[1], :<, calls[0]
|
|
197
|
+
end
|
|
198
|
+
|
|
135
199
|
def test_render_text_line_with_cursor_search_and_syntax_highlights_fits_width
|
|
136
200
|
editor = RuVim::Editor.new
|
|
137
201
|
buf = editor.add_empty_buffer
|
|
@@ -286,4 +350,244 @@ class ScreenTest < Minitest::Test
|
|
|
286
350
|
assert_includes row2, ">"
|
|
287
351
|
assert_match(/\s>|\>\s/, row2)
|
|
288
352
|
end
|
|
353
|
+
|
|
354
|
+
def test_wrap_keeps_cursor_visible_after_very_long_previous_line
|
|
355
|
+
editor = RuVim::Editor.new
|
|
356
|
+
buf = editor.add_empty_buffer
|
|
357
|
+
win = editor.add_window(buffer_id: buf.id)
|
|
358
|
+
buf.replace_all_lines!(["x" * 200, "tail"])
|
|
359
|
+
editor.set_option("wrap", true, scope: :window, window: win, buffer: buf)
|
|
360
|
+
win.cursor_y = 1
|
|
361
|
+
win.cursor_x = 0
|
|
362
|
+
|
|
363
|
+
term = TerminalStub.new([6, 8]) # text_rows=4, content width ~8 (no gutter)
|
|
364
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
365
|
+
screen.render(editor)
|
|
366
|
+
|
|
367
|
+
assert_equal 1, win.row_offset
|
|
368
|
+
|
|
369
|
+
rows, cols = term.winsize
|
|
370
|
+
text_rows, text_cols = editor.text_viewport_size(rows:, cols:)
|
|
371
|
+
rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
|
|
372
|
+
row, _col = screen.send(:cursor_screen_position, editor, text_rows, rects)
|
|
373
|
+
assert_equal 1, row
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def test_rich_mode_horizontal_scroll_preserves_column_alignment
|
|
377
|
+
editor = RuVim::Editor.new
|
|
378
|
+
buf = editor.add_empty_buffer
|
|
379
|
+
win = editor.add_window(buffer_id: buf.id)
|
|
380
|
+
# Create rows where raw lines differ in length but formatted lines are aligned
|
|
381
|
+
buf.replace_all_lines!(["Short\tSecond\tThird", "LongerField\tB\tC"])
|
|
382
|
+
buf.options["filetype"] = "tsv"
|
|
383
|
+
RuVim::RichView.open!(editor, format: "tsv")
|
|
384
|
+
|
|
385
|
+
# Move cursor to end of line (like pressing $)
|
|
386
|
+
win.cursor_y = 0
|
|
387
|
+
win.cursor_x = buf.line_length(0)
|
|
388
|
+
|
|
389
|
+
# Use a narrow terminal so that the formatted line won't fit
|
|
390
|
+
term = TerminalStub.new([6, 20])
|
|
391
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
392
|
+
screen.render(editor)
|
|
393
|
+
|
|
394
|
+
# After render, col_offset should be in formatted space.
|
|
395
|
+
# Both rendered lines should use the same col_offset, keeping separators aligned.
|
|
396
|
+
rows_key, cols_key = term.winsize
|
|
397
|
+
text_rows, text_cols = editor.text_viewport_size(rows: rows_key, cols: cols_key)
|
|
398
|
+
rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
|
|
399
|
+
frame = screen.send(:build_frame, editor, rows: rows_key, cols: cols_key, text_rows:, text_cols:, rects:)
|
|
400
|
+
|
|
401
|
+
# Strip ANSI and check that "|" separators are at the same column in both rows
|
|
402
|
+
row1 = frame[:lines][1].to_s.gsub(/\e\[[0-9;?]*[A-Za-z]/, "")
|
|
403
|
+
row2 = frame[:lines][2].to_s.gsub(/\e\[[0-9;?]*[A-Za-z]/, "")
|
|
404
|
+
|
|
405
|
+
sep_positions_row1 = row1.enum_for(:scan, /\|/).map { Regexp.last_match.begin(0) }
|
|
406
|
+
sep_positions_row2 = row2.enum_for(:scan, /\|/).map { Regexp.last_match.begin(0) }
|
|
407
|
+
|
|
408
|
+
# They should have the same separator positions (column alignment preserved)
|
|
409
|
+
assert_equal sep_positions_row1, sep_positions_row2,
|
|
410
|
+
"Separators should align: row1=#{row1.inspect} row2=#{row2.inspect}"
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
def test_rich_mode_cjk_horizontal_scroll_preserves_display_column_alignment
|
|
414
|
+
editor = RuVim::Editor.new
|
|
415
|
+
buf = editor.add_empty_buffer
|
|
416
|
+
win = editor.add_window(buffer_id: buf.id)
|
|
417
|
+
buf.replace_all_lines!([
|
|
418
|
+
"色\t果物名\t産地",
|
|
419
|
+
"赤\tりんご\t青森",
|
|
420
|
+
"緑\tキウイフルーツジャム\t静岡"
|
|
421
|
+
])
|
|
422
|
+
buf.options["filetype"] = "tsv"
|
|
423
|
+
RuVim::RichView.open!(editor, format: "tsv")
|
|
424
|
+
|
|
425
|
+
# Move to end of line to trigger horizontal scroll
|
|
426
|
+
win.cursor_y = 2
|
|
427
|
+
win.cursor_x = buf.line_length(2)
|
|
428
|
+
|
|
429
|
+
# Narrow terminal so formatted line doesn't fit
|
|
430
|
+
term = TerminalStub.new([6, 30])
|
|
431
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
432
|
+
screen.render(editor)
|
|
433
|
+
|
|
434
|
+
rows_key, cols_key = term.winsize
|
|
435
|
+
text_rows, text_cols = editor.text_viewport_size(rows: rows_key, cols: cols_key)
|
|
436
|
+
rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
|
|
437
|
+
frame = screen.send(:build_frame, editor, rows: rows_key, cols: cols_key, text_rows:, text_cols:, rects:)
|
|
438
|
+
|
|
439
|
+
# Strip ANSI, collect visible lines
|
|
440
|
+
visible_rows = (1..3).map do |r|
|
|
441
|
+
frame[:lines][r].to_s.gsub(/\e\[[0-9;?]*[A-Za-z]/, "")
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
# All rows should have separator "|" at the same display column
|
|
445
|
+
pipe_display_cols = visible_rows.map do |row|
|
|
446
|
+
col = 0
|
|
447
|
+
pipe_col = nil
|
|
448
|
+
row.each_char do |ch|
|
|
449
|
+
if ch == "|"
|
|
450
|
+
pipe_col = col
|
|
451
|
+
break
|
|
452
|
+
end
|
|
453
|
+
col += RuVim::DisplayWidth.cell_width(ch, col: col, tabstop: 2)
|
|
454
|
+
end
|
|
455
|
+
pipe_col
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
# Filter out rows where pipe might not be visible (scrolled away)
|
|
459
|
+
visible_pipes = pipe_display_cols.compact
|
|
460
|
+
assert(visible_pipes.length >= 2, "At least 2 rows should show a pipe separator")
|
|
461
|
+
assert_equal 1, visible_pipes.uniq.length,
|
|
462
|
+
"Pipe separators should align at same display column: #{pipe_display_cols.inspect} in #{visible_rows.inspect}"
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def test_truncate_respects_display_width_for_wide_chars
|
|
466
|
+
editor = RuVim::Editor.new
|
|
467
|
+
buf = editor.add_empty_buffer
|
|
468
|
+
editor.add_window(buffer_id: buf.id)
|
|
469
|
+
term = TerminalStub.new([6, 20])
|
|
470
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
471
|
+
|
|
472
|
+
# "Unknown key: あ" => 13 ASCII + 1 wide char (display width 2) = 15 display cols
|
|
473
|
+
result = screen.send(:truncate, "Unknown key: あ", 20)
|
|
474
|
+
dw = RuVim::DisplayWidth.display_width(result)
|
|
475
|
+
assert_equal 20, dw, "truncate must produce exactly 20 display columns, got #{dw}"
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def test_error_message_with_wide_char_does_not_exceed_terminal_width
|
|
479
|
+
editor = RuVim::Editor.new
|
|
480
|
+
buf = editor.add_empty_buffer
|
|
481
|
+
editor.add_window(buffer_id: buf.id)
|
|
482
|
+
|
|
483
|
+
editor.echo_error("Unknown key: あ")
|
|
484
|
+
|
|
485
|
+
term = TerminalStub.new([6, 20])
|
|
486
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
487
|
+
|
|
488
|
+
rows, cols = term.winsize
|
|
489
|
+
text_rows, text_cols = editor.text_viewport_size(rows:, cols:)
|
|
490
|
+
rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
|
|
491
|
+
frame = screen.send(:build_frame, editor, rows:, cols:, text_rows:, text_cols:, rects:)
|
|
492
|
+
|
|
493
|
+
error_row = frame[:lines][text_rows + 2]
|
|
494
|
+
# Strip ANSI codes and measure display width
|
|
495
|
+
plain = error_row.to_s.gsub(/\e\[[0-9;?]*[A-Za-z]/, "")
|
|
496
|
+
dw = RuVim::DisplayWidth.display_width(plain)
|
|
497
|
+
assert_operator dw, :<=, cols, "error line display width #{dw} exceeds terminal cols #{cols}"
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def test_rich_mode_cursor_visible_after_end_of_line
|
|
501
|
+
editor = RuVim::Editor.new
|
|
502
|
+
buf = editor.add_empty_buffer
|
|
503
|
+
win = editor.add_window(buffer_id: buf.id)
|
|
504
|
+
buf.replace_all_lines!(["A\tB\tC", "DD\tEE\tFF"])
|
|
505
|
+
buf.options["filetype"] = "tsv"
|
|
506
|
+
RuVim::RichView.open!(editor, format: "tsv")
|
|
507
|
+
|
|
508
|
+
# Move cursor to end of raw line
|
|
509
|
+
win.cursor_y = 0
|
|
510
|
+
win.cursor_x = buf.line_length(0) # last char
|
|
511
|
+
|
|
512
|
+
# Narrow terminal
|
|
513
|
+
term = TerminalStub.new([6, 15])
|
|
514
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
515
|
+
screen.render(editor)
|
|
516
|
+
|
|
517
|
+
rows_key, cols_key = term.winsize
|
|
518
|
+
text_rows, text_cols = editor.text_viewport_size(rows: rows_key, cols: cols_key)
|
|
519
|
+
rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
|
|
520
|
+
_cursor_row, cursor_col = screen.send(:cursor_screen_position, editor, text_rows, rects)
|
|
521
|
+
|
|
522
|
+
# Cursor should be within the visible area
|
|
523
|
+
assert_operator cursor_col, :>=, 1
|
|
524
|
+
assert_operator cursor_col, :<=, cols_key
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def test_status_line_shows_tab_indicator_when_multiple_tabs
|
|
528
|
+
editor = RuVim::Editor.new
|
|
529
|
+
buf = editor.add_empty_buffer
|
|
530
|
+
editor.add_window(buffer_id: buf.id)
|
|
531
|
+
editor.tabnew
|
|
532
|
+
editor.tabnew
|
|
533
|
+
|
|
534
|
+
term = TerminalStub.new([6, 60])
|
|
535
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
536
|
+
line = screen.send(:status_line, editor, 60)
|
|
537
|
+
|
|
538
|
+
assert_includes line, "tab:3/3"
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def test_status_line_hides_tab_indicator_when_single_tab
|
|
542
|
+
editor = RuVim::Editor.new
|
|
543
|
+
buf = editor.add_empty_buffer
|
|
544
|
+
editor.add_window(buffer_id: buf.id)
|
|
545
|
+
|
|
546
|
+
term = TerminalStub.new([6, 60])
|
|
547
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
548
|
+
line = screen.send(:status_line, editor, 60)
|
|
549
|
+
|
|
550
|
+
refute_includes line, "tab:"
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def test_window_rects_nested_vsplit_hsplit
|
|
554
|
+
editor = RuVim::Editor.new
|
|
555
|
+
buf = editor.add_empty_buffer
|
|
556
|
+
# win1
|
|
557
|
+
editor.add_window(buffer_id: buf.id)
|
|
558
|
+
win1 = editor.current_window
|
|
559
|
+
# vsplit → win2
|
|
560
|
+
editor.split_current_window(layout: :vertical)
|
|
561
|
+
win2 = editor.current_window
|
|
562
|
+
# split win2 → win3
|
|
563
|
+
editor.split_current_window(layout: :horizontal)
|
|
564
|
+
win3 = editor.current_window
|
|
565
|
+
|
|
566
|
+
term = TerminalStub.new([22, 80])
|
|
567
|
+
screen = RuVim::Screen.new(terminal: term)
|
|
568
|
+
rows, cols = term.winsize
|
|
569
|
+
text_rows, text_cols = editor.text_viewport_size(rows:, cols:)
|
|
570
|
+
rects = screen.send(:window_rects, editor, text_rows:, text_cols:)
|
|
571
|
+
|
|
572
|
+
# All three windows should have rects
|
|
573
|
+
assert rects.key?(win1.id), "win1 should have a rect"
|
|
574
|
+
assert rects.key?(win2.id), "win2 should have a rect"
|
|
575
|
+
assert rects.key?(win3.id), "win3 should have a rect"
|
|
576
|
+
|
|
577
|
+
# win1 should be on the left, win2/win3 should be on the right
|
|
578
|
+
assert_operator rects[win1.id][:left], :<, rects[win2.id][:left]
|
|
579
|
+
assert_operator rects[win1.id][:left], :<, rects[win3.id][:left]
|
|
580
|
+
|
|
581
|
+
# win2 and win3 should share the same left position (same column)
|
|
582
|
+
assert_equal rects[win2.id][:left], rects[win3.id][:left]
|
|
583
|
+
|
|
584
|
+
# win2 should be above win3
|
|
585
|
+
assert_operator rects[win2.id][:top], :<, rects[win3.id][:top]
|
|
586
|
+
|
|
587
|
+
# win1 should span the full height
|
|
588
|
+
assert_equal rects[win1.id][:height], text_rows
|
|
589
|
+
|
|
590
|
+
# win2 + win3 heights + separator should equal text_rows
|
|
591
|
+
assert_equal text_rows, rects[win2.id][:height] + rects[win3.id][:height] + 1
|
|
592
|
+
end
|
|
289
593
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruvim
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Koichi Sasada
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: minitest
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
12
26
|
description: vim clone on Ruby by codex
|
|
13
27
|
email:
|
|
14
28
|
- ko1@atdot.net
|
|
@@ -18,6 +32,8 @@ extensions: []
|
|
|
18
32
|
extra_rdoc_files: []
|
|
19
33
|
files:
|
|
20
34
|
- ".github/workflows/test.yml"
|
|
35
|
+
- AGENTS.md
|
|
36
|
+
- CLAUDE.md
|
|
21
37
|
- README.md
|
|
22
38
|
- Rakefile
|
|
23
39
|
- docs/binding.md
|
|
@@ -51,6 +67,16 @@ files:
|
|
|
51
67
|
- lib/ruvim/input.rb
|
|
52
68
|
- lib/ruvim/keymap_manager.rb
|
|
53
69
|
- lib/ruvim/keyword_chars.rb
|
|
70
|
+
- lib/ruvim/lang/base.rb
|
|
71
|
+
- lib/ruvim/lang/csv.rb
|
|
72
|
+
- lib/ruvim/lang/json.rb
|
|
73
|
+
- lib/ruvim/lang/markdown.rb
|
|
74
|
+
- lib/ruvim/lang/ruby.rb
|
|
75
|
+
- lib/ruvim/lang/scheme.rb
|
|
76
|
+
- lib/ruvim/lang/tsv.rb
|
|
77
|
+
- lib/ruvim/rich_view.rb
|
|
78
|
+
- lib/ruvim/rich_view/markdown_renderer.rb
|
|
79
|
+
- lib/ruvim/rich_view/table_renderer.rb
|
|
54
80
|
- lib/ruvim/screen.rb
|
|
55
81
|
- lib/ruvim/terminal.rb
|
|
56
82
|
- lib/ruvim/text_metrics.rb
|
|
@@ -65,6 +91,7 @@ files:
|
|
|
65
91
|
- test/app_startup_test.rb
|
|
66
92
|
- test/app_text_object_test.rb
|
|
67
93
|
- test/app_unicode_behavior_test.rb
|
|
94
|
+
- test/arglist_test.rb
|
|
68
95
|
- test/buffer_test.rb
|
|
69
96
|
- test/cli_test.rb
|
|
70
97
|
- test/config_dsl_test.rb
|
|
@@ -77,9 +104,13 @@ files:
|
|
|
77
104
|
- test/fixtures/render_basic_snapshot_nonumber.txt
|
|
78
105
|
- test/fixtures/render_unicode_scrolled_snapshot.txt
|
|
79
106
|
- test/highlighter_test.rb
|
|
107
|
+
- test/indent_test.rb
|
|
80
108
|
- test/input_screen_integration_test.rb
|
|
81
109
|
- test/keymap_manager_test.rb
|
|
110
|
+
- test/markdown_renderer_test.rb
|
|
111
|
+
- test/on_save_hook_test.rb
|
|
82
112
|
- test/render_snapshot_test.rb
|
|
113
|
+
- test/rich_view_test.rb
|
|
83
114
|
- test/screen_test.rb
|
|
84
115
|
- test/search_option_test.rb
|
|
85
116
|
- test/test_helper.rb
|