vimamsa 0.1.9 → 0.1.11
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 +29 -7
- data/custom_example.rb +12 -2
- data/demo.txt +2 -2
- data/exe/vimamsa +1 -1
- data/lib/vimamsa/ack.rb +57 -46
- data/lib/vimamsa/actions.rb +1 -1
- data/lib/vimamsa/buffer.rb +287 -55
- data/lib/vimamsa/buffer_list.rb +83 -48
- data/lib/vimamsa/buffer_manager.rb +19 -3
- data/lib/vimamsa/conf.rb +10 -1
- data/lib/vimamsa/debug.rb +15 -11
- data/lib/vimamsa/easy_jump.rb +9 -5
- data/lib/vimamsa/editor.rb +73 -54
- data/lib/vimamsa/encrypt.rb +2 -2
- data/lib/vimamsa/file_finder.rb +70 -72
- data/lib/vimamsa/file_history.rb +2 -3
- data/lib/vimamsa/file_manager.rb +10 -8
- data/lib/vimamsa/form_generator.rb +122 -0
- data/lib/vimamsa/gui.rb +469 -118
- data/lib/vimamsa/gui_image.rb +12 -6
- data/lib/vimamsa/gui_menu.rb +26 -21
- data/lib/vimamsa/gui_select_window.rb +40 -21
- data/lib/vimamsa/gui_sourceview.rb +173 -79
- data/lib/vimamsa/hyper_plain_text.rb +36 -3
- data/lib/vimamsa/key_actions.rb +13 -1
- data/lib/vimamsa/key_binding_tree.rb +32 -20
- data/lib/vimamsa/key_bindings_vimlike.rb +54 -25
- data/lib/vimamsa/langservp.rb +172 -0
- data/lib/vimamsa/macro.rb +9 -8
- data/lib/vimamsa/main.rb +3 -4
- data/lib/vimamsa/rbvma.rb +7 -4
- data/lib/vimamsa/search.rb +3 -2
- data/lib/vimamsa/search_replace.rb +50 -120
- data/lib/vimamsa/text_transforms.rb +1 -1
- data/lib/vimamsa/util.rb +47 -1
- data/lib/vimamsa/version.rb +1 -1
- data/lib/vimamsa.rb +1 -6
- data/styles/molokai_edit.xml +3 -0
- data/vimamsa.gemspec +10 -10
- metadata +22 -20
data/lib/vimamsa/buffer_list.rb
CHANGED
@@ -3,7 +3,7 @@ def save_buffer_list()
|
|
3
3
|
message("Save buffer list")
|
4
4
|
buffn = get_dot_path("buffers.txt")
|
5
5
|
f = File.open(buffn, "w")
|
6
|
-
bufstr =
|
6
|
+
bufstr = vma.buffers.collect { |buf| buf.fname }.inspect
|
7
7
|
f.write(bufstr)
|
8
8
|
f.close()
|
9
9
|
end
|
@@ -21,18 +21,31 @@ def load_buffer_list()
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class BufferList < Array
|
24
|
-
attr_reader :current_buf
|
24
|
+
attr_reader :current_buf, :last_dir, :buffer_history
|
25
25
|
|
26
|
+
def initialize()
|
27
|
+
@last_dir = File.expand_path(".")
|
28
|
+
@buffer_history = []
|
29
|
+
super
|
30
|
+
@current_buf=0
|
31
|
+
end
|
26
32
|
|
33
|
+
# lastdir = File.expand_path(".") if lastdir.nil?
|
27
34
|
def <<(_buf)
|
28
35
|
super
|
29
|
-
|
36
|
+
vma.buf = _buf
|
30
37
|
@current_buf = self.size - 1
|
31
|
-
|
38
|
+
@buffer_history << @current_buf
|
32
39
|
@recent_ind = 0
|
33
|
-
$hook.call(:change_buffer,
|
34
|
-
|
35
|
-
gui_set_cursor_pos(
|
40
|
+
$hook.call(:change_buffer, vma.buf)
|
41
|
+
vma.gui.set_current_buffer(vma.buf.id)
|
42
|
+
gui_set_cursor_pos(vma.buf.id, vma.buf.pos)
|
43
|
+
update_last_dir(_buf)
|
44
|
+
end
|
45
|
+
|
46
|
+
def add(_buf)
|
47
|
+
self.append(_buf)
|
48
|
+
@buffer_history << self.size - 1
|
36
49
|
end
|
37
50
|
|
38
51
|
def switch()
|
@@ -44,10 +57,15 @@ class BufferList < Array
|
|
44
57
|
set_current_buffer(@current_buf)
|
45
58
|
end
|
46
59
|
|
60
|
+
def get_last_visited_id
|
61
|
+
last_buf = @buffer_history[-2]
|
62
|
+
return self[last_buf].id
|
63
|
+
end
|
64
|
+
|
47
65
|
def switch_to_last_buf()
|
48
66
|
debug "SWITCH TO LAST BUF:"
|
49
|
-
debug
|
50
|
-
last_buf =
|
67
|
+
debug @buffer_history
|
68
|
+
last_buf = @buffer_history[-2]
|
51
69
|
if last_buf
|
52
70
|
set_current_buffer(last_buf)
|
53
71
|
end
|
@@ -58,27 +76,46 @@ class BufferList < Array
|
|
58
76
|
buf_idx = self.index { |b| b.fname == fname }
|
59
77
|
return buf_idx
|
60
78
|
end
|
61
|
-
|
62
|
-
|
79
|
+
|
80
|
+
def get_buffer_by_id(id)
|
63
81
|
buf_idx = self.index { |b| b.id == id }
|
64
82
|
return buf_idx
|
65
83
|
end
|
66
|
-
|
84
|
+
|
85
|
+
def add_buf_to_history(buf_idx)
|
86
|
+
if self.include?(buf_idx)
|
87
|
+
@buffer_history << @buf_idx
|
88
|
+
@recent_ind = 0
|
89
|
+
compact_buf_history()
|
90
|
+
else
|
91
|
+
debug "buffer_list, no such id:#{buf_idx}"
|
92
|
+
return
|
93
|
+
end
|
94
|
+
end
|
67
95
|
|
68
96
|
def add_current_buf_to_history()
|
69
97
|
@recent_ind = 0
|
70
|
-
|
98
|
+
@buffer_history << @current_buf
|
71
99
|
compact_buf_history()
|
72
100
|
end
|
73
101
|
|
102
|
+
def set_current_buffer_by_id(buf_id, update_history = true)
|
103
|
+
idx = get_buffer_by_id(buf_id)
|
104
|
+
if idx.nil?
|
105
|
+
debug "IDX=nil"
|
106
|
+
return
|
107
|
+
end
|
108
|
+
set_current_buffer(idx, update_history)
|
109
|
+
end
|
110
|
+
|
74
111
|
def set_current_buffer(buffer_i, update_history = true)
|
75
112
|
buffer_i = self.size -1 if buffer_i > self.size
|
76
113
|
buffer_i = 0 if buffer_i < 0
|
77
|
-
|
78
|
-
return if
|
114
|
+
vma.buf = self[buffer_i]
|
115
|
+
return if !vma.buf
|
79
116
|
@current_buf = buffer_i
|
80
117
|
debug "SWITCH BUF2. bufsize:#{self.size}, curbuf: #{@current_buf}"
|
81
|
-
fpath =
|
118
|
+
fpath = vma.buf.fname
|
82
119
|
if fpath and fpath.size > 50
|
83
120
|
fpath = fpath[-50..-1]
|
84
121
|
end
|
@@ -87,36 +124,37 @@ class BufferList < Array
|
|
87
124
|
add_current_buf_to_history
|
88
125
|
end
|
89
126
|
|
90
|
-
|
91
|
-
|
127
|
+
vma.hook.call(:change_buffer, vma.buf)
|
128
|
+
vma.buf.set_active
|
129
|
+
|
130
|
+
vma.gui.set_current_buffer(vma.buf.id)
|
92
131
|
|
93
|
-
|
94
|
-
|
132
|
+
gui_set_window_title(vma.buf.title, vma.buf.subtitle)
|
133
|
+
|
134
|
+
if vma.buf.fname
|
135
|
+
@last_dir = File.dirname(vma.buf.fname)
|
136
|
+
end
|
95
137
|
|
96
138
|
# hpt_scan_images() if $debug # experimental
|
97
139
|
end
|
98
140
|
|
99
|
-
def
|
100
|
-
|
101
|
-
|
102
|
-
lastdir = File.dirname($buffer.fname)
|
103
|
-
else
|
104
|
-
for bufid in $buffer_history.reverse[1..-1]
|
105
|
-
bf = $buffers[bufid]
|
106
|
-
debug "FNAME:#{bf.fname}"
|
107
|
-
if bf.fname
|
108
|
-
lastdir = File.dirname(bf.fname)
|
109
|
-
break
|
110
|
-
end
|
111
|
-
end
|
141
|
+
def update_last_dir(buf)
|
142
|
+
if buf.fname
|
143
|
+
@last_dir = File.dirname(buf.fname)
|
112
144
|
end
|
113
|
-
|
114
|
-
|
145
|
+
end
|
146
|
+
|
147
|
+
def last_dir=(d)
|
148
|
+
@last_dir = d
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_last_dir
|
152
|
+
return @last_dir
|
115
153
|
end
|
116
154
|
|
117
155
|
def get_recent_buffers()
|
118
156
|
bufs = []; b = {}
|
119
|
-
|
157
|
+
@buffer_history.reverse.each { |x| bufs << x if !b[x] && x < self.size; b[x] = true }
|
120
158
|
return bufs
|
121
159
|
end
|
122
160
|
|
@@ -141,30 +179,27 @@ class BufferList < Array
|
|
141
179
|
def compact_buf_history()
|
142
180
|
h = {}
|
143
181
|
# Keep only first occurence in history
|
144
|
-
bh =
|
145
|
-
|
182
|
+
bh = @buffer_history.reverse.select { |x| r = h[x] == nil; h[x] = true; r }
|
183
|
+
@buffer_history = bh.reverse
|
146
184
|
end
|
147
185
|
|
148
|
-
|
149
186
|
# Close buffer in the background
|
150
187
|
# TODO: if open in another widget
|
151
188
|
def close_other_buffer(buffer_i)
|
152
189
|
return if self.size <= buffer_i
|
153
190
|
return if @current_buf == buffer_i
|
154
|
-
|
191
|
+
|
155
192
|
bufname = self[buffer_i].basename
|
156
193
|
message("Closed buffer #{bufname}")
|
157
194
|
|
158
195
|
self.slice!(buffer_i)
|
159
|
-
|
160
|
-
|
196
|
+
@buffer_history = @buffer_history.collect { |x| r = x; r = x - 1 if x > buffer_i; r = nil if x == buffer_i; r }.compact
|
161
197
|
end
|
162
198
|
|
163
|
-
|
164
199
|
def close_buffer(buffer_i, from_recent = false)
|
165
200
|
return if buffer_i.nil?
|
166
201
|
return if self.size <= buffer_i
|
167
|
-
|
202
|
+
|
168
203
|
bufname = self[buffer_i].basename
|
169
204
|
message("Closed buffer #{bufname}")
|
170
205
|
recent = get_recent_buffers
|
@@ -172,17 +207,17 @@ class BufferList < Array
|
|
172
207
|
jump_to_buf = 0 if jump_to_buf == nil
|
173
208
|
|
174
209
|
self.slice!(buffer_i)
|
175
|
-
|
210
|
+
@buffer_history = @buffer_history.collect { |x| r = x; r = x - 1 if x > buffer_i; r = nil if x == buffer_i; r }.compact
|
176
211
|
|
177
212
|
if @current_buf == buffer_i
|
178
213
|
if from_recent
|
179
214
|
@current_buf = jump_to_buf
|
180
215
|
else
|
181
|
-
|
216
|
+
# Find last edited buffer that is not already open
|
217
|
+
@current_buf = @buffer_history.filter{|x| !vma.gui.is_buffer_open(self[x].id)}.last
|
182
218
|
end
|
183
219
|
end
|
184
|
-
|
185
|
-
if self.size == 0
|
220
|
+
if self.size == 0 or @current_buf.nil?
|
186
221
|
self << Buffer.new("\n")
|
187
222
|
@current_buf = 0
|
188
223
|
else
|
@@ -43,8 +43,11 @@ class BufferManager
|
|
43
43
|
buf_i = buf_of_current_line()
|
44
44
|
return if buf_i.nil?
|
45
45
|
|
46
|
-
vma.buffers.close_current_buffer()
|
46
|
+
# vma.buffers.close_current_buffer() #TODO:??
|
47
47
|
vma.buffers.set_current_buffer(buf_i)
|
48
|
+
|
49
|
+
bid = vma.buffers.get_buffer_by_id(@buf.id)
|
50
|
+
vma.buffers.close_other_buffer(bid)
|
48
51
|
@@cur = nil
|
49
52
|
end
|
50
53
|
|
@@ -64,20 +67,33 @@ class BufferManager
|
|
64
67
|
s << @header.join("\n")
|
65
68
|
s << "\n"
|
66
69
|
i = 0
|
70
|
+
jump_to_line = 0
|
67
71
|
for b in vma.buffers.sort_by { |x| x.list_str }
|
72
|
+
if b.id == vma.buf.id # current file
|
73
|
+
# s << " "
|
74
|
+
jump_to_line = i
|
75
|
+
end
|
68
76
|
x = b.list_str
|
69
77
|
s << "#{x}\n"
|
70
78
|
@line_to_id[i] = b.id
|
71
79
|
i += 1
|
72
80
|
end
|
73
81
|
|
82
|
+
|
83
|
+
|
74
84
|
if @buf.nil?
|
75
|
-
@buf =
|
85
|
+
@buf = create_new_buffer(s,"bufmgr")
|
76
86
|
@buf.module = self
|
77
87
|
@buf.active_kbd_mode = :buf_mgr
|
78
88
|
else
|
79
89
|
@buf.set_content(s)
|
80
90
|
end
|
81
|
-
|
91
|
+
# Position on the line of the active buffer
|
92
|
+
# @buf.set_content(s)
|
93
|
+
newlpos = @header.size + jump_to_line
|
94
|
+
|
95
|
+
@buf.set_line_and_column_pos(newlpos, 0)
|
96
|
+
|
97
|
+
# Thread.new{sleep 0.1; center_on_current_line()} # TODO
|
82
98
|
end
|
83
99
|
end
|
data/lib/vimamsa/conf.rb
CHANGED
@@ -12,10 +12,19 @@ def setcnf(id, val)
|
|
12
12
|
set_conf(id, val)
|
13
13
|
end
|
14
14
|
|
15
|
+
setcnf :custom_lsp, {}
|
16
|
+
conf(:custom_lsp)[:ruby] = {name: "solargraph", command:"solargraph stdio", type: "stdio"}
|
17
|
+
conf(:custom_lsp)[:cpp] = {name: "clangd", command:"clangd-12 --offset-encoding=utf-8", type: "stdio"}
|
18
|
+
conf(:custom_lsp)[:python] = {name: "pyright", command:"pyright-langserver --stdio --verbose", type: "stdio"}
|
19
|
+
|
15
20
|
setcnf :indent_based_on_last_line, true
|
16
|
-
setcnf :extensions_to_open, [".txt", ".h", ".c", ".cpp", ".hpp", ".rb", ".inc", ".php", ".sh", ".m", ".gd", ".js"]
|
21
|
+
setcnf :extensions_to_open, [".txt", ".h", ".c", ".cpp", ".hpp", ".rb", ".inc", ".php", ".sh", ".m", ".gd", ".js", ".py"]
|
22
|
+
setcnf :default_search_extensions, ["txt", "rb"]
|
17
23
|
|
18
24
|
|
19
25
|
setcnf "log.verbose", 1
|
20
26
|
setcnf :tab_width, 4
|
27
|
+
setcnf :enable_lsp, false
|
28
|
+
|
29
|
+
setcnf :workspace_folders, []
|
21
30
|
|
data/lib/vimamsa/debug.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require "fileutils"
|
2
2
|
|
3
|
-
def debug(message)
|
3
|
+
def debug(message, severity = 1)
|
4
4
|
if $debug
|
5
|
+
if severity > 1
|
6
|
+
# Add red colour and bold for attention
|
7
|
+
# https://en.wikipedia.org/wiki/ANSI_escape_code
|
8
|
+
message = "\033[1;31m!!! \033[0m#{message}"
|
9
|
+
end
|
5
10
|
puts "[#{DateTime.now().strftime("%H:%M:%S")}] #{message}"
|
6
11
|
$stdout.flush
|
7
12
|
end
|
@@ -22,7 +27,7 @@ end
|
|
22
27
|
|
23
28
|
$log_messages = []
|
24
29
|
|
25
|
-
def log_message(message,vlevel=1)
|
30
|
+
def log_message(message, vlevel = 1)
|
26
31
|
puts message if conf("log.verbose") >= vlevel
|
27
32
|
$log_messages << message
|
28
33
|
end
|
@@ -81,19 +86,19 @@ end
|
|
81
86
|
|
82
87
|
def run_test(test_id)
|
83
88
|
target_results = read_file("", "tests/test_#{test_id}_output.txt")
|
84
|
-
old_buffer =
|
85
|
-
|
89
|
+
old_buffer = vma.buf
|
90
|
+
vma.buf = Buffer.new("", "")
|
86
91
|
load "tests/test_#{test_id}.rb"
|
87
|
-
test_ok =
|
92
|
+
test_ok = vma.buf.to_s.strip == target_results.strip
|
88
93
|
puts "##################"
|
89
94
|
puts target_results
|
90
95
|
puts "##################"
|
91
|
-
puts
|
96
|
+
puts vma.buf.to_s
|
92
97
|
puts "##################"
|
93
98
|
puts "TEST OK" if test_ok
|
94
99
|
puts "TEST FAILED" if !test_ok
|
95
100
|
puts "##################"
|
96
|
-
|
101
|
+
vma.buf = old_buffer
|
97
102
|
end
|
98
103
|
|
99
104
|
#TODO: remove?
|
@@ -121,7 +126,7 @@ def run_random_jump_test__tmpl(test_time = 60 * 60 * 10)
|
|
121
126
|
# puts buf.current_line()
|
122
127
|
# puts "======================"
|
123
128
|
|
124
|
-
render_buffer(
|
129
|
+
render_buffer(vma.buf)
|
125
130
|
|
126
131
|
gui_sleep(rand() / 2)
|
127
132
|
if rand() < (1 / 40.0)
|
@@ -130,14 +135,13 @@ def run_random_jump_test__tmpl(test_time = 60 * 60 * 10)
|
|
130
135
|
|
131
136
|
gui_trigger_event
|
132
137
|
buf.insert_txt("X") if rand() > 0.25
|
133
|
-
render_buffer(
|
138
|
+
render_buffer(vma.buf)
|
134
139
|
|
135
|
-
|
140
|
+
vma.buffers.set_current_buffer(rand(vma.buffers.size)) if rand > 0.25
|
136
141
|
step += 1
|
137
142
|
end
|
138
143
|
end
|
139
144
|
|
140
|
-
|
141
145
|
def start_ripl
|
142
146
|
Ripl.start :binding => binding
|
143
147
|
end
|
data/lib/vimamsa/easy_jump.rb
CHANGED
@@ -22,18 +22,20 @@ class EasyJump
|
|
22
22
|
r = false if lsh[x] or lsh[x - 1] or lsh[x - 2]
|
23
23
|
r
|
24
24
|
}
|
25
|
+
|
26
|
+
wsmarks = [0] if wsmarks.empty?
|
25
27
|
|
26
28
|
# Exclude those word start positions that are too close to each other
|
27
29
|
wsmarks.sort!
|
28
30
|
wsm2 = [wsmarks[0]]
|
29
31
|
for i in 1..(wsmarks.size - 1)
|
30
32
|
if (wsmarks[i] - wsm2[-1]) >= 4 or visible_text[wsm2[-1]..wsmarks[i]].include?("\n")
|
31
|
-
|
32
33
|
wsm2 << wsmarks[i]
|
33
34
|
end
|
34
35
|
end
|
35
36
|
wsmarks = wsm2
|
36
37
|
|
38
|
+
|
37
39
|
linestart_buf = (line_starts).collect { |x| x + visible_range[0] }
|
38
40
|
wsmarks_buf = (wsmarks).collect { |x| x + visible_range[0] }
|
39
41
|
|
@@ -57,9 +59,11 @@ class EasyJump
|
|
57
59
|
if @jump_sequence.include?(@easy_jump_input)
|
58
60
|
jshash = Hash[@jump_sequence.map.with_index.to_a]
|
59
61
|
nthword = jshash[@easy_jump_input]
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
newpos = @easy_jump_wsmarks[nthword]
|
63
|
+
if !newpos.nil?
|
64
|
+
debug "nthword:#{nthword} #{[@easy_jump_wsmarks[nthword], @jump_sequence[nthword]]}"
|
65
|
+
buf.set_pos(@easy_jump_wsmarks[nthword])
|
66
|
+
end
|
63
67
|
vma.kbd.remove_keyhandling_override
|
64
68
|
@jump_sequence = []
|
65
69
|
vma.gui.clear_overlay()
|
@@ -76,7 +80,7 @@ class EasyJump
|
|
76
80
|
def easy_jump_draw()
|
77
81
|
vma.gui.start_overlay_draw
|
78
82
|
for i in 0..(@easy_jump_wsmarks.size - 1)
|
79
|
-
vma.gui.overlay_draw_text(@jump_sequence[i], @easy_jump_wsmarks[i])
|
83
|
+
vma.gui.overlay_draw_text(@jump_sequence[i], @easy_jump_wsmarks[i])
|
80
84
|
end
|
81
85
|
vma.gui.end_overlay_draw
|
82
86
|
end
|