vimamsa 0.1.13 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/custom_example.rb +12 -0
  3. data/lib/vimamsa/ack.rb +3 -4
  4. data/lib/vimamsa/actions.rb +1 -2
  5. data/lib/vimamsa/audio.rb +25 -1
  6. data/lib/vimamsa/buffer.rb +116 -591
  7. data/lib/vimamsa/buffer_changetext.rb +272 -0
  8. data/lib/vimamsa/buffer_cursor.rb +303 -0
  9. data/lib/vimamsa/buffer_list.rb +137 -133
  10. data/lib/vimamsa/buffer_manager.rb +15 -15
  11. data/lib/vimamsa/clipboard.rb +36 -0
  12. data/lib/vimamsa/conf.rb +136 -5
  13. data/lib/vimamsa/constants.rb +0 -10
  14. data/lib/vimamsa/debug.rb +9 -8
  15. data/lib/vimamsa/editor.rb +57 -84
  16. data/lib/vimamsa/encrypt.rb +6 -11
  17. data/lib/vimamsa/file_history.rb +0 -8
  18. data/lib/vimamsa/file_manager.rb +142 -10
  19. data/lib/vimamsa/gui.rb +106 -85
  20. data/lib/vimamsa/gui_dialog.rb +113 -0
  21. data/lib/vimamsa/gui_menu.rb +5 -1
  22. data/lib/vimamsa/gui_sourceview.rb +46 -29
  23. data/lib/vimamsa/gui_sourceview_autocomplete.rb +141 -0
  24. data/lib/vimamsa/gui_text.rb +49 -0
  25. data/lib/vimamsa/hyper_plain_text.rb +19 -5
  26. data/lib/vimamsa/key_actions.rb +41 -202
  27. data/lib/vimamsa/key_binding_tree.rb +129 -41
  28. data/lib/vimamsa/key_bindings_vimlike.rb +58 -48
  29. data/lib/vimamsa/langservp.rb +23 -3
  30. data/lib/vimamsa/macro.rb +35 -25
  31. data/lib/vimamsa/main.rb +7 -10
  32. data/lib/vimamsa/rbvma.rb +13 -11
  33. data/lib/vimamsa/search.rb +1 -1
  34. data/lib/vimamsa/search_replace.rb +106 -160
  35. data/lib/vimamsa/terminal.rb +34 -0
  36. data/lib/vimamsa/tests.rb +122 -0
  37. data/lib/vimamsa/util.rb +43 -4
  38. data/lib/vimamsa/version.rb +1 -1
  39. data/vimamsa.gemspec +5 -2
  40. metadata +59 -9
  41. /data/lib/vimamsa/{form_generator.rb → gui_form_generator.rb} +0 -0
data/lib/vimamsa/gui.rb CHANGED
@@ -1,12 +1,31 @@
1
1
  $idle_scroll_to_mark = false
2
2
 
3
+ $removed_controllers = []
4
+
5
+ def gui_remove_controllers(widget)
6
+ clist = widget.observe_controllers
7
+ to_remove = []
8
+ (0..(clist.n_items - 1)).each { |x|
9
+ ctr = clist.get_item(x)
10
+ to_remove << ctr
11
+ }
12
+ if to_remove.size > 0
13
+ # debug "Removing controllers:"
14
+ # pp to_remove
15
+ to_remove.each { |x|
16
+ # To avoid GC. https://github.com/ruby-gnome/ruby-gnome/issues/15790
17
+ $removed_controllers << x
18
+ widget.remove_controller(x)
19
+ }
20
+ end
21
+ end
22
+
3
23
  def gui_open_file_dialog(dirpath)
4
24
  dialog = Gtk::FileChooserDialog.new(:title => "Open file",
5
25
  :action => :open,
6
26
  :buttons => [["Open", :accept],
7
27
  ["Cancel", :cancel]])
8
28
  dialog.set_current_folder(Gio::File.new_for_path(dirpath))
9
- # dialog.set_current_folder(Gio::File.new_for_path("/tmp"))
10
29
 
