vimamsa 0.1.10 → 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 +20 -3
- data/custom_example.rb +11 -1
- data/demo.txt +2 -2
- data/exe/vimamsa +1 -1
- data/lib/vimamsa/ack.rb +57 -9
- data/lib/vimamsa/actions.rb +1 -1
- data/lib/vimamsa/buffer.rb +272 -44
- data/lib/vimamsa/buffer_list.rb +57 -16
- data/lib/vimamsa/buffer_manager.rb +19 -3
- data/lib/vimamsa/conf.rb +10 -1
- data/lib/vimamsa/debug.rb +7 -3
- data/lib/vimamsa/easy_jump.rb +9 -5
- data/lib/vimamsa/editor.rb +55 -41
- data/lib/vimamsa/file_finder.rb +70 -72
- data/lib/vimamsa/file_history.rb +2 -3
- data/lib/vimamsa/file_manager.rb +1 -1
- data/lib/vimamsa/form_generator.rb +122 -0
- data/lib/vimamsa/gui.rb +467 -120
- 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 +171 -78
- data/lib/vimamsa/hyper_plain_text.rb +34 -1
- data/lib/vimamsa/key_actions.rb +13 -1
- data/lib/vimamsa/key_binding_tree.rb +26 -14
- 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 +0 -1
- data/lib/vimamsa/rbvma.rb +7 -4
- data/lib/vimamsa/search.rb +2 -1
- data/lib/vimamsa/search_replace.rb +36 -106
- 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 +24 -22
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,73 +1,56 @@
|
|
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
15
|
# def initialize(title = nil,bufo=nil)
|
19
|
-
def initialize(title,bufo)
|
16
|
+
def initialize(title, bufo)
|
20
17
|
# super(:toplevel)
|
21
18
|
@highlight_matching_brackets = true
|
19
|
+
@idle_func_running = false
|
22
20
|
super()
|
23
21
|
@bufo = bufo #object of Buffer class buffer.rb
|
24
22
|
debug "vsource init"
|
25
23
|
@last_keyval = nil
|
26
24
|
@last_event = [nil, nil]
|
27
|
-
|
28
|
-
self.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
imgpath = CGI.unescape(data.uris[0])
|
47
|
-
m = imgpath.match(/^file:\/\/(.*)/)
|
48
|
-
if m
|
49
|
-
fp = m[1]
|
50
|
-
handle_drag_and_drop(fp)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
true
|
54
|
-
end
|
55
|
-
|
56
|
-
signal_connect("key_press_event") do |widget, event|
|
57
|
-
handle_key_event(event, :key_press_event)
|
58
|
-
true
|
59
|
-
end
|
60
|
-
|
61
|
-
signal_connect("key_release_event") do |widget, event|
|
62
|
-
handle_key_event(event, :key_release_event)
|
63
|
-
true
|
64
|
-
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
|
65
44
|
|
66
45
|
signal_connect("move-cursor") do |widget, event|
|
46
|
+
debug("MOVE-CURSOR",2)
|
67
47
|
$update_cursor = true
|
68
48
|
false
|
69
49
|
end
|
70
50
|
|
51
|
+
return
|
52
|
+
|
53
|
+
#TODO:gtk4
|
71
54
|
signal_connect "button-release-event" do |widget, event|
|
72
55
|
vma.buf.set_pos(buffer.cursor_position)
|
73
56
|
false
|
@@ -75,7 +58,78 @@ class VSourceView < GtkSource::View
|
|
75
58
|
@curpos_mark = nil
|
76
59
|
end
|
77
60
|
|
78
|
-
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)
|
79
133
|
if $update_cursor
|
80
134
|
curpos = buffer.cursor_position
|
81
135
|
debug "MOVE CURSOR: #{curpos}"
|
@@ -85,13 +139,14 @@ class VSourceView < GtkSource::View
|
|
85
139
|
debug $view.visible_rect.inspect
|
86
140
|
|
87
141
|
debug "key event"
|
88
|
-
debug event
|
142
|
+
# debug event
|
89
143
|
|
90
|
-
key_name = event.string
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
95
150
|
|
96
151
|
keyval_trans = {}
|
97
152
|
keyval_trans[Gdk::Keyval::KEY_Control_L] = "ctrl"
|
@@ -122,29 +177,48 @@ class VSourceView < GtkSource::View
|
|
122
177
|
|
123
178
|
key_trans = {}
|
124
179
|
key_trans["\e"] = "esc"
|
125
|
-
tk = keyval_trans[
|
126
|
-
|
180
|
+
tk = keyval_trans[keyval]
|
181
|
+
keyname = tk if !tk.nil?
|
127
182
|
|
128
183
|
key_str_parts = []
|
129
|
-
key_str_parts << "ctrl" if
|
130
|
-
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
|
131
202
|
|
132
|
-
key_str_parts << key_name
|
133
203
|
key_str = key_str_parts.join("-")
|
134
|
-
|
204
|
+
if key_str == "\u0000"
|
205
|
+
key_str = ""
|
206
|
+
end
|
207
|
+
|
208
|
+
keynfo = { :key_str => key_str, :key_name => keyname, :keyval => keyval }
|
135
209
|
debug keynfo.inspect
|
136
210
|
# $kbd.match_key_conf(key_str, nil, :key_press)
|
137
211
|
# debug "key_str=#{key_str} key_"
|
138
212
|
|
139
213
|
if key_str != "" # or prefixed_key_str != ""
|
140
|
-
if sig == :
|
214
|
+
if sig == :key_release and keyval == @last_keyval
|
141
215
|
$kbd.match_key_conf(key_str + "!", nil, :key_release)
|
142
|
-
@last_event = [
|
143
|
-
elsif sig == :
|
216
|
+
@last_event = [keynfo, :key_release]
|
217
|
+
elsif sig == :key_press
|
144
218
|
$kbd.match_key_conf(key_str, nil, :key_press)
|
145
|
-
@last_event = [
|
219
|
+
@last_event = [keynfo, key_str, :key_press]
|
146
220
|
end
|
147
|
-
@last_keyval =
|
221
|
+
@last_keyval = keyval #TODO: outside if?
|
148
222
|
end
|
149
223
|
|
150
224
|
handle_deltas
|
@@ -158,7 +232,9 @@ class VSourceView < GtkSource::View
|
|
158
232
|
b = buffer
|
159
233
|
iter = b.get_iter_at(:offset => i)
|
160
234
|
iterxy = get_iter_location(iter)
|
161
|
-
winw = parent_window.width
|
235
|
+
# winw = parent_window.width #TODO:gtk4
|
236
|
+
winw = width #TODO
|
237
|
+
|
162
238
|
view_width = visible_rect.width
|
163
239
|
gutter_width = winw - view_width
|
164
240
|
|
@@ -168,7 +244,6 @@ class VSourceView < GtkSource::View
|
|
168
244
|
# buffer_to_window_coords(Gtk::TextWindowType::TEXT, iterxy.x, iterxy.y).inspect
|
169
245
|
# debug buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y).inspect
|
170
246
|
(x, y) = buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y)
|
171
|
-
# Ripl.start :binding => binding
|
172
247
|
|
173
248
|
return [x, y]
|
174
249
|
end
|
@@ -191,7 +266,8 @@ class VSourceView < GtkSource::View
|
|
191
266
|
end
|
192
267
|
end
|
193
268
|
if any_change
|
194
|
-
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)
|
195
271
|
end
|
196
272
|
|
197
273
|
# sanity_check #TODO
|
@@ -237,7 +313,6 @@ class VSourceView < GtkSource::View
|
|
237
313
|
# scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
|
238
314
|
|
239
315
|
# $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
|
240
|
-
# Ripl.start :binding => binding
|
241
316
|
draw_cursor
|
242
317
|
|
243
318
|
return true
|
@@ -252,6 +327,9 @@ class VSourceView < GtkSource::View
|
|
252
327
|
# iter = buffer.get_iter_at(:offset => buffer.cursor_position)
|
253
328
|
# iterxy = get_iter_location(iter)
|
254
329
|
|
330
|
+
# This is not the current buffer
|
331
|
+
return false if vma.gui.view != self
|
332
|
+
|
255
333
|
sleep(0.01)
|
256
334
|
# intr = iterxy.intersect(vr)
|
257
335
|
if is_cursor_visible == false
|
@@ -266,8 +344,9 @@ class VSourceView < GtkSource::View
|
|
266
344
|
|
267
345
|
scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
|
268
346
|
|
269
|
-
|
347
|
+
return true # Call this func again
|
270
348
|
else
|
349
|
+
@idle_func_running = false
|
271
350
|
return false # Don't call this idle func again
|
272
351
|
end
|
273
352
|
end
|
@@ -283,9 +362,6 @@ class VSourceView < GtkSource::View
|
|
283
362
|
if intr.nil?
|
284
363
|
debug iterxy.inspect
|
285
364
|
debug vr.inspect
|
286
|
-
# Ripl.start :binding => binding
|
287
|
-
|
288
|
-
# exit!
|
289
365
|
return false
|
290
366
|
else
|
291
367
|
return true
|
@@ -293,7 +369,12 @@ class VSourceView < GtkSource::View
|
|
293
369
|
end
|
294
370
|
|
295
371
|
def ensure_cursor_visible
|
372
|
+
return #TODO:gtk4
|
373
|
+
debug "@idle_func_running=#{@idle_func_running}"
|
374
|
+
return if @idle_func_running
|
296
375
|
if is_cursor_visible == false
|
376
|
+
@idle_func_running = true
|
377
|
+
debug "Starting idle func"
|
297
378
|
Thread.new {
|
298
379
|
sleep 0.01
|
299
380
|
GLib::Idle.add(proc { cursor_visible_idle_func })
|
@@ -302,21 +383,33 @@ class VSourceView < GtkSource::View
|
|
302
383
|
end
|
303
384
|
|
304
385
|
def draw_cursor
|
305
|
-
|
386
|
+
mode = vma.kbd.get_mode
|
387
|
+
ctype = vma.kbd.get_cursor_type
|
388
|
+
# if is_command_mode
|
389
|
+
if ctype == :command
|
306
390
|
itr = buffer.get_iter_at(:offset => @bufo.pos)
|
307
391
|
itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
|
308
|
-
|
309
|
-
|
392
|
+
buffer.select_range(itr, itr2)
|
393
|
+
# elsif @bufo.visual_mode?
|
394
|
+
elsif ctype == :visual
|
310
395
|
debug "VISUAL MODE"
|
311
396
|
(_start, _end) = @bufo.get_visual_mode_range2
|
312
397
|
debug "#{_start}, #{_end}"
|
313
398
|
itr = buffer.get_iter_at(:offset => _start)
|
314
399
|
itr2 = buffer.get_iter_at(:offset => _end + 1)
|
315
|
-
|
316
|
-
|
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
|
317
404
|
itr = buffer.get_iter_at(:offset => @bufo.pos)
|
318
|
-
|
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
|
+
|
319
411
|
debug "INSERT MODE"
|
412
|
+
else # TODO
|
320
413
|
end
|
321
414
|
end
|
322
415
|
end
|
@@ -51,6 +51,35 @@ def translate_path(fn, bf)
|
|
51
51
|
return outfn
|
52
52
|
end
|
53
53
|
|
54
|
+
# Scan audio files inserted with ⟦audio:filepath⟧ syntax
|
55
|
+
#TODO: merge code with hpt_scan_images
|
56
|
+
def hpt_scan_audio(bf = nil)
|
57
|
+
bf = buf() if bf.nil?
|
58
|
+
return if bf.nil?
|
59
|
+
return if !bf.fname
|
60
|
+
return if !bf.fname.match(/.*txt$/)
|
61
|
+
imgpos = scan_indexes(bf, /⟦audio:.+?⟧/)
|
62
|
+
imgtags = bf.scan(/(⟦audio:(.+?)⟧)/)
|
63
|
+
c = 0
|
64
|
+
imgpos.each.with_index { |x, i|
|
65
|
+
a = imgpos[i]
|
66
|
+
t = imgtags[i]
|
67
|
+
insert_pos = a + t[0].size + c
|
68
|
+
fn = t[1]
|
69
|
+
imgfn = translate_path(fn, bf)
|
70
|
+
next if !File.exist?(imgfn)
|
71
|
+
# Show as image in gui, handle as empty space in txt file
|
72
|
+
|
73
|
+
if bf[insert_pos..(insert_pos + 2)] != "\n \n"
|
74
|
+
bf.insert_txt_at("\n \n", insert_pos)
|
75
|
+
bf.view.handle_deltas
|
76
|
+
c += 3
|
77
|
+
end
|
78
|
+
bf.add_audio(imgfn, insert_pos + 1)
|
79
|
+
}
|
80
|
+
# vma.gui.delex.run #TODO:gtk4
|
81
|
+
end
|
82
|
+
|
54
83
|
# Scan images inserted with ⟦img:filepath⟧ syntax
|
55
84
|
def hpt_scan_images(bf = nil)
|
56
85
|
bf = buf() if bf.nil?
|
@@ -76,5 +105,9 @@ def hpt_scan_images(bf = nil)
|
|
76
105
|
end
|
77
106
|
bf.add_image(imgfn, insert_pos + 1)
|
78
107
|
}
|
79
|
-
|
108
|
+
|
109
|
+
# Need to scale after buffer loaded
|
110
|
+
GLib::Idle.add(proc { vma.gui.scale_all_images })
|
111
|
+
|
112
|
+
# vma.gui.delex.run #TODO:gtk4
|
80
113
|
end
|