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.
@@ -1,4 +1,3 @@
1
-
2
1
  # Following this example:
3
2
  # https://gabmus.org/posts/create_an_auto-resizing_image_widget_with_gtk3_and_python/
4
3
  class ResizableImage < Gtk::DrawingArea
@@ -18,26 +17,33 @@ class ResizableImage < Gtk::DrawingArea
18
17
  def scale_image()
19
18
  pb = @pixbuf
20
19
  view = @view
21
- imglimit = view.visible_rect.width - 10
20
+ if view.visible_rect.width > 0
21
+ imglimit = view.visible_rect.width - 50
22
+ else
23
+ imglimit = 500
24
+ end
22
25
 
23
26
  if @oldimg.width > imglimit or @oldimg.width < imglimit - 10
24
27
  nwidth = imglimit
25
28
  nwidth = pb.width if pb.width < imglimit
26
29
  nheight = (pb.height * (nwidth.to_f / pb.width)).to_i
30
+ # Ripl.start :binding => binding
31
+
27
32
  pb = pb.scale_simple(nwidth, nheight, GdkPixbuf::InterpType::HYPER)
28
33
  else
29
34
  pb = @oldimg
30
35
  end
31
36
  @draw_image = pb
32
37
  @oldimg = pb
33
- self.set_size_request(pb.width, pb.height)
34
-
38
+ #TODO: Should be better way to compensate for the gutter
39
+ self.set_size_request(pb.width+@view.gutter_width, pb.height)
35
40
  end
36
41
 
37
42
  def do_draw(da, cr)
38
43
  # puts @fpath
39
- cr.set_source_pixbuf(@draw_image, 0, 0)
44
+ # Ripl.start :binding => binding
45
+
46
+ cr.set_source_pixbuf(@draw_image, @view.gutter_width, 0)
40
47
  cr.paint
41
48
  end
42
49
  end
43
-
@@ -16,7 +16,6 @@ module Vimamsa
16
16
  end
17
17
 
18
18
  def add_menu_items()
19
-
20
19
  add_to_menu "File.Example", { :label => "<span foreground='#888888'>Action, [mode] key binding</span>", :action => nil }
21
20
  add_to_menu "File.Save", { :label => "Save", :action => :buf_save }
22
21
  add_to_menu "File.Save as", { :label => "Save As...", :action => :buf_save_as }
@@ -40,14 +39,13 @@ module Vimamsa
40
39
  add_to_menu "Actions.FileHistoryFinder", { :label => "Search files in history", :action => :gui_file_history_finder }
41
40
 
42
41
  add_to_menu "Actions.experimental.Diff", { :label => "Show Diff of\nunsaved changes", :action => :diff_buffer }
43
-
42
+
44
43
  add_to_menu "Actions.experimental.EnableDebug", { :label => "Enable debug", :action => :enable_debug }
45
44
  add_to_menu "Actions.experimental.DisableDebug", { :label => "Disable debug", :action => :disable_debug }
46
45
  add_to_menu "Actions.experimental.ShowImages", { :label => "Show images ⟦img:path⟧", :action => :show_images }
47
-
46
+
48
47
  add_to_menu "Actions.EncryptFile", { :label => "Encrypt file", :action => :encrypt_file }
49
48
  add_to_menu "Help.KeyBindings", { :label => "Show key bindings", :action => :show_key_bindings }
50
-
51
49
 
52
50
  #TODO: :auto_indent_buffer
53
51
 
@@ -55,26 +53,19 @@ module Vimamsa
55
53
 
56
54
  end
57
55
 
58
- def initialize(menubar)
59
- # nfo["file"] = { :items => {}, :label => "File" }
60
- # nfo["actions"] = { :items => {}, :label => "Actions" }
61
- # nfo["help"] = { :items => {}, :label => "Help" }
62
-
56
+ def initialize(menubar, _app)
57
+ @app = _app
63
58
  @nfo = {}
64
59
 
65
60
  add_menu_items
66
61
 
67
- # add_to_menu("help.extra.keybindings", { :label => "Show keybindings" })
68
- # add_to_menu("help.extra.nfo.keybindings", { :label => "Show keybindings" })
69
- # add_to_menu("help.keybindings", { :label => "Show keybindings <span foreground='#888888' >C ? k</span>" }) #font='12' weight='ultrabold'
70
-
71
62
  for k, v in @nfo
72
63
  build_menu(v, menubar)
73
64
  end
74
65
  end
75
66
 
76
67
  def build_menu(nfo, parent)
