vimamsa 0.1.11 → 0.1.12

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: 97397b2b0eb7e2d07c23e67d4c9cebeec0df6925f43a70b2d42ad87d2f5383fb
4
- data.tar.gz: fe0040694d69b1b860d942fb7cf3bea5fc671ba482b72a991f4d8f6d0031524c
3
+ metadata.gz: 33b88d4f4c567a38c726a1eee1a408fb051a972a54afebfee29add1e81f7761d
4
+ data.tar.gz: '0366913aba4ccf3f687cbce63fec3815df7cf8c98ae1e00272be32d898f4ec48'
5
5
  SHA512:
6
- metadata.gz: 749aa7833a6db40dc85620884f2e7be97c3d54b4e681f96255f54aa1a76148d80640f78e194f3b688e80f770c4afedbba9c096ac58a56da455102fc2ece4bcec
7
- data.tar.gz: 74df362a22e70517ababecf5a61d29cc5655147f3c163764d264febfb83fa8b65182cb0f2cfc92e26e157ed3e2618c03c53f06c0d73ba5c06a18a4aa4b162201
6
+ metadata.gz: 3eaa999737e313cfbfb1028031d60101c7c3fcbcfb30504991c4a7a350da374f0969502e13facf46cc69f63b60d576817fa86cbd87981be8988e7998fef119b7
7
+ data.tar.gz: 298335f27adce1d7164ea138908419db2b7d1192014ad780651779f36d1a384cde34e5196fa3cae021beaf178e551de08e92a81f03643dec476bbb01a2e1d566
data/exe/vimamsa CHANGED
@@ -1,12 +1,9 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
  require "ripl/multi_line"
3
3
  require "tempfile"
4
4
  # Ripl.config[:multi_line_prompt] = ' > '
5
5
  require "pathname"
6
6
 
7
- ENV["GTK_THEME"] = "Adwaita:dark"
8
- # ENV["GTK_THEME"] = "Adwaita:light"
9
-
10
7
  selfpath = __FILE__
11
8
  selfpath = File.readlink(selfpath) if File.lstat(selfpath).symlink?
12
9
  scriptdir = File.expand_path(File.dirname(selfpath) + "/..")
@@ -13,7 +13,6 @@ $update_highlight = false
13
13
  $ifuncon = false
14
14
 
15
15
  class Buffer < String
16
-
17
16
  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
18
17
  attr_writer :call_func, :update_highlight
19
18
  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
@@ -207,9 +206,7 @@ class Buffer < String
207
206
  # If this is done too early, the gutter is not yet drawn which
208
207
  # will result in wrong position
209
208
  if @audiofiles.size == 1
210
- Thread.new {
211
- GLib::Idle.add(proc { self.reset_audio_widget_positions })
212
- }
209
+ run_as_idle proc { self.reset_audio_widget_positions }
213
210
  end
214
211
  $audiof = mf
215
212
  end
@@ -15,6 +15,7 @@ class BufferManager
15
15
 
16
16
  bindkey "bmgr enter", :bmgr_select
17
17
  bindkey "bmgr c", :bmgr_close
18
+ bindkey "bmgr x", :close_current_buffer
18
19
  end
19
20
 
20
21
  def initialize()
@@ -60,7 +61,7 @@ class BufferManager
60
61
  @@cur = self
61
62
  @header = []
62
63
  @header << "Current buffers:"
63
- @header << "keys: <enter> to select, <c> to close buffer"
64
+ @header << "keys: <enter> to select, <c> to close buffer, <x> exit"
64
65
  @header << "=" * 40
65
66
 
66
67
  s = ""
@@ -72,7 +72,7 @@ class EasyJump
72
72
  # @kbd.set_mode(:command)
73
73
  vma.kbd.remove_keyhandling_override
74
74
  @jump_sequence = []
75
- vma.gui.clear_overlay()
75
+ vma.gui.clear_overlay
76
76
  end
77
77
  return true
78
78
  end
@@ -93,6 +93,7 @@ class Editor
93
93
  $kbd = @kbd
