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.
- checksums.yaml +4 -4
- data/README.md +29 -7
- data/custom_example.rb +12 -2
- data/demo.txt +2 -2
- data/exe/vimamsa +1 -1
- data/lib/vimamsa/ack.rb +57 -46
- data/lib/vimamsa/actions.rb +1 -1
- data/lib/vimamsa/buffer.rb +287 -55
- data/lib/vimamsa/buffer_list.rb +83 -48
- data/lib/vimamsa/buffer_manager.rb +19 -3
- data/lib/vimamsa/conf.rb +10 -1
- data/lib/vimamsa/debug.rb +15 -11
- data/lib/vimamsa/easy_jump.rb +9 -5
- data/lib/vimamsa/editor.rb +73 -54
- data/lib/vimamsa/encrypt.rb +2 -2
- data/lib/vimamsa/file_finder.rb +70 -72
- data/lib/vimamsa/file_history.rb +2 -3
- data/lib/vimamsa/file_manager.rb +10 -8
- data/lib/vimamsa/form_generator.rb +122 -0
- data/lib/vimamsa/gui.rb +469 -118
- data/lib/vimamsa/gui_image.rb +12 -6
- data/lib/vimamsa/gui_menu.rb +26 -21
- data/lib/vimamsa/gui_select_window.rb +40 -21
- data/lib/vimamsa/gui_sourceview.rb +173 -79
- data/lib/vimamsa/hyper_plain_text.rb +36 -3
- data/lib/vimamsa/key_actions.rb +13 -1
- data/lib/vimamsa/key_binding_tree.rb +32 -20
- data/lib/vimamsa/key_bindings_vimlike.rb +54 -25
- data/lib/vimamsa/langservp.rb +172 -0
- data/lib/vimamsa/macro.rb +9 -8
- data/lib/vimamsa/main.rb +3 -4
- data/lib/vimamsa/rbvma.rb +7 -4
- data/lib/vimamsa/search.rb +3 -2
- data/lib/vimamsa/search_replace.rb +50 -120
- data/lib/vimamsa/text_transforms.rb +1 -1
- data/lib/vimamsa/util.rb +47 -1
- data/lib/vimamsa/version.rb +1 -1
- data/lib/vimamsa.rb +1 -6
- data/styles/molokai_edit.xml +3 -0
- data/vimamsa.gemspec +10 -10
- metadata +22 -20
data/lib/vimamsa/gui_image.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
data/lib/vimamsa/gui_menu.rb
CHANGED
@@ -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
|
-
|
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 =
|
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
|
-
|
90
|
-
menuitem.
|
91
|
-
|
92
|
-
|
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 =
|
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.
|
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(
|
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
|
-
|
54
|
-
|
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.
|
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
|
-
|
79
|
-
|
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.
|
83
|
-
|
84
|
-
|
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
|
108
|
+
elsif keyval == Gdk::Keyval::KEY_Up
|
91
109
|
set_selected_row(@selected_row - 1)
|
92
110
|
debug "UP"
|
93
111
|
true
|
94
|
-
elsif
|
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
|
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.
|
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.
|
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
|
-
|
27
|
-
self.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
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
|
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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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[
|
125
|
-
|
180
|
+
tk = keyval_trans[keyval]
|
181
|
+
keyname = tk if !tk.nil?
|
126
182
|
|
127
183
|
key_str_parts = []
|
128
|
-
key_str_parts << "ctrl" if
|
129
|
-
key_str_parts << "alt" if
|
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
|
-
|
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 == :
|
214
|
+
if sig == :key_release and keyval == @last_keyval
|
140
215
|
$kbd.match_key_conf(key_str + "!", nil, :key_release)
|
141
|
-
@last_event = [
|
142
|
-
elsif sig == :
|
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 = [
|
219
|
+
@last_event = [keynfo, key_str, :key_press]
|
145
220
|
end
|
146
|
-
@last_keyval =
|
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
|
-
|
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
|
-
|
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
|
-
|
308
|
-
|
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
|
-
|
315
|
-
|
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
|
-
|
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
|