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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4603a715f3fd3b549cc38a9744d93617b3a87ba3d95268f77ed2c98c2c04643d
4
- data.tar.gz: 26e82f3a6564a78dcd7188a69037f97bae3fb53c43be807560facfab8e70dd51
3
+ metadata.gz: e861051f02f35b286c8e97c225b69b9377f1d5cdf3dcf311de89a2ababb9dcd9
4
+ data.tar.gz: c27f3bc13a925dbd0293592f9d692a1918e91a7ce8047868c340098be76d1613
5
5
  SHA512:
6
- metadata.gz: 1f05aad90407dfdd0e9c310f08f5e79274a5901f714d63e353e7291f25c7f4dba3d402163f338cebf01fef4f8fae07522f85a58d62e76086661007f24b14a0bd
7
- data.tar.gz: f503976439de2a311778b48a427354fc21a1b42434eb6a0bcfa5e3c00144fc3508abe029a058249c2b433e9f41f983679f44927ae095b1ec4a4eb36fafdbfe93
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 ack_buffer(_instr, b = nil)
114
- instr = Shellwords.escape(_instr)
115
- bufstr = ""
116
- for path in vma.get_content_search_paths
117
- bufstr += run_cmd("ack -Q --type-add=gd=.gd -ki --nohtml --nojs --nojson #{instr} #{path}")
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
- if bufstr.size > 5
120
- b = create_new_buffer(bufstr, "ack")
121
- Gui.highlight_match(b, _instr, color: cnf.match.highlight.color!)
122
- else
123
- message("No results for input:#{instr}")
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
@@ -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
- # def call(id)
36
- # call_action(id)
37
- # end
31
+ #TODO: remove?
32
+ def call_action(id)
33
+ vma.actions.call(id)
34
+ end
38
35
 
39
- $acth = []
36
+ class ActionList
37
+ def initialize
38
+ @acth = []
39
+ @actions = {}
40
+ end
40
41
 
41
- def call_action(id)
42
- $acth << id
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 last_action
52
- return $acth[-1]
53
- end
46
+ def include?(act)
47
+ return @actions.has_key?(act)
48
+ end
54
49
 
55
- def search_actions()
56
- l = []
57
- opt = { :title => "Search for actions", :desc => "Fuzzy search for actions. <up> or <down> to change selcted. <enter> to select current." }
58
- $select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
50
+ def [](id)
51
+ @actions[id]
52
+ end
59
53
 
60
- gui_select_update_window(l, $select_keys.collect { |x| x.upcase },
61
- "search_actions_select_callback",
62
- "search_actions_update_callback",
63
- opt)
64
- end
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
- $item_list = []
64
+ def last_action
65
+ return @acth[-1]
66
+ end
67
67
 
68
- def search_actions_update_callback(search_str = "")
69
- return [] if search_str == ""
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
- item_list2 = []
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
- for mode_str in ["C", "V"]
78
- c_kbd = vma.kbd.act_bindings[mode_str][act_id]
79
- if c_kbd.class == String
80
- item[:key] = "[#{mode_str} #{c_kbd}] "
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 = item_list2
81
+ @item_list = []
94
82
 
95
- a = filter_items(item_list, 0, search_str)
96
- debug a.inspect
83
+ def search_actions_update_callback(search_str = "")
84
+ return [] if search_str == ""
97
85
 
98
- r = a.collect { |x| [x[0][0], 0, x] }
99
- debug r.inspect
100
- $item_list = r
86
+ item_list2 = []
87
+ for act_id in @actions.keys
88
+ act = @actions[act_id]
89
+ item = {}
90
+ item[:key] = ""
101
91
 
102
- # Ripl.start :binding => binding
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
- r = a.collect { |x| ["#{x[0][:key]}#{x[0][:str]}", 0, x] }
105
- return r
106
- end
109
+ item_list = item_list2
107
110
 
108
- def search_actions_select_callback(search_str, idx)
109
- item = $item_list[idx][2]
110
- acc = item[0][:action]
111
+ a = filter_items(item_list, 0, search_str)
112
+ debug a.inspect
111
113
 
112
- debug "Selected:" + acc.to_s
113
- gui_select_window_close(0)
114
+ r = a.collect { |x| [x[0][0], 0, x] }
115
+ debug r.inspect
116
+ @item_list = r
114
117
 