94
94
  require "vimamsa/key_bindings_vimlike"
95
95
  sleep(0.03)
96
+
96
97
 
97
98
  FileManager.init
98
99
  BufferManager.init
@@ -169,7 +170,6 @@ class Editor
169
170
  #Load plugins
170
171
  require "vimamsa/file_history.rb"
171
172
  @fh = FileHistory.new
172
- # @_plugins[:FileFinder] = FileFinder.new
173
173
  @_plugins[:FileHistory] = @fh
174
174
 
175
175
  register_plugin(:FileHistory, @fh)
@@ -389,7 +389,7 @@ def show_key_bindings()
389
389
  kbd_s << vma.kbd.to_s
390
390
  kbd_s << "\n"
391
391
  kbd_s << "===============================================\n"
392
- b = create_new_file(nil, kbd_s)
392
+ b = create_new_buffer(kbd_s,"key-bindings")
393
393
  gui_set_file_lang(b.id, "hyperplaintext")
394
394
  #
395
395
  end
@@ -509,11 +509,11 @@ def create_new_file(filename = nil, file_contents = "\n")
509
509
  return buffer
510
510
  end
511
511
 
512
- def create_new_buffer(file_contents = "\n",prefix="buf")
512
+ def create_new_buffer(file_contents = "\n",prefix="buf", setcurrent=true)
513
513
  debug "NEW BUFFER CREATED"
514
514
  buffer = Buffer.new(file_contents,nil,prefix)
515
515
  vma.buffers.add(buffer)
516
- vma.buffers.set_current_buffer_by_id(buffer.id)
516
+ vma.buffers.set_current_buffer_by_id(buffer.id) if setcurrent
517
517
  buffer.set_content(file_contents)
518
518
 
519
519
  return buffer
@@ -15,12 +15,12 @@ class FileFinder
15
15
 
16
16
  def initialize()
17
17
  vma.hook.register(:shutdown, self.method("save"))
18
- @dir_list = vma.marshal_load("file_index")
18
+ @@dir_list = vma.marshal_load("file_index")
19
19
  end
20
20
 
21
21
  def save()
22
22
  debug "SAVE FILE INDEX", 2
23
- vma.marshal_save("file_index", @dir_list)
23
+ vma.marshal_save("file_index", @@dir_list)
24
24
  end
25
25
 
26
26
  def start_gui()
@@ -30,7 +30,7 @@ class FileFinder
30
30
  end
31
31
  l = []
32
32
  $select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
33
- if @dir_list == nil
33
+ if @@dir_list == nil
34
34
  Thread.new { FileFinder.recursively_find_files() }
35
35
  end
36
36
 
@@ -71,16 +71,16 @@ class FileFinder
71
71
  debug("FIND FILEs IN #{d}")
72
72
  dlist = dlist + Dir.glob("#{d}/**/*").select { |e| File.file?(e) and $find_extensions.include?(File.extname(e)) }
73
73
  debug("FIND FILEs IN #{d} END")
74
- end #@dir_list = Dir.glob('./**/*').select { |e| File.file? e }
75
- debug("END find files2")
76
- @dir_list = dlist
74
+ end
75
+ @@dir_list = dlist
77
76
  debug("END find files")
78
- return @dir_list
77
+ return @@dir_list
79
78
  end
80
79
 
81
80
  def filter_files(search_str)
82
81
  dir_hash = {}
83
- scores = Parallel.map(@dir_list, in_threads: 8) do |file|
82
+
83
+ scores = Parallel.map(@@dir_list, in_threads: 8) do |file|
84
84
  [file, srn_dst(search_str, file)]
85
85
  end
86
86
  for s in scores
data/lib/vimamsa/gui.rb CHANGED
@@ -178,38 +178,6 @@ def gui_set_cursor_pos(id, pos)
178
178
  vma.buf.view.set_cursor_pos(pos)
179
179
  end
180
180
 
