vimamsa 0.1.16 → 0.1.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,12 @@
1
1
  require "pty"
2
2
 
3
- def handle_drag_and_drop(fname)
4
- debug "EDITOR:handle_drag_and_drop"
5
- buf.handle_drag_and_drop(fname)
6
- end
7
-
3
+ # def handle_drag_and_drop(fname)
4
+ # debug "EDITOR:handle_drag_and_drop"
5
+ # buf.handle_drag_and_drop(fname)
6
+ # end
8
7
 
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)
@@ -126,9 +129,12 @@ class Editor
126
129
  FileManager.init
127
130
  Autocomplete.init
128
131
 
132
+ if cnf.audio.enabled?
133
+ require "vimamsa/audio"
134
+ end
135
+
129
136
  if cnf.lsp.enabled?
130
137
  require "vimamsa/langservp"
131
- require "vimamsa/audio" # TODO:config
132
138
  @langsrv["ruby"] = LangSrv.new("ruby")
133
139
  @langsrv["cpp"] = LangSrv.new("cpp")
134
140
  end
@@ -548,12 +554,14 @@ def load_buffer(fname)
548
554
  end
549
555
 
550
556
  def jump_to_file(filename, tnum = nil, charn = nil)
551
- open_new_file(filename)
557
+ b = open_new_file(filename)
558
+ return if b.nil?
559
+ # debug "open_new_file #{filename}, #{tnum} = nil, #{charn}",2
552
560
 
553
561
  # Link to character position
554
562
  if !charn.nil?
555
563
  if charn == "c"
556
- buf.jump_to_pos(tnum) # tnum=character position
564
+ b.jump_to_pos(tnum) # tnum=character position
557
565
  center_on_current_line
558
566
  return
559
567
  end
@@ -561,7 +569,7 @@ def jump_to_file(filename, tnum = nil, charn = nil)
561
569
 
562
570
  # Link to line
563
571
  if !tnum.nil?
564
- buf.jump_to_line(tnum) # tnum=line position
572
+ b.jump_to_line(tnum) # tnum=line position
565
573
  center_on_current_line
566
574
  return
567
575
  end
@@ -579,7 +587,7 @@ def open_new_file(filename, file_contents = "")
579
587
  # File is already opened to existing buffer
580
588
  if b != nil
581
589
  message "Switching to: #{filename}"
582
- vma.buffers.set_current_buffer(b)
590
+ bu = vma.buffers.set_current_buffer(b)
583
591
  else
584
592
  if !is_path_writable(filename)
585
593
  message("Path #{filename} cannot be written to")
@@ -591,11 +599,16 @@ def open_new_file(filename, file_contents = "")
591
599
  message("File #{filename} does not contain text")
592
600
  return false
593
601
  end
602
+ if Encrypt.is_encrypted?(filename)
603
+ decrypt_dialog(filename: filename)
604
+ return nil
605
+ end
594
606
  message "New file opened: #{filename}"
595
607
  fname = filename
596
- bf = load_buffer(fname)
597
- vma.buffers.set_current_buffer_by_id(bf.id)
608
+ bu = load_buffer(fname)
609
+ vma.buffers.set_current_buffer_by_id(bu.id)
598
610
  end
611
+ return bu
599
612
  end
600
613
 
601
614
  def scan_word_start_marks(search_str)
@@ -1,6 +1,44 @@
1
1
  require "openssl"
2
2
 
3
+ def decrypt_dialog(filename:, wrong_pass: false)
4
+ callback = proc { |x| Encrypt.open(filename, x) }
5
+ msg = ""
6
+ msg = "\nWRONG PASSWORD!\n" if wrong_pass
7
+ gui_one_input_action("Decrypt file \n #{filename}\n#{msg}", "Password:", "Decrypt", callback, { :hide => true })
8
+ end
9
+
3
10
  class Encrypt