11
30
  dialog.signal_connect("response") do |dialog, response_id|
12
31
  if response_id == Gtk::ResponseType::ACCEPT
@@ -24,7 +43,7 @@ def gui_file_saveas(dirpath)
24
43
  :action => :save,
25
44
  :buttons => [["Save", :accept],
26
45
  ["Cancel", :cancel]])
27
- # dialog.set_current_folder(dirpath) #TODO:gtk4
46
+ dialog.set_current_folder(Gio::File.new_for_path(dirpath))
28
47
  dialog.signal_connect("response") do |dialog, response_id|
29
48
  if response_id == Gtk::ResponseType::ACCEPT
30
49
  file_saveas(dialog.file.parse_name)
@@ -36,32 +55,6 @@ def gui_file_saveas(dirpath)
36
55
  dialog.show
37
56
  end
38
57
 
39
- def idle_func
40
- # debug "IDLEFUNC"
41
- if $idle_scroll_to_mark
42
- # $view.get_visible_rect
43
- vr = $view.visible_rect
44
-
45
- # iter = b.get_iter_at(:offset => i)
46
-
47
- b = $view.buffer
48
- iter = b.get_iter_at(:offset => b.cursor_position)
49
- iterxy = $view.get_iter_location(iter)
50
- # debug "ITERXY" + iterxy.inspect
51
-
52
- intr = iterxy.intersect(vr)
53
- if intr.nil?
54
- $view.set_cursor_pos($view.buffer.cursor_position)
55
- else
56
- $idle_scroll_to_mark = false
57
- end
58
-
59
- sleep(0.1)
60
- end
61
- sleep(0.01)
62
- return true
63
- end
64
-
65
58
  def center_on_current_line()
66
59
  b = $view.buffer
67
60
  iter = b.get_iter_at(:offset => b.cursor_position)
@@ -80,20 +73,15 @@ def get_visible_area()
80
73
  return [startpos, endpos]
81
74
  end
82
75
 
83
- def page_up
84
- $view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), -1, false)
85
- return true
86
- end
87
-
88
- def page_down
89
- $view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), 1, false)
90
- return true
91
- end
92
-
76
+ # def page_up
77
+ # $view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), -1, false)
78
+ # return true
79
+ # end
93
80
 
94
- def set_system_clipboard(arg)
95
- vma.gui.window.display.clipboard.set(arg)
96
- end
81
+ # def page_down
82
+ # $view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), 1, false)
83
+ # return true
84
+ # end
97
85
 
98
86
  def gui_create_buffer(id, bufo)
99
87
  debug "gui_create_buffer(#{id})"
@@ -101,7 +89,6 @@ def gui_create_buffer(id, bufo)
101
89
  view = VSourceView.new(nil, bufo)
102
90
 
103
91
  view.register_signals()
104
- $debug = true
105
92
 
106
93
  ssm = GtkSource::StyleSchemeManager.new
107
94
  ssm.set_search_path(ssm.search_path << ppath("styles/"))
@@ -115,7 +102,8 @@ def gui_create_buffer(id, bufo)
115
102
  view.set_buffer(buf1)
116
103
 
117
104
  provider = Gtk::CssProvider.new
118
- provider.load(data: "textview { font-family: Monospace; font-size: 11pt; }")
105
+
106
+ provider.load(data: "textview { font-family: #{cnf.font.family!}; font-size: #{cnf.font.size!}pt; }")
119
107
  view.style_context.add_provider(provider)
120
108
  view.wrap_mode = :char
121
109
  view.set_tab_width(conf(:tab_width))
@@ -143,7 +131,8 @@ end
143
131
 
144
132
  def gui_set_buffer_contents(id, txt)
145
133
  debug "gui_set_buffer_contents(#{id}, txt)"
146
- vma.gui.buffers[id].buffer.set_text(txt)
134
+ # vma.gui.buffers[id].buffer.set_text(txt)
135
+ vma.gui.buffers[id].set_content(txt)
147
136
  end
148
137
 
149
138
  #TODO: remove