181
- def gui_set_active_window(winid)
182
- sw = vma.gui.sw
183
- if winid == 2
184
- sw = vma.gui.sw2
185
- end
186
-
187
- sw.set_child(view)
188
- view.grab_focus
189
-
190
- vma.gui.view = view
191
- vma.gui.buf1 = view.buffer
192
- $view = view
193
- $vbuf = view.buffer
194
- end
195
-
196
- #TODO:delete?
197
- def gui_attach_buf_to_window(id, winid)
198
- view = vma.gui.buffers[id]
199
- sw = vma.gui.sw
200
- if winid == 2
201
- sw = vma.gui.sw2
202
- end
203
-
204
- sw.set_child(view)
205
- view.grab_focus
206
-
207
- vma.gui.view = view
208
- vma.gui.buf1 = view.buffer
209
- $view = view
210
- $vbuf = view.buffer
211
- end
212
-
213
181
  def gui_set_current_buffer(id)
214
182
  vma.gui.set_current_buffer(id)
215
183
  return
@@ -328,69 +296,53 @@ class VMAgui
328
296
  @da.show
329
297
  end
330
298
 
331
- def toggle_overlay
332
- @show_overlay = @show_overlay ^ 1
333
- if !@show_overlay
334
- if @da != nil
335
- @overlay.remove(@da)
336
- end
337
- return
338
- else
339
- @da = Gtk::Fixed.new
340
- @overlay.add_overlay(@da)
341
- @overlay.set_overlay_pass_through(@da, true)
299
+ def remove_overlay_cursor()
300
+ if !@cursorov.nil?
301
+ @overlay.remove_overlay(@cursorov)
302
+ @cursorov = nil
342
303
  end
304
+ end
343
305
 
344
- (startpos, endpos) = get_visible_area
345
- s = @view.buffer.text
346
- wpos = s.enum_for(:scan, /\W(\w)/).map { Regexp.last_match.begin(0) + 1 }
347
- wpos = wpos[0..130]
348
-
349
- # vr = @view.visible_rect
350
- # # gtk_text_view_get_line_at_y
351
- # # gtk_text_view_get_iter_at_position
352
- # gtk_text_view_get_iter_at_position(vr.
353
- # istart = @view.get_iter_at_position(vr.x,vr.y)
354
- # istart = @view.get_iter_at_y(vr.y)
355
- # startpos = @view.get_iter_at_position_raw(vr.x,vr.y)[1].offset
356
- # endpos = @view.get_iter_at_position_raw(vr.x+vr.width,vr.y+vr.height)[1].offset
357
- # debug "startpos,endpos:#{[startpos, endpos]}"
358
-
359
- da = @da
360
- if false
361
- da.signal_connect "draw" do |widget, cr|
362
- cr.save
363
- for pos in wpos
364
- (x, y) = @view.pos_to_coord(pos)
365
-
366
- layout = da.create_pango_layout("XY")
367
- desc = Pango::FontDescription.new("sans bold 11")
368
- layout.font_description = desc
369
-
370
- cr.move_to(x, y)
371
- # cr.move_to(gutter_width, 300)
372
- cr.pango_layout_path(layout)
373
-
374
- cr.set_source_rgb(1.0, 0.0, 0.0)
375
- cr.fill_preserve
376
- end
377
- cr.restore
378
- false # = draw other
379
- # true # = Don't draw others
306
+ def overlay_draw_cursor(textpos)
307
+ # return
308
+ remove_overlay_cursor
309
+ GLib::Idle.add(proc { self.overlay_draw_cursor_(textpos) })
310
+ # overlay_draw_cursor_(textpos)
311
+ end
312
+
313
+ # Run proc after animated scrolling has stopped (e.g. after page down)
314
+ def run_after_scrolling(p)
315
+ Thread.new {
316
+ while Time.now - @last_adj_time < 0.1
317
+ sleep 0.1
380
318
  end
381
- end
319
+ run_as_idle p
320
+ }
321
+ end
382
322
 
