ruvim 0.2.0 → 0.4.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 +96 -0
- data/CLAUDE.md +1 -0
- data/README.md +15 -1
- data/docs/binding.md +39 -0
- data/docs/command.md +163 -4
- data/docs/config.md +12 -4
- data/docs/done.md +21 -0
- data/docs/spec.md +214 -18
- data/docs/todo.md +1 -5
- data/docs/tutorial.md +24 -0
- data/docs/vim_diff.md +105 -173
- data/lib/ruvim/app.rb +1165 -70
- data/lib/ruvim/buffer.rb +47 -1
- data/lib/ruvim/cli.rb +18 -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 +466 -71
- data/lib/ruvim/ex_command_registry.rb +2 -0
- data/lib/ruvim/file_watcher.rb +243 -0
- data/lib/ruvim/git/blame.rb +245 -0
- data/lib/ruvim/git/branch.rb +97 -0
- data/lib/ruvim/git/commit.rb +102 -0
- data/lib/ruvim/git/diff.rb +129 -0
- data/lib/ruvim/git/handler.rb +84 -0
- data/lib/ruvim/git/log.rb +41 -0
- data/lib/ruvim/git/status.rb +103 -0
- data/lib/ruvim/global_commands.rb +1066 -105
- data/lib/ruvim/highlighter.rb +19 -22
- data/lib/ruvim/input.rb +40 -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/diff.rb +41 -0
- data/lib/ruvim/lang/json.rb +52 -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/json_renderer.rb +131 -0
- data/lib/ruvim/rich_view/jsonl_renderer.rb +57 -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 +109 -0
- data/lib/ruvim/screen.rb +503 -109
- 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 +24 -0
- data/test/app_completion_test.rb +98 -0
- data/test/app_dot_repeat_test.rb +13 -0
- data/test/app_motion_test.rb +13 -0
- data/test/app_scenario_test.rb +898 -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/cli_test.rb +14 -0
- data/test/clipboard_test.rb +67 -0
- data/test/command_line_test.rb +118 -0
- data/test/config_dsl_test.rb +87 -0
- data/test/dispatcher_test.rb +322 -0
- data/test/display_width_test.rb +41 -0
- data/test/editor_register_test.rb +23 -0
- data/test/file_watcher_test.rb +197 -0
- data/test/follow_test.rb +199 -0
- data/test/git_blame_test.rb +713 -0
- data/test/highlighter_test.rb +165 -0
- data/test/indent_test.rb +287 -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 +734 -0
- data/test/screen_test.rb +304 -0
- data/test/search_option_test.rb +19 -0
- data/test/test_helper.rb +9 -0
- metadata +49 -2
data/test/highlighter_test.rb
CHANGED
|
@@ -13,4 +13,169 @@ class HighlighterTest < Minitest::Test
|
|
|
13
13
|
assert_equal "\e[36m", cols[1] # key chars
|
|
14
14
|
assert_equal "\e[33m", cols[6] # number start
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
def test_jsonl_highlighter_reuses_json_colors
|
|
18
|
+
cols = RuVim::Highlighter.color_columns("jsonl", '{"a": 10}')
|
|
19
|
+
assert_equal "\e[36m", cols[1] # key chars
|
|
20
|
+
assert_equal "\e[33m", cols[6] # number start
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_ruby_highlighter_marks_instance_variables_and_constants
|
|
24
|
+
cols = RuVim::Highlighter.color_columns("ruby", "@x = Foo")
|
|
25
|
+
assert_equal "\e[93m", cols[0] # @x
|
|
26
|
+
assert_equal "\e[96m", cols[5] # F
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# --- Markdown ---
|
|
30
|
+
|
|
31
|
+
def test_markdown_heading_h1
|
|
32
|
+
cols = RuVim::Highlighter.color_columns("markdown", "# Hello")
|
|
33
|
+
refute_empty cols
|
|
34
|
+
assert_equal "\e[1;33m", cols[0] # bold yellow for H1
|
|
35
|
+
assert_equal "\e[1;33m", cols[6] # entire line colored
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_markdown_heading_h2
|
|
39
|
+
cols = RuVim::Highlighter.color_columns("markdown", "## Section")
|
|
40
|
+
assert_equal "\e[1;36m", cols[0] # bold cyan for H2
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_markdown_heading_h3_to_h6
|
|
44
|
+
colors = {
|
|
45
|
+
3 => "\e[1;32m",
|
|
46
|
+
4 => "\e[1;35m",
|
|
47
|
+
5 => "\e[1;34m",
|
|
48
|
+
6 => "\e[1;90m"
|
|
49
|
+
}
|
|
50
|
+
colors.each do |level, expected_color|
|
|
51
|
+
line = "#{"#" * level} Title"
|
|
52
|
+
cols = RuVim::Highlighter.color_columns("markdown", line)
|
|
53
|
+
assert_equal expected_color, cols[0], "H#{level} should use correct color"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_markdown_fence_line
|
|
58
|
+
cols = RuVim::Highlighter.color_columns("markdown", "```ruby")
|
|
59
|
+
refute_empty cols
|
|
60
|
+
assert_equal "\e[90m", cols[0] # dim
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_markdown_hr
|
|
64
|
+
cols = RuVim::Highlighter.color_columns("markdown", "---")
|
|
65
|
+
refute_empty cols
|
|
66
|
+
assert_equal "\e[90m", cols[0] # dim
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_markdown_block_quote_marker
|
|
70
|
+
cols = RuVim::Highlighter.color_columns("markdown", "> quoted text")
|
|
71
|
+
assert_equal "\e[36m", cols[0] # cyan for >
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_markdown_inline_bold
|
|
75
|
+
cols = RuVim::Highlighter.color_columns("markdown", "hello **bold** world")
|
|
76
|
+
# ** markers and content should be bold
|
|
77
|
+
assert_equal "\e[1m", cols[6] # first *
|
|
78
|
+
assert_equal "\e[1m", cols[13] # last *
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_markdown_inline_code
|
|
82
|
+
cols = RuVim::Highlighter.color_columns("markdown", "use `foo()` here")
|
|
83
|
+
assert_equal "\e[33m", cols[4] # backtick
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_markdown_empty_line
|
|
87
|
+
cols = RuVim::Highlighter.color_columns("markdown", "")
|
|
88
|
+
assert_empty cols
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_markdown_plain_text
|
|
92
|
+
cols = RuVim::Highlighter.color_columns("markdown", "plain text")
|
|
93
|
+
assert_empty cols
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# --- Scheme ---
|
|
97
|
+
|
|
98
|
+
def test_scheme_keyword_define
|
|
99
|
+
cols = RuVim::Highlighter.color_columns("scheme", "(define x 42)")
|
|
100
|
+
assert_equal "\e[36m", cols[1] # "define" keyword
|
|
101
|
+
assert_equal "\e[36m", cols[6] # end of "define"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_scheme_keyword_lambda
|
|
105
|
+
cols = RuVim::Highlighter.color_columns("scheme", "(lambda (x) x)")
|
|
106
|
+
assert_equal "\e[36m", cols[1] # "lambda"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_scheme_string
|
|
110
|
+
cols = RuVim::Highlighter.color_columns("scheme", '(display "hello")')
|
|
111
|
+
assert_equal "\e[32m", cols[9] # opening quote
|
|
112
|
+
assert_equal "\e[32m", cols[15] # closing quote
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_scheme_number
|
|
116
|
+
cols = RuVim::Highlighter.color_columns("scheme", "(+ 1 2.5)")
|
|
117
|
+
assert_equal "\e[33m", cols[3] # "1"
|
|
118
|
+
assert_equal "\e[33m", cols[5] # "2"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_scheme_boolean
|
|
122
|
+
cols = RuVim::Highlighter.color_columns("scheme", "(if #t #f)")
|
|
123
|
+
assert_equal "\e[35m", cols[4] # "#t"
|
|
124
|
+
assert_equal "\e[35m", cols[7] # "#f"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_scheme_comment
|
|
128
|
+
cols = RuVim::Highlighter.color_columns("scheme", "; this is a comment")
|
|
129
|
+
assert_equal "\e[90m", cols[0] # ";"
|
|
130
|
+
assert_equal "\e[90m", cols[18] # end of comment
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_scheme_char_literal
|
|
134
|
+
cols = RuVim::Highlighter.color_columns("scheme", '#\a #\space')
|
|
135
|
+
assert_equal "\e[32m", cols[0] # "#\a"
|
|
136
|
+
assert_equal "\e[32m", cols[4] # "#\space"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_scheme_empty_line
|
|
140
|
+
cols = RuVim::Highlighter.color_columns("scheme", "")
|
|
141
|
+
assert_empty cols
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# --- Diff ---
|
|
145
|
+
|
|
146
|
+
def test_diff_add_line_green
|
|
147
|
+
cols = RuVim::Highlighter.color_columns("diff", "+added line")
|
|
148
|
+
refute_empty cols
|
|
149
|
+
assert_equal "\e[32m", cols[0]
|
|
150
|
+
assert_equal "\e[32m", cols[5]
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_diff_delete_line_red
|
|
154
|
+
cols = RuVim::Highlighter.color_columns("diff", "-removed line")
|
|
155
|
+
refute_empty cols
|
|
156
|
+
assert_equal "\e[31m", cols[0]
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def test_diff_hunk_header_cyan
|
|
160
|
+
cols = RuVim::Highlighter.color_columns("diff", "@@ -1,3 +1,4 @@ def foo")
|
|
161
|
+
refute_empty cols
|
|
162
|
+
assert_equal "\e[36m", cols[0]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def test_diff_header_bold
|
|
166
|
+
cols = RuVim::Highlighter.color_columns("diff", "diff --git a/foo.rb b/foo.rb")
|
|
167
|
+
refute_empty cols
|
|
168
|
+
assert_equal "\e[1m", cols[0]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_diff_context_line_no_color
|
|
172
|
+
cols = RuVim::Highlighter.color_columns("diff", " context line")
|
|
173
|
+
assert_empty cols
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def test_diff_meta_line_yellow
|
|
177
|
+
cols = RuVim::Highlighter.color_columns("diff", "index abc..def 100644")
|
|
178
|
+
refute_empty cols
|
|
179
|
+
assert_equal "\e[33m", cols[0]
|
|
180
|
+
end
|
|
16
181
|
end
|
data/test/indent_test.rb
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
require_relative "test_helper"
|
|
2
|
+
|
|
3
|
+
class JsonIndentTest < Minitest::Test
|
|
4
|
+
def calc(lines, target_row, sw = 2)
|
|
5
|
+
RuVim::Lang::Json.calculate_indent(lines, target_row, sw)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_first_line_is_zero
|
|
9
|
+
assert_equal 0, calc(["{"], 0)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_after_open_brace
|
|
13
|
+
lines = ["{", ' "key": "value"']
|
|
14
|
+
assert_equal 2, calc(lines, 1)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_close_brace
|
|
18
|
+
lines = ["{", ' "key": "value"', "}"]
|
|
19
|
+
assert_equal 0, calc(lines, 2)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_after_open_bracket
|
|
23
|
+
lines = ["[", " 1"]
|
|
24
|
+
assert_equal 2, calc(lines, 1)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_close_bracket
|
|
28
|
+
lines = ["[", " 1,", " 2", "]"]
|
|
29
|
+
assert_equal 0, calc(lines, 3)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_nested_objects
|
|
33
|
+
lines = [
|
|
34
|
+
"{",
|
|
35
|
+
' "a": {',
|
|
36
|
+
' "b": 1',
|
|
37
|
+
" }",
|
|
38
|
+
"}"
|
|
39
|
+
]
|
|
40
|
+
assert_equal 2, calc(lines, 1)
|
|
41
|
+
assert_equal 4, calc(lines, 2)
|
|
42
|
+
assert_equal 2, calc(lines, 3)
|
|
43
|
+
assert_equal 0, calc(lines, 4)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_array_in_object
|
|
47
|
+
lines = [
|
|
48
|
+
"{",
|
|
49
|
+
' "items": [',
|
|
50
|
+
" 1,",
|
|
51
|
+
" 2",
|
|
52
|
+
" ]",
|
|
53
|
+
"}"
|
|
54
|
+
]
|
|
55
|
+
assert_equal 2, calc(lines, 1)
|
|
56
|
+
assert_equal 4, calc(lines, 2)
|
|
57
|
+
assert_equal 4, calc(lines, 3)
|
|
58
|
+
assert_equal 2, calc(lines, 4)
|
|
59
|
+
assert_equal 0, calc(lines, 5)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_shiftwidth_4
|
|
63
|
+
lines = ["{", ' "key": 1', "}"]
|
|
64
|
+
assert_equal 4, calc(lines, 1, 4)
|
|
65
|
+
assert_equal 0, calc(lines, 2, 4)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_indent_trigger_open_brace
|
|
69
|
+
assert RuVim::Lang::Json.indent_trigger?("{")
|
|
70
|
+
assert RuVim::Lang::Json.indent_trigger?(' "key": {')
|
|
71
|
+
assert RuVim::Lang::Json.indent_trigger?(' "key": [')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_indent_trigger_no_trigger
|
|
75
|
+
refute RuVim::Lang::Json.indent_trigger?(' "key": "value"')
|
|
76
|
+
refute RuVim::Lang::Json.indent_trigger?("}")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_dedent_trigger_close_brace
|
|
80
|
+
assert_kind_of Regexp, RuVim::Lang::Json.dedent_trigger("}")
|
|
81
|
+
assert_kind_of Regexp, RuVim::Lang::Json.dedent_trigger("]")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_dedent_trigger_no_trigger
|
|
85
|
+
assert_nil RuVim::Lang::Json.dedent_trigger("a")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class RubyIndentTest < Minitest::Test
|
|
90
|
+
def calc(lines, target_row, sw = 2)
|
|
91
|
+
RuVim::Lang::Ruby.calculate_indent(lines, target_row, sw)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_first_line_is_zero
|
|
95
|
+
assert_equal 0, calc(["hello"], 0)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_after_def
|
|
99
|
+
lines = ["def foo", " bar"]
|
|
100
|
+
assert_equal 2, calc(lines, 1)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_end_returns_to_zero
|
|
104
|
+
lines = ["def foo", " bar", "end"]
|
|
105
|
+
assert_equal 0, calc(lines, 2)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_class_def_end_nesting
|
|
109
|
+
lines = [
|
|
110
|
+
"class Foo",
|
|
111
|
+
" def bar",
|
|
112
|
+
" baz",
|
|
113
|
+
" end",
|
|
114
|
+
"end"
|
|
115
|
+
]
|
|
116
|
+
assert_equal 2, calc(lines, 1) # def bar
|
|
117
|
+
assert_equal 4, calc(lines, 2) # baz
|
|
118
|
+
assert_equal 2, calc(lines, 3) # end (inner)
|
|
119
|
+
assert_equal 0, calc(lines, 4) # end (outer)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def test_if_else_end
|
|
123
|
+
lines = [
|
|
124
|
+
"if cond",
|
|
125
|
+
" a",
|
|
126
|
+
"else",
|
|
127
|
+
" b",
|
|
128
|
+
"end"
|
|
129
|
+
]
|
|
130
|
+
assert_equal 2, calc(lines, 1) # a
|
|
131
|
+
assert_equal 0, calc(lines, 2) # else
|
|
132
|
+
assert_equal 2, calc(lines, 3) # b
|
|
133
|
+
assert_equal 0, calc(lines, 4) # end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_if_elsif_else_end
|
|
137
|
+
lines = [
|
|
138
|
+
"if a",
|
|
139
|
+
" x",
|
|
140
|
+
"elsif b",
|
|
141
|
+
" y",
|
|
142
|
+
"else",
|
|
143
|
+
" z",
|
|
144
|
+
"end"
|
|
145
|
+
]
|
|
146
|
+
assert_equal 2, calc(lines, 1) # x
|
|
147
|
+
assert_equal 0, calc(lines, 2) # elsif
|
|
148
|
+
assert_equal 2, calc(lines, 3) # y
|
|
149
|
+
assert_equal 0, calc(lines, 4) # else
|
|
150
|
+
assert_equal 2, calc(lines, 5) # z
|
|
151
|
+
assert_equal 0, calc(lines, 6) # end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_modifier_if_does_not_increase_indent
|
|
155
|
+
lines = [
|
|
156
|
+
"def foo",
|
|
157
|
+
" return if true",
|
|
158
|
+
" bar",
|
|
159
|
+
"end"
|
|
160
|
+
]
|
|
161
|
+
assert_equal 2, calc(lines, 1) # return if true
|
|
162
|
+
assert_equal 2, calc(lines, 2) # bar
|
|
163
|
+
assert_equal 0, calc(lines, 3) # end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def test_do_end_block
|
|
167
|
+
lines = [
|
|
168
|
+
"items.each do |x|",
|
|
169
|
+
" puts x",
|
|
170
|
+
"end"
|
|
171
|
+
]
|
|
172
|
+
assert_equal 2, calc(lines, 1) # puts x
|
|
173
|
+
assert_equal 0, calc(lines, 2) # end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def test_brace_block
|
|
177
|
+
lines = [
|
|
178
|
+
"items.map {",
|
|
179
|
+
" |x| x + 1",
|
|
180
|
+
"}"
|
|
181
|
+
]
|
|
182
|
+
assert_equal 2, calc(lines, 1)
|
|
183
|
+
assert_equal 0, calc(lines, 2)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def test_case_when
|
|
187
|
+
lines = [
|
|
188
|
+
"case x",
|
|
189
|
+
"when 1",
|
|
190
|
+
" a",
|
|
191
|
+
"when 2",
|
|
192
|
+
" b",
|
|
193
|
+
"end"
|
|
194
|
+
]
|
|
195
|
+
assert_equal 0, calc(lines, 1) # when 1
|
|
196
|
+
assert_equal 2, calc(lines, 2) # a
|
|
197
|
+
assert_equal 0, calc(lines, 3) # when 2
|
|
198
|
+
assert_equal 2, calc(lines, 4) # b
|
|
199
|
+
assert_equal 0, calc(lines, 5) # end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def test_rescue_ensure
|
|
203
|
+
lines = [
|
|
204
|
+
"begin",
|
|
205
|
+
" risky",
|
|
206
|
+
"rescue => e",
|
|
207
|
+
" handle",
|
|
208
|
+
"ensure",
|
|
209
|
+
" cleanup",
|
|
210
|
+
"end"
|
|
211
|
+
]
|
|
212
|
+
assert_equal 2, calc(lines, 1) # risky
|
|
213
|
+
assert_equal 0, calc(lines, 2) # rescue
|
|
214
|
+
assert_equal 2, calc(lines, 3) # handle
|
|
215
|
+
assert_equal 0, calc(lines, 4) # ensure
|
|
216
|
+
assert_equal 2, calc(lines, 5) # cleanup
|
|
217
|
+
assert_equal 0, calc(lines, 6) # end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def test_unless_until_while_for
|
|
221
|
+
%w[unless until while for].each do |kw|
|
|
222
|
+
lines = ["#{kw} cond", " body", "end"]
|
|
223
|
+
assert_equal 2, calc(lines, 1), "body after #{kw}"
|
|
224
|
+
assert_equal 0, calc(lines, 2), "end after #{kw}"
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def test_module_nesting
|
|
229
|
+
lines = [
|
|
230
|
+
"module A",
|
|
231
|
+
" module B",
|
|
232
|
+
" def foo",
|
|
233
|
+
" bar",
|
|
234
|
+
" end",
|
|
235
|
+
" end",
|
|
236
|
+
"end"
|
|
237
|
+
]
|
|
238
|
+
assert_equal 2, calc(lines, 1) # module B
|
|
239
|
+
assert_equal 4, calc(lines, 2) # def foo
|
|
240
|
+
assert_equal 6, calc(lines, 3) # bar
|
|
241
|
+
assert_equal 4, calc(lines, 4) # end (inner)
|
|
242
|
+
assert_equal 2, calc(lines, 5) # end (mid)
|
|
243
|
+
assert_equal 0, calc(lines, 6) # end (outer)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def test_comment_lines_are_skipped
|
|
247
|
+
lines = [
|
|
248
|
+
"def foo",
|
|
249
|
+
" # comment",
|
|
250
|
+
" bar",
|
|
251
|
+
"end"
|
|
252
|
+
]
|
|
253
|
+
assert_equal 2, calc(lines, 1) # comment
|
|
254
|
+
assert_equal 2, calc(lines, 2) # bar
|
|
255
|
+
assert_equal 0, calc(lines, 3) # end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def test_shiftwidth_4
|
|
259
|
+
lines = ["def foo", " bar", "end"]
|
|
260
|
+
assert_equal 4, calc(lines, 1, 4)
|
|
261
|
+
assert_equal 0, calc(lines, 2, 4)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def test_paren_bracket_nesting
|
|
265
|
+
lines = [
|
|
266
|
+
"x = [",
|
|
267
|
+
" 1,",
|
|
268
|
+
" 2",
|
|
269
|
+
"]"
|
|
270
|
+
]
|
|
271
|
+
assert_equal 2, calc(lines, 1)
|
|
272
|
+
assert_equal 2, calc(lines, 2)
|
|
273
|
+
assert_equal 0, calc(lines, 3)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def test_empty_lines_preserve_depth
|
|
277
|
+
lines = [
|
|
278
|
+
"def foo",
|
|
279
|
+
"",
|
|
280
|
+
" bar",
|
|
281
|
+
"end"
|
|
282
|
+
]
|
|
283
|
+
assert_equal 2, calc(lines, 1) # empty line inside def
|
|
284
|
+
assert_equal 2, calc(lines, 2) # bar
|
|
285
|
+
assert_equal 0, calc(lines, 3) # end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
@@ -56,7 +56,7 @@ class InputScreenIntegrationTest < Minitest::Test
|
|
|
56
56
|
app.instance_variable_set(:@screen, screen)
|
|
57
57
|
|
|
58
58
|
stdin = FakeTTY.new("\e[6~")
|
|
59
|
-
input = RuVim::Input.new(stdin
|
|
59
|
+
input = RuVim::Input.new(stdin)
|
|
60
60
|
|
|
61
61
|
with_fake_select do
|
|
62
62
|
key = input.read_key(timeout: 0.2)
|
|
@@ -72,11 +72,49 @@ class InputScreenIntegrationTest < Minitest::Test
|
|
|
72
72
|
|
|
73
73
|
def test_input_keeps_repeated_arrow_sequences_separate
|
|
74
74
|
stdin = FakeTTY.new("\e[A\e[A")
|
|
75
|
-
input = RuVim::Input.new(stdin
|
|
75
|
+
input = RuVim::Input.new(stdin)
|
|
76
76
|
|
|
77
77
|
with_fake_select do
|
|
78
78
|
assert_equal :up, input.read_key(timeout: 0.2)
|
|
79
79
|
assert_equal :up, input.read_key(timeout: 0.2)
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
|
+
|
|
83
|
+
def test_input_reads_ctrl_z
|
|
84
|
+
stdin = FakeTTY.new("\u001a")
|
|
85
|
+
input = RuVim::Input.new(stdin)
|
|
86
|
+
|
|
87
|
+
with_fake_select do
|
|
88
|
+
assert_equal :ctrl_z, input.read_key(timeout: 0.2)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_input_shift_arrow_sequences
|
|
93
|
+
{
|
|
94
|
+
"\e[1;2A" => :shift_up,
|
|
95
|
+
"\e[1;2B" => :shift_down,
|
|
96
|
+
"\e[1;2C" => :shift_right,
|
|
97
|
+
"\e[1;2D" => :shift_left
|
|
98
|
+
}.each do |seq, expected|
|
|
99
|
+
stdin = FakeTTY.new(seq)
|
|
100
|
+
input = RuVim::Input.new(stdin)
|
|
101
|
+
|
|
102
|
+
with_fake_select do
|
|
103
|
+
assert_equal expected, input.read_key(timeout: 0.2), "Expected #{expected} for sequence #{seq.inspect}"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_has_pending_input_returns_true_when_data_available
|
|
109
|
+
stdin = FakeTTY.new("abc")
|
|
110
|
+
input = RuVim::Input.new(stdin)
|
|
111
|
+
|
|
112
|
+
with_fake_select do
|
|
113
|
+
assert input.has_pending_input?
|
|
114
|
+
input.read_key(timeout: 0)
|
|
115
|
+
input.read_key(timeout: 0)
|
|
116
|
+
input.read_key(timeout: 0)
|
|
117
|
+
refute input.has_pending_input?
|
|
118
|
+
end
|
|
119
|
+
end
|
|
82
120
|
end
|