vimamsa 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|