383
- for pos in wpos
384
- (x, y) = @view.pos_to_coord(pos)
385
- # da.put(Gtk::Label.new("AB"), x, y)
386
- label = Gtk::Label.new("<span background='#00000088' foreground='#ff0000' weight='ultrabold'>AB</span>")
387
- label.use_markup = true
388
- da.put(label, x, y)
389
- end
323
+ # To draw on empty lines and line-ends (where select_range doesn't work)
324
+ def overlay_draw_cursor_(textpos)
325
+ # Thread.new {
326
+ # GLib::Idle.add(proc { p.call; false })
327
+ # }
390
328
 
391
- # debug @view.pos_to_coord(300).inspect
329
+ # while Time.now - @last_adj_time < 0.3
330
+ # return true
331
+ # end
392
332
 
393
- @da.show
333
+ remove_overlay_cursor
334
+ @cursorov = Gtk::Fixed.new
335
+ @overlay.add_overlay(@cursorov)
336
+
337
+ (x, y) = @view.pos_to_coord(textpos)
338
+ pp [x, y]
339
+
340
+ # Trying to draw only background of character "I"
341
+ label = Gtk::Label.new("<span background='#00ffaaff' foreground='#00ffaaff' weight='ultrabold'>I</span>")
342
+ label.use_markup = true
343
+ @cursorov.put(label, x, y)
344
+ @cursorov.show
345
+ return false
394
346
  end
395
347
 
396
348
  def handle_deltas()
@@ -551,6 +503,7 @@ class VMAgui
551
503
  return true
552
504
  end
553
505
 
506
+ # Remove widget event controllers added by gtk, and add our own.
554
507
  def reset_controllers
555
508
  clist = @window.observe_controllers
556
509
  to_remove = []
@@ -629,23 +582,32 @@ class VMAgui
629
582
  end
630
583
  end
631
584
 
585
+ def idle_set_size()
586
+ # Need to wait for a while to window to be maximized to get correct @window.width
587
+ sleep 0.1
588
+ width = @window.width / 2
589
+ height = @window.height - 5
590
+ # Ripl.start :binding => binding
591
+ @window.unmaximize
592
+ @window.set_size_request(width, height)
593
+ return false
594
+ end
595
+
632
596
  def init_window
633
597
  @last_debug_idle = Time.now
634
598
  app = Gtk::Application.new("net.samiddhi.vimamsa.r#{rand(1000)}", :flags_none)
635
599
  @app = app
636
600
 
637
- app.signal_connect "activate" do
601
+ Gtk::Settings.default.gtk_application_prefer_dark_theme = true
602
+ Gtk::Settings.default.gtk_theme_name = "Adwaita"
638
603
 
639
- # @window = Gtk::Window.new(:toplevel)
640
- # @window = Gtk::Window.new()
604
+ app.signal_connect "activate" do
641
605
  @window = Gtk::ApplicationWindow.new(app)
642
606
  @window.set_application(app)
643
607
 
644
- # sh = @window.screen.height #TODO:gtk4
645
- # sw = @window.screen.width #TODO:gtk4
646
- # TODO:Maximise vertically
647
- # @window.set_default_size((sw * 0.45).to_i, sh - 20) #TODO:gtk4
648
- @window.set_default_size(800, 600)
608
+ @window.maximize
609
+ # Need to let Gtk process after maximize
610
+ run_as_idle proc { idle_set_size }
649
611
 
650
612
  @window.title = "Multiple Views"
651
613
  @vpaned = Gtk::Paned.new(:vertical)
@@ -659,15 +621,21 @@ class VMAgui
659
621
 
660
622
  reset_controllers
661
623
 
662
- # @window.signal_connect("key-pressed") { puts "Hello World!" }
663
- # @window.signal_connect("clicked") { puts "Hello World!" }
664
-
665
- # @menubar = Gtk::PopoverMenuBar.new #TODO:gtk4
666
- # @menubar.expand = false #TODO:gtk4
667
-
668
624
  @sw = Gtk::ScrolledWindow.new
669
625
  @sw.set_policy(:automatic, :automatic)