11
+ def self.is_encrypted?(fn)
12
+ debug "self.is_encrypted?(fn)", 2
13
+ begin
14
+ file = File.open(fn, "r")
15
+ first_11_characters = file.read(11)
16
+ return true if first_11_characters == "VMACRYPT001"
17
+ rescue Errno::ENOENT
18
+ puts "File not found: #{file_path}"
19
+ rescue => e
20
+ puts "An error occurred: #{e.message}"
21
+ ensure
22
+ file&.close
23
+ end
24
+ return false
25
+ end
26
+
27
+ def self.open(fn, password)
28
+ debug "open_encrypted(filename,password)", 2
29
+ encrypted = read_file("", fn)[11..-1]
30
+ begin
31
+ crypt = Encrypt.new(password)
32
+ str = crypt.decrypt(encrypted)
33
+ # debug "PASS OK!", 2
34
+ bu = create_new_buffer(str)
35
+ bu.init_encrypted(crypt: crypt, filename: fn, encrypted: encrypted)
36
+ rescue OpenSSL::Cipher::CipherError => e
37
+ # Wrong password
38
+ decrypt_dialog(filename: fn, wrong_pass: true)
39
+ end
40
+ end
41
+
4
42
  def initialize(pass_phrase)
5
43
  salt = "uvgixEtU"
6
44
  @enc = OpenSSL::Cipher.new "AES-128-CBC"
@@ -31,7 +69,6 @@ class Encrypt
31
69
  end
32
70
  end
33
71
 
34
-
35
72
  def encrypt_cur_buffer()
36
73
  callback = proc { |x| encrypt_cur_buffer_callback(x) }
37
74
  gui_one_input_action("Encrypt", "Password:", "Encrypt", callback, { :hide => true })
@@ -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
@@ -123,7 +123,7 @@ class FileManager
123
123
  def cut_file
124
124
  fn = cur_file
125
125
  debug "CUT FILE #{fn}", 2
126
- @cut_files << fn
126
+ @cut_files << fn if !@cut_files.include?(fn)
127
127
  @copied_files = []
128
128
  end
129
129
 
data/lib/vimamsa/gui.rb CHANGED
@@ -2,6 +2,42 @@ $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
+ def start_profiler
12
+ require "ruby-prof"
13
+ RubyProf.start
14
+ end
15
+
16
+ def end_profiler
17
+ result = RubyProf.stop
18
+ printer = RubyProf::FlatPrinter.new(result)
19
+ printer.print(STDOUT)
20
+ end
21
+
22
+ # Wait for window resize to take effect
23
+ # GTk3 had a resize notify event which got removed in gtk4
24
+ # https://discourse.gnome.org/t/gtk4-any-way-to-connect-to-a-window-resize-signal/14869/3
25
+ def wait_for_resize(window, tries = 200)
26
+ i = 0
27
+ widthold = @window.width
28
+ heightold = @window.height
29
+ while true
30
+ iterate_gui_main_loop
31
+ break if widthold != window.width
32
+ break if heightold != window.height
33
+ if i >= tries
34
+ debug "i >= tries", 2
35
+ break
36
+ end
37
+ i += 1
38
+ end
39
+ end
40
+
5
41
  def gui_remove_controllers(widget)
6
42
  clist = widget.observe_controllers
7
43
  to_remove = []
@@ -102,7 +138,7 @@ def gui_create_buffer(id, bufo)
102
138
  view.set_buffer(buf1)
103
139
 
104
140
  provider = Gtk::CssProvider.new
105
-
141
+
106
142
  provider.load(data: "textview { font-family: #{cnf.font.family!}; font-size: #{cnf.font.size!}pt; }")
107
143
  view.style_context.add_provider(provider)
108
144
  view.wrap_mode = :char
@@ -168,21 +204,6 @@ class VMAgui
168
204
  @img_resizer_active = false
169
205
  @windows = {}
170
206
  @app = nil
171
- # imgproc = proc {
172
- # GLib::Idle.add(proc {
173
- # if !buf.images.empty?
174
- # vma.gui.scale_all_images
175
-
176
- # w = Gtk::Window.new(:toplevel)
177
- # w.set_default_size(1, 1)
178
- # w.show_all
179
- # Thread.new { sleep 0.1; w.destroy }
180
- # end
181
-
182
- # false
183
- # })
184
- # }
185
- # @delex = DelayExecutioner.new(1, imgproc)
186
207
  end
187
208
 
