vimamsa 0.1.22 → 0.1.24

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +32 -0
  3. data/Dockerfile +45 -0
  4. data/README.md +2 -2
  5. data/custom_example.rb +38 -9
  6. data/docker_cmd.sh +7 -0
  7. data/exe/run_tests.rb +23 -0
  8. data/img/screenshot1.png +0 -0
  9. data/img/screenshot2.png +0 -0
  10. data/lib/vimamsa/actions.rb +8 -0
  11. data/lib/vimamsa/buffer.rb +165 -53
  12. data/lib/vimamsa/buffer_changetext.rb +68 -14
  13. data/lib/vimamsa/buffer_cursor.rb +9 -3
  14. data/lib/vimamsa/buffer_list.rb +14 -28
  15. data/lib/vimamsa/buffer_manager.rb +1 -1
  16. data/lib/vimamsa/conf.rb +33 -1
  17. data/lib/vimamsa/diff_buffer.rb +185 -0
  18. data/lib/vimamsa/editor.rb +149 -80
  19. data/lib/vimamsa/file_finder.rb +6 -2
  20. data/lib/vimamsa/gui.rb +330 -135
  21. data/lib/vimamsa/gui_dialog.rb +2 -0
  22. data/lib/vimamsa/gui_file_panel.rb +94 -0
  23. data/lib/vimamsa/gui_form_generator.rb +4 -2
  24. data/lib/vimamsa/gui_func_panel.rb +127 -0
  25. data/lib/vimamsa/gui_image.rb +2 -4
  26. data/lib/vimamsa/gui_menu.rb +54 -1
  27. data/lib/vimamsa/gui_select_window.rb +18 -6
  28. data/lib/vimamsa/gui_settings.rb +486 -0
  29. data/lib/vimamsa/gui_sourceview.rb +196 -8
  30. data/lib/vimamsa/gui_text.rb +0 -22
  31. data/lib/vimamsa/hyper_plain_text.rb +1 -0
  32. data/lib/vimamsa/key_actions.rb +54 -31
  33. data/lib/vimamsa/key_binding_tree.rb +154 -8
  34. data/lib/vimamsa/key_bindings_vimlike.rb +48 -35
  35. data/lib/vimamsa/langservp.rb +161 -7
  36. data/lib/vimamsa/macro.rb +54 -7
  37. data/lib/vimamsa/main.rb +1 -0
  38. data/lib/vimamsa/rbvma.rb +5 -0
  39. data/lib/vimamsa/string_util.rb +56 -0
  40. data/lib/vimamsa/test_framework.rb +137 -0
  41. data/lib/vimamsa/util.rb +3 -36
  42. data/lib/vimamsa/version.rb +1 -1
  43. data/modules/calculator/calculator.rb +318 -0
  44. data/modules/calculator/calculator_info.rb +3 -0
  45. data/modules/terminal/terminal.rb +140 -0
  46. data/modules/terminal/terminal_info.rb +3 -0
  47. data/run_tests.rb +89 -0
  48. data/styles/dark.xml +1 -1
  49. data/styles/molokai_edit.xml +2 -2
  50. data/tests/key_bindings.rb +2 -0
  51. data/tests/test_basic_editing.rb +86 -0
  52. data/tests/test_copy_paste.rb +88 -0
  53. data/tests/test_key_bindings.rb +152 -0
  54. data/tests/test_module_interface.rb +98 -0
  55. data/tests/test_undo.rb +201 -0
  56. data/vimamsa.gemspec +6 -5
  57. metadata +52 -14