670
626
 
627
+ @last_adj_time = Time.now
628
+ @sw.vadjustment.signal_connect("value-changed") { |x|
629
+ # pp x.page_increment
630
+ # pp x.page_size
631
+ # pp x.step_increment
632
+ # pp x.upper
633
+ # pp x.value
634
+ # pp x
635
+ @last_adj_time = Time.now
636
+ # puts "@sw.vadjustment"
637
+ }
638
+
671
639
  # @sw.signal_connect("clicked") { puts "Hello World!" }
672
640
  # @sw.signal_connect("key-pressed") { puts "Hello World!" }
673
641
  @overlay = Gtk::Overlay.new
@@ -813,10 +781,10 @@ class VMAgui
813
781
  @vbox.remove(@overlay)
814
782
 
815
783
  # numbers: left, top, width, height
816
- @pane.set_start_child(@overlay)
817
- @pane.set_end_child(@overlay2)
784
+ @pane.set_start_child(@overlay2)
785
+ @pane.set_end_child(@overlay)
818
786
 
819
- @vbox.attach(@pane, 0, 1, 2, 1)
787
+ @vbox.attach(@pane, 0, 2, 2, 1)
820
788
 
821
789
  @sw2.vexpand = true
822
790
  @sw2.hexpand = true
@@ -831,7 +799,7 @@ class VMAgui
831
799
  last = vma.buffers.get_last_visited_id
832
800
  set_buffer_to_window(last, 2)
833
801
  else
834
- bf = create_new_buffer "\n\n"
802
+ bf = create_new_buffer "\n\n", "buff", false
835
803
  set_buffer_to_window(bf.id, 2)
836
804
  end
837
805
  end
@@ -848,8 +816,14 @@ class VMAgui
848
816
  else
849
817
  set_active_window(1)
850
818
  end
819
+ end
851
820
 
852
- vma.buffers.set_current_buffer_by_id(@sw.child.bufo.id)
821
+ # activate that window which has the given view
822
+ def set_current_view(view)
823
+ w = @windows.find { |k, v| v[:sw].child == view }
824
+ if !w.nil?
825
+ set_active_window(w[0])
826
+ end
853
827
  end
854
828
 
855
829
  def set_active_window(id)
@@ -868,16 +842,26 @@ class VMAgui
868
842
  @sw = @windows[id][:sw]
869
843
  @overlay = @windows[id][:overlay]
870
844
 
845
+ vma.buffers.set_current_buffer_by_id(@sw.child.bufo.id)
846
+
871
847
  #TODO: set buf & view of active window??
872
848
 
873
849
  end
874
850
 
851
+ def current_view
852
+ return @sw.child
853
+ end
854
+
875
855
  def set_buffer_to_window(bufid, winid)
876
856
  view = @buffers[bufid]
877
857
  debug "vma.gui.set_buffer_to_window(#{bufid}), winid=#{winid}"
878
858
  buf1 = view.buffer
879
859
 
880
860
  @windows[winid][:sw].set_child(view)
861
+ idle_ensure_cursor_drawn
862
+
863
+ # @overlay = Gtk::Overlay.new
864
+ # @overlay.add_overlay(view)
881
865
 
882
866
  #TODO:???
883
867
  # @view = view
@@ -896,19 +880,26 @@ class VMAgui
896
880
  $view = view
897
881
  $vbuf = buf1
898
882
 
899
- # If already open in another column
900
-
883
+ # Check if buffer is already open in another column
901
884
  if @two_column and @active_column == 2 and id == @sw1.child.bufo.id
902
885
  toggle_active_window
903
- elsif @two_column and @active_column == 1 and id == @sw2.child.bufo.id
886
+ elsif @two_column && @active_column == 1 && !@sw2.child.nil? && id == @sw2.child.bufo.id
887
+ #TODO: should not need !@sw2.child.nil? here. If this happens then other column is empty.
904
888
  toggle_active_window
905
889
  else
906
890
  @sw.set_child(view)
907
891
  end