188
209
  def run
@@ -200,16 +221,13 @@ class VMAgui
200
221
  end
201
222
  end
202
223
 
203
- def delay_scale()
204
- if Time.now - @dtime > 2.0
205
- end
206
- end
207
-
208
224
  def scale_all_images
209
- debug "scale all", 2
210
- for img in buf.images
211
- if !img[:obj].destroyed?
212
- img[:obj].scale_image
225
+ for k, window in @windows
226
+ bu = window[:sw].child.bufo
227
+ for img in bu.images
228
+ if !img[:obj].destroyed?
229
+ img[:obj].scale_image
230
+ end
213
231
  end
214
232
  end
215
233
  false
@@ -549,11 +567,24 @@ class VMAgui
549
567
 
550
568
  def idle_set_size()
551
569
  # Need to wait for a while to window to be maximized to get correct @window.width
552
- sleep 0.1
570
+ @window.maximize
571
+ wait_for_resize(@window)
572
+ # Set new size as half of the screeen
553
573
  width = @window.width / 2
554
574
  height = @window.height - 5
575
+ width = 600 if width < 600
576
+ height = 600 if height < 600
577
+
578
+ #Minimum size:
579
+ @window.set_size_request(600, 600)
580
+ @window.set_default_size(width, height)
581
+ debug "size #{[width, height]}", 2
555
582
  @window.unmaximize
583
+
584
+ #set_default_size doesn't always have effect if run immediately
585
+ wait_for_resize(@window)
556
586
  @window.set_default_size(width, height)
587
+
557
588
  return false
558
589
  end
559
590
 
@@ -569,10 +600,6 @@ class VMAgui
569
600
  @window = Gtk::ApplicationWindow.new(app)
570
601
  @window.set_application(app)
571
602
 
572
- @window.maximize
573
- # Need to let Gtk process after maximize
574
- run_as_idle proc { idle_set_size }
575
-
576
603
  @window.title = "Multiple Views"
577
604
  @vpaned = Gtk::Paned.new(:vertical)
578
605
 
@@ -664,6 +691,8 @@ class VMAgui
664
691
 
665
692
  @window.show
666
693
 
694
+ run_as_idle proc { idle_set_size }
695
+
667
696
  prov = Gtk::CssProvider.new
668
697
  # See gtk-4.9.4/gtk/theme/Default/_common.scss on how to theme
669
698
  # gtksourceview/gtksourcestyleschemepreview.c
@@ -699,12 +728,28 @@ class VMAgui
699
728
  end
700
729
 
701
730
  # Vimamsa::Menu.new(@menubar) #TODO:gtk4
731
+ GLib::Idle.add(proc { self.monitor })
732
+
702
733
  app.run
703
734
 
704
735
  # @window.show_all
705
736
  # @window.show
706
737
  end
707
738
 
739
+ def monitor
740
+ @monitor_time ||= Time.now
741
+ @sw_width ||= @sw.width
742
+ return true if Time.now - @monitor_time < 0.2
743
+ # Detect element resize
744
+ if @sw.width != @sw_width
745
+ # puts "@sw.width=#{@sw.width}"
746
+ @sw_width = @sw.width
747
+ DelayExecutioner.exec(id: :scale_images, wait: 0.7, callable: proc { vma.gui.scale_all_images })
748
+ end
749
+ @monitor_time = Time.now
750
+ return true
751
+ end
752
+
708
753
  def init_menu
709
754
  Vimamsa::Menu.new(@menubar, @app)
710
755
  end
@@ -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
@@ -79,7 +79,6 @@ class VSourceView < GtkSource::View
79
79
  end
80
80
 
81
81
  def set_content(str)
82
- delete_cursorchar
83
82
  self.buffer.set_text(str)
84
83
  end
85
84
 
@@ -123,6 +122,52 @@ class VSourceView < GtkSource::View
123
122
  def register_signals()
124
123
  check_controllers
125
124
 