77
- menu = Gtk::Menu.new
68
+ menu = Gio::Menu.new
78
69
  if nfo[:action]
79
70
  kbd_str = ""
80
71
  for mode_str in ["C", "V"]
@@ -86,24 +77,38 @@ module Vimamsa
86
77
  end
87
78
 
88
79
  label_str = nfo[:label] + kbd_str
89
- menuitem = Gtk::MenuItem.new(:label => label_str)
90
- menuitem.children[0].set_markup(label_str)
91
-
92
- menuitem.signal_connect("activate") do
80
+ actkey = nfo[:action].to_s
81
+ menuitem = Gio::MenuItem.new(label_str, "app.#{actkey}")
82
+
83
+ # This worked in GTK3:
84
+ # But seems there is no way to access the Label object in GTK4
85
+ # menuitem.children[0].set_markup(label_str)
86
+
87
+ act = Gio::SimpleAction.new(actkey)
88
+ @app.add_action(act)
89
+ act.signal_connect "activate" do |_simple_action, _parameter|
93
90
  call_action(nfo[:action])
94
91
  end
95
92
  else
96
- menuitem = Gtk::MenuItem.new(:label => nfo[:label])
97
- menuitem.children[0].set_markup(nfo[:label])
93
+ menuitem = Gio::MenuItem.new(nfo[:label], nil)
98
94
  end
99
95
 
96
+ # Apparently requires Gtk 4.6 to work.
97
+ # According to instructions in: https://discourse.gnome.org/t/gtk4-and-pango-markup-in-menu-items/16082
98
+ # Boolean true here should work but doesn't yet in GTK 4.6. The string version does work.
99
+ menuitem.set_attribute_value("use-markup", "true")
100
+ # menuitem.set_attribute_value("use-markup", true)
101
+ # This might change in the future(?), but the string version still works in gtk-4.13.0 (gtk/gtkmenutrackeritem.c)
102
+
103
+
100
104
  if !nfo[:items].nil? and !nfo[:items].empty?
101
105
  for k2, item in nfo[:items]
102
106
  build_menu(item, menu)
103
107
  end
104
108
  menuitem.submenu = menu
105
109
  end
106
- parent.append(menuitem)
110
+ o = parent.append_item(menuitem)
111
+
107
112
  end
108
113
  end #end class
109
114
  end
@@ -1,4 +1,4 @@
1
- def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt={})
1
+ def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt = {})
2
2
  $selup = SelectUpdateWindow.new(nil, item_list, jump_keys, select_callback, update_callback, opt)
3
3
  $selup.run
4
4
  # opt fields:
@@ -39,7 +39,7 @@ class SelectUpdateWindow
39
39
  end
40
40
 
41
41
  def initialize(main_window, item_list, jump_keys, select_callback, update_callback, opt = {})
42
- @window = Gtk::Window.new(:toplevel)
42
+ @window = Gtk::Window.new()
43
43
  # @window.screen = main_window.screen
44
44
  @window.title = ""
45
45
  if !opt[:title].nil?
@@ -50,12 +50,23 @@ class SelectUpdateWindow
50
50
  @opt = opt
51
51
 
52
52
  debug item_list.inspect
53
- @update_callback = method(update_callback)
54
- @select_callback = method(select_callback)
53
+
54
+ if select_callback.class == Method
55
+ @select_callback = select_callback
56
+ else
57
+ @select_callback = method(select_callback)
58
+ end
59
+ if update_callback.class == Method
60
+ @update_callback = update_callback
61
+ else
62
+ @update_callback = method(update_callback)
63
+ end
55
64
  # debug @update_callback_m.call("").inspect
56
65
 
57
66
  vbox = Gtk::Box.new(:vertical, 8)
58
- vbox.margin = 8
67
+ vbox.margin_bottom = 8
68
+ vbox.margin_top = 8
69
+
59
70
  @window.add(vbox)
60
71
 
61
72
  @entry = Gtk::SearchEntry.new
@@ -74,24 +85,31 @@ class SelectUpdateWindow
74
85
  # item_list = @update_callback.call("")
75
86
  update_item_list(item_list)
76
87
 
77
- @window.signal_connect("key-press-event") do |_widget, event|
78
- # debug "KEYPRESS 1"
79
- @entry.handle_event(event)
80
- end
88
+ # @window.signal_connect("key-press-event") do |_widget, event| #TODO:gtk4
89
+ # debug "KEYPRESS 1"
90
+ # @entry.handle_event(event)
91
+ # end
92
+
93
+ press = Gtk::EventControllerKey.new
94
+ press.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
81
95
 