@@ -164,7 +153,7 @@ def gui_set_window_title(wtitle, subtitle = "")
164
153
  end
165
154
 
166
155
  class VMAgui
167
- attr_accessor :buffers, :sw, :sw1, :sw2, :view, :buf1, :window, :delex, :statnfo, :overlay, :overlay1, :overlay2, :sws, :two_c
156
+ attr_accessor :buffers, :sw, :sw1, :sw2, :view, :buf1, :window, :delex, :statnfo, :overlay, :sws, :two_c
168
157
  attr_reader :two_column, :windows, :subtitle, :app
169
158
 
170
159
  def initialize()
@@ -356,7 +345,6 @@ class VMAgui
356
345
  overlay = Gtk::Overlay.new
357
346
  overlay.set_child(sw)
358
347
  @vbox.attach(overlay, 0, 3, 2, 1)
359
- $sw2 = sw
360
348
  sw.set_size_request(-1, 12)
361
349
 
362
350
  view = VSourceView.new(nil, nil)
@@ -494,8 +482,8 @@ class VMAgui
494
482
  end
495
483
  }
496
484
  if to_remove.size > 0
497
- puts "Removing controllers:"
498
- pp to_remove
485
+ # debug "Removing controllers:"
486
+ # pp to_remove
499
487
  to_remove.each { |x| @window.remove_controller(x) }
500
488
  end
501
489
 
@@ -509,7 +497,7 @@ class VMAgui
509
497
  name = Gdk::Keyval.to_name(keyval)
510
498
  uki = Gdk::Keyval.to_unicode(keyval)
511
499
  keystr = uki.chr("UTF-8")
512
- puts "key-pressed #{keyval} #{keycode} name:#{name} str:#{keystr} unicode:#{uki}"
500
+ debug "key pressed #{keyval} #{keycode} name:#{name} str:#{keystr} unicode:#{uki}"
513
501
  buf.view.handle_key_event(keyval, keystr, :key_press)
514
502
  true
515
503
  end
@@ -530,19 +518,16 @@ class VMAgui
530
518
  # button1_mask?
531
519
  # ...
532
520
  # button5_mask?
533
- true
521
+ true # = handled, do not propagate further
534
522
  end
535
523
 
536
524
  press.signal_connect "key-released" do |gesture, keyval, keycode, y|
537
525
  name = Gdk::Keyval.to_name(keyval)
538
526
  uki = Gdk::Keyval.to_unicode(keyval)
539
527
  keystr = uki.chr("UTF-8")
540
- puts "key released #{keyval} #{keycode} name:#{name} str:#{keystr} unicode:#{uki}"
528
+ debug "key released #{keyval} #{keycode} name:#{name} str:#{keystr} unicode:#{uki}"
541
529
  buf.view.handle_key_event(keyval, keystr, :key_release)
542
- # vma.kbd.match_key_conf(keystr, nil, :key_press)
543
- # buf.view.handle_deltas
544
- # buf.view.handle_key_event(keyval, keystr, :key_press)
545
- true
530
+ true # = handled, do not propagate further
546
531
  end
547
532
  end
548
533
 
@@ -556,8 +541,8 @@ class VMAgui
556
541
  end
557
542
  }
558
543
  if to_remove.size > 0
559
- puts "Removing controllers:"
560
- pp to_remove
544
+ # puts "Removing controllers:"
545
+ # pp to_remove
561
546
  to_remove.each { |x| vma.gui.window.remove_controller(x) }
562
547
  end
563
548
  end
@@ -567,9 +552,8 @@ class VMAgui
567
552
  sleep 0.1
568
553
  width = @window.width / 2
569
554
  height = @window.height - 5
570
- # Ripl.start :binding => binding
571
555
  @window.unmaximize
572
- @window.set_size_request(width, height)
556
+ @window.set_default_size(width, height)
573
557
  return false
574
558
  end
575
559
 
@@ -604,7 +588,6 @@ class VMAgui
604
588
  @sw = Gtk::ScrolledWindow.new