125
+ # TODO: accept GLib::Type::STRING also?
126
+ @dt = Gtk::DropTarget.new(GLib::Type["GFile"], [Gdk::DragAction::COPY, Gdk::DragAction::MOVE])
127
+ # GLib::Type::INVALID
128
+
129
+ self.add_controller(@dt)
130
+ @dt.signal_connect "drop" do |obj, v, x, y|
131
+ if v.value.gtype == GLib::Type["GLocalFile"]
132
+ uri = v.value.uri
133
+ elsif v.value.class == String
134
+ uri = v.value.gsub(/\r\n$/, "")
135
+ end
136
+ debug "dt,drop #{v.value},#{x},#{y}", 2
137
+ begin
138
+ fp = URI(uri).path
139
+ buf.handle_drag_and_drop(fp)
140
+ rescue URI::InvalidURIError
141
+ end
142
+ true
143
+ end
144
+
145
+ @dt.signal_connect "enter" do |gesture, x, y, z, m|
146
+ debug "dt,enter", 2
147
+ Gdk::DragAction::COPY
148
+ end
149
+
150
+ @dt.signal_connect "motion" do |obj, x, y|
151
+ debug "dt,move", 2
152
+
153
+ Gdk::DragAction::COPY
154
+ end
155
+
156
+ # dc = Gtk::DropControllerMotion.new
157
+ # self.add_controller(dc)
158
+ # dc.signal_connect "enter" do |gesture, x, y|
159
+ # debug "enter", 2
160
+ # debug [x, y]
161
+ # # Ripl.start :binding => binding
162
+ # true
163
+ # end
164
+
165
+ # dc.signal_connect "motion" do |gesture, x, y|
166
+ # debug "move", 2
167
+ # debug [x, y]
168
+ # true
169
+ # end
170
+
126
171
  # Implement mouse selections using @cnt_mo and @cnt_drag
127
172
  @cnt_mo = Gtk::EventControllerMotion.new
128
173
  self.add_controller(@cnt_mo)
@@ -149,10 +194,13 @@ class VSourceView < GtkSource::View
149
194
  debug "drag-end", 2
150
195
  if offsetx.abs < 5 and offsety.abs < 5
151
196
  debug "Not enough drag", 2
152
- @range_start = nil
153
- elsif !buf.visual_mode? and vma.kbd.get_scope != :editor
197
+ buf.end_selection
198
+ # elsif !buf.visual_mode? and vma.kbd.get_scope != :editor
199
+ elsif vma.kbd.get_scope != :editor
154
200
  # Can't transition from editor wide mode to buffer specific mode
155
- buf.start_visual_mode
201
+ vma.kbd.set_mode(:visual)
202
+ else
203
+ buf.end_selection
156
204
  end
157
205
  @range_start = nil
158
206
  end
@@ -233,14 +281,12 @@ class VSourceView < GtkSource::View
233
281
 
234
282
  def handle_scrolling()
235
283
  return # TODO
236
- delete_cursorchar
237
284
  # curpos = buffer.cursor_position
238
285
  # debug "MOVE CURSOR: #{curpos}"
239
286
  return nil if vma.gui.nil?
240
287
  return nil if @bufo.nil?