82
- @entry.signal_connect("key_press_event") do |widget, event|
83
- # debug "KEYPRESS 2"
84
- if event.keyval == Gdk::Keyval::KEY_Down
96
+ @entry.add_controller(press)
97
+ # @window.add_controller(press)
98
+ press.signal_connect "key-pressed" do |gesture, keyval, keycode, y|
99
+ name = Gdk::Keyval.to_name(keyval)
100
+ uki = Gdk::Keyval.to_unicode(keyval)
101
+ keystr = uki.chr("UTF-8")
102
+ debug "keyval=#{keyval}"
103
+
104
+ if keyval == Gdk::Keyval::KEY_Down
85
105
  debug "DOWN"
86
106
  set_selected_row(@selected_row + 1)
87
- # fixed = iter[COLUMN_FIXED]
88
-
89
107
  true
90
- elsif event.keyval == Gdk::Keyval::KEY_Up
108
+ elsif keyval == Gdk::Keyval::KEY_Up
91
109
  set_selected_row(@selected_row - 1)
92
110
  debug "UP"
93
111
  true
94
- elsif event.keyval == Gdk::Keyval::KEY_Return
112
+ elsif keyval == Gdk::Keyval::KEY_Return
95
113
  path = Gtk::TreePath.new(@selected_row.to_s)
96
114
  iter = @model.get_iter(path)
97
115
  ret = iter[1]
@@ -99,7 +117,7 @@ class SelectUpdateWindow
99
117
  @window.destroy
100
118
  # debug iter[1].inspect
101
119
  true
102
- elsif event.keyval == Gdk::Keyval::KEY_Escape
120
+ elsif keyval == Gdk::Keyval::KEY_Escape
103
121
  @window.destroy
104
122
  true
105
123
  else
@@ -131,11 +149,12 @@ class SelectUpdateWindow
131
149
 
132
150
  vbox.pack_start(container, :expand => false, :fill => false, :padding => 0)
133
151
  sw = Gtk::ScrolledWindow.new(nil, nil)
134
- sw.shadow_type = :etched_in
152
+ # sw.shadow_type = :etched_in #TODO:gtk4
135
153
  sw.set_policy(:never, :automatic)
136
- vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
154
+ vbox.pack_end(sw, :expand => true, :fill => true, :padding => 0)
137
155
 
138
- sw.add(treeview)
156
+ # sw.add(treeview) #TODO:gtk4
157
+ sw.set_child(treeview)
139
158
 
140
159
  if !opt[:columns].nil?
141
160
  for col in opt[:columns]
@@ -168,7 +187,7 @@ class SelectUpdateWindow
168
187
 
169
188
  def run
170
189
  if !@window.visible?
171
- @window.show_all
190
+ @window.show
172
191
  # add_spinner
173
192
  else
174
193
  @window.destroy
@@ -1,80 +1,135 @@
1
-
2
-
3
1
  # class VSourceView < Gtk::TextView
4
2
  class VSourceView < GtkSource::View
5
- attr_accessor :bufo
3
+ attr_accessor :bufo
6
4
  # :highlight_matching_brackets
7
-
5
+
8
6
  # def set_highlight_current_line(vbool)
9
7
  # end
10
-
8
+
11
9
  # def set_show_line_numbers(vbool)
12
10
  # end
13
-
11
+
14
12
  # def highlight_matching_brackets=(vbool)
15
13
  # end
16
-
17
14
 
18
- def initialize(title = nil,bufo=nil)
15
+ # def initialize(title = nil,bufo=nil)
16
+ def initialize(title, bufo)
19
17
  # super(:toplevel)
20
18
  @highlight_matching_brackets = true
19
+ @idle_func_running = false
21
20
  super()
22
21
  @bufo = bufo #object of Buffer class buffer.rb
23
22
  debug "vsource init"
24
23
  @last_keyval = nil
25
24
  @last_event = [nil, nil]