605
589
  @sw.set_policy(:automatic, :automatic)
606
590
 
607
-
608
591
  @last_adj_time = Time.now
609
592
  @sw.vadjustment.signal_connect("value-changed") { |x|
610
593
  # pp x.page_increment
@@ -614,17 +597,10 @@ class VMAgui
614
597
  # pp x.value
615
598
  # pp x
616
599
  @last_adj_time = Time.now
617
- # puts "@sw.vadjustment"
618
600
  }
619
601
 
620
- # @sw.signal_connect("clicked") { puts "Hello World!" }
621
- # @sw.signal_connect("key-pressed") { puts "Hello World!" }
622
602
  @overlay = Gtk::Overlay.new
623
- # @overlay.add(@sw) #TODO:gtk4
624
- @overlay.add_overlay(@sw) #TODO:gtk4
625
- @overlay1 = @overlay
626
-
627
- # init_header_bar #TODO:gtk4
603
+ @overlay.add_overlay(@sw)
628
604
 
629
605
  @statnfo = Gtk::Label.new
630
606
  @subtitle = Gtk::Label.new("")
@@ -652,8 +628,6 @@ class VMAgui
652
628
 
653
629
  init_minibuffer
654
630
 
655
- # p = Gtk::Popover.new
656
-
657
631
  name = "save"
658
632
  window = @window
659
633
  action = Gio::SimpleAction.new(name)
@@ -690,16 +664,6 @@ class VMAgui
690
664
 
691
665
  @window.show
692
666
 
693
- press = Gtk::GestureClick.new
694
- press.button = Gdk::BUTTON_SECONDARY
695
- @window.add_controller(press)
696
- press.signal_connect "pressed" do |gesture, n_press, x, y|
697
- puts "FOOBARpressed"
698
- # clear_surface(surface)
699
- # drawing_area.queue_draw
700
- end
701
- @sw1 = @sw
702
-
703
667
  prov = Gtk::CssProvider.new
704
668
  # See gtk-4.9.4/gtk/theme/Default/_common.scss on how to theme
705
669
  # gtksourceview/gtksourcestyleschemepreview.c
@@ -725,6 +689,7 @@ class VMAgui
725
689
  min-width: 15px;
726
690
  }
727
691
 
692
+ popover background > contents { padding: 8px; border-radius: 20px; }
728
693
  ")
729
694
  @window.style_context.add_provider(prov)
730
695
 
@@ -744,6 +709,28 @@ class VMAgui
744
709
  Vimamsa::Menu.new(@menubar, @app)
745
710
  end
746
711
 
712
+ def toggle_two_column
713
+ if @two_column
714
+ set_one_column
715
+ else
716
+ set_two_column
717
+ end
718
+ end
719
+
720
+ def set_one_column
721
+ return if !@two_column
722
+ @windows[2][:sw].set_child(nil)
723
+ @windows.delete(2)
724
+
725
+ @pane.set_start_child(nil)
726
+ @pane.set_end_child(nil)
727
+
728
+ @vbox.remove(@pane)
729
+ @vbox.attach(@overlay, 0, 2, 2, 1)
730
+ @vbox.attach(@statbox, 1, 1, 1, 1)
731
+ @two_column = false
732
+ end
733
+
747
734
  def set_two_column
748
735
  return if @two_column
749
736
  # @window.set_default_size(800, 600) #TODO:gtk4
@@ -761,10 +748,10 @@ class VMAgui
761
748
 
762
749
  @vbox.remove(@overlay)
763
750
 
764
- # numbers: left, top, width, height
765
751
  @pane.set_start_child(@overlay2)
766
752
  @pane.set_end_child(@overlay)
767
753
 
754
+ # numbers: left, top, width, height
768
755
  @vbox.attach(@pane, 0, 2, 2, 1)
769
756
 
770
757
  @sw2.vexpand = true
@@ -776,8 +763,8 @@ class VMAgui
776
763
  @sw2.show
777
764
  @two_column = true
778
765
 