@@ -0,0 +1,88 @@
1
+ class TestCopyPaste < VmaTest
2
+
3
+ def test_copy_line_paste_after
4
+ act 'buf.insert_txt("hello\n")'
5
+ act :jump_to_start_of_buffer
6
+ act :copy_cur_line
7
+ act :jump_to_end_of_buffer
8
+ act :paste_after_cursor
9
+ assert_buf "hello\n\nhello\n"
10
+ end
11
+
12
+ def test_copy_line_paste_before
13
+ act 'buf.insert_txt("hello\n")'
14
+ act 'buf.insert_txt("world")'
15
+ act :jump_to_start_of_buffer
16
+ act :copy_cur_line
17
+ act "buf.move(FORWARD_LINE)"
18
+ act :paste_before_cursor
19
+ assert_buf "hello\nhello\nworld\n"
20
+ end
21
+
22
+ def test_copy_paste_twice
23
+ act 'buf.insert_txt("abc")'
24
+ act :jump_to_start_of_buffer
25
+ act :copy_cur_line
26
+ act :jump_to_end_of_buffer
27
+ act :paste_after_cursor
28
+ act :paste_after_cursor
29
+ assert_buf "abc\nabc\nabc\n"
30
+ end
31
+
32
+ def test_cut_selection_paste
33
+ act 'buf.insert_txt("hello world")'
34
+ act :jump_to_start_of_buffer
35
+ # Select "hello" (5 chars)
36
+ act "buf.start_selection"
37
+ 4.times { act "buf.move(FORWARD_CHAR)" }
38
+ act :cut_selection
39
+ assert_buf " world\n"
40
+ act "buf.jump(END_OF_LINE)"
41
+ act :paste_after_cursor
42
+ assert_buf " worldhello\n"
43
+ end
44
+
45
+ def test_copy_selection_paste
46
+ act 'buf.insert_txt("foo bar")'
47
+ act :jump_to_start_of_buffer
48
+ act "buf.start_selection"
49
+ 2.times { act "buf.move(FORWARD_CHAR)" }
50
+ act :copy_selection
51
+ # Original buffer unchanged
52
+ assert_buf "foo bar\n"
53
+ act "buf.jump(END_OF_LINE)"
54
+ act :paste_after_cursor
55
+ assert_buf "foo barfoo\n"
56
+ end
57
+
58
+ def test_clipboard_set_get
59
+ vma.clipboard.set("testvalue")
60
+ assert_eq "testvalue", vma.clipboard.get
61
+ end
62
+
63
+ def test_copy_line_updates_clipboard
64
+ act 'buf.insert_txt("myline")'
65
+ act :jump_to_start_of_buffer
66
+ act :copy_cur_line
67
+ assert_eq "myline\n", vma.clipboard.get
68
+ end
69
+
70
+ def test_cut_selection_updates_clipboard
71
+ act 'buf.insert_txt("hello")'
72
+ act :jump_to_start_of_buffer
73
+ act "buf.start_selection"
74
+ 2.times { act "buf.move(FORWARD_CHAR)" }
75
+ act :cut_selection
76
+ assert_eq "hel", vma.clipboard.get
77
+ end
78
+
79
+ def test_paste_multiline
80
+ act 'buf.insert_txt("line1\nline2\nline3")'
81
+ act :jump_to_start_of_buffer
82
+ act :copy_cur_line
83
+ act :jump_to_end_of_buffer
84
+ act :paste_after_cursor
85
+ assert_buf "line1\nline2\nline3\nline1\n"
86
+ end
87
+
88
+ end
@@ -0,0 +1,152 @@
1
+ class TestKeyBindings < VmaTest
2
+
3
+ # ── bindkey / basic dispatch ─────────────────────────────────────────────
4
+
5
+ def test_bindkey_symbol_action_fires
6
+ triggered = false
7
+ reg_act(:_test_bindkey_symbol, proc { triggered = true }, "test")
8
+ bindkey "C t e s t 1", :_test_bindkey_symbol
9
+ keys "t e s t 1"
10
+ assert triggered, "action should have fired"
11
+ end
12
+
13
+ def test_bindkey_string_action_fires
14
+ $test_str_fired = false
15
+ bindkey "C t e s t 2", '$test_str_fired = true'
16
+ keys "t e s t 2"
17
+ assert $test_str_fired, "string action should have fired"
18
+ end
19
+
20
+ def test_bindkey_proc_via_array
21
+ $test_arr_fired = false
22
+ bindkey "C t e s t 3", [:_test_arr_action, proc { $test_arr_fired = true }, "test"]
23
+ keys "t e s t 3"
24
+ assert $test_arr_fired, "array-style action should have fired"
25
+ end
26
+
27
+ # ── multi-key chord ──────────────────────────────────────────────────────
28
+
29
+ def test_chord_requires_full_sequence
30
+ count = 0
31
+ reg_act(:_test_chord, proc { count += 1 }, "test chord")
32
+ bindkey "C , x q", :_test_chord
33
+
34
+ keys "," # partial — should not fire yet
35
+ assert_eq 0, count, "should not fire after partial chord"
36
+
37
+ keys "x q" # complete chord
38
+ assert_eq 1, count, "should fire after complete chord"
39
+ end
40
+
41
+ def test_chord_wrong_key_resets
42
+ count = 0
43
+ reg_act(:_test_chord_reset, proc { count += 1 }, "test")
44
+ bindkey "C , x r", :_test_chord_reset
45
+
46
+ keys ", x z" # wrong last key — resets, does not fire
47
+ assert_eq 0, count, "wrong key should not fire the action"
48
+
49
+ keys ", x r" # correct sequence
50
+ assert_eq 1, count, "correct chord should fire"
51
+ end
52
+
53
+ # ── mode specificity ─────────────────────────────────────────────────────
54
+
55
+ def test_command_binding_does_not_fire_in_insert_mode
56
+ count = 0
57
+ reg_act(:_test_cmd_only, proc { count += 1 }, "test")
58
+ bindkey "C , x c", :_test_cmd_only
59
+
60
+ # Switch to insert mode and send the keys
61
+ vma.kbd.set_mode(:insert)
62
+ keys ", x c"
63
+ vma.kbd.set_mode(:command)
64
+ assert_eq 0, count, "command binding should not fire in insert mode"
65
+ end
66
+
67
+ def test_insert_binding_fires_in_insert_mode
68
+ count = 0
69
+ reg_act(:_test_ins_only, proc { count += 1 }, "test")
70
+ bindkey "I ctrl-F9", :_test_ins_only # unlikely to conflict
71
+
72
+ vma.kbd.set_mode(:insert)
73
+ keys "ctrl-F9"
74
+ vma.kbd.set_mode(:command)
75
+ assert_eq 1, count, "insert binding should fire in insert mode"
76
+ end
77
+
78
+ # ── unbindkey ────────────────────────────────────────────────────────────
79
+
80
+ def test_unbindkey_removes_binding
81
+ count = 0
82
+ reg_act(:_test_unbind, proc { count += 1 }, "test")
83
+ bindkey "C , x u", :_test_unbind
84
+
85
+ keys ", x u"
86
+ assert_eq 1, count, "should fire before unbind"
87
+
88
+ unbindkey "C , x u"
89
+
90
+ keys ", x u"
91
+ assert_eq 1, count, "should not fire after unbind"
92
+ end
93
+
94
+ def test_unbindkey_pipe_syntax
95
+ count = 0
96
+ reg_act(:_test_unbind_pipe, proc { count += 1 }, "test")
97
+ bindkey "C , x p || C , x q", :_test_unbind_pipe
98
+
99
+ keys ", x p"
100
+ keys ", x q"
101
+ assert_eq 2, count, "both bindings should fire"
102
+
103
+ unbindkey "C , x p || C , x q"
104
+
105
+ keys ", x p"
106
+ keys ", x q"
107
+ assert_eq 2, count, "neither binding should fire after unbind"
108
+ end
109
+
110
+ # ── || (pipe) multi-binding syntax ───────────────────────────────────────
111
+
112
+ def test_pipe_syntax_both_keys_trigger_same_action
113
+ count = 0
114
+ reg_act(:_test_pipe, proc { count += 1 }, "test")
115
+ bindkey "C , x a || C , x b", :_test_pipe
116
+
117
+ keys ", x a"
118
+ assert_eq 1, count
119
+ keys ", x b"
120
+ assert_eq 2, count
121
+ end
122
+
123
+ # ── repeat count ─────────────────────────────────────────────────────────
124
+
125
+ def test_repeat_count_executes_action_n_times
126
+ count = 0
127
+ reg_act(:_test_repeat, proc { count += 1 }, "test")
128
+ bindkey "C , x 9", :_test_repeat
129
+
130
+ # Set repeat count to 3 then fire action
131
+ vma.kbd.set_next_command_count(3)
132
+ keys ", x 9"
133
+ assert_eq 3, count, "action should run 3 times with count=3"
134
+ end
135
+
136
+ # ── mode switching ───────────────────────────────────────────────────────
137
+
138
+ def test_escape_returns_to_command_from_insert
139
+ keys "i"
140
+ assert_mode :insert
141
+ keys "esc"
142
+ assert_mode :command
143
+ end
144
+
145
+ def test_i_enters_insert_mode
146
+ assert_mode :command
147
+ keys "i"
148
+ assert_mode :insert
149
+ keys "esc"
150
+ end
151
+
152
+ end
@@ -0,0 +1,98 @@
1
+ class TestModuleInterface < VmaTest
2
+ # Ensure the calculator is inactive before each test that needs a clean slate.
3
+ def ensure_disabled
4
+ if vma.actions.include?(:insert_calculator)
5
+ calculator_disable if respond_to?(:calculator_disable, true)
6
+ end
7
+ end
8
+
9
+ def load_calculator
10
+ load ppath("modules/calculator/calculator.rb")
11
+ end
12
+
13
+ # --- _info ---
14
+
15
+ def test_info_structure
16
+ load ppath("modules/calculator/calculator_info.rb")
17
+ info = calculator_info
18
+ assert info[:name].is_a?(String), "name should be a String"
19
+ assert !info[:name].empty?, "name should not be empty"
20
+ assert info.key?(:no_restart), "no_restart key missing"
21
+ assert_eq true, info[:no_restart], "calculator should be no_restart"
22
+ end
23
+
24
+ # --- _init ---
25
+
26
+ def test_init_registers_action
27
+ ensure_disabled
28
+ load_calculator
29
+ calculator_init
30
+ assert vma.actions.include?(:insert_calculator), "action not registered after init"
31
+ ensure
32
+ calculator_disable
33
+ end
34
+
35
+ def test_init_adds_menu_item
36
+ ensure_disabled
37
+ load_calculator
38
+ calculator_init
39
+ assert vma.gui.menu.module_action?(:insert_calculator), "menu item missing after init"
40
+ ensure
41
+ calculator_disable
42
+ end
43
+
44
+ # --- _disable ---
45
+
46
+ def test_disable_unregisters_action
47
+ ensure_disabled
48
+ load_calculator
49
+ calculator_init
50
+ calculator_disable
51
+ assert !vma.actions.include?(:insert_calculator), "action still registered after disable"
52
+ end
53
+
54
+ def test_disable_removes_menu_item
55
+ ensure_disabled
56
+ load_calculator
57
+ calculator_init
58
+ calculator_disable
59
+ assert !vma.gui.menu.module_action?(:insert_calculator), "menu item still present after disable"
60
+ end
61
+
62
+ # --- cycle ---
63
+
64
+ def test_init_disable_cycle
65
+ ensure_disabled
66
+ load_calculator
67
+ 3.times do |i|
68
+ calculator_init
69
+ assert vma.actions.include?(:insert_calculator), "action missing after init (cycle #{i})"
70
+ assert vma.gui.menu.module_action?(:insert_calculator), "menu missing after init (cycle #{i})"
71
+ calculator_disable
72
+ assert !vma.actions.include?(:insert_calculator), "action present after disable (cycle #{i})"
73
+ assert !vma.gui.menu.module_action?(:insert_calculator), "menu present after disable (cycle #{i})"
74
+ end
75
+ end
76
+
77
+ # --- all_settings_defs ---
78
+
79
+ def test_settings_defs_has_modules_section
80
+ defs = all_settings_defs
81
+ assert defs.any? { |s| s[:label] == "Modules" }, "no Modules section"
82
+ end
83
+
84
+ def test_settings_defs_calculator_key_present
85
+ defs = all_settings_defs
86
+ mod = defs.find { |s| s[:label] == "Modules" }
87
+ assert !mod.nil?, "no Modules section"
88
+ calc = mod[:settings].find { |s| s[:key] == [:modules, :calculator, :enabled] }
89
+ assert !calc.nil?, "calculator key missing from Modules section"
90
+ end
91
+
92
+ def test_settings_defs_no_restart_flag
93
+ defs = all_settings_defs
94
+ mod = defs.find { |s| s[:label] == "Modules" }
95
+ calc = mod[:settings].find { |s| s[:key] == [:modules, :calculator, :enabled] }
96
+ assert_eq true, calc[:no_restart], "calculator should have no_restart: true"
97
+ end
98
+ end
@@ -0,0 +1,201 @@
1
+ class TestUndo < VmaTest
2
+
3
+ # ── Basic undo / redo ────────────────────────────────────────────────────
4
+
5
+ def test_undo_restores_empty_buffer
6
+ act 'buf.insert_txt("hello")'
7
+ act :undo
8
+ assert_buf "\n"
9
+ end
10
+
11
+ def test_undo_on_empty_buffer_is_noop
12
+ act :undo
13
+ assert_buf "\n"
14
+ end
15
+
16
+ def test_redo_after_undo
17
+ act 'buf.insert_txt("hello")'
18
+ act :undo
19
+ act :redo
20
+ assert_buf "hello\n"
21
+ end
22
+
23
+ def test_redo_on_empty_stack_is_noop
24
+ act :undo
25
+ act :redo
26
+ assert_buf "\n"
27
+ end
28
+
29
+ def test_new_edit_clears_redo_stack
30
+ act 'buf.insert_txt("hello")'
31
+ act :undo
32
+ assert_buf "\n"
33
+ act 'buf.insert_txt("world")'
34
+ # redo stack was cleared — redo should be a no-op
35
+ act :redo
36
+ assert_buf "world\n"
37
+ end
38
+
39
+ def test_undo_delete_char
40
+ act 'buf.insert_txt("abcde")'
41
+ act :jump_to_start_of_buffer
42
+ vma.buf.new_undo_group
43
+ act :delete_char_forward
44
+ act :delete_char_forward
45
+ vma.buf.new_undo_group
46
+ assert_buf "cde\n"
47
+ act :undo
48
+ assert_buf "abcde\n"
49
+ end
50
+
51
+ def test_undo_delete_line
52
+ act 'buf.insert_txt("first\n")'
53
+ act 'buf.insert_txt("second")'
54
+ vma.buf.new_undo_group
55
+ act :jump_to_start_of_buffer
56
+ act :delete_line
57
+ vma.buf.new_undo_group
58
+ assert_buf "second\n"
59
+ act :undo
60
+ assert_buf "first\nsecond\n"
61
+ end
62
+
63
+ def test_undo_redo_multiple_times
64
+ act 'buf.insert_txt("first")'
65
+ vma.buf.new_undo_group
66
+ act 'buf.insert_txt(" second")'
67
+ assert_buf "first second\n"
68
+
69
+ act :undo
70
+ assert_buf "first\n"
71
+ act :redo
72
+ assert_buf "first second\n"
73
+ act :undo
74
+ assert_buf "first\n"
75
+ act :undo
76
+ assert_buf "\n"
77
+ end
78
+
79
+ # ── Explicit group boundaries ─────────────────────────────────────────────
80
+
81
+ def test_new_undo_group_creates_separate_steps
82
+ act 'buf.insert_txt("aaa")'
83
+ vma.buf.new_undo_group
84
+ act 'buf.insert_txt("bbb")'
85
+ vma.buf.new_undo_group
86
+ act 'buf.insert_txt("ccc")'
87
+ vma.buf.new_undo_group
88
+ assert_buf "aaabbbccc\n"
89
+
90
+ act :undo
91
+ assert_buf "aaabbb\n"
92
+ act :undo
93
+ assert_buf "aaa\n"
94
+ act :undo
95
+ assert_buf "\n"
96
+ end
97
+
98
+ # ── Mode-change group boundaries ─────────────────────────────────────────
99
+
100
+ def test_mode_change_creates_undo_group_boundary
101
+ # Each insert-mode session should be a separate undo group
102
+ keys "i h e l l o esc"
103
+ keys "i space w o r l d esc"
104
+ assert_buf "hello world\n"
105
+
106
+ act :undo
107
+ assert_buf "hello\n" # second insert session (" world") undone
108
+ act :undo
109
+ assert_buf "\n" # first insert session ("hello") undone
110
+ end
111
+
112
+ # ── Macro undo ────────────────────────────────────────────────────────────
113
+
114
+ def test_macro_run_is_single_undo_group
115
+ # An entire macro run should collapse into one undo step
116
+ vma.macro.run_actions([
117
+ 'buf.insert_txt("line1\n")',
118
+ 'buf.insert_txt("line2\n")',
119
+ 'buf.insert_txt("line3")',
120
+ ])
121
+ drain_idle
122
+ assert_buf "line1\nline2\nline3\n"
123
+
124
+ act :undo
125
+ assert_buf "\n"
126
+ end
127
+
128
+ def test_macro_multiple_runs_each_undoable_separately
129
+ # Each run of the macro should be its own undo group
130
+ vma.macro.run_actions(['buf.insert_txt("abc")'])
131
+ drain_idle
132
+ vma.macro.run_actions(['buf.insert_txt("def")'])
133
+ drain_idle
134
+ assert_buf "abcdef\n"
135
+
136
+ act :undo
137
+ assert_buf "abc\n"
138
+ act :undo
139
+ assert_buf "\n"
140
+ end
141
+
142
+ def test_macro_does_not_undo_pre_existing_content
143
+ # Content that existed before the macro run should survive macro undo
144
+ act 'buf.insert_txt("base")'
145
+ vma.buf.new_undo_group
146
+ vma.macro.run_actions(['buf.insert_txt(" appended")'])
147
+ drain_idle
148
+ assert_buf "base appended\n"
149
+
150
+ act :undo
151
+ assert_buf "base\n"
152
+ act :undo
153
+ assert_buf "\n"
154
+ end
155
+
156
+ def test_macro_record_and_run_then_undo
157
+ # Record a macro via key sequence, run it, then undo each step
158
+ keys "q a" # start recording into slot "a"
159
+ keys "i f o o esc" # insert "foo", return to (macro) command mode
160
+ keys "q" # end recording
161
+ drain_idle
162
+ assert_buf "foo\n" # recording-time insertion is in the buffer
163
+
164
+ vma.macro.run_macro("a")
165
+ drain_idle
166
+ assert_buf "foofoo\n"
167
+
168
+ act :undo # undo the macro run
169
+ assert_buf "foo\n"
170
+ act :undo # undo the recording-time insertion
171
+ assert_buf "\n"
172
+ end
173
+
174
+ def test_macro_redo_after_undo
175
+ vma.macro.run_actions(['buf.insert_txt("hello")'])
176
+ drain_idle
177
+ assert_buf "hello\n"
178
+
179
+ act :undo
180
+ assert_buf "\n"
181
+ act :redo
182
+ assert_buf "hello\n"
183
+ end
184
+
185
+ def test_macro_with_delete_is_single_undo_group
186
+ act 'buf.insert_txt("hello world")'
187
+ vma.buf.new_undo_group
188
+
189
+ # Macro that jumps to start and deletes a word
190
+ vma.macro.run_actions([
191
+ 'buf.jump(BEGINNING_OF_LINE)',
192
+ 'buf.delete2(:to_word_end)',
193
+ ])
194
+ drain_idle
195
+ assert_buf " world\n"
196
+
197
+ act :undo
198
+ assert_buf "hello world\n"
199
+ end
200
+
201
+ end
data/vimamsa.gemspec CHANGED
@@ -22,17 +22,18 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib","ext"]
24
24
 