26
- self.drag_dest_add_image_targets
27
- self.drag_dest_add_uri_targets
28
-
29
- signal_connect "button-press-event" do |_widget, event|
30
- if event.button == Gdk::BUTTON_PRIMARY
31
- # debug "Gdk::BUTTON_PRIMARY"
32
- false
33
- elsif event.button == Gdk::BUTTON_SECONDARY
34
- # debug "Gdk::BUTTON_SECONDARY"
35
- true
36
- else
37
- true
38
- end
39
- end
40
-
41
- signal_connect("drag-data-received") do |widget, event, x, y, data, info, time|
42
- puts "drag-data-received"
43
- puts
44
- if data.uris.size >= 1
45
- imgpath = CGI.unescape(data.uris[0])
46
- m = imgpath.match(/^file:\/\/(.*)/)
47
- if m
48
- fp = m[1]
49
- handle_drag_and_drop(fp)
50
- end
51
- end
52
- true
53
- end
54
-
55
- signal_connect("key_press_event") do |widget, event|
56
- handle_key_event(event, :key_press_event)
57
- true
58
- end
59
-
60
- signal_connect("key_release_event") do |widget, event|
61
- handle_key_event(event, :key_release_event)
62
- true
63
- end
25
+ @removed_controllers = []
26
+ self.highlight_current_line = true
27
+
28
+ # self.drag_dest_add_image_targets #TODO:gtk4
29
+ # self.drag_dest_add_uri_targets #TODO:gtk4
30
+
31
+ # signal_connect("drag-data-received") do |widget, event, x, y, data, info, time| #TODO:gtk4
32
+ # puts "drag-data-received"
33
+ # puts
34
+ # if data.uris.size >= 1
35
+ # imgpath = CGI.unescape(data.uris[0])
36
+ # m = imgpath.match(/^file:\/\/(.*)/)
37
+ # if m
38
+ # fp = m[1]
39
+ # handle_drag_and_drop(fp)
40
+ # end
41
+ # end
42
+ # true
43
+ # end
64
44
 
65
45
  signal_connect("move-cursor") do |widget, event|
46
+ debug("MOVE-CURSOR",2)
66
47
  $update_cursor = true
67
48
  false
68
49
  end
69
50
 
51
+ return
52
+
53
+ #TODO:gtk4
70
54
  signal_connect "button-release-event" do |widget, event|
71
- $buffer.set_pos(buffer.cursor_position)
55
+ vma.buf.set_pos(buffer.cursor_position)
72
56
  false
73
57
  end
74
58
  @curpos_mark = nil
75
59
  end
76
60
 
77
- def handle_key_event(event, sig)
61
+ def gutter_width()
62
+ winwidth = width
63
+ view_width = visible_rect.width
64
+ gutter_width = winwidth - view_width
65
+ end
66
+
67
+ def show_controllers
68
+ clist = self.observe_controllers
69
+ (0..(clist.n_items - 1)).each { |x|
70
+ ctr = clist.get_item(x)
71
+ pp ctr
72
+ }
73
+ end
74
+
75
+ def check_controllers
76
+ clist = self.observe_controllers
77
+ to_remove = []
78
+ (0..(clist.n_items - 1)).each { |x|
79
+ ctr = clist.get_item(x)
80
+ # Sometimes a GestureClick EventController appears from somewhere
81
+ # not initiated from this file.
82
+
83
+ # if ctr.class == Gtk::EventControllerKey or ctr.class == Gtk::GestureClick
84
+ if ctr != @click
85
+ # to_remove << ctr if ctr.class != Gtk::GestureDrag
86
+ to_remove << ctr
87
+ end
88
+ }
89
+ if to_remove.size > 0
90
+ debug "Removing controllers:"
91
+ pp to_remove
92
+ to_remove.each { |x|
93
+ # To avoid GC. https://github.com/ruby-gnome/ruby-gnome/issues/15790
94
+ @removed_controllers << x
95
+ self.remove_controller(x)
96
+ }
97
+ end
98
+ end
99
+
100
+ def register_signals()
101
+
102
+ #TODO: Doesn't seem to catch "move-cursor" signal since upgrade to gtk4
103
+ # self.signal_connect("move-cursor") do |widget, event|
104
+ # $update_cursor = true
105
+ # false
106
+ # end
107
+
108
+ check_controllers
109
+ click = Gtk::GestureClick.new
110
+ click.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
111
+ self.add_controller(click)
112
+ # Detect mouse click
113
+ @click = click
114
+ click.signal_connect "pressed" do |gesture, n_press, x, y, z|
115
+ debug "SourceView, GestureClick x=#{x} y=#{y}"
116
+ pp visible_rect
117
+ winw = width
118
+ view_width = visible_rect.width
119
+ gutter_width = winw - view_width
120
+
121
+ i = get_iter_at_location((x - gutter_width).to_i, (y + visible_rect.y).to_i)
122
+ if !i.nil?
123
+ @bufo.set_pos(i.offset)
124
+ else
125
+ debug "iter nil 0000"
126
+ end
127
+ true
128
+ end
129
+ end
130
+
131
+ # def handle_key_event(event, sig)
132
+ def handle_key_event(keyval, keyname, sig)
78
133
  if $update_cursor