779
- if vma.buffers.size > 1
780
- last = vma.buffers.get_last_visited_id
766
+ last = vma.buffers.get_last_visited_id
767
+ if !last.nil?
781
768
  set_buffer_to_window(last, 2)
782
769
  else
783
770
  bf = create_new_buffer "\n\n", "buff", false
@@ -862,19 +849,53 @@ class VMAgui
862
849
  $vbuf = buf1
863
850
 
864
851
  # Check if buffer is already open in another column
865
- if @two_column and @active_column == 2 and id == @sw1.child.bufo.id
852
+ if @two_column and @active_column == 2 and id == @windows[1][:sw].child.bufo.id
866
853
  toggle_active_window
867
- elsif @two_column && @active_column == 1 && !@sw2.child.nil? && id == @sw2.child.bufo.id
854
+ elsif @two_column && @active_column == 1 && !@windows[2][:sw].child.nil? && id == @windows[2][:sw].child.bufo.id
868
855
  #TODO: should not need !@sw2.child.nil? here. If this happens then other column is empty.
869
856
  toggle_active_window
870
857
  else
858
+ #TODO: improve
859
+ @overlay.remove_overlay(@sw)
860
+ @sw.set_child(nil)
861
+ # Creating a new ScrolledWindow every time to avoid a layout bug
862
+ # https://gitlab.gnome.org/GNOME/gtk/-/issues/6189
863
+ @sw = new_scrolled_window
871
864
  @sw.set_child(view)
865
+ @overlay.add_overlay(@sw)
866
+ @active_window[:sw] = @sw
872
867
  end
873
868
  view.grab_focus
874
869
 
875
870
  idle_ensure_cursor_drawn
876
871
  end
877
872
 
873
+ def new_scrolled_window
874
+ sw = Gtk::ScrolledWindow.new
875
+ sw.set_policy(:automatic, :automatic)
876
+ @last_adj_time = Time.now
877
+ sw.vadjustment.signal_connect("value-changed") { |x|
878
+ @last_adj_time = Time.now
879
+ debug "@sw.vadjustment #{x.value}", 2
880
+ }
881
+ return sw
882
+ end
883
+
884
+ def page_down(multip: 1.0)
885
+ va = @sw.vadjustment
886
+ newval = va.value + va.page_increment * multip
887
+ va.value = newval
888
+ @sw.child.set_cursor_to_top
889
+ end
890
+
891
+ def page_up(multip: 1.0)
892
+ va = @sw.vadjustment
893
+ newval = va.value - va.page_increment * multip
894
+ newval = 0 if newval < 0
895
+ va.value = newval
896
+ @sw.child.set_cursor_to_top
897
+ end
898
+
878
899
  def idle_ensure_cursor_drawn
879
900
  run_as_idle proc { self.ensure_cursor_drawn }
880
901
  end