25
- spec.add_development_dependency "bundler", "~> 2.4.21"
25
+ spec.add_development_dependency "bundler", ">= 2.4"
26
26
  spec.add_development_dependency "rake", "~> 13.1.0"
27
27
 
28
28
  spec.add_runtime_dependency 'rufo', '~> 0.16.2'
29
29
 
30
30
  spec.add_runtime_dependency 'ripl', '~> 0.7.1'
31
31
  spec.add_runtime_dependency 'ripl-multi_line', '~> 0.3.1'
32
- spec.add_runtime_dependency 'gdk4', '~> 4.2.1'
33
- spec.add_runtime_dependency 'gtk4', '~> 4.2.1'
34
- spec.add_runtime_dependency 'gtksourceview5', '~> 4.2.1'
35
- spec.add_runtime_dependency 'gstreamer', '~> 4.2.1'
32
+ spec.add_runtime_dependency 'gdk4', '~> 4.3.5'
33
+ spec.add_runtime_dependency 'gtk4', '~> 4.3.5'
34
+ spec.add_runtime_dependency 'gtksourceview5', '~> 4.3.5'
35
+ spec.add_runtime_dependency 'gstreamer', '~> 4.3.5'
36
+ spec.add_runtime_dependency 'vte4', '~> 4.3.5'
36
37
  spec.add_runtime_dependency 'rambling-trie', '~> 2.3.1'
37
38
 
38
39
  spec.add_runtime_dependency 'differ', '~> 0.1.2'