79
134
  curpos = buffer.cursor_position
80
135
  debug "MOVE CURSOR: #{curpos}"
@@ -84,13 +139,14 @@ class VSourceView < GtkSource::View
84
139
  debug $view.visible_rect.inspect
85
140
 
86
141
  debug "key event"
87
- debug event
142
+ # debug event
88
143
 
89
- key_name = event.string
90
- if event.state.control_mask?
91
- key_name = Gdk::Keyval.to_name(event.keyval)
92
- # Gdk::Keyval.to_name()
93
- end
144
+ # key_name = event.string
145
+ #TODO:??
146
+ # if event.state.control_mask?
147
+ # key_name = Gdk::Keyval.to_name(event.keyval)
148
+ # Gdk::Keyval.to_name()
149
+ # end
94
150
 
95
151
  keyval_trans = {}
96
152
  keyval_trans[Gdk::Keyval::KEY_Control_L] = "ctrl"
@@ -121,29 +177,48 @@ class VSourceView < GtkSource::View
121
177
 
122
178
  key_trans = {}
123
179
  key_trans["\e"] = "esc"
124
- tk = keyval_trans[event.keyval]
125
- key_name = tk if !tk.nil?
180
+ tk = keyval_trans[keyval]
181
+ keyname = tk if !tk.nil?
126
182
 
127
183
  key_str_parts = []
128
- key_str_parts << "ctrl" if event.state.control_mask? and key_name != "ctrl"
129
- key_str_parts << "alt" if event.state.mod1_mask? and key_name != "alt"
184
+ key_str_parts << "ctrl" if vma.kbd.modifiers[:ctrl]
185
+ key_str_parts << "alt" if vma.kbd.modifiers[:alt]
186
+ key_str_parts << "shift" if vma.kbd.modifiers[:shift]
187
+ key_str_parts << "meta" if vma.kbd.modifiers[:meta]
188
+ key_str_parts << "super" if vma.kbd.modifiers[:super]
189
+ key_str_parts << keyname
190
+
191
+ if key_str_parts[0] == key_str_parts[1]
192
+ # We don't want "ctrl-ctrl" or "alt-alt"
193
+ # TODO:There should be a better way to do this
194
+ key_str_parts.delete_at(0)
195
+ end
196
+
197
+ if key_str_parts[0] == "shift" and key_str_parts[1].class == String
198
+ #"shift-P" to just "P"
199
+ # key_str_parts.delete_at(0) if key_str_parts[1].match(/^[[:upper:]]$/)
200
+ key_str_parts.delete_at(0)
201
+ end
130
202
 
131
- key_str_parts << key_name
132
203
  key_str = key_str_parts.join("-")
133
- keynfo = { :key_str => key_str, :key_name => key_name, :keyval => event.keyval }
204
+ if key_str == "\u0000"
205
+ key_str = ""
206
+ end
207
+
208
+ keynfo = { :key_str => key_str, :key_name => keyname, :keyval => keyval }
134
209
  debug keynfo.inspect
135
210
  # $kbd.match_key_conf(key_str, nil, :key_press)
136
211
  # debug "key_str=#{key_str} key_"
137
212
 
138
213
  if key_str != "" # or prefixed_key_str != ""
139
- if sig == :key_release_event and event.keyval == @last_keyval
214
+ if sig == :key_release and keyval == @last_keyval
140
215
  $kbd.match_key_conf(key_str + "!", nil, :key_release)
141
- @last_event = [event, :key_release]
142
- elsif sig == :key_press_event
216
+ @last_event = [keynfo, :key_release]
217
+ elsif sig == :key_press
143
218
  $kbd.match_key_conf(key_str, nil, :key_press)
144
- @last_event = [event, key_str, :key_press]
219
+ @last_event = [keynfo, key_str, :key_press]
145
220
  end
146
- @last_keyval = event.keyval #TODO: outside if?
221
+ @last_keyval = keyval #TODO: outside if?
147
222
  end
148
223
 
149
224
  handle_deltas
@@ -157,7 +232,9 @@ class VSourceView < GtkSource::View
157
232
  b = buffer
158
233
  iter = b.get_iter_at(:offset => i)
159
234
  iterxy = get_iter_location(iter)