@@ -0,0 +1,113 @@
1
+ module Gui
2
+ def self.confirm(title, callback, param: nil)
3
+ params = {}
4
+ params["title"] = title
5
+ params["inputs"] = {}
6
+ params["inputs"]["yes_btn"] = { :label => "Yes", :type => :button, :default_focus => true }
7
+ params[:callback] = callback
8
+ PopupFormGenerator.new(params).run
9
+ end
10
+ end
11
+
12
+ module Gtk
13
+ class Frame
14
+ def margin=(a)
15
+ self.margin_bottom = a
16
+ self.margin_top = a
17
+ self.margin_end = a
18
+ self.margin_start = a
19
+ end
20
+ end
21
+
22
+ class Box
23
+ def margin=(a)
24
+ self.margin_bottom = a
25
+ self.margin_top = a
26
+ self.margin_end = a
27
+ self.margin_start = a
28
+ end
29
+ end
30
+ end
31
+
32
+ def set_margin_all(widget, m)
33
+ widget.margin_bottom = m
34
+ widget.margin_top = m
35
+ widget.margin_end = m
36
+ widget.margin_start = m
37
+ end
38
+
39
+ class OneInputAction
40
+ def initialize(main_window, title, field_label, button_title, callback, opt = {})
41
+ @window = Gtk::Window.new()
42
+ # @window.screen = main_window.screen
43
+ # @window.title = title
44
+ @window.title = ""
45
+
46
+ frame = Gtk::Frame.new()
47
+ # frame.margin = 20
48
+ @window.set_child(frame)
49
+
50
+ infolabel = Gtk::Label.new
51
+ infolabel.markup = title
52
+
53
+ vbox = Gtk::Box.new(:vertical, 8)
54
+ vbox.margin = 10
55
+ frame.set_child(vbox)
56
+
57
+ hbox = Gtk::Box.new(:horizontal, 8)
58
+ # @window.add(hbox)
59
+ vbox.pack_end(infolabel, :expand => false, :fill => false, :padding => 0)
60
+ vbox.pack_end(hbox, :expand => false, :fill => false, :padding => 0)
61
+
62
+ button = Gtk::Button.new(:label => button_title)
63
+ cancel_button = Gtk::Button.new(:label => "Cancel")
64
+
65
+ label = Gtk::Label.new(field_label)
66
+
67
+ @entry1 = Gtk::Entry.new
68
+
69
+ if opt[:hide]
70
+ @entry1.visibility = false
71
+ end
72
+
73
+ button.signal_connect "clicked" do
74
+ callback.call(@entry1.text)
75
+ @window.destroy
76
+ end
77
+
78
+ cancel_button.signal_connect "clicked" do
79
+ @window.destroy
80
+ end
81
+
82
+ press = Gtk::EventControllerKey.new
83
+ press.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
84
+ @window.add_controller(press)
85
+ press.signal_connect "key-pressed" do |gesture, keyval, keycode, y|
86
+ if keyval == Gdk::Keyval::KEY_Return
87
+ callback.call(@entry1.text)
88
+ @window.destroy
89
+ true
90
+ elsif keyval == Gdk::Keyval::KEY_Escape
91
+ @window.destroy
92
+ true
93
+ else
94
+ false
95
+ end
96
+ end
97
+
98
+ hbox.pack_end(label, :expand => false, :fill => false, :padding => 0)
99
+ hbox.pack_end(@entry1, :expand => false, :fill => false, :padding => 0)
100
+ hbox.pack_end(button, :expand => false, :fill => false, :padding => 0)
101
+ hbox.pack_end(cancel_button, :expand => false, :fill => false, :padding => 0)
102
+ return
103
+ end
104
+
105
+ def run
106
+ if !@window.visible?
107
+ @window.show
108
+ else
109
+ @window.destroy
110
+ end
111
+ @window
112
+ end
113
+ end
@@ -31,6 +31,9 @@ module Vimamsa
31
31
  add_to_menu "Edit.Redo", { :label => "Redo edit", :action => :edit_redo }
32
32
  add_to_menu "Edit.SearchReplace", { :label => "Search and replace", :action => :gui_search_replace }
33
33
  add_to_menu "Edit.Find", { :label => "Find", :action => :find_in_buffer }
34
+
35
+ add_to_menu "Edit.StartCompletion", { :label => "StartCompletion", :action => :start_autocomplete }
36
+ add_to_menu "Edit.ShowCompletion", { :label => "ShowCompletion", :action => :show_autocomplete }
34
37
 
35
38
  add_to_menu "Actions.SearchForActions", { :label => "Search for Actions", :action => :search_actions }
36
39
 
@@ -44,8 +47,9 @@ module Vimamsa
44
47
  add_to_menu "Actions.experimental.DisableDebug", { :label => "Disable debug", :action => :disable_debug }
45
48
  add_to_menu "Actions.experimental.ShowImages", { :label => "Show images ⟦img:path⟧", :action => :show_images }
46
49
 
50
+ add_to_menu "Actions.debug.dumpkbd", { :label => "Dump kbd state", :action => :kbd_dump_state }
47
51
 
48
- add_to_menu "View.TwoColumn", { :label => "Start two column mode", :action => :toggle_two_column }
52
+ add_to_menu "View.TwoColumn", { :label => "Toggle two column mode", :action => :toggle_two_column }
49
53
 