908
892
  view.grab_focus
909
- # TODO:needed?
910
- # view.set_cursor_visible(true)
911
- # view.place_cursor_onscreen
912
- # @sw.show
893
+
894
+ idle_ensure_cursor_drawn
895
+ end
896
+
897
+ def idle_ensure_cursor_drawn
898
+ run_as_idle proc { self.ensure_cursor_drawn }
899
+ end
900
+
901
+ def ensure_cursor_drawn
902
+ # view.place_cursor_onscreen #TODO: needed?
903
+ view.draw_cursor
913
904
  end
914
905
  end
@@ -43,6 +43,10 @@ module Vimamsa
43
43
  add_to_menu "Actions.experimental.EnableDebug", { :label => "Enable debug", :action => :enable_debug }
44
44
  add_to_menu "Actions.experimental.DisableDebug", { :label => "Disable debug", :action => :disable_debug }
45
45
  add_to_menu "Actions.experimental.ShowImages", { :label => "Show images ⟦img:path⟧", :action => :show_images }
46
+
47
+
48
+ add_to_menu "View.TwoColumn", { :label => "Start two column mode", :action => :toggle_two_column }
49
+
46
50
 
47
51
  add_to_menu "Actions.EncryptFile", { :label => "Encrypt file", :action => :encrypt_file }
48
52
  add_to_menu "Help.KeyBindings", { :label => "Show key bindings", :action => :show_key_bindings }
@@ -25,6 +25,8 @@ class VSourceView < GtkSource::View
25
25
  @removed_controllers = []
26
26
  self.highlight_current_line = true
27
27
 
28
+ @tt = nil
29
+
28
30
  # self.drag_dest_add_image_targets #TODO:gtk4
29
31
  # self.drag_dest_add_uri_targets #TODO:gtk4
30
32
 
@@ -42,9 +44,19 @@ class VSourceView < GtkSource::View
42
44
  # true
43
45
  # end
44
46
 
47
+ # Mainly after page-up or page-down
45
48
  signal_connect("move-cursor") do |widget, event|
46
- debug("MOVE-CURSOR",2)
49
+ debug("MOVE-CURSOR", 2)
47
50
  $update_cursor = true
51
+ # handle_scrolling()
52
+ # curpos = buffer.cursor_position
53
+ # debug "MOVE CURSOR (sig): #{curpos}"
54
+
55
+ # run_as_idle proc {
56
+ # curpos = buffer.cursor_position
57
+ # debug "MOVE CURSOR (sig2): #{curpos}"
58
+ # }
59
+
48
60
  false
49
61
  end
50
62
 
@@ -83,7 +95,7 @@ class VSourceView < GtkSource::View
83
95
  # if ctr.class == Gtk::EventControllerKey or ctr.class == Gtk::GestureClick
84
96
  if ctr != @click
85
97
  # to_remove << ctr if ctr.class != Gtk::GestureDrag
86
- to_remove << ctr
98
+ to_remove << ctr
87
99
  end
88
100
  }
89
101
  if to_remove.size > 0
@@ -118,23 +130,57 @@ class VSourceView < GtkSource::View
118
130
  view_width = visible_rect.width
119
131
  gutter_width = winw - view_width
120
132
 
121
- i = get_iter_at_location((x - gutter_width).to_i, (y + visible_rect.y).to_i)
133
+ xloc = (x - gutter_width).to_i
134
+ yloc = (y + visible_rect.y).to_i
135
+ debug "xloc=#{xloc} yloc=#{yloc}"
136
+
137
+ # This needs to happen after xloc calculation, otherwise xloc gets a wrong value (around 200 bigger)
138
+ if vma.gui.current_view != self
139
+ vma.gui.set_current_view(self)
140
+ end
141
+
142
+ i = get_iter_at_location(xloc, yloc)
122
143
  if !i.nil?
123
144
  @bufo.set_pos(i.offset)
124
145
  else
125
- debug "iter nil 0000"
146
+ debug "iter nil"
147
+ #TODO: find correct line position some other way
126
148
  end