160
- winw = parent_window.width
235
+ # winw = parent_window.width #TODO:gtk4
236
+ winw = width #TODO
237
+
161
238
  view_width = visible_rect.width
162
239
  gutter_width = winw - view_width
163
240
 
@@ -167,7 +244,6 @@ class VSourceView < GtkSource::View
167
244
  # buffer_to_window_coords(Gtk::TextWindowType::TEXT, iterxy.x, iterxy.y).inspect
168
245
  # debug buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y).inspect
169
246
  (x, y) = buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y)
170
- # Ripl.start :binding => binding
171
247
 
172
248
  return [x, y]
173
249
  end
@@ -190,7 +266,8 @@ class VSourceView < GtkSource::View
190
266
  end
191
267
  end
192
268
  if any_change
193
- gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
269
+ # gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
270
+ self.set_cursor_pos(pos)
194
271
  end
195
272
 
196
273
  # sanity_check #TODO
@@ -236,7 +313,6 @@ class VSourceView < GtkSource::View
236
313
  # scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
237
314
 
238
315
  # $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
239
- # Ripl.start :binding => binding
240
316
  draw_cursor
241
317
 
242
318
  return true
@@ -251,6 +327,9 @@ class VSourceView < GtkSource::View
251
327
  # iter = buffer.get_iter_at(:offset => buffer.cursor_position)
252
328
  # iterxy = get_iter_location(iter)
253
329
 
330
+ # This is not the current buffer
331
+ return false if vma.gui.view != self
332
+
254
333
  sleep(0.01)
255
334
  # intr = iterxy.intersect(vr)
256
335
  if is_cursor_visible == false
@@ -265,8 +344,9 @@ class VSourceView < GtkSource::View
265
344
 
266
345
  scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
267
346
 
268
- # return true # Call this func again
347
+ return true # Call this func again
269
348
  else
349
+ @idle_func_running = false
270
350
  return false # Don't call this idle func again
271
351
  end
272
352
  end
@@ -282,9 +362,6 @@ class VSourceView < GtkSource::View
282
362
  if intr.nil?
283
363
  debug iterxy.inspect
284
364
  debug vr.inspect
285
- # Ripl.start :binding => binding
286
-
287
- # exit!
288
365
  return false
289
366
  else
290
367
  return true
@@ -292,7 +369,12 @@ class VSourceView < GtkSource::View
292
369
  end
293
370
 
294
371
  def ensure_cursor_visible
372
+ return #TODO:gtk4
373
+ debug "@idle_func_running=#{@idle_func_running}"
374
+ return if @idle_func_running
295
375
  if is_cursor_visible == false
376
+ @idle_func_running = true
377
+ debug "Starting idle func"
296
378
  Thread.new {
297
379
  sleep 0.01
298
380
  GLib::Idle.add(proc { cursor_visible_idle_func })
@@ -301,21 +383,33 @@ class VSourceView < GtkSource::View
301
383
  end
302
384
 
303
385
  def draw_cursor
304
- if is_command_mode
386
+ mode = vma.kbd.get_mode
387
+ ctype = vma.kbd.get_cursor_type
388
+ # if is_command_mode
389
+ if ctype == :command
305
390
  itr = buffer.get_iter_at(:offset => @bufo.pos)
306
391
  itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
307
- $view.buffer.select_range(itr, itr2)
308
- elsif @bufo.visual_mode?
392
+ buffer.select_range(itr, itr2)
393
+ # elsif @bufo.visual_mode?
394
+ elsif ctype == :visual
309
395
  debug "VISUAL MODE"
310
396
  (_start, _end) = @bufo.get_visual_mode_range2
311
397
  debug "#{_start}, #{_end}"
312
398
  itr = buffer.get_iter_at(:offset => _start)
313
399
  itr2 = buffer.get_iter_at(:offset => _end + 1)
314
- $view.buffer.select_range(itr, itr2)
315
- else # Insert mode
400
+ # Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
401
+ buffer.select_range(itr, itr2)
402
+ elsif ctype == :insert
403
+ # Not sure why this is needed
316
404
  itr = buffer.get_iter_at(:offset => @bufo.pos)
317
- $view.buffer.select_range(itr, itr)
405
+ buffer.select_range(itr, itr)
406
+
407
+ # Via trial and error, this combination is only thing that seems to work:
408
+ vma.gui.sw.child.toggle_cursor_visible
409
+ vma.gui.sw.child.cursor_visible = true
410
+
318
411
  debug "INSERT MODE"
412
+ else # TODO
319
413
  end
320
414
  end
321
415
  end