50
54
 
51
55
  add_to_menu "Actions.EncryptFile", { :label => "Encrypt file", :action => :encrypt_file }
@@ -1,6 +1,6 @@
1
1
  # class VSourceView < Gtk::TextView
2
2
  class VSourceView < GtkSource::View
3
- attr_accessor :bufo
3
+ attr_accessor :bufo, :autocp_active, :cpl_list
4
4
  # :highlight_matching_brackets
5
5
 
6
6
  # def set_highlight_current_line(vbool)
@@ -18,7 +18,7 @@ class VSourceView < GtkSource::View
18
18
  @highlight_matching_brackets = true
19
19
  @idle_func_running = false
20
20
  super()
21
- @bufo = bufo #object of Buffer class buffer.rb
21
+ @bufo = bufo #object of Buffer class (buffer.rb)
22
22
  debug "vsource init"
23
23
  @last_keyval = nil
24
24
  @last_event = [nil, nil]
@@ -45,13 +45,14 @@ class VSourceView < GtkSource::View
45
45
  # true
46
46
  # end
47
47
 
48
+ # signal_connect("show-completion") do |x, y, z|
49
+ # debug "SHOW-COMPLETION", 2
50
+ # false
51
+ # end
52
+
48
53
  # Mainly after page-up or page-down
49
54
  signal_connect("move-cursor") do |widget, event|
50
55
  if event.name == "GTK_MOVEMENT_PAGES" and (last_action == "page_up" or last_action == "page_down")
51
- # Ripl.start :binding => binding
52
-
53
- debug("MOVE-CURSOR", 2)
54
- # $update_cursor = true
55
56
  handle_scrolling()
56
57
  end
57
58
 
@@ -77,6 +78,11 @@ class VSourceView < GtkSource::View
77
78
  @curpos_mark = nil
78
79
  end
79
80
 
81
+ def set_content(str)
82
+ delete_cursorchar
83
+ self.buffer.set_text(str)
84
+ end
85
+
80
86
  def gutter_width()
81
87
  winwidth = width
82
88
  view_width = visible_rect.width
@@ -106,8 +112,6 @@ class VSourceView < GtkSource::View
106
112
  end
107
113
  }
108
114
  if to_remove.size > 0
109
- debug "Removing controllers:"
110
- pp to_remove
111
115
  to_remove.each { |x|
112
116
  # To avoid GC. https://github.com/ruby-gnome/ruby-gnome/issues/15790
113
117
  @removed_controllers << x
@@ -138,17 +142,17 @@ class VSourceView < GtkSource::View
138
142
  i = coord_to_iter(x, y, true)
139
143
  pp i
140
144
  @range_start = i
141
- if !buf.visual_mode?
142
- buf.start_visual_mode
143
- end
145
+ buf.start_selection
144
146
  end
145
147
 
146
148
  @cnt_drag.signal_connect "drag-end" do |gesture, offsetx, offsety|
147
149
  debug "drag-end", 2
148
-
149
- # Not enough drag
150
150
  if offsetx.abs < 5 and offsety.abs < 5
151
- buf.end_visual_mode
151
+ debug "Not enough drag",2
152
+ @range_start = nil
153
+ elsif !buf.visual_mode? and vma.kbd.get_scope != :editor
154
+ # Can't transition from editor wide mode to buffer specific mode
155
+ buf.start_visual_mode
152
156
  end
153
157
  @range_start = nil
154
158
  end
@@ -228,6 +232,7 @@ class VSourceView < GtkSource::View
228
232
  end
229
233
 
230
234
  def handle_scrolling()
235
+ return # TODO
231
236
  delete_cursorchar
232
237
  # curpos = buffer.cursor_position
233
238
  # debug "MOVE CURSOR: #{curpos}"
@@ -247,6 +252,19 @@ class VSourceView < GtkSource::View
247
252
  }
248
253
  end
249
254
 