149
+
127
150
  true
128
151
  end
129
152
  end
130
153
 
154
+ def handle_scrolling()
155
+ delete_cursorchar
156
+ # curpos = buffer.cursor_position
157
+ # debug "MOVE CURSOR: #{curpos}"
158
+ return nil if vma.gui.nil?
159
+ return nil if @bufo.nil?
160
+ vma.gui.run_after_scrolling proc {
161
+ delete_cursorchar
162
+ bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
163
+ if !bc.nil?
164
+ # Try to get exact character position
165
+ i = get_iter_at_location(bc[0], bc[1])
166
+ if i.nil?
167
+ # If doesn't work, at least get the start of correct line
168
+ i = get_line_at_y(bc[1])
169
+ i = i[0]
170
+ end
171
+ if !i.nil?
172
+ @bufo.set_pos(i.offset)
173
+ end
174
+ end
175
+ $update_cursor = false
176
+ }
177
+ end
178
+
131
179
  # def handle_key_event(event, sig)
132
180
  def handle_key_event(keyval, keyname, sig)
181
+ delete_cursorchar
133
182
  if $update_cursor
134
- curpos = buffer.cursor_position
135
- debug "MOVE CURSOR: #{curpos}"
136
- buf.set_pos(curpos)
137
- $update_cursor = false
183
+ handle_scrolling
138
184
  end
139
185
  debug $view.visible_rect.inspect
140
186
 
@@ -226,17 +272,17 @@ class VSourceView < GtkSource::View
226
272
  # set_focus(5)
227
273
  # false
228
274
 
275
+ draw_cursor #TODO: only when needed
229
276
  end
230
277
 
231
278
  def pos_to_coord(i)
232
279
  b = buffer
233
280
  iter = b.get_iter_at(:offset => i)
234
281
  iterxy = get_iter_location(iter)
235
- # winw = parent_window.width #TODO:gtk4
236
282
  winw = width #TODO
237
283
 
238
284
  view_width = visible_rect.width
239
- gutter_width = winw - view_width
285
+ gutter_width = winw - view_width #TODO
240
286
 
241
287
  x = iterxy.x + gutter_width
242
288
  y = iterxy.y
@@ -249,6 +295,7 @@ class VSourceView < GtkSource::View
249
295
  end
250
296
 
251
297
  def handle_deltas()
298
+ delete_cursorchar
252
299
  any_change = false
253
300
  while d = @bufo.deltas.shift
254
301
  any_change = true
@@ -266,7 +313,7 @@ class VSourceView < GtkSource::View
266
313
  end
267
314
  end
268
315
  if any_change
269
- # gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
316
+ #TODO: only when necessary
270
317
  self.set_cursor_pos(pos)
271
318
  end
272
319
 
@@ -289,6 +336,7 @@ class VSourceView < GtkSource::View
289
336
  end
290
337
 
291
338
  def set_cursor_pos(pos)
339
+ delete_cursorchar
292
340
  # return
293
341
  itr = buffer.get_iter_at(:offset => pos)
294
342
  itr2 = buffer.get_iter_at(:offset => pos + 1)
@@ -382,14 +430,51 @@ class VSourceView < GtkSource::View
382
430
  end
383
431
  end
384
432
 
433
+ # Delete the extra char added to buffer to represent the cursor
434
+ def delete_cursorchar
435
+ if !@cursorchar.nil?
436
+ itr = buffer.get_iter_at(:offset => @cursorchar)
437
+ itr2 = buffer.get_iter_at(:offset => @cursorchar + 1)
438
+ buffer.delete(itr, itr2)
439
+ @cursorchar = nil
440
+ end
441
+ end
442
+
385
443
  def draw_cursor
444
+ # if @tt.nil?
445
+ # @tt = buffer.create_tag("font_tag")
446
+ # @tt.font = "Arial"
447
+ # end
448
+
386
449
  mode = vma.kbd.get_mode
387
450
  ctype = vma.kbd.get_cursor_type