115
- if acc.class == String
116
- eval(acc)
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 filter_items(item_list, item_key, search_str)
124
- item_hash = {}
125
- # debug item_list.inspect
126
- scores = Parallel.map(item_list, in_threads: 8) do |item|
127
- if item[:str].class != String
128
- puts item.inspect
129
- exit!
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
- return scores
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
@@ -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 start_visual_mode()
1262
- @visual_mode = true
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
- $kbd.set_mode(:visual)
1271
- #TODO: implement without setting kbd mode
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
@@ -155,6 +155,7 @@ class BufferList
155
155
  end
156
156
 
157
157
  # hpt_scan_images() if cnf.debug? # experimental
158
+ return bu
158
159
  end
159
160
 
160
161
  def to_s
@@ -73,7 +73,7 @@ class BufferManager
73
73
  for b in vma.buffers.list
74
74
  if !b.fname.nil?
75
75
  bname = File.basename(b.fname)
76
- dname = File.dirname(b.dirname)
76
+ dname = File.dirname(b.fname)
77
77
  else
78
78
  bname = b.list_str
79
79
  dname = "*"
data/lib/vimamsa/conf.rb CHANGED
@@ -159,3 +159,6 @@ cnf.font.size = 11
159
159
  cnf.font.family = "Monospace"
160
160
 
161
161
 
162
+ cnf.macro.animation_delay = 0.02
163
+
164
+
@@ -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
- buf.jump_to_pos(tnum) # tnum=character position
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
- buf.jump_to_line(tnum) # tnum=line position
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
- bf = load_buffer(fname)
597
- vma.buffers.set_current_buffer_by_id(bf.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)
@@ -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 $vma.fh.history.empty?
79
+ return [] if vma.fh.history.empty?
80
80
  $search_list = []
81
- files = $vma.fh.history.keys.sort.collect { |x| [x, 0] }
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, $vma.fh.history.keys, 40)
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
- sleep 0.1
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
@@ -12,6 +12,8 @@ class SelectUpdateWindow
12
12
 
13
13
  def update_item_list(item_list)
14
14
  # debug item_list.inspect
15
+ return if item_list.empty?
16
+
15
17
  @model.clear
16
18
  for item in item_list
17
19
  iter = @model.append
@@ -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
- handle_scrolling()
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
- @range_start = nil
153
- elsif !buf.visual_mode? and vma.kbd.get_scope != :editor
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
- buf.start_visual_mode
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)
@@ -166,7 +166,7 @@ act_list = {
166
166
  # { :proc => proc { },
167
167
  # :desc => "", :group => : },
168
168
 
169
- :search_actions => { :proc => proc { search_actions },
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 !$actions[t.action].nil?
294
- a = $actions[t.action].method_name
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 !$actions.has_key?(action)
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
- # vma.kbd.show_state_trail
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
- "VC pagedown" => :page_down,
132
- "VC pageup" => :page_up,
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" => 'buf.insert_tab',
141
- "I shift-tab" => 'buf.unindent',
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
- "VCIX left" => "buf.move(BACKWARD_CHAR)",
146
- "VCIX right" => "buf.move(FORWARD_CHAR)",
147
- "VCIX down" => "buf.move(FORWARD_LINE)",
148
- "VCIX up" => "buf.move(BACKWARD_LINE)",
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.start_visual_mode",
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
  }
@@ -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
- fpuri = URI.join("file:///", fp).to_s
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
@@ -18,9 +18,7 @@ require "vimamsa/util"
18
18
  require "vimamsa/main"
19
19
  require "vimamsa/terminal"
20
20
 
21
- require "vimamsa/actions"
22
21
  require "vimamsa/key_binding_tree"
23
- require "vimamsa/key_actions"
24
22
 
25
23
  require "vimamsa/clipboard"
26
24
 
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 << "test #{t} FAILED"
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
@@ -1,3 +1,3 @@
1
1
  module Vimamsa
2
- VERSION = "0.1.16"
2
+ VERSION = "0.1.17"
3
3
  end
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.16
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-19 00:00:00.000000000 Z
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.26
301
+ rubygems_version: 3.2.3
302
302
  signing_key:
303
303
  specification_version: 4
304
304
  summary: Vimamsa