vimamsa 0.1.16 → 0.1.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vimamsa/ack.rb +91 -13
- data/lib/vimamsa/actions.rb +99 -84
- data/lib/vimamsa/buffer.rb +21 -9
- data/lib/vimamsa/buffer_list.rb +1 -0
- data/lib/vimamsa/buffer_manager.rb +1 -1
- data/lib/vimamsa/conf.rb +3 -0
- data/lib/vimamsa/editor.rb +13 -8
- data/lib/vimamsa/file_history.rb +3 -3
- data/lib/vimamsa/gui.rb +42 -6
- data/lib/vimamsa/gui_select_window.rb +2 -0
- data/lib/vimamsa/gui_sourceview.rb +20 -6
- data/lib/vimamsa/key_actions.rb +1 -1
- data/lib/vimamsa/key_binding_tree.rb +5 -6
- data/lib/vimamsa/key_bindings_vimlike.rb +53 -18
- data/lib/vimamsa/langservp.rb +3 -1
- data/lib/vimamsa/macro.rb +4 -1
- data/lib/vimamsa/rbvma.rb +0 -2
- data/lib/vimamsa/tests.rb +6 -9
- data/lib/vimamsa/util.rb +8 -0
- data/lib/vimamsa/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e861051f02f35b286c8e97c225b69b9377f1d5cdf3dcf311de89a2ababb9dcd9
|
4
|
+
data.tar.gz: c27f3bc13a925dbd0293592f9d692a1918e91a7ce8047868c340098be76d1613
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2dbc0c1b7c6f42f0d4eca33c82b5a7e007ca549dda77b4e4d23056264a16b853b2cacbaa120ff24a1b25eb010aeea79efc955a6f3b9018bf9cca1249276f2410
|
7
|
+
data.tar.gz: b9e9deb8f5c3faf4a0f5e03757a8070d91e79e1bc959c991ca101df288fb62f809acc15154e7eab234647ad3d9b2d7a2b488b6013ff3a5c6db1978cf06e1654c
|
data/lib/vimamsa/ack.rb
CHANGED
@@ -13,7 +13,6 @@ Will search all .txt files in the following directories:
|
|
13
13
|
</span>"
|
14
14
|
|
15
15
|
callback = proc { |x| FileContentSearch.search_buffer(x) }
|
16
|
-
# gui_one_input_action(nfo, "Search:", "search", callback)
|
17
16
|
|
18
17
|
params = {}
|
19
18
|
params["inputs"] = {}
|
@@ -21,7 +20,6 @@ Will search all .txt files in the following directories:
|
|
21
20
|
params["inputs"]["extensions"] = { :label => "Limit to file extensions:", :type => :entry }
|
22
21
|
params["inputs"]["extensions"][:initial_text] = conf(:default_search_extensions).join(",")
|
23
22
|
params["inputs"]["btn1"] = { :label => "Search", :type => :button }
|
24
|
-
# callback = proc { |x| gui_replace_callback(x) }
|
25
23
|
|
26
24
|
params[:callback] = callback
|
27
25
|
PopupFormGenerator.new(params).run
|
@@ -106,20 +104,100 @@ Will search the following directories:
|
|
106
104
|
If .vma_project exists in parent directory of current file, searches within that directory.
|
107
105
|
</span>"
|
108
106
|
|
109
|
-
callback = proc { |x| ack_buffer(x) }
|
107
|
+
callback = proc { |x| Ack.new.ack_buffer(x) }
|
110
108
|
gui_one_input_action(nfo, "Search:", "search", callback)
|
111
109
|
end
|
112
110
|
|
113
|
-
def
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
111
|
+
def group_by_folder(list)
|
112
|
+
bh = {}
|
113
|
+
for b in list
|
114
|
+
fpath = b[:fpath]
|
115
|
+
if !fpath.nil?
|
116
|
+
bname = File.basename(b[:fpath])
|
117
|
+
dname = File.dirname(b[:fpath])
|
118
|
+
else
|
119
|
+
#TODO
|
120
|
+
end
|
121
|
+
bh[dname] ||= {}
|
122
|
+
bh[dname][:files] ||= []
|
123
|
+
bh[dname][:files] << { bname: bname, nfo: b }
|
124
|
+
end
|
125
|
+
arr = []
|
126
|
+
|
127
|
+
for k in bh.keys.sort
|
128
|
+
tp = tilde_path(k)
|
129
|
+
arr << { type: :dir, path: tp }
|
130
|
+
for f in bh[k][:files].sort_by { |x| x[:bname] }
|
131
|
+
arr << { type: :file, bname: f[:bname], nfo: f[:nfo] }
|
132
|
+
end
|
118
133
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
134
|
+
return arr
|
135
|
+
end
|
136
|
+
|
137
|
+
class Ack
|
138
|
+
attr_reader :buf
|
139
|
+
@@cur = nil # Current object of class
|
140
|
+
|
141
|
+
def self.cur()
|
142
|
+
return @@cur
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.init()
|
146
|
+
end
|
147
|
+
|
148
|
+
def initialize()
|
149
|
+
@buf = nil
|
150
|
+
@line_to_id = {}
|
151
|
+
end
|
152
|
+
|
153
|
+
def ack_buffer(_instr, b = nil)
|
154
|
+
instr = Shellwords.escape(_instr)
|
155
|
+
bufstr = ""
|
156
|
+
for path in vma.get_content_search_paths
|
157
|
+
bufstr += run_cmd("ack -Q --type-add=gd=.gd -ki --nohtml --nojs --nojson #{instr} #{path}")
|
158
|
+
end
|
159
|
+
|
160
|
+
b = ""
|
161
|
+
list = []
|
162
|
+
for x in bufstr.lines
|
163
|
+
if x.match(/(.*?):(\d+):(.+)/) # non greedy: *?
|
164
|
+
fn = $1
|
165
|
+
lineno = $2
|
166
|
+
matchpart = $3
|
167
|
+
pp [fn, lineno, matchpart]
|
168
|
+
b << "[#{fn},#{lineno},#{matchpart}]\n"
|
169
|
+
list << { fpath: fn, lineno: lineno, matchpart: matchpart }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
gb = group_by_folder(list)
|
174
|
+
s = ""
|
175
|
+
@line_to_nfo = {}
|
176
|
+
i = 0
|
177
|
+
for x in gb
|
178
|
+
if x[:type] == :file
|
179
|
+
s << "╰─#{x[:bname]}:#{x[:nfo][:lineno]}:#{x[:nfo][:matchpart]}\n"
|
180
|
+
@line_to_nfo[i] = x
|
181
|
+
end
|
182
|
+
if x[:type] == :dir
|
183
|
+
s << "📂#{x[:path]}:\n"
|
184
|
+
end
|
185
|
+
i += 1
|
186
|
+
end
|
187
|
+
|
188
|
+
if s.size > 5
|
189
|
+
@buf = create_new_buffer(s, "ack")
|
190
|
+
@buf.module = self
|
191
|
+
@buf.line_action_handler = self.method("select_line")
|
192
|
+
Gui.highlight_match(@buf, _instr, color: cnf.match.highlight.color!)
|
193
|
+
else
|
194
|
+
message("No results for input:#{instr}")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def select_line(lineno)
|
199
|
+
debug "def select_line #{lineno}", 2
|
200
|
+
nfo = @line_to_nfo[lineno][:nfo]
|
201
|
+
jump_to_file(nfo[:fpath], nfo[:lineno].to_i)
|
124
202
|
end
|
125
203
|
end
|
data/lib/vimamsa/actions.rb
CHANGED
@@ -6,13 +6,10 @@ class Action
|
|
6
6
|
@id = id
|
7
7
|
@method = method
|
8
8
|
@opt = opt
|
9
|
-
|
10
|
-
$actions[id] = self
|
9
|
+
vma.actions.register(id, self) # TODO: handle this in Editor class
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
14
|
-
$actions = {}
|
15
|
-
|
16
13
|
def reg_act(id, callfunc, name = "", opt = {})
|
17
14
|
if callfunc.class == Proc
|
18
15
|
a = Action.new(id, name, callfunc, opt)
|
@@ -31,108 +28,126 @@ def missing_callfunc
|
|
31
28
|
debug "missing_callfunc"
|
32
29
|
end
|
33
30
|
|
34
|
-
#TODO: remove
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
#TODO: remove?
|
32
|
+
def call_action(id)
|
33
|
+
vma.actions.call(id)
|
34
|
+
end
|
38
35
|
|
39
|
-
|
36
|
+
class ActionList
|
37
|
+
def initialize
|
38
|
+
@acth = []
|
39
|
+
@actions = {}
|
40
|
+
end
|
40
41
|
|
41
|
-
def
|
42
|
-
|
43
|
-
a = $actions[id]
|
44
|
-
if a
|
45
|
-
a.method.call()
|
46
|
-
else
|
47
|
-
message("Unknown action: " + id.inspect)
|
42
|
+
def register(id, obj)
|
43
|
+
@actions[id] = obj
|
48
44
|
end
|
49
|
-
end
|
50
45
|
|
51
|
-
def
|
52
|
-
|
53
|
-
end
|
46
|
+
def include?(act)
|
47
|
+
return @actions.has_key?(act)
|
48
|
+
end
|
54
49
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
$select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
|
50
|
+
def [](id)
|
51
|
+
@actions[id]
|
52
|
+
end
|
59
53
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
def call(id)
|
55
|
+
@acth << id
|
56
|
+
a = @actions[id]
|
57
|
+
if a
|
58
|
+
a.method.call()
|
59
|
+
else
|
60
|
+
message("Unknown action: " + id.inspect)
|
61
|
+
end
|
62
|
+
end
|
65
63
|
|
66
|
-
|
64
|
+
def last_action
|
65
|
+
return @acth[-1]
|
66
|
+
end
|
67
67
|
|
68
|
-
def
|
69
|
-
|
68
|
+
def gui_search()
|
69
|
+
l = []
|
70
|
+
opt = { :title => "Search for actions", :desc => "Fuzzy search for actions. <up> or <down> to change selcted. <enter> to select current.",
|
71
|
+
:columns => [{ :title => "Shortcut", :id => 0 }, { :title => "Action", :id => 1 }] }
|
70
72
|
|
71
|
-
|
72
|
-
for act_id in $actions.keys
|
73
|
-
act = $actions[act_id]
|
74
|
-
item = {}
|
75
|
-
item[:key] = ""
|
73
|
+
@select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
break
|
82
|
-
end
|
83
|
-
end
|
84
|
-
# c_kbd = vma.kbd.act_bindings[mode_str][nfo[:action]]
|
85
|
-
item[:action] = act_id
|
86
|
-
item[:str] = act_id.to_s
|
87
|
-
if $actions[act_id].method_name != ""
|
88
|
-
item[:str] = $actions[act_id].method_name
|
89
|
-
end
|
90
|
-
item_list2 << item
|
75
|
+
gui_select_update_window(l, @select_keys.collect { |x| x.upcase },
|
76
|
+
self.method("search_actions_select_callback"),
|
77
|
+
self.method("search_actions_update_callback"),
|
78
|
+
opt)
|
91
79
|
end
|
92
80
|
|
93
|
-
item_list =
|
81
|
+
@item_list = []
|
94
82
|
|
95
|
-
|
96
|
-
|
83
|
+
def search_actions_update_callback(search_str = "")
|
84
|
+
return [] if search_str == ""
|
97
85
|
|
98
|
-
|
99
|
-
|
100
|
-
|
86
|
+
item_list2 = []
|
87
|
+
for act_id in @actions.keys
|
88
|
+
act = @actions[act_id]
|
89
|
+
item = {}
|
90
|
+
item[:key] = ""
|
101
91
|
|
102
|
-
|
92
|
+
for mode_str in ["C", "V"]
|
93
|
+
c_kbd = vma.kbd.act_bindings[mode_str][act_id]
|
94
|
+
if c_kbd.class == String
|
95
|
+
item[:key] = "[#{mode_str}] #{c_kbd} "
|
96
|
+
item[:key] = "" if item[:key].size > 15
|
97
|
+
break
|
98
|
+
end
|
99
|
+
end
|
100
|
+
# c_kbd = vma.kbd.act_bindings[mode_str][nfo[:action]]
|
101
|
+
item[:action] = act_id
|
102
|
+
item[:str] = act_id.to_s
|
103
|
+
if @actions[act_id].method_name != ""
|
104
|
+
item[:str] = @actions[act_id].method_name
|
105
|
+
end
|
106
|
+
item_list2 << item
|
107
|
+
end
|
103
108
|
|
104
|
-
|
105
|
-
return r
|
106
|
-
end
|
109
|
+
item_list = item_list2
|
107
110
|
|
108
|
-
|
109
|
-
|
110
|
-
acc = item[0][:action]
|
111
|
+
a = filter_items(item_list, 0, search_str)
|
112
|
+
debug a.inspect
|
111
113
|
|
112
|
-
|
113
|
-
|
114
|
+
r = a.collect { |x| [x[0][0], 0, x] }
|
115
|
+
debug r.inspect
|
116
|
+
@item_list = r
|
114
117
|
|
115
|
-
|
116
|
-
|
117
|
-
elsif acc.class == Symbol
|
118
|
-
debug "Symbol"
|
119
|
-
call_action(acc)
|
118
|
+
r = a.collect { |x| [x[0][:key], x[0][:str]] }
|
119
|
+
return r
|
120
120
|
end
|
121
|
-
end
|
122
121
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
122
|
+
def search_actions_select_callback(search_str, idx)
|
123
|
+
item = @item_list[idx][2]
|
124
|
+
acc = item[0][:action]
|
125
|
+
|
126
|
+
debug "Selected:" + acc.to_s
|
127
|
+
gui_select_window_close(0)
|
128
|
+
|
129
|
+
if acc.class == String
|
130
|
+
eval(acc)
|
131
|
+
elsif acc.class == Symbol
|
132
|
+
debug "Symbol"
|
133
|
+
call(acc)
|
130
134
|
end
|
131
|
-
[item, srn_dst(search_str, item[:str])]
|
132
135
|
end
|
133
|
-
scores.sort_by! { |x| -x[1] }
|
134
|
-
debug scores.inspect
|
135
|
-
scores = scores[0..30]
|
136
136
|
|
137
|
-
|
137
|
+
def filter_items(item_list, item_key, search_str)
|
138
|
+
item_hash = {}
|
139
|
+
# debug item_list.inspect
|
140
|
+
scores = Parallel.map(item_list, in_threads: 8) do |item|
|
141
|
+
if item[:str].class != String
|
142
|
+
puts item.inspect
|
143
|
+
exit!
|
144
|
+
end
|
145
|
+
[item, srn_dst(search_str, item[:str])]
|
146
|
+
end
|
147
|
+
scores.sort_by! { |x| -x[1] }
|
148
|
+
debug scores.inspect
|
149
|
+
scores = scores[0..30]
|
150
|
+
|
151
|
+
return scores
|
152
|
+
end
|
138
153
|
end
|
data/lib/vimamsa/buffer.rb
CHANGED
@@ -12,7 +12,7 @@ $update_highlight = false
|
|
12
12
|
$ifuncon = false
|
13
13
|
|
14
14
|
class Buffer < String
|
15
|
-
attr_reader :pos, :lpos, :cpos, :deltas, :edit_history, :fname, :call_func, :pathname, :basename, :dirname, :update_highlight, :marks, :is_highlighted, :syntax_detect_failed, :id, :lang, :images, :last_save, :access_time
|
15
|
+
attr_reader :pos, :lpos, :cpos, :deltas, :edit_history, :fname, :call_func, :pathname, :basename, :dirname, :update_highlight, :marks, :is_highlighted, :syntax_detect_failed, :id, :lang, :images, :last_save, :access_time, :selection_active
|
16
16
|
attr_writer :call_func, :update_highlight
|
17
17
|
attr_accessor :gui_update_highlight, :update_hl_startpos, :update_hl_endpos, :hl_queue, :syntax_parser, :highlights, :gui_reset_highlight, :is_parsing_syntax, :line_ends, :bt, :line_action_handler, :module, :active_kbd_mode, :title, :subtitle, :paste_lines, :mode_stack, :default_mode
|
18
18
|
|
@@ -1051,7 +1051,7 @@ class Buffer < String
|
|
1051
1051
|
|
1052
1052
|
# Activated when enter/return pressed
|
1053
1053
|
def handle_line_action()
|
1054
|
-
if line_action_handler.class == Proc
|
1054
|
+
if line_action_handler.class == Proc or line_action_handler.class == Method
|
1055
1055
|
# Custom handler
|
1056
1056
|
line_action_handler.call(lpos)
|
1057
1057
|
else
|
@@ -1258,18 +1258,28 @@ class Buffer < String
|
|
1258
1258
|
@need_redraw = false
|
1259
1259
|
end
|
1260
1260
|
|
1261
|
-
def
|
1262
|
-
@
|
1263
|
-
@selection_start = @pos
|
1264
|
-
$kbd.set_mode(:visual)
|
1261
|
+
def selection_active?
|
1262
|
+
@selection_active
|
1265
1263
|
end
|
1266
1264
|
|
1265
|
+
def end_selection()
|
1266
|
+
@selection_start = nil
|
1267
|
+
@selection_active = false
|
1268
|
+
@visual_mode = false
|
1269
|
+
#TODO: remove @visual_mode
|
1270
|
+
end
|
1271
|
+
|
1267
1272
|
def start_selection()
|
1268
|
-
@visual_mode = true
|
1269
1273
|
@selection_start = @pos
|
1270
|
-
|
1271
|
-
|
1274
|
+
@selection_active = true
|
1275
|
+
@visual_mode = true
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
# Start selection if not already started
|
1279
|
+
def continue_selection()
|
1280
|
+
start_selection if !@selection_active
|
1272
1281
|
end
|
1282
|
+
|
1273
1283
|
|
1274
1284
|
def copy_active_selection(x = nil)
|
1275
1285
|
debug "!COPY SELECTION"
|
@@ -1297,6 +1307,7 @@ class Buffer < String
|
|
1297
1307
|
txt.gsub!(/\w+/, &:capitalize) if op == :capitalize
|
1298
1308
|
txt.swapcase! if op == :swapcase
|
1299
1309
|
txt.reverse! if op == :reverse
|
1310
|
+
txt = to_camel_case(txt) if op == :camelcase
|
1300
1311
|
|
1301
1312
|
replace_range(r, txt)
|
1302
1313
|
end_visual_mode
|
@@ -1380,6 +1391,7 @@ class Buffer < String
|
|
1380
1391
|
# TODO: should not happen
|
1381
1392
|
end
|
1382
1393
|
debug "End visual mode"
|
1394
|
+
end_selection
|
1383
1395
|
vma.kbd.to_previous_mode
|
1384
1396
|
@visual_mode = false
|
1385
1397
|
return true
|
data/lib/vimamsa/buffer_list.rb
CHANGED
data/lib/vimamsa/conf.rb
CHANGED
data/lib/vimamsa/editor.rb
CHANGED
@@ -5,9 +5,8 @@ def handle_drag_and_drop(fname)
|
|
5
5
|
buf.handle_drag_and_drop(fname)
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
8
|
class Editor
|
10
|
-
attr_reader :file_content_search_paths, :file_name_search_paths, :gui, :hook, :macro
|
9
|
+
attr_reader :file_content_search_paths, :file_name_search_paths, :gui, :hook, :macro, :actions
|
11
10
|
attr_accessor :converters, :fh, :paint_stack, :kbd, :langsrv, :register, :cur_register, :clipboard
|
12
11
|
#attr_writer :call_func, :update_highlight
|
13
12
|
|
@@ -63,6 +62,10 @@ class Editor
|
|
63
62
|
|
64
63
|
$hook = Hook.new
|
65
64
|
@hook = $hook
|
65
|
+
require "vimamsa/actions"
|
66
|
+
@actions = ActionList.new
|
67
|
+
require "vimamsa/key_actions"
|
68
|
+
|
66
69
|
register_plugin(:Hook, @hook)
|
67
70
|
@macro = Macro.new
|
68
71
|
register_plugin(:Macro, @macro)
|
@@ -548,12 +551,13 @@ def load_buffer(fname)
|
|
548
551
|
end
|
549
552
|
|
550
553
|
def jump_to_file(filename, tnum = nil, charn = nil)
|
551
|
-
open_new_file(filename)
|
554
|
+
b = open_new_file(filename)
|
555
|
+
# debug "open_new_file #{filename}, #{tnum} = nil, #{charn}",2
|
552
556
|
|
553
557
|
# Link to character position
|
554
558
|
if !charn.nil?
|
555
559
|
if charn == "c"
|
556
|
-
|
560
|
+
b.jump_to_pos(tnum) # tnum=character position
|
557
561
|
center_on_current_line
|
558
562
|
return
|
559
563
|
end
|
@@ -561,7 +565,7 @@ def jump_to_file(filename, tnum = nil, charn = nil)
|
|
561
565
|
|
562
566
|
# Link to line
|
563
567
|
if !tnum.nil?
|
564
|
-
|
568
|
+
b.jump_to_line(tnum) # tnum=line position
|
565
569
|
center_on_current_line
|
566
570
|
return
|
567
571
|
end
|
@@ -579,7 +583,7 @@ def open_new_file(filename, file_contents = "")
|
|
579
583
|
# File is already opened to existing buffer
|
580
584
|
if b != nil
|
581
585
|
message "Switching to: #{filename}"
|
582
|
-
vma.buffers.set_current_buffer(b)
|
586
|
+
bu = vma.buffers.set_current_buffer(b)
|
583
587
|
else
|
584
588
|
if !is_path_writable(filename)
|
585
589
|
message("Path #{filename} cannot be written to")
|
@@ -593,9 +597,10 @@ def open_new_file(filename, file_contents = "")
|
|
593
597
|
end
|
594
598
|
message "New file opened: #{filename}"
|
595
599
|
fname = filename
|
596
|
-
|
597
|
-
vma.buffers.set_current_buffer_by_id(
|
600
|
+
bu = load_buffer(fname)
|
601
|
+
vma.buffers.set_current_buffer_by_id(bu.id)
|
598
602
|
end
|
603
|
+
return bu
|
599
604
|
end
|
600
605
|
|
601
606
|
def scan_word_start_marks(search_str)
|
data/lib/vimamsa/file_history.rb
CHANGED
@@ -76,12 +76,12 @@ end
|
|
76
76
|
|
77
77
|
def gui_file_history_update_callback(search_str = "")
|
78
78
|
debug "gui_file_history_update_callback: #{search_str}"
|
79
|
-
return [] if
|
79
|
+
return [] if vma.fh.history.empty?
|
80
80
|
$search_list = []
|
81
|
-
files =
|
81
|
+
files = vma.fh.history.keys.sort.collect { |x| [x, 0] }
|
82
82
|
|
83
83
|
if (search_str.size > 1)
|
84
|
-
files = fuzzy_filter(search_str,
|
84
|
+
files = fuzzy_filter(search_str, vma.fh.history.keys, 40)
|
85
85
|
end
|
86
86
|
|
87
87
|
$search_list = files
|
data/lib/vimamsa/gui.rb
CHANGED
@@ -2,6 +2,31 @@ $idle_scroll_to_mark = false
|
|
2
2
|
|
3
3
|
$removed_controllers = []
|
4
4
|
|
5
|
+
# Run one iteration of GMainLoop
|
6
|
+
# https://developer.gnome.org/documentation/tutorials/main-contexts.html
|
7
|
+
def iterate_gui_main_loop
|
8
|
+
GLib::MainContext.default.iteration(true)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Wait for window resize to take effect
|
12
|
+
# GTk3 had a resize notify event which got removed in gtk4
|
13
|
+
# https://discourse.gnome.org/t/gtk4-any-way-to-connect-to-a-window-resize-signal/14869/3
|
14
|
+
def wait_for_resize(window, tries = 200)
|
15
|
+
i = 0
|
16
|
+
widthold = @window.width
|
17
|
+
heightold = @window.height
|
18
|
+
while true
|
19
|
+
iterate_gui_main_loop
|
20
|
+
break if widthold != window.width
|
21
|
+
break if heightold != window.height
|
22
|
+
if i >= tries
|
23
|
+
debug "i >= tries", 2
|
24
|
+
break
|
25
|
+
end
|
26
|
+
i += 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
5
30
|
def gui_remove_controllers(widget)
|
6
31
|
clist = widget.observe_controllers
|
7
32
|
to_remove = []
|
@@ -102,7 +127,7 @@ def gui_create_buffer(id, bufo)
|
|
102
127
|
view.set_buffer(buf1)
|
103
128
|
|
104
129
|
provider = Gtk::CssProvider.new
|
105
|
-
|
130
|
+
|
106
131
|
provider.load(data: "textview { font-family: #{cnf.font.family!}; font-size: #{cnf.font.size!}pt; }")
|
107
132
|
view.style_context.add_provider(provider)
|
108
133
|
view.wrap_mode = :char
|
@@ -549,11 +574,24 @@ class VMAgui
|
|
549
574
|
|
550
575
|
def idle_set_size()
|
551
576
|
# Need to wait for a while to window to be maximized to get correct @window.width
|
552
|
-
|
577
|
+
@window.maximize
|
578
|
+
wait_for_resize(@window)
|
579
|
+
# Set new size as half of the screeen
|
553
580
|
width = @window.width / 2
|
554
581
|
height = @window.height - 5
|
582
|
+
width = 600 if width < 600
|
583
|
+
height = 600 if height < 600
|
584
|
+
|
585
|
+
#Minimum size:
|
586
|
+
@window.set_size_request(600, 600)
|
587
|
+
@window.set_default_size(width, height)
|
588
|
+
debug "size #{[width, height]}", 2
|
555
589
|
@window.unmaximize
|
590
|
+
|
591
|
+
#set_default_size doesn't always have effect if run immediately
|
592
|
+
wait_for_resize(@window)
|
556
593
|
@window.set_default_size(width, height)
|
594
|
+
|
557
595
|
return false
|
558
596
|
end
|
559
597
|
|
@@ -569,10 +607,6 @@ class VMAgui
|
|
569
607
|
@window = Gtk::ApplicationWindow.new(app)
|
570
608
|
@window.set_application(app)
|
571
609
|
|
572
|
-
@window.maximize
|
573
|
-
# Need to let Gtk process after maximize
|
574
|
-
run_as_idle proc { idle_set_size }
|
575
|
-
|
576
610
|
@window.title = "Multiple Views"
|
577
611
|
@vpaned = Gtk::Paned.new(:vertical)
|
578
612
|
|
@@ -664,6 +698,8 @@ class VMAgui
|
|
664
698
|
|
665
699
|
@window.show
|
666
700
|
|
701
|
+
run_as_idle proc { idle_set_size }
|
702
|
+
|
667
703
|
prov = Gtk::CssProvider.new
|
668
704
|
# See gtk-4.9.4/gtk/theme/Default/_common.scss on how to theme
|
669
705
|
# gtksourceview/gtksourcestyleschemepreview.c
|
@@ -52,9 +52,9 @@ class VSourceView < GtkSource::View
|
|
52
52
|
|
53
53
|
# Mainly after page-up or page-down
|
54
54
|
signal_connect("move-cursor") do |widget, event|
|
55
|
-
if event.name == "GTK_MOVEMENT_PAGES" and (last_action == "page_up" or last_action == "page_down")
|
56
|
-
|
57
|
-
end
|
55
|
+
# if event.name == "GTK_MOVEMENT_PAGES" and (vma.actions.last_action == "page_up" or vma.actions.last_action == "page_down")
|
56
|
+
# handle_scrolling()
|
57
|
+
# end
|
58
58
|
|
59
59
|
# handle_scrolling()
|
60
60
|
# curpos = buffer.cursor_position
|
@@ -149,10 +149,13 @@ class VSourceView < GtkSource::View
|
|
149
149
|
debug "drag-end", 2
|
150
150
|
if offsetx.abs < 5 and offsety.abs < 5
|
151
151
|
debug "Not enough drag", 2
|
152
|
-
|
153
|
-
|
152
|
+
buf.end_selection
|
153
|
+
# elsif !buf.visual_mode? and vma.kbd.get_scope != :editor
|
154
|
+
elsif vma.kbd.get_scope != :editor
|
154
155
|
# Can't transition from editor wide mode to buffer specific mode
|
155
|
-
|
156
|
+
vma.kbd.set_mode(:visual)
|
157
|
+
else
|
158
|
+
buf.end_selection
|
156
159
|
end
|
157
160
|
@range_start = nil
|
158
161
|
end
|
@@ -523,6 +526,15 @@ class VSourceView < GtkSource::View
|
|
523
526
|
end
|
524
527
|
end
|
525
528
|
|
529
|
+
def after_action
|
530
|
+
delete_cursorchar
|
531
|
+
iterate_gui_main_loop
|
532
|
+
handle_deltas
|
533
|
+
iterate_gui_main_loop
|
534
|
+
draw_cursor
|
535
|
+
iterate_gui_main_loop
|
536
|
+
end
|
537
|
+
|
526
538
|
def set_cursor_color(ctype)
|
527
539
|
if @ctype != ctype
|
528
540
|
bg = $confh[:mode][ctype][:cursor][:background]
|
@@ -547,6 +559,8 @@ class VSourceView < GtkSource::View
|
|
547
559
|
|
548
560
|
mode = vma.kbd.get_mode
|
549
561
|
ctype = vma.kbd.get_cursor_type
|
562
|
+
ctype = :visual if vma.buf.selection_active?
|
563
|
+
|
550
564
|
delete_cursorchar
|
551
565
|
vma.gui.remove_overlay_cursor
|
552
566
|
if [:command, :replace, :browse].include?(ctype)
|
data/lib/vimamsa/key_actions.rb
CHANGED
@@ -166,7 +166,7 @@ act_list = {
|
|
166
166
|
# { :proc => proc { },
|
167
167
|
# :desc => "", :group => : },
|
168
168
|
|
169
|
-
:search_actions => { :proc => proc {
|
169
|
+
:search_actions => { :proc => proc { vma.actions.gui_search },
|
170
170
|
:desc => "Search actions", :group => :search },
|
171
171
|
|
172
172
|
:toggle_active_window => { :proc => proc { vma.gui.toggle_active_window },
|
@@ -67,6 +67,7 @@ class KeyBindingTree
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def set_mode(label)
|
70
|
+
return if get_mode == :label
|
70
71
|
@match_state = [@modes[label]] # used for matching input
|
71
72
|
@mode_root_state = @modes[label]
|
72
73
|
# @default_mode = label
|
@@ -290,8 +291,8 @@ class KeyBindingTree
|
|
290
291
|
else
|
291
292
|
method_desc = t.action
|
292
293
|
if t.action.class == Symbol
|
293
|
-
if
|
294
|
-
a =
|
294
|
+
if vma.actions.include?(t.action)
|
295
|
+
a = vma.actions[t.action].method_name
|
295
296
|
if !a.nil? and !a.empty?
|
296
297
|
method_desc = a
|
297
298
|
end
|
@@ -477,7 +478,7 @@ class KeyBindingTree
|
|
477
478
|
# return
|
478
479
|
# end
|
479
480
|
# $action_list << { :action => action, :key => key }
|
480
|
-
if
|
481
|
+
if !vma.actions.include?(action)
|
481
482
|
if action.class == String
|
482
483
|
reg_act(action, proc { eval(action) }, action)
|
483
484
|
end
|
@@ -566,7 +567,7 @@ class KeyBindingTree
|
|
566
567
|
end
|
567
568
|
|
568
569
|
def handle_key_bindigs_action(action, c)
|
569
|
-
$acth << action
|
570
|
+
# $acth << action #TODO:needed here?
|
570
571
|
@method_handles_repeat = false #TODO:??
|
571
572
|
n = 1
|
572
573
|
if @next_command_count and !(action.class == String and action.include?("set_next_command_count"))
|
@@ -619,8 +620,6 @@ def bindkey(key, action)
|
|
619
620
|
$kbd.bindkey(key, action)
|
620
621
|
end
|
621
622
|
|
622
|
-
$action_list = []
|
623
|
-
|
624
623
|
def exec_action(action)
|
625
624
|
$kbd.last_action = $kbd.cur_action
|
626
625
|
$kbd.cur_action = action
|
@@ -17,11 +17,31 @@ cnf.mode.default.cursor.background = "#03fcca"
|
|
17
17
|
cnf.mode.visual.cursor.background = "#bc6040"
|
18
18
|
cnf.mode.replace.cursor.background = "#fc0331"
|
19
19
|
cnf.mode.browse.cursor.background = "#f803fc"
|
20
|
-
|
20
|
+
|
21
|
+
def _insert_move(op)
|
22
|
+
if op == :pagedown
|
23
|
+
vma.gui.page_down
|
24
|
+
elsif op == :pageup
|
25
|
+
vma.gui.page_up
|
26
|
+
else
|
27
|
+
buf.move(op)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def insert_select_move(op)
|
32
|
+
buf.continue_selection
|
33
|
+
_insert_move(op)
|
34
|
+
end
|
35
|
+
|
36
|
+
def insert_move(op)
|
37
|
+
buf.end_selection
|
38
|
+
_insert_move(op)
|
39
|
+
end
|
21
40
|
|
22
41
|
bindkey ["VCB M", "B m"], :run_last_macro
|
23
42
|
|
24
43
|
bindkey "VC s", :easy_jump
|
44
|
+
bindkey "I alt-s", :easy_jump
|
25
45
|
bindkey "VC , m f", [:find_macro_gui, proc { vma.macro.find_macro_gui }, "Find named macro"]
|
26
46
|
bindkey "C , m n", [:gui_name_macro, proc { vma.macro.gui_name_macro }, "Name last macro"]
|
27
47
|
bindkey "C , j r", :jump_to_random
|
@@ -86,8 +106,8 @@ bindkey "B z", "center_on_current_line();call_action(:exit_browse_mode)"
|
|
86
106
|
bindkey "B enter || B return || B esc || B j || B ctrl!", :exit_browse_mode
|
87
107
|
bindkey "B s", :page_up
|
88
108
|
bindkey "B d", :page_down
|
89
|
-
bindkey "B r", proc { vma.gui.page_down(multip:0.25)}
|
90
|
-
bindkey "B e", proc { vma.gui.page_up(multip:0.25)}
|
109
|
+
bindkey "B r", proc { vma.gui.page_down(multip: 0.25) }
|
110
|
+
bindkey "B e", proc { vma.gui.page_up(multip: 0.25) }
|
91
111
|
|
92
112
|
bindkey "B i", :jump_to_start_of_buffer
|
93
113
|
bindkey "B o", :jump_to_end_of_buffer
|
@@ -128,24 +148,41 @@ default_keys = {
|
|
128
148
|
# "VC j" => "buf.move(FORWARD_LINE)",
|
129
149
|
# "VC k" => "buf.move(BACKWARD_LINE)",
|
130
150
|
|
131
|
-
"
|
132
|
-
"
|
151
|
+
"VCI pagedown" => :page_down,
|
152
|
+
"VCI pageup" => :page_up,
|
133
153
|
|
134
154
|
"I down(vma.buf.view.autocp_active)" => "vma.buf.view.autocp_select_next",
|
135
155
|
"I tab(vma.buf.view.autocp_active)" => "vma.buf.view.autocp_select_next",
|
136
156
|
"I up(vma.buf.view.autocp_active)" => "vma.buf.view.autocp_select_previous",
|
137
157
|
"I shift-tab(vma.buf.view.autocp_active)" => "vma.buf.view.autocp_select_previous",
|
138
158
|
"I enter(vma.buf.view.autocp_active)" => "vma.buf.view.autocp_select",
|
139
|
-
|
140
|
-
"I tab" =>
|
141
|
-
"I shift-tab" =>
|
142
|
-
|
159
|
+
|
160
|
+
"I tab" => "buf.insert_tab",
|
161
|
+
"I shift-tab" => "buf.unindent",
|
162
|
+
|
143
163
|
"I enter" => :insert_new_line,
|
144
164
|
|
145
|
-
"
|
146
|
-
"
|
147
|
-
"
|
148
|
-
"
|
165
|
+
"I shift-down" => "insert_select_move(BACKWARD_CHAR)",
|
166
|
+
"I shift-right" => "insert_select_move(FORWARD_CHAR)",
|
167
|
+
"I shift-down" => "insert_select_move(FORWARD_LINE)",
|
168
|
+
"I shift-up" => "insert_select_move(BACKWARD_LINE)",
|
169
|
+
"I shift-pagedown" => "insert_select_move(:pagedown)",
|
170
|
+
"I shift-pageup" => "insert_select_move(:pageup)",
|
171
|
+
|
172
|
+
"I left" => "insert_move(BACKWARD_CHAR)",
|
173
|
+
"I right" => "insert_move(FORWARD_CHAR)",
|
174
|
+
"I down" => "insert_move(FORWARD_LINE)",
|
175
|
+
"I up" => "insert_move(BACKWARD_LINE)",
|
176
|
+
"I pagedown" => "insert_move(:pagedown)",
|
177
|
+
"I pageup" => "insert_move(:pageup)",
|
178
|
+
|
179
|
+
#TODO:
|
180
|
+
"I @shift-click" => "insert_mode_shift_click(charpos)",
|
181
|
+
|
182
|
+
"VCX left" => "buf.move(BACKWARD_CHAR)",
|
183
|
+
"VCX right" => "buf.move(FORWARD_CHAR)",
|
184
|
+
"VCX down" => "buf.move(FORWARD_LINE)",
|
185
|
+
"VCX up" => "buf.move(BACKWARD_LINE)",
|
149
186
|
|
150
187
|
"VC w" => "buf.jump_word(FORWARD,WORD_START)",
|
151
188
|
"VC b" => "buf.jump_word(BACKWARD,WORD_START)",
|
@@ -192,7 +229,7 @@ default_keys = {
|
|
192
229
|
"C , d c" => "debug_dump_clipboard",
|
193
230
|
"C , d d" => "debug_dump_deltas",
|
194
231
|
"C , d m" => :kbd_dump_state,
|
195
|
-
|
232
|
+
|
196
233
|
"VC O" => "buf.jump(END_OF_LINE)",
|
197
234
|
"VC $" => "buf.jump(END_OF_LINE)",
|
198
235
|
|
@@ -209,7 +246,7 @@ default_keys = {
|
|
209
246
|
|
210
247
|
# Command mode only:
|
211
248
|
"C ctrl-r" => "buf.redo()", # TODO:???
|
212
|
-
"C v" => "buf.
|
249
|
+
"C v" => "buf.start_selection;vma.kbd.set_mode(:visual)",
|
213
250
|
"C P" => "buf.paste(BEFORE)", # TODO: implement as replace for visual mode
|
214
251
|
"C space <char>" => "buf.insert_txt(<char>)",
|
215
252
|
"C space space" => "buf.insert_txt(' ')",
|
@@ -269,7 +306,7 @@ default_keys = {
|
|
269
306
|
"C i" => "vma.kbd.set_mode(:insert)",
|
270
307
|
"C R" => "vma.kbd.set_mode(:replace)",
|
271
308
|
"C ctrl!" => "vma.kbd.set_mode(:insert)",
|
272
|
-
|
309
|
+
|
273
310
|
# Replace mode
|
274
311
|
"X esc || X ctrl!" => "vma.kbd.to_previous_mode",
|
275
312
|
"X <char>" => "buf.replace_with_char(<char>);buf.move(FORWARD_CHAR)",
|
@@ -312,7 +349,6 @@ default_keys = {
|
|
312
349
|
|
313
350
|
"I ctrl-h" => :show_autocomplete,
|
314
351
|
"I ctrl-j" => "vma.buf.view.hide_completions",
|
315
|
-
|
316
352
|
|
317
353
|
"I space" => 'buf.insert_txt(" ")',
|
318
354
|
# "I return" => 'buf.insert_new_line()',
|
@@ -320,7 +356,6 @@ default_keys = {
|
|
320
356
|
|
321
357
|
bindkey "C , i p", "generate_password_to_buf(15)"
|
322
358
|
|
323
|
-
|
324
359
|
default_keys.each { |key, value|
|
325
360
|
bindkey(key, value)
|
326
361
|
}
|
data/lib/vimamsa/langservp.rb
CHANGED
@@ -176,7 +176,9 @@ class LangSrv
|
|
176
176
|
def open_file(fp, fc = nil)
|
177
177
|
debug "open_file", 2
|
178
178
|
fc = IO.read(fp) if fc.nil?
|
179
|
-
|
179
|
+
|
180
|
+
encoded_filepath = URI.encode_www_form_component(fp)
|
181
|
+
fpuri = URI.parse("file://#{encoded_filepath}")
|
180
182
|
|
181
183
|
a = LSP::Interface::DidOpenTextDocumentParams.new(
|
182
184
|
text_document: LSP::Interface::TextDocumentItem.new(
|
data/lib/vimamsa/macro.rb
CHANGED
@@ -127,9 +127,12 @@ class Macro
|
|
127
127
|
ret = exec_action(a)
|
128
128
|
if ret == false
|
129
129
|
error "Error while running macro"
|
130
|
-
isok=false
|
130
|
+
isok = false
|
131
131
|
break
|
132
132
|
end
|
133
|
+
|
134
|
+
vma.buf.view.after_action
|
135
|
+
sleep cnf.macro.animation_delay!
|
133
136
|
end
|
134
137
|
end
|
135
138
|
@running_macro = false
|
data/lib/vimamsa/rbvma.rb
CHANGED
data/lib/vimamsa/tests.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
require "digest"
|
2
2
|
|
3
3
|
def run_tests()
|
4
|
-
tests = ["test_paste_0","test_delete_0"]
|
4
|
+
tests = ["test_paste_0", "test_delete_0"]
|
5
5
|
stats = []
|
6
6
|
for t in tests
|
7
7
|
r = eval(t)
|
8
8
|
if r == true
|
9
9
|
stats << "test #{t} OK"
|
10
10
|
else
|
11
|
-
stats <<
|
11
|
+
stats << "test #{t} FAILED"
|
12
12
|
end
|
13
13
|
end
|
14
|
-
debug "TEST RESULTS:",2
|
14
|
+
debug "TEST RESULTS:", 2
|
15
15
|
puts stats.join("\n")
|
16
16
|
puts "===================="
|
17
|
-
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
19
|
#
|
22
20
|
|
23
21
|
def test_paste_0(runmacro = true)
|
22
|
+
return
|
23
|
+
#TODO: update macro
|
24
24
|
b = create_new_buffer(file_contents = "\n", prefix = "buf", setcurrent = true)
|
25
25
|
|
26
26
|
b.insert_txt(JABBERWOCKY)
|
@@ -47,7 +47,7 @@ def test_paste_0(runmacro = true)
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def macro_test(macro, correct_hex, runmacro=true)
|
50
|
+
def macro_test(macro, correct_hex, runmacro = true)
|
51
51
|
b = create_new_buffer(file_contents = "\n", prefix = "buf", setcurrent = true)
|
52
52
|
b.insert_txt(JABBERWOCKY)
|
53
53
|
b.insert_txt(LOREM_IPSUM)
|
@@ -117,6 +117,3 @@ O frabjous day! Callooh! Callay!”
|
|
117
117
|
All mimsy were the borogoves,
|
118
118
|
And the mome raths outgrabe.
|
119
119
|
"
|
120
|
-
|
121
|
-
|
122
|
-
|
data/lib/vimamsa/util.rb
CHANGED
@@ -8,6 +8,14 @@ def tilde_path(abspath)
|
|
8
8
|
abspath.sub(/^#{Regexp.escape(userhome)}\//, "~/")
|
9
9
|
end
|
10
10
|
|
11
|
+
def to_camel_case(str)
|
12
|
+
words = str.split(/\W+/) # Split the input string into words
|
13
|
+
camel_case_words = words.map.with_index do |word, index|
|
14
|
+
index == 0 ? word.downcase : word.capitalize
|
15
|
+
end
|
16
|
+
camel_case_words.join
|
17
|
+
end
|
18
|
+
|
11
19
|
def generate_password(length)
|
12
20
|
password = ""
|
13
21
|
while password.size < length
|
data/lib/vimamsa/version.rb
CHANGED
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.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sami Sieranoja
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -298,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
298
298
|
- !ruby/object:Gem::Version
|
299
299
|
version: '0'
|
300
300
|
requirements: []
|
301
|
-
rubygems_version: 3.3
|
301
|
+
rubygems_version: 3.2.3
|
302
302
|
signing_key:
|
303
303
|
specification_version: 4
|
304
304
|
summary: Vimamsa
|