388
- # if is_command_mode
451
+ delete_cursorchar
452
+ vma.gui.remove_overlay_cursor
389
453
  if ctype == :command
390
- itr = buffer.get_iter_at(:offset => @bufo.pos)
391
- itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
392
- buffer.select_range(itr, itr2)
454
+ if @bufo[@bufo.pos] == "\n"
455
+ # 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:
456
+ # (ruby:21016): Gtk-WARNING **: 19:52:23.181: Trying to snapshot GtkSourceView 0x55a97524c8c0 without a current allocation
457
+ # (ruby:21016): Gtk-WARNING **: 19:52:23.181: Trying to snapshot GtkGizmo 0x55a9727d2580 without a current allocation
458
+ # (ruby:21016): Gtk-WARNING **: 19:52:23.243: Trying to snapshot GtkSourceView 0x55a97524c8c0 without a current allocation
459
+ # vma.gui.overlay_draw_cursor(@bufo.pos)
460
+
461
+ # 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.
462
+ itr = buffer.get_iter_at(:offset => @bufo.pos)
463
+ buffer.insert(itr, " ") # normal space
464
+ # buffer.insert(itr, " ") # thin space (U+2009)
465
+ # buffer.insert(itr, "l")
466
+ @cursorchar = @bufo.pos
467
+
468
+ # Apparently we need to redo this after buffer.insert:
469
+ itr = buffer.get_iter_at(:offset => @bufo.pos)
470
+ itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
471
+ # buffer.apply_tag(@tt, itr, itr2)
472
+ buffer.select_range(itr, itr2)
473
+ else
474
+ itr = buffer.get_iter_at(:offset => @bufo.pos)
475
+ itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
476
+ buffer.select_range(itr, itr2)
477
+ end
393
478
  # elsif @bufo.visual_mode?
394
479
  elsif ctype == :visual
395
480
  debug "VISUAL MODE"
@@ -75,7 +75,7 @@ bindkey "B c", :close_current_buffer
75
75
  bindkey "B ;", "buf.jump_to_last_edit"
76
76
  bindkey "B q", :jump_to_last_edit
77
77
  bindkey "B w", :jump_to_next_edit
78
- bindkey "C , d", :diff_buffer
78
+ # bindkey "C , d", :diff_buffer
79
79
  bindkey "C , g", :invoke_grep_search
80
80
  #bindkey 'C , g', proc{invoke_grep_search}
81
81
  bindkey "C , v", :auto_indent_buffer
@@ -156,6 +156,7 @@ default_keys = {
156
156
 
157
157
  # Debug
158
158
  "C , d r p" => "start_ripl",
159
+ "C , d o" => "vma.gui.clear_overlay",
159
160
  "C , D" => "debug_print_buffer",
160
161
  "C , c s" => "bufs.close_scrap_buffers",
161
162
  "C , d b" => "debug_print_buffer",
data/lib/vimamsa/util.rb CHANGED
@@ -1,3 +1,12 @@
1
+ # Run idle proc once
2
+ # Delay execution of proc until Gtk has fully processed the last calls.
3
+ def run_as_idle(p)
4
+ if p.class == Proc
5
+ Thread.new {
6
+ GLib::Idle.add(proc { p.call; false })
7
+ }
8
+ end
9
+ end
1
10
 
2
11
  class HSafe
3
12
  def initialize(hash)
@@ -44,7 +53,6 @@ end
44
53
  # pp HSafe.new(h)[2]["sdf"][:llz].val
45
54
  # pp HSafe.new(h)["SDFSDFD"]["sdf"][:llz].val
46
55
 
47
-
48
56
  # From https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
49
57
  # Cross-platform way of finding an executable in the $PATH.
50
58
  #
@@ -1,3 +1,3 @@
1
1
  module Vimamsa
2
- VERSION = "0.1.11"
2
+ VERSION = "0.1.12"
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.11
4
+ version: 0.1.12
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-10-20 00:00:00.000000000 Z
11
+ date: 2023-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler