vimamsa 0.1.20 → 0.1.21
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/README.md +16 -1
- data/lib/vimamsa/buffer.rb +26 -1
- data/lib/vimamsa/buffer_changetext.rb +2 -0
- data/lib/vimamsa/buffer_list.rb +1 -1
- data/lib/vimamsa/editor.rb +2 -2
- data/lib/vimamsa/file_finder.rb +12 -3
- data/lib/vimamsa/gui_sourceview.rb +34 -17
- data/lib/vimamsa/key_actions.rb +2 -0
- data/lib/vimamsa/key_binding_tree.rb +9 -8
- data/lib/vimamsa/key_bindings_vimlike.rb +3 -1
- data/lib/vimamsa/macro.rb +3 -1
- data/lib/vimamsa/tests.rb +81 -2
- data/lib/vimamsa/text_transforms.rb +2 -0
- data/lib/vimamsa/util.rb +19 -1
- data/lib/vimamsa/version.rb +1 -1
- data/vimamsa.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b44f279b048a7cd7baba9e21e70dc9666a251f9608466f9e4bd38094c486738
|
4
|
+
data.tar.gz: ef57b1ad00c480d30720ec8d272df38ec289640c7951b8a04a070837e43a261a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 756f7c861bff64427fac5e397f8e0b4d539f46dd9d72edf39ddbc190eefff09cb86c0107ec38664ee9a1c450c2de9912f6960aee7c990c8b99c4c914cf0f5a56
|
7
|
+
data.tar.gz: 15a6b06c01f13435a154a2b64c544e8d5b14f253bed3e4b65e845dc510f591fcd77c1e9c278d4cf7b67699205c97952ad6ab8042fffe222260d972b88db42bee
|
data/README.md
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
# Vimamsa
|
2
2
|
|
3
|
-
Vi/Vim -inspired experimental GUI-oriented text editor written with Ruby and GTK.
|
3
|
+
Vi/Vim -inspired experimental GUI-oriented text editor written with Ruby and GTK.
|
4
4
|
|
5
|
+
<!-- toc -->
|
6
|
+
|
7
|
+
- [Requirements](#requirements)
|
8
|
+
- [Installation](#installation)
|
9
|
+
* [Other install options](#other-install-options)
|
10
|
+
- [Run](#run)
|
11
|
+
- [Screenshots](#screenshots)
|
12
|
+
- [Key bindings](#key-bindings)
|
13
|
+
- [Current limitations](#current-limitations)
|
14
|
+
|
15
|
+
<!-- tocstop -->
|
5
16
|
|
6
17
|
## Requirements
|
7
18
|
- Ruby 3.0+
|
@@ -144,6 +155,10 @@ For example, to bind ctrl-n to action "create new file":
|
|
144
155
|
bindkey 'C ctrl-n', 'create_new_file()'
|
145
156
|
```
|
146
157
|
|
158
|
+
|
159
|
+
## Known issues
|
160
|
+
- Cursor sometimes vanishes when dragging or resizing the window. At least some cases are fixed in new GTK4 versions ( >= 4.18, in Ubuntu Ubuntu 25.04). Workaround is to press ctrl key twice.
|
161
|
+
|
147
162
|
## Current limitations
|
148
163
|
- UTF8 only
|
149
164
|
- Line endings with "\n"
|
data/lib/vimamsa/buffer.rb
CHANGED
@@ -41,6 +41,7 @@ class Buffer < String
|
|
41
41
|
@module = nil
|
42
42
|
|
43
43
|
@last_save = @last_asked_from_user = @file_last_cheked = Time.now
|
44
|
+
@t_modified = @last_save
|
44
45
|
|
45
46
|
@crypt = nil
|
46
47
|
@update_highlight = true
|
@@ -1295,6 +1296,16 @@ class Buffer < String
|
|
1295
1296
|
end_visual_mode
|
1296
1297
|
end
|
1297
1298
|
|
1299
|
+
def eval_whole_buf(x = 888)
|
1300
|
+
s = self.to_s
|
1301
|
+
begin
|
1302
|
+
eval(s)
|
1303
|
+
rescue Exception
|
1304
|
+
message("Error running eval")
|
1305
|
+
else
|
1306
|
+
end
|
1307
|
+
end
|
1308
|
+
|
1298
1309
|
def convert_selected_text(converter_id)
|
1299
1310
|
return if !@visual_mode
|
1300
1311
|
r = get_visual_mode_range
|
@@ -1503,6 +1514,7 @@ class Buffer < String
|
|
1503
1514
|
#TODO: show message box
|
1504
1515
|
end
|
1505
1516
|
@last_save = Time.now
|
1517
|
+
refresh_title
|
1506
1518
|
debug "file saved on #{@last_save}"
|
1507
1519
|
sleep 3
|
1508
1520
|
}
|
@@ -1515,6 +1527,20 @@ class Buffer < String
|
|
1515
1527
|
end
|
1516
1528
|
end
|
1517
1529
|
|
1530
|
+
def unsaved_changes?
|
1531
|
+
pp [@t_modified, @last_save]
|
1532
|
+
return true if @t_modified > @last_save
|
1533
|
+
return false
|
1534
|
+
end
|
1535
|
+
|
1536
|
+
def refresh_title
|
1537
|
+
if vma.buf == self
|
1538
|
+
pfx = ""
|
1539
|
+
pfx = "+ " if vma.buf.unsaved_changes?
|
1540
|
+
gui_set_window_title(pfx + vma.buf.title, vma.buf.subtitle)
|
1541
|
+
end
|
1542
|
+
end
|
1543
|
+
|
1518
1544
|
def check_if_modified_outside
|
1519
1545
|
# Don't check if less than 8 seconds since last checked
|
1520
1546
|
return false if @fname.nil?
|
@@ -1597,4 +1623,3 @@ def backup_all_buffers()
|
|
1597
1623
|
end
|
1598
1624
|
message("Backup all buffers")
|
1599
1625
|
end
|
1600
|
-
|
@@ -5,6 +5,7 @@ class Buffer < String
|
|
5
5
|
|
6
6
|
#TODO: change to apply=true as default
|
7
7
|
def add_delta(delta, apply = false, auto_update_cpos = false)
|
8
|
+
@t_modified = Time.now
|
8
9
|
return if !is_delta_ok(delta)
|
9
10
|
if delta[1] == DELETE
|
10
11
|
return if delta[0] >= self.size
|
@@ -26,6 +27,7 @@ class Buffer < String
|
|
26
27
|
add_delta([self.size, INSERT, 1, "\n"], true)
|
27
28
|
end
|
28
29
|
reset_larger_cpos #TODO: correct here?
|
30
|
+
refresh_title
|
29
31
|
end
|
30
32
|
|
31
33
|
# TODO: rename ot auto-format. separate module?
|
data/lib/vimamsa/buffer_list.rb
CHANGED
data/lib/vimamsa/editor.rb
CHANGED
@@ -139,7 +139,7 @@ class Editor
|
|
139
139
|
fname = fname_
|
140
140
|
end
|
141
141
|
else
|
142
|
-
fname = ppath("demo.txt")
|
142
|
+
# fname = ppath("demo.txt")
|
143
143
|
end
|
144
144
|
fname = ARGV[0] if ARGV.size >= 1 and File.file?(File.expand_path(ARGV[0]))
|
145
145
|
# vma.add_content_search_path(Dir.pwd)
|
@@ -645,7 +645,7 @@ def find_project_dir_of_fn(fn)
|
|
645
645
|
break
|
646
646
|
end
|
647
647
|
end
|
648
|
-
return if !projdir.nil?
|
648
|
+
return projdir if !projdir.nil?
|
649
649
|
end
|
650
650
|
return projdir
|
651
651
|
end
|
data/lib/vimamsa/file_finder.rb
CHANGED
@@ -8,6 +8,7 @@ cnf.search_dirs = []
|
|
8
8
|
class StringIndex
|
9
9
|
def initialize()
|
10
10
|
@idx = StrIdx::StringIndex.new
|
11
|
+
@idx.setDirSeparator("/")
|
11
12
|
end
|
12
13
|
|
13
14
|
def find(str, minChars: 2)
|
@@ -94,10 +95,15 @@ class FileFinder
|
|
94
95
|
select_callback = self.method("gui_file_finder_select_callback")
|
95
96
|
update_callback = self.method("gui_file_finder_update_callback")
|
96
97
|
|
98
|
+
|
99
|
+
opt = { :title => "Fuzzy filename search",
|
100
|
+
:desc => "Search for files in folders defined in cnf.search_dirs" ,
|
101
|
+
:columns => [{:title=>'Filename',:id=>0}]
|
102
|
+
}
|
103
|
+
|
97
104
|
gui_select_update_window(l, $select_keys.collect { |x| x.upcase },
|
98
|
-
# "gui_file_finder_select_callback",
|
99
105
|
select_callback,
|
100
|
-
update_callback)
|
106
|
+
update_callback, opt)
|
101
107
|
end
|
102
108
|
|
103
109
|
def gui_file_finder_update_callback(search_str = "")
|
@@ -105,8 +111,11 @@ class FileFinder
|
|
105
111
|
if (search_str.size >= 3)
|
106
112
|
files = filter_files(search_str)
|
107
113
|
@file_search_list = files
|
114
|
+
if files.size > 1
|
115
|
+
files = files.collect{|x|[tilde_path(x[0])]}
|
116
|
+
end
|
117
|
+
|
108
118
|
return files
|
109
|
-
#debug files.inspect
|
110
119
|
#return files.values
|
111
120
|
end
|
112
121
|
return []
|
@@ -104,9 +104,18 @@ class VSourceView < GtkSource::View
|
|
104
104
|
# Sometimes a GestureClick EventController appears from somewhere
|
105
105
|
# not initiated from this file.
|
106
106
|
|
107
|
-
#
|
108
|
-
|
109
|
-
|
107
|
+
# TODO: Check which of these are needed:
|
108
|
+
# puts ctr.class
|
109
|
+
# Gtk::DropTarget
|
110
|
+
# Gtk::EventControllerFocus
|
111
|
+
# Gtk::EventControllerKey
|
112
|
+
# Gtk::EventControllerMotion
|
113
|
+
# Gtk::EventControllerScroll
|
114
|
+
# Gtk::GestureClick
|
115
|
+
# Gtk::GestureDrag
|
116
|
+
# Gtk::ShortcutController
|
117
|
+
|
118
|
+
if ctr != @click and [Gtk::DropControllerMotion, Gtk::DropTarget, Gtk::GestureDrag, Gtk::GestureClick, Gtk::EventControllerKey].include?(ctr.class)
|
110
119
|
to_remove << ctr
|
111
120
|
end
|
112
121
|
}
|
@@ -120,20 +129,19 @@ class VSourceView < GtkSource::View
|
|
120
129
|
end
|
121
130
|
|
122
131
|
def focus_out()
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
132
|
+
set_cursor_color(:inactive)
|
133
|
+
|
134
|
+
# This does not seem to work: (TODO:why?)
|
135
|
+
# self.cursor_visible = false
|
127
136
|
end
|
128
|
-
|
137
|
+
|
129
138
|
def focus_in()
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
139
|
+
set_cursor_color(@ctype)
|
140
|
+
self.cursor_visible = false
|
141
|
+
self.cursor_visible = true
|
142
|
+
self.grab_focus
|
134
143
|
end
|
135
|
-
|
136
|
-
|
144
|
+
|
137
145
|
def register_signals()
|
138
146
|
check_controllers
|
139
147
|
|
@@ -332,7 +340,7 @@ class VSourceView < GtkSource::View
|
|
332
340
|
end
|
333
341
|
debug $view.visible_rect.inspect
|
334
342
|
|
335
|
-
debug "key event"
|
343
|
+
debug "key event" + [keyval, @last_keyval, keyname, sig].to_s
|
336
344
|
# debug event
|
337
345
|
|
338
346
|
# key_name = event.string
|
@@ -353,6 +361,7 @@ class VSourceView < GtkSource::View
|
|
353
361
|
keyval_trans[Gdk::Keyval::KEY_KP_Enter] = "enter"
|
354
362
|
keyval_trans[Gdk::Keyval::KEY_Alt_L] = "alt"
|
355
363
|
keyval_trans[Gdk::Keyval::KEY_Alt_R] = "alt"
|
364
|
+
keyval_trans[Gdk::Keyval::KEY_Caps_Lock] = "caps"
|
356
365
|
|
357
366
|
keyval_trans[Gdk::Keyval::KEY_BackSpace] = "backspace"
|
358
367
|
keyval_trans[Gdk::Keyval::KEY_KP_Page_Down] = "pagedown"
|
@@ -383,6 +392,15 @@ class VSourceView < GtkSource::View
|
|
383
392
|
key_str_parts << "super" if vma.kbd.modifiers[:super]
|
384
393
|
key_str_parts << keyname
|
385
394
|
|
395
|
+
# After remapping capslock to control in gnome-tweak tool,
|
396
|
+
# if pressing and immediately releasing the capslock (control) key,
|
397
|
+
# we get first "caps" on keydown and ctrl-"caps" on keyup (keyval 65509, Gdk::Keyval::KEY_Caps_Lock)
|
398
|
+
# If mapping capslock to ctrl in hardware, we get keyval 65507 (Gdk::Keyval::KEY_Control_L) instead
|
399
|
+
if key_str_parts[0] == "ctrl" and key_str_parts[1] == "caps"
|
400
|
+
# Replace ctrl-caps with ctrl
|
401
|
+
key_str_parts.delete_at(1)
|
402
|
+
end
|
403
|
+
|
386
404
|
if key_str_parts[0] == key_str_parts[1]
|
387
405
|
# We don't want "ctrl-ctrl" or "alt-alt"
|
388
406
|
# TODO:There should be a better way to do this
|
@@ -415,8 +433,8 @@ class VSourceView < GtkSource::View
|
|
415
433
|
$kbd.match_key_conf(key_str, nil, :key_press)
|
416
434
|
@last_event = [keynfo, key_str, :key_press]
|
417
435
|
end
|
418
|
-
@last_keyval = keyval #TODO: outside if?
|
419
436
|
end
|
437
|
+
@last_keyval = keyval
|
420
438
|
|
421
439
|
handle_deltas
|
422
440
|
|
@@ -596,7 +614,6 @@ class VSourceView < GtkSource::View
|
|
596
614
|
end
|
597
615
|
|
598
616
|
def draw_cursor
|
599
|
-
|
600
617
|
sv = vma.gui.active_window[:sw].child
|
601
618
|
return if sv.nil?
|
602
619
|
if sv != self # if we are not the current buffer
|
data/lib/vimamsa/key_actions.rb
CHANGED
@@ -33,6 +33,8 @@ reg_act(:command_to_buf, proc { command_to_buf }, "Execute command, output to bu
|
|
33
33
|
reg_act(:lsp_debug, proc { vma.buf.lsp_get_def }, "LSP get definition")
|
34
34
|
reg_act(:lsp_jump_to_definition, proc { vma.buf.lsp_jump_to_def }, "LSP jump to definition")
|
35
35
|
|
36
|
+
reg_act(:eval_buf, proc { vma.buf.eval_whole_buf }, "Eval whole current buffer as ruby code (DANGEROUS)")
|
37
|
+
|
36
38
|
reg_act(:enable_debug, proc { cnf.debug = true }, "Enable debug")
|
37
39
|
reg_act(:disable_debug, proc { cnf.debug = false }, "Disable debug")
|
38
40
|
|
@@ -632,11 +632,12 @@ end
|
|
632
632
|
|
633
633
|
# Try to clear modifiers when program loses focus
|
634
634
|
# e.g. after alt-tab
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
635
|
+
# TODO
|
636
|
+
# def focus_out
|
637
|
+
# debug "RB Clear modifiers"
|
638
|
+
# $kbd.clear_modifiers()
|
639
|
+
# end
|
640
|
+
|
641
|
+
# def handle_key_event(event)
|
642
|
+
# $kbd.handle_key_event(event)
|
643
|
+
# end
|
@@ -127,6 +127,7 @@ bindkey "C p", [:paste_after, proc { buf.paste(AFTER) }, ""] # TODO: implement a
|
|
127
127
|
bindkey "V d", [:delete_selection, proc { buf.delete(SELECTION) }, ""]
|
128
128
|
bindkey "V a d", [:delete_append_selection, proc { buf.delete(SELECTION, :append) }, "Delete and append selection"]
|
129
129
|
|
130
|
+
|
130
131
|
default_keys = {
|
131
132
|
|
132
133
|
# File handling
|
@@ -266,6 +267,7 @@ default_keys = {
|
|
266
267
|
"C d <num> e" => "delete_next_word",
|
267
268
|
"C d ' <char>" => "buf.delete2(:to_mark,<char>)",
|
268
269
|
"C r <char>" => "buf.replace_with_char(<char>)", # TODO
|
270
|
+
"C r space" => "buf.replace_with_char(' ')", # TODO
|
269
271
|
"C , l b" => "load_buffer_list",
|
270
272
|
"C , l l" => "save_buffer_list",
|
271
273
|
"C , r <char>" => "vma.set_register(<char>)", # TODO
|
@@ -331,7 +333,7 @@ default_keys = {
|
|
331
333
|
"CV ctrl-q" => :quit,
|
332
334
|
"CV , R" => "restart_application",
|
333
335
|
# "I ctrl!" => "vma.kbd.to_previous_mode",
|
334
|
-
"C shift!" => "buf.save",
|
336
|
+
"C shift! s" => "buf.save",
|
335
337
|
"I ctrl-s" => "buf.save",
|
336
338
|
"I <char>" => "buf.insert_txt(<char>)",
|
337
339
|
"I esc || I ctrl!" => "vma.kbd.to_previous_mode",
|
data/lib/vimamsa/macro.rb
CHANGED
@@ -118,8 +118,10 @@ class Macro
|
|
118
118
|
|
119
119
|
# Run the provided list of actions
|
120
120
|
def run_actions(acts)
|
121
|
+
acts = [acts] if acts.class != Array
|
121
122
|
isok = true
|
122
|
-
if acts.kind_of?(Array) and acts.any?
|
123
|
+
# if acts.kind_of?(Array) and acts.any?
|
124
|
+
if acts.any?
|
123
125
|
@running_macro = true
|
124
126
|
# TODO:needed?
|
125
127
|
# set_last_command({ method: vma.macro.method("run_macro"), params: [name] })
|
data/lib/vimamsa/tests.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
require "digest"
|
2
2
|
|
3
3
|
def run_tests()
|
4
|
-
|
4
|
+
# DelayExecutioner.exec(id: :run_tests, wait: 0.7, callable: proc { run_tests_0 })
|
5
|
+
|
6
|
+
# Reload class
|
7
|
+
# if Object.constants.include?(:EditorTests)
|
8
|
+
# Object.send(:remove_const, :EditorTests)
|
9
|
+
# end
|
10
|
+
load __FILE__
|
11
|
+
|
12
|
+
run_edit_tests
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_tests_0()
|
16
|
+
tests = ["test_write_0"]
|
5
17
|
stats = []
|
6
18
|
for t in tests
|
7
19
|
r = eval(t)
|
@@ -16,7 +28,74 @@ def run_tests()
|
|
16
28
|
puts "===================="
|
17
29
|
end
|
18
30
|
|
19
|
-
|
31
|
+
def run_edit_tests()
|
32
|
+
edt = EditorTests.new
|
33
|
+
tests = edt.methods.select { |x| x.match(/test_.*/) }.collect { |x| { :method => edt.method(x), :name => x } }
|
34
|
+
for t in tests
|
35
|
+
b = create_new_buffer(file_contents = "\n", prefix = "buf", setcurrent = true)
|
36
|
+
|
37
|
+
edits = t[:method].call
|
38
|
+
# next if t[:name] != :test_create_close_buf
|
39
|
+
errors = 0
|
40
|
+
edits.each_with_index do |x, i|
|
41
|
+
if x.class == Array
|
42
|
+
(act, target) = x
|
43
|
+
|
44
|
+
vma.macro.run_actions(act)
|
45
|
+
# bufc = b.to_s
|
46
|
+
bufc = vma.buf.to_s
|
47
|
+
if bufc != target
|
48
|
+
puts "ERROR[#{t[:name]}:#{i}] act=#{act.inspect} content=#{bufc.inspect} != #{target.inspect}"
|
49
|
+
errors += 1
|
50
|
+
end
|
51
|
+
else
|
52
|
+
vma.macro.run_actions(x)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
if errors == 0
|
56
|
+
puts "TEST #{t[:name]} passed"
|
57
|
+
else
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class EditorTests
|
63
|
+
def test_write
|
64
|
+
#[[action to run, expected buffer contents after], ...]
|
65
|
+
[['buf.insert_txt("zzzz")', "zzzz\n"],
|
66
|
+
# At end of file replace should not change anything
|
67
|
+
['buf.replace_with_char("-")', "zzzz\n"],
|
68
|
+
'buf.insert_txt("\n")',
|
69
|
+
['buf.insert_txt("yy")', "zzzz\nyy\n"],
|
70
|
+
:e_move_backward_char, :e_move_backward_char,
|
71
|
+
['buf.insert_txt("0")', "zzzz\n0yy\n"],
|
72
|
+
"buf.jump(START_OF_BUFFER)",
|
73
|
+
['buf.replace_with_char("1")', "1zzz\n0yy\n"]]
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_delete
|
77
|
+
[['buf.insert_txt("abcdef")', "abcdef\n"],
|
78
|
+
'buf.insert_txt("\n")',
|
79
|
+
['buf.insert_txt("yy")', "abcdef\nyy\n"],
|
80
|
+
"buf.jump(START_OF_BUFFER)",
|
81
|
+
:delete_char_forward,
|
82
|
+
[:delete_char_forward, "cdef\nyy\n"],
|
83
|
+
"buf.jump(END_OF_LINE)",
|
84
|
+
"buf.delete(BACKWARD_CHAR)",
|
85
|
+
["buf.delete(BACKWARD_CHAR)", "cd\nyy\n"]]
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_create_close_buf
|
89
|
+
['buf.insert_txt("abcdef")',
|
90
|
+
[:buf_new,"\n"],
|
91
|
+
'buf.insert_txt("a")',
|
92
|
+
'buf.insert_txt("b")',
|
93
|
+
'buf.insert_txt("c")',
|
94
|
+
'buf.insert_txt("d")',
|
95
|
+
['buf.insert_txt("e")',"abcde\n"],
|
96
|
+
[:close_current_buffer, "abcdef\n"]]
|
97
|
+
end
|
98
|
+
end
|
20
99
|
|
21
100
|
def test_paste_0(runmacro = true)
|
22
101
|
return
|
@@ -19,6 +19,8 @@ end
|
|
19
19
|
Converter.new(lambda { |x| x.split("\n").collect { |x| r = x.strip }.select { |y| !y.empty? }.join(" ") + "\n" }, :lambda, :joinlines)
|
20
20
|
|
21
21
|
Converter.new(lambda { |x| x.split("\n").sort.join("\n") }, :lambda, :sortlines)
|
22
|
+
Converter.new(lambda { |x| x.split("\n").reverse.join("\n") }, :lambda, :reverse_lines)
|
23
|
+
|
22
24
|
Converter.new(lambda { |x| x.split(/\s+/).sort.join(" ") }, :lambda, :sortwords)
|
23
25
|
Converter.new(lambda { |x| x.split("\n").collect { |b| b.scan(/(\d+(\.\d+)?)/).collect { |c| c[0] }.join(" ") }.join("\n") }, :lambda, :getnums_on_lines)
|
24
26
|
|
data/lib/vimamsa/util.rb
CHANGED
@@ -93,7 +93,7 @@ end
|
|
93
93
|
|
94
94
|
# file --mime-type --mime-encoding
|
95
95
|
|
96
|
-
# Run idle proc once
|
96
|
+
# Run idle proc once (return false)
|
97
97
|
# Delay execution of proc until Gtk has fully processed the last calls.
|
98
98
|
def run_as_idle(p, delay: 0.0)
|
99
99
|
if p.class == Proc
|
@@ -141,6 +141,24 @@ def exec_cmd(bin_name, arg1 = nil, arg2 = nil, arg3 = nil, arg4 = nil, arg5 = ni
|
|
141
141
|
return ret_str
|
142
142
|
end
|
143
143
|
|
144
|
+
def pipe_to_external(program, text)
|
145
|
+
# Open a pipe to the external program
|
146
|
+
IO.popen(program, "r+") do |pipe|
|
147
|
+
# Send the text to the program
|
148
|
+
pipe.write(text)
|
149
|
+
pipe.close_write # Close the write end to signal EOF to the program
|
150
|
+
# Read and return the output from the program
|
151
|
+
output = pipe.read
|
152
|
+
return output
|
153
|
+
end
|
154
|
+
rescue Errno::ENOENT
|
155
|
+
puts "Error: The program '#{program}' was not found."
|
156
|
+
nil
|
157
|
+
rescue => e
|
158
|
+
puts "An error occurred: #{e.message}"
|
159
|
+
nil
|
160
|
+
end
|
161
|
+
|
144
162
|
def mkdir_if_not_exists(_dirpath)
|
145
163
|
dirpath = File.expand_path(_dirpath)
|
146
164
|
Dir.mkdir(dirpath) unless File.exist?(dirpath)
|
data/lib/vimamsa/version.rb
CHANGED
data/vimamsa.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "vimamsa/version"
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "vimamsa"
|
8
|
-
spec.version = Vimamsa::VERSION
|
8
|
+
spec.version = Vimamsa::VERSION # in lib/vimamsa/version.rb
|
9
9
|
spec.authors = ["Sami Sieranoja"]
|
10
10
|
spec.email = ["sami.sieranoja@gmail.com"]
|
11
11
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vimamsa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sami Sieranoja
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -295,7 +295,7 @@ homepage: https://github.com/SamiSieranoja/vimamsa
|
|
295
295
|
licenses:
|
296
296
|
- GPL-3.0+
|
297
297
|
metadata: {}
|
298
|
-
post_install_message:
|
298
|
+
post_install_message:
|
299
299
|
rdoc_options: []
|
300
300
|
require_paths:
|
301
301
|
- lib
|
@@ -311,8 +311,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
311
311
|
- !ruby/object:Gem::Version
|
312
312
|
version: '0'
|
313
313
|
requirements: []
|
314
|
-
rubygems_version: 3.
|
315
|
-
signing_key:
|
314
|
+
rubygems_version: 3.4.20
|
315
|
+
signing_key:
|
316
316
|
specification_version: 4
|
317
317
|
summary: Vimamsa
|
318
318
|
test_files: []
|