241
288
  vma.gui.run_after_scrolling proc {
242
289
  debug "START UPDATE POS AFTER SCROLLING", 2
243
- delete_cursorchar
244
290
  bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
245
291
  if !bc.nil?
246
292
  i = coord_to_iter(bc[0], bc[1])
@@ -254,7 +300,6 @@ class VSourceView < GtkSource::View
254
300
 
255
301
  def set_cursor_to_top
256
302
  debug "set_cursor_to_top", 2
257
- delete_cursorchar
258
303
  bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
259
304
  if !bc.nil?
260
305
  i = coord_to_iter(bc[0], bc[1])
@@ -267,7 +312,6 @@ class VSourceView < GtkSource::View
267
312
 
268
313
  # def handle_key_event(event, sig)
269
314
  def handle_key_event(keyval, keyname, sig)
270
- delete_cursorchar
271
315
  if $update_cursor
272
316
  handle_scrolling
273
317
  end
@@ -391,7 +435,6 @@ class VSourceView < GtkSource::View
391
435
  end
392
436
 
393
437
  def handle_deltas()
394
- delete_cursorchar
395
438
  any_change = false
396
439
  while d = @bufo.deltas.shift
397
440
  any_change = true
@@ -432,7 +475,6 @@ class VSourceView < GtkSource::View
432
475
  end
433
476
 
434
477
  def set_cursor_pos(pos)
435
- delete_cursorchar
436
478
  itr = buffer.get_iter_at(:offset => pos)
437
479
  itr2 = buffer.get_iter_at(:offset => pos + 1)
438
480
  buffer.place_cursor(itr)
@@ -451,7 +493,7 @@ class VSourceView < GtkSource::View
451
493
  $idle_scroll_to_mark = true
452
494
  ensure_cursor_visible
453
495
 
454
- draw_cursor
496
+ # draw_cursor
455
497
 
456
498
  return true
457
499
  end
@@ -513,14 +555,12 @@ class VSourceView < GtkSource::View
513
555
  end
514
556
  end
515
557
 
516
- # Delete the extra char added to buffer to represent the cursor
517
- def delete_cursorchar
518
- if !@cursorchar.nil?
519
- itr = buffer.get_iter_at(:offset => @cursorchar)
520
- itr2 = buffer.get_iter_at(:offset => @cursorchar + 1)
521
- buffer.delete(itr, itr2)
522
- @cursorchar = nil
523
- end
558
+ def after_action
559
+ iterate_gui_main_loop
560
+ handle_deltas
561
+ iterate_gui_main_loop
562
+ draw_cursor
563
+ iterate_gui_main_loop
524
564
  end
525
565
 
526
566
  def set_cursor_color(ctype)
@@ -531,7 +571,8 @@ class VSourceView < GtkSource::View
531
571
  self.style_context.remove_provider(@cursor_prov)
532
572
  end
533
573
  prov = Gtk::CssProvider.new
534
- prov.load(data: ".view text selection { background-color: #{bg}; color: #ffffff; }")
574
+ # prov.load(data: ".view text selection { background-color: #{bg}; color: #ffffff; }")
575
+ prov.load(data: ".view text selection { background-color: #{bg}; color: #ffffff; } .view { caret-color: #{bg}; }")
535
576
  self.style_context.add_provider(prov)
536
577
  @cursor_prov = prov
537
578
  end
@@ -545,38 +586,28 @@ class VSourceView < GtkSource::View
545
586
  # @tt.font = "Arial"
546
587
  # end
547
588
 
589
+ sv = vma.gui.sw.child
548
590
  mode = vma.kbd.get_mode
549
591
  ctype = vma.kbd.get_cursor_type
550
- delete_cursorchar
592
+ ctype = :visual if vma.buf.selection_active?
593
+
551
594
  vma.gui.remove_overlay_cursor
552
595
  if [:command, :replace, :browse].include?(ctype)
553
596
  set_cursor_color(ctype)
554
- if @bufo[@bufo.pos] == "\n"
555
- # If we are at end of line, it's not possible to draw the cursor by making a selection. I tried to do this by drawing an overlay, but that generates issues. If moving the cursor causes the ScrolledWindow to be scrolled, these errors randomly appear and the whole view shows blank:
556
- # (ruby:21016): Gtk-WARNING **: 19:52:23.181: Trying to snapshot GtkSourceView 0x55a97524c8c0 without a current allocation
557
- # (ruby:21016): Gtk-WARNING **: 19:52:23.181: Trying to snapshot GtkGizmo 0x55a9727d2580 without a current allocation
558
- # (ruby:21016): Gtk-WARNING **: 19:52:23.243: Trying to snapshot GtkSourceView 0x55a97524c8c0 without a current allocation
559
- # vma.gui.overlay_draw_cursor(@bufo.pos)
560
-
561
- # Current workaround is to add an empty space to the place where the cursor is and then remove this whenever we get any kind of event that might cause this class to be accessed.
562
- itr = buffer.get_iter_at(:offset => @bufo.pos)
563
- buffer.insert(itr, " ") # normal space
564
- # buffer.insert(itr, " ") # thin space (U+2009)
565
- # buffer.insert(itr, "l")
566
- @cursorchar = @bufo.pos
567
-
568
- # Apparently we need to redo this after buffer.insert:
569
- itr = buffer.get_iter_at(:offset => @bufo.pos)
570
- itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
571
- # buffer.apply_tag(@tt, itr, itr2)
572
- buffer.select_range(itr, itr2)
573
- else
574
- itr = buffer.get_iter_at(:offset => @bufo.pos)
575
- itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
576
- buffer.select_range(itr, itr2)
577
- end
578
- # elsif @bufo.visual_mode?
579
597
 
598
+ sv.overwrite = true
599
+ # sv.cursor_visible = true
600
+ # sv.reset_cursor_blink
601
+
602
+ # (Via trial and error) This combination is needed to make cursor visible:
603
+ sv.cursor_visible = false
604
+ sv.cursor_visible = true
605
+
606
+ # sv.reset_cursor_blink
607
+ Gtk::Settings.default.gtk_cursor_blink = false
608
+ # Gtk::Settings.default.gtk_cursor_blink_time = 8000
609
+ # vma.gui.sw.child.toggle_cursor_visible
610
+ # vma.gui.sw.child.cursor_visible = true
580
611
  elsif ctype == :visual
581
612
  set_cursor_color(ctype)
582
613
  # debug "VISUAL MODE"
@@ -587,16 +618,19 @@ class VSourceView < GtkSource::View
587
618
  # Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
588
619
  buffer.select_range(itr, itr2)
589
620
  elsif ctype == :insert
590
- # Not sure why this is needed
591
- itr = buffer.get_iter_at(:offset => @bufo.pos)
592
- buffer.select_range(itr, itr)
593
-
594
- # Via trial and error, this combination is only thing that seems to work:
595
- vma.gui.sw.child.toggle_cursor_visible
596
- vma.gui.sw.child.cursor_visible = true
597
-
621
+ set_cursor_color(ctype)
622
+ sv.overwrite = false
623
+ # sv.cursor_visible = false
624
+ # sv.cursor_visible = true
598
625
  debug "INSERT MODE"
599
626
  else # TODO
600
627
  end
628
+ if [:insert, :command, :replace, :browse].include?(ctype)
629
+ # Place cursor where it already is
630
+ # Without this hack, the cursor doesn't always get drawn
631
+ pos = @bufo.pos
632
+ itr = buffer.get_iter_at(:offset => pos)
633
+ buffer.place_cursor(itr)
634
+ end
601
635
  end
602
636
  end
@@ -24,7 +24,9 @@ class Autocomplete
24
24
 
25
25
  def self.add_words(words)
26
26
  for w in words
27
- @@trie << w
27
+ if w.size < 100
28
+ @@trie << w
29
+ end
28
30
  end
29
31
  end
30
32
 
@@ -7,7 +7,7 @@ def hpt_check_cur_word(w)
7
7
  dn = File.dirname(vma.buf.fname)
8
8
 
9
9
  fcands = []
10
- if fpfx[0] != "/"
10
+ if fpfx[0] != "/" and fpfx[0] != "~"
11
11
  fcands << "#{dn}/#{fpfx}"
12
12
  fcands << "#{dn}/#{fpfx}.txt"
13
13
  end
@@ -26,7 +26,7 @@ def hpt_check_cur_word(w)
26
26
  if fn
27
27
  if m[2] == "audio"
28
28
  # Thread.new { Audio.play(fn) }
29
- Audio.play(fn)
29
+ Audio.play(fn) if cnf.audio.enabled?
30
30
  else
31
31
  if !file_is_text_file(fn)
32
32
  message "Not text file #{fn}"
@@ -52,6 +52,7 @@ def hpt_check_cur_word(w)
52
52
  return nil
53
53
  end
54
54
 
55
+
55
56
  def hpt_create_new_file(fn)
56
57
  create_new_file(fn)
57
58
  end
@@ -128,7 +129,7 @@ def hpt_scan_images(bf = nil)
128
129
  }
129
130
 
130
131
  # Need to scale after buffer loaded
131
- GLib::Idle.add(proc { vma.gui.scale_all_images })
132
+ run_as_idle proc { vma.gui.scale_all_images }
132
133
 
133
134
  # vma.gui.delex.run #TODO:gtk4
134
135
  end
@@ -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 },