255
+ def set_cursor_to_top
256
+ debug "set_cursor_to_top", 2
257
+ delete_cursorchar
258
+ bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
259
+ if !bc.nil?
260
+ i = coord_to_iter(bc[0], bc[1])
261
+ if !i.nil?
262
+ @bufo.set_pos(i)
263
+ set_cursor_pos(i)
264
+ end
265
+ end
266
+ end
267
+
250
268
  # def handle_key_event(event, sig)
251
269
  def handle_key_event(keyval, keyname, sig)
252
270
  delete_cursorchar
@@ -291,6 +309,7 @@ class VSourceView < GtkSource::View
291
309
  keyval_trans[Gdk::Keyval::KEY_Shift_L] = "shift"
292
310
  keyval_trans[Gdk::Keyval::KEY_Shift_R] = "shift"
293
311
  keyval_trans[Gdk::Keyval::KEY_Tab] = "tab"
312
+ keyval_trans[Gdk::Keyval::KEY_ISO_Left_Tab] = "tab"
294
313
 
295
314
  key_trans = {}
296
315
  key_trans["\e"] = "esc"
@@ -311,10 +330,12 @@ class VSourceView < GtkSource::View
311
330
  key_str_parts.delete_at(0)
312
331
  end
313
332
 
314
- if key_str_parts[0] == "shift" and key_str_parts[1].class == String
315
- #"shift-P" to just "P"
316
- # key_str_parts.delete_at(0) if key_str_parts[1].match(/^[[:upper:]]$/)
317
- key_str_parts.delete_at(0)
333
+ if key_str_parts[0] == "shift" and key_str_parts.size == 2
334
+ if key_str_parts[1].size == 1 # and key_str_parts[1].match(/^[[:upper:]]$/)
335
+ #"shift-P" to just "P" etc.
336
+ # but keep shift-tab as is
337
+ key_str_parts.delete_at(0)
338
+ end
318
339
  end
319
340
 
320
341
  key_str = key_str_parts.join("-")
@@ -365,6 +386,10 @@ class VSourceView < GtkSource::View
365
386
  return [x, y]
366
387
  end
367
388
 
389
+ def cur_pos_xy
390
+ return pos_to_coord(buffer.cursor_position)
391
+ end
392
+
368
393
  def handle_deltas()
369
394
  delete_cursorchar
370
395
  any_change = false
@@ -408,7 +433,6 @@ class VSourceView < GtkSource::View
408
433
 
409
434
  def set_cursor_pos(pos)
410
435
  delete_cursorchar
411
- # return
412
436
  itr = buffer.get_iter_at(:offset => pos)
413
437
  itr2 = buffer.get_iter_at(:offset => pos + 1)
414
438
  buffer.place_cursor(itr)
@@ -433,13 +457,9 @@ class VSourceView < GtkSource::View
433
457
  end
434
458
 
435
459
  def cursor_visible_idle_func
460
+ # return false
436
461
  debug "cursor_visible_idle_func"
437
462
  # From https://picheta.me/articles/2013/08/gtk-plus--a-method-to-guarantee-scrolling.html
438
- # vr = visible_rect
439
-
440
- # b = $view.buffer
441
- # iter = buffer.get_iter_at(:offset => buffer.cursor_position)
442
- # iterxy = get_iter_location(iter)
443
463
 
444
464
  # This is not the current buffer
445
465
  return false if vma.gui.view != self
@@ -483,16 +503,13 @@ class VSourceView < GtkSource::View
483
503
  end
484
504
 
485
505
  def ensure_cursor_visible
486
- return #TODO:gtk4
506
+ # return
487
507
  debug "@idle_func_running=#{@idle_func_running}"
488
508
  return if @idle_func_running
489
509
  if is_cursor_visible == false
490
510
  @idle_func_running = true
491
511
  debug "Starting idle func"
492
- Thread.new {
493
- sleep 0.01
494
- GLib::Idle.add(proc { cursor_visible_idle_func })
495
- }
512
+ GLib::Idle.add(proc { cursor_visible_idle_func })
496
513
  end
497
514
  end
498
515