vimamsa 0.1.5 → 0.1.6

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.
@@ -0,0 +1,294 @@
1
+
2
+ class VSourceView < GtkSource::View
3
+ def initialize(title = nil)
4
+ # super(:toplevel)
5
+ super()
6
+ puts "vsource init"
7
+ @last_keyval = nil
8
+ @last_event = [nil, nil]
9
+
10
+ signal_connect "button-press-event" do |_widget, event|
11
+ if event.button == Gdk::BUTTON_PRIMARY
12
+ # puts "Gdk::BUTTON_PRIMARY"
13
+ false
14
+ elsif event.button == Gdk::BUTTON_SECONDARY
15
+ # puts "Gdk::BUTTON_SECONDARY"
16
+ true
17
+ else
18
+ true
19
+ end
20
+ end
21
+
22
+ signal_connect("key_press_event") do |widget, event|
23
+ handle_key_event(event, :key_press_event)
24
+ true
25
+ end
26
+
27
+ signal_connect("key_release_event") do |widget, event|
28
+ handle_key_event(event, :key_release_event)
29
+ true
30
+ end
31
+
32
+ signal_connect("move-cursor") do |widget, event|
33
+ $update_cursor = true
34
+ false
35
+ end
36
+
37
+ signal_connect "button-release-event" do |widget, event|
38
+ $buffer.set_pos(buffer.cursor_position)
39
+ false
40
+ end
41
+ @curpos_mark = nil
42
+ end
43
+
44
+ def handle_key_event(event, sig)
45
+ if $update_cursor
46
+ curpos = buffer.cursor_position
47
+ puts "MOVE CURSOR: #{curpos}"
48
+ buf.set_pos(curpos)
49
+ $update_cursor = false
50
+ end
51
+ puts $view.visible_rect.inspect
52
+
53
+ puts "key event"
54
+ puts event
55
+
56
+ key_name = event.string
57
+ if event.state.control_mask?
58
+ key_name = Gdk::Keyval.to_name(event.keyval)
59
+ # Gdk::Keyval.to_name()
60
+ end
61
+
62
+ keyval_trans = {}
63
+ keyval_trans[Gdk::Keyval::KEY_Control_L] = "ctrl"
64
+ keyval_trans[Gdk::Keyval::KEY_Control_R] = "ctrl"
65
+
66
+ keyval_trans[Gdk::Keyval::KEY_Escape] = "esc"
67
+
68
+ keyval_trans[Gdk::Keyval::KEY_Return] = "enter"
69
+ keyval_trans[Gdk::Keyval::KEY_ISO_Enter] = "enter"
70
+ keyval_trans[Gdk::Keyval::KEY_KP_Enter] = "enter"
71
+ keyval_trans[Gdk::Keyval::KEY_Alt_L] = "alt"
72
+ keyval_trans[Gdk::Keyval::KEY_Alt_R] = "alt"
73
+
74
+ keyval_trans[Gdk::Keyval::KEY_BackSpace] = "backspace"
75
+ keyval_trans[Gdk::Keyval::KEY_KP_Page_Down] = "pagedown"
76
+ keyval_trans[Gdk::Keyval::KEY_KP_Page_Up] = "pageup"
77
+ keyval_trans[Gdk::Keyval::KEY_Page_Down] = "pagedown"
78
+ keyval_trans[Gdk::Keyval::KEY_Page_Up] = "pageup"
79
+ keyval_trans[Gdk::Keyval::KEY_Left] = "left"
80
+ keyval_trans[Gdk::Keyval::KEY_Right] = "right"
81
+ keyval_trans[Gdk::Keyval::KEY_Down] = "down"
82
+ keyval_trans[Gdk::Keyval::KEY_Up] = "up"
83
+ keyval_trans[Gdk::Keyval::KEY_space] = "space"
84
+
85
+ keyval_trans[Gdk::Keyval::KEY_Shift_L] = "shift"
86
+ keyval_trans[Gdk::Keyval::KEY_Shift_R] = "shift"
87
+ keyval_trans[Gdk::Keyval::KEY_Tab] = "tab"
88
+
89
+ key_trans = {}
90
+ key_trans["\e"] = "esc"
91
+ tk = keyval_trans[event.keyval]
92
+ key_name = tk if !tk.nil?
93
+
94
+ key_str_parts = []
95
+ key_str_parts << "ctrl" if event.state.control_mask? and key_name != "ctrl"
96
+ key_str_parts << "alt" if event.state.mod1_mask? and key_name != "alt"
97
+
98
+ key_str_parts << key_name
99
+ key_str = key_str_parts.join("-")
100
+ keynfo = { :key_str => key_str, :key_name => key_name, :keyval => event.keyval }
101
+ puts keynfo.inspect
102
+ # $kbd.match_key_conf(key_str, nil, :key_press)
103
+ # puts "key_str=#{key_str} key_"
104
+
105
+ if key_str != "" # or prefixed_key_str != ""
106
+ if sig == :key_release_event and event.keyval == @last_keyval
107
+ $kbd.match_key_conf(key_str + "!", nil, :key_release)
108
+ @last_event = [event, :key_release]
109
+ elsif sig == :key_press_event
110
+ $kbd.match_key_conf(key_str, nil, :key_press)
111
+ @last_event = [event, key_str, :key_press]
112
+ end
113
+ @last_keyval = event.keyval #TODO: outside if?
114
+ end
115
+
116
+ handle_deltas
117
+
118
+ # set_focus(5)
119
+ # false
120
+
121
+ end
122
+
123
+ def pos_to_coord(i)
124
+ b = buffer
125
+ iter = b.get_iter_at(:offset => i)
126
+ iterxy = get_iter_location(iter)
127
+ winw = parent_window.width
128
+ view_width = visible_rect.width
129
+ gutter_width = winw - view_width
130
+
131
+ x = iterxy.x + gutter_width
132
+ y = iterxy.y
133
+
134
+ # buffer_to_window_coords(Gtk::TextWindowType::TEXT, iterxy.x, iterxy.y).inspect
135
+ # puts buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y).inspect
136
+ (x, y) = buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y)
137
+ # Ripl.start :binding => binding
138
+
139
+ return [x, y]
140
+ end
141
+
142
+ def handle_deltas()
143
+ any_change = false
144
+ while d = buf.deltas.shift
145
+ any_change = true
146
+ pos = d[0]
147
+ op = d[1]
148
+ num = d[2]
149
+ txt = d[3]
150
+ if op == DELETE
151
+ startiter = buffer.get_iter_at(:offset => pos)
152
+ enditer = buffer.get_iter_at(:offset => pos + num)
153
+ buffer.delete(startiter, enditer)
154
+ elsif op == INSERT
155
+ startiter = buffer.get_iter_at(:offset => pos)
156
+ buffer.insert(startiter, txt)
157
+ end
158
+ end
159
+ if any_change
160
+ gui_set_cursor_pos($buffer.id, $buffer.pos) #TODO: only when necessary
161
+ end
162
+
163
+ # sanity_check #TODO
164
+ end
165
+
166
+ def sanity_check()
167
+ a = buffer.text
168
+ b = buf.to_s
169
+ # puts "===================="
170
+ # puts a.lines[0..10].join()
171
+ # puts "===================="
172
+ # puts b.lines[0..10].join()
173
+ # puts "===================="
174
+ if a == b
175
+ puts "Buffers match"
176
+ else
177
+ puts "ERROR: Buffer's don't match."
178
+ end
179
+ end
180
+
181
+ def set_cursor_pos(pos)
182
+ # return
183
+ itr = buffer.get_iter_at(:offset => pos)
184
+ itr2 = buffer.get_iter_at(:offset => pos + 1)
185
+ buffer.place_cursor(itr)
186
+
187
+ # $view.signal_emit("extend-selection", Gtk::MovementStep.new(:PAGES), -1, false)
188
+
189
+ within_margin = 0.075 #margin as a [0.0,0.5) fraction of screen size
190
+ use_align = false
191
+ xalign = 0.5 #0.0=top 1.0=bottom, 0.5=center
192
+ yalign = 0.5
193
+
194
+ if @curpos_mark.nil?
195
+ @curpos_mark = buffer.create_mark("cursor", itr, false)
196
+ else
197
+ buffer.move_mark(@curpos_mark, itr)
198
+ end
199
+ scroll_to_mark(@curpos_mark, within_margin, use_align, xalign, yalign)
200
+ $idle_scroll_to_mark = true
201
+ ensure_cursor_visible
202
+
203
+ # scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
204
+
205
+ # $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
206
+ # Ripl.start :binding => binding
207
+ draw_cursor
208
+
209
+ return true
210
+ end
211
+
212
+ def cursor_visible_idle_func
213
+ puts "cursor_visible_idle_func"
214
+ # From https://picheta.me/articles/2013/08/gtk-plus--a-method-to-guarantee-scrolling.html
215
+ # vr = visible_rect
216
+
217
+ # b = $view.buffer
218
+ # iter = buffer.get_iter_at(:offset => buffer.cursor_position)
219
+ # iterxy = get_iter_location(iter)
220
+
221
+ sleep(0.01)
222
+ # intr = iterxy.intersect(vr)
223
+ if is_cursor_visible == false
224
+ # set_cursor_pos(buffer.cursor_position)
225
+
226
+ itr = buffer.get_iter_at(:offset => buffer.cursor_position)
227
+
228
+ within_margin = 0.075 #margin as a [0.0,0.5) fraction of screen size
229
+ use_align = false
230
+ xalign = 0.5 #0.0=top 1.0=bottom, 0.5=center
231
+ yalign = 0.5
232
+
233
+ scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
234
+
235
+ # return true # Call this func again
236
+ else
237
+ return false # Don't call this idle func again
238
+ end
239
+ end
240
+
241
+ def is_cursor_visible
242
+ vr = visible_rect
243
+ iter = buffer.get_iter_at(:offset => buffer.cursor_position)
244
+ iterxy = get_iter_location(iter)
245
+ iterxy.width = 1 if iterxy.width == 0
246
+ iterxy.height = 1 if iterxy.height == 0
247
+
248
+ intr = iterxy.intersect(vr)
249
+ if intr.nil?
250
+ puts iterxy.inspect
251
+ puts vr.inspect
252
+ # Ripl.start :binding => binding
253
+
254
+ # exit!
255
+ return false
256
+ else
257
+ return true
258
+ end
259
+ end
260
+
261
+ def ensure_cursor_visible
262
+ if is_cursor_visible == false
263
+ Thread.new {
264
+ sleep 0.01
265
+ GLib::Idle.add(proc { cursor_visible_idle_func })
266
+ }
267
+ end
268
+ end
269
+
270
+ def draw_cursor
271
+ if is_command_mode
272
+ itr = buffer.get_iter_at(:offset => buf.pos)
273
+ itr2 = buffer.get_iter_at(:offset => buf.pos + 1)
274
+ $view.buffer.select_range(itr, itr2)
275
+ elsif buf.visual_mode?
276
+ puts "VISUAL MODE"
277
+ (_start, _end) = buf.get_visual_mode_range2
278
+ puts "#{_start}, #{_end}"
279
+ itr = buffer.get_iter_at(:offset => _start)
280
+ itr2 = buffer.get_iter_at(:offset => _end + 1)
281
+ $view.buffer.select_range(itr, itr2)
282
+ else # Insert mode
283
+ itr = buffer.get_iter_at(:offset => buf.pos)
284
+ $view.buffer.select_range(itr, itr)
285
+ puts "INSERT MODE"
286
+ end
287
+ end
288
+
289
+ # def quit
290
+ # destroy
291
+ # true
292
+ # end
293
+ end
294
+
@@ -0,0 +1,100 @@
1
+ module Vimamsa
2
+ class Menu
3
+ def add_to_menu(_mpath, x)
4
+ mpath = _mpath.split(".")
5
+ curnfo = @nfo
6
+ for y in mpath
7
+ puts curnfo.inspect
8
+ if y.equal?(mpath.last)
9
+ curnfo[y] = x
10
+ elsif curnfo[y].nil?
11
+ curnfo[y] = { :label => y, :items => {} }
12
+ end
13
+ curnfo[y][:items] = {} if curnfo[y][:items].class != Hash
14
+ curnfo = curnfo[y][:items]
15
+ end #end for
16
+ end
17
+
18
+ def add_menu_items()
19
+ add_to_menu "File.Save", { :label => "Save", :action => :buf_save }
20
+ add_to_menu "File.Save as", { :label => "Save As...", :action => :buf_save_as }
21
+ add_to_menu "File.Open", { :label => "Open", :action => :open_file_dialog }
22
+
23
+ add_to_menu "File.New", { :label => "New file", :action => :buf_new }
24
+ add_to_menu "File.Revert", { :label => "Reload file from disk", :action => :buf_revert }
25
+
26
+ add_to_menu "File.Quit", { :label => "Quit", :action => :quit }
27
+
28
+ add_to_menu "Edit.Undo", { :label => "Undo edit", :action => :edit_undo }
29
+ add_to_menu "Edit.Redo", { :label => "Redo edit", :action => :edit_redo }
30
+ add_to_menu "Edit.SearchReplace", { :label => "Search and replace", :action => :gui_search_replace }
31
+ add_to_menu "Edit.Find", { :label => "Find", :action => :find_in_buffer }
32
+
33
+ add_to_menu "Actions.SearchForActions", { :label => "Search for Actions", :action => :search_actions }
34
+
35
+ add_to_menu "Actions.Grep", { :label => "Grep lines", :action => :invoke_grep_search }
36
+
37
+ add_to_menu "Actions.FileHistoryFinder", { :label => "Search files in history", :action => :gui_file_history_finder }
38
+
39
+ add_to_menu "Actions.experimental.Diff", { :label => "Show Diff of\nunsaved changes", :action => :diff_buffer }
40
+
41
+ add_to_menu "Actions.EncryptFile", { :label => "Encrypt file", :action => :encrypt_file }
42
+
43
+ #TODO: :auto_indent_buffer
44
+
45
+ # add_to_menu "Actions.Ack", { :label => "source code search (Ack)", :action => :ack_search }
46
+
47
+ end
48
+
49
+ def initialize(menubar)
50
+ # nfo["file"] = { :items => {}, :label => "File" }
51
+ # nfo["actions"] = { :items => {}, :label => "Actions" }
52
+ # nfo["help"] = { :items => {}, :label => "Help" }
53
+
54
+ @nfo = {}
55
+
56
+ add_menu_items
57
+
58
+ # add_to_menu("help.extra.keybindings", { :label => "Show keybindings" })
59
+ # add_to_menu("help.extra.nfo.keybindings", { :label => "Show keybindings" })
60
+ # add_to_menu("help.keybindings", { :label => "Show keybindings <span foreground='#888888' >C ? k</span>" }) #font='12' weight='ultrabold'
61
+
62
+ for k, v in @nfo
63
+ build_menu(v, menubar)
64
+ end
65
+ end
66
+
67
+ def build_menu(nfo, parent)
68
+ menu = Gtk::Menu.new
69
+ if nfo[:action]
70
+ kbd_str = ""
71
+ for mode_str in ["C", "V"]
72
+ c_kbd = vma.kbd.act_bindings[mode_str][nfo[:action]]
73
+ if c_kbd.class == String
74
+ kbd_str = " <span foreground='#888888'><span weight='bold'>[#{mode_str}]</span> #{c_kbd}</span>"
75
+ break
76
+ end
77
+ end
78
+
79
+ label_str = nfo[:label] + kbd_str
80
+ menuitem = Gtk::MenuItem.new(:label => label_str)
81
+ menuitem.children[0].set_markup(label_str)
82
+
83
+ menuitem.signal_connect("activate") do
84
+ call_action(nfo[:action])
85
+ end
86
+ else
87
+ menuitem = Gtk::MenuItem.new(:label => nfo[:label])
88
+ menuitem.children[0].set_markup(nfo[:label])
89
+ end
90
+
91
+ if !nfo[:items].nil? and !nfo[:items].empty?
92
+ for k2, item in nfo[:items]
93
+ build_menu(item, menu)
94
+ end
95
+ menuitem.submenu = menu
96
+ end
97
+ parent.append(menuitem)
98
+ end
99
+ end #end class
100
+ end
@@ -0,0 +1,177 @@
1
+ def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt={})
2
+ $selup = SelectUpdateWindow.new(nil, item_list, jump_keys, select_callback, update_callback, opt)
3
+ $selup.run
4
+ end
5
+
6
+ class SelectUpdateWindow
7
+ COLUMN_JUMP_KEY = 0
8
+ COLUMN_DESCRIPTION = 1
9
+
10
+ def update_item_list(item_list)
11
+ # puts item_list.inspect
12
+ @model.clear
13
+ for item in item_list
14
+ iter = @model.append
15
+ if !@opt[:columns].nil?
16
+ v = item
17
+ else
18
+ v = ["", item[0]]
19
+ end
20
+ puts v.inspect
21
+ iter.set_values(v)
22
+ end
23
+
24
+ set_selected_row(0)
25
+ end
26
+
27
+ def set_selected_row(rownum)
28
+ rownum = 0 if rownum < 0
29
+ @selected_row = rownum
30
+
31
+ if @model.count > 0
32
+ path = Gtk::TreePath.new(@selected_row.to_s)
33
+ iter = @model.get_iter(path)
34
+ @tv.selection.select_iter(iter)
35
+ end
36
+ end
37
+
38
+ def initialize(main_window, item_list, jump_keys, select_callback, update_callback, opt = {})
39
+ @window = Gtk::Window.new(:toplevel)
40
+ # @window.screen = main_window.screen
41
+ @window.title = ""
42
+ if !opt[:title].nil?
43
+ @window.title = opt[:title]
44
+ end
45
+
46
+ @selected_row = 0
47
+ @opt = opt
48
+
49
+ puts item_list.inspect
50
+ @update_callback = method(update_callback)
51
+ @select_callback = method(select_callback)
52
+ # puts @update_callback_m.call("").inspect
53
+
54
+ vbox = Gtk::Box.new(:vertical, 8)
55
+ vbox.margin = 8
56
+ @window.add(vbox)
57
+
58
+ @entry = Gtk::SearchEntry.new
59
+ @entry.width_chars = 45
60
+ container = Gtk::Box.new(:horizontal, 10)
61
+ # container.halign = :start
62
+ container.halign = :center
63
+ container.pack_start(@entry,
64
+ :expand => false, :fill => false, :padding => 0)
65
+
66
+ # create tree view
67
+ @model = Gtk::ListStore.new(String, String)
68
+ treeview = Gtk::TreeView.new(@model)
69
+ treeview.search_column = COLUMN_DESCRIPTION
70
+ @tv = treeview
71
+ # item_list = @update_callback.call("")
72
+ update_item_list(item_list)
73
+
74
+ @window.signal_connect("key-press-event") do |_widget, event|
75
+ # puts "KEYPRESS 1"
76
+ @entry.handle_event(event)
77
+ end
78
+
79
+ @entry.signal_connect("key_press_event") do |widget, event|
80
+ # puts "KEYPRESS 2"
81
+ if event.keyval == Gdk::Keyval::KEY_Down
82
+ puts "DOWN"
83
+ set_selected_row(@selected_row + 1)
84
+ # fixed = iter[COLUMN_FIXED]
85
+
86
+ true
87
+ elsif event.keyval == Gdk::Keyval::KEY_Up
88
+ set_selected_row(@selected_row - 1)
89
+ puts "UP"
90
+ true
91
+ elsif event.keyval == Gdk::Keyval::KEY_Return
92
+ path = Gtk::TreePath.new(@selected_row.to_s)
93
+ iter = @model.get_iter(path)
94
+ ret = iter[1]
95
+ @select_callback.call(ret, @selected_row)
96
+ @window.destroy
97
+ # puts iter[1].inspect
98
+ true
99
+ elsif event.keyval == Gdk::Keyval::KEY_Escape
100
+ @window.destroy
101
+ true
102
+ else
103
+ false
104
+ end
105
+ end
106
+
107
+ @entry.signal_connect("search-changed") do |widget|
108
+ puts "search changed: #{widget.text || ""}"
109
+ item_list = @update_callback.call(widget.text)
110
+
111
+ update_item_list(item_list)
112
+ # label.text = widget.text || ""
113
+ end
114
+ @entry.signal_connect("changed") { puts "[changed] " }
115
+ @entry.signal_connect("next-match") { puts "[next-match] " }
116
+
117
+ if !opt[:desc].nil?
118
+ descl = Gtk::Label.new(opt[:desc])
119
+ vbox.pack_start(descl, :expand => false, :fill => false, :padding => 0)
120
+ end
121
+
122
+ # label = Gtk::Label.new(<<-EOF)
123
+ # Search:
124
+ # EOF
125
+
126
+ # label = Gtk::Label.new("Input:")
127
+ # vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
128
+
129
+ vbox.pack_start(container, :expand => false, :fill => false, :padding => 0)
130
+ sw = Gtk::ScrolledWindow.new(nil, nil)
131
+ sw.shadow_type = :etched_in
132
+ sw.set_policy(:never, :automatic)
133
+ vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
134
+
135
+ sw.add(treeview)
136
+
137
+ if !opt[:columns].nil?
138
+ for col in opt[:columns]
139
+ renderer = Gtk::CellRendererText.new
140
+ column = Gtk::TreeViewColumn.new(col[:title],
141
+ renderer,
142
+ "text" => col[:id])
143
+ column.sort_column_id = col[:id]
144
+ treeview.append_column(column)
145
+ end
146
+ else
147
+ renderer = Gtk::CellRendererText.new
148
+ column = Gtk::TreeViewColumn.new("JMP",
149
+ renderer,
150
+ "text" => COLUMN_JUMP_KEY)
151
+ column.sort_column_id = COLUMN_JUMP_KEY
152
+ treeview.append_column(column)
153
+
154
+ renderer = Gtk::CellRendererText.new
155
+ column = Gtk::TreeViewColumn.new("Description",
156
+ renderer,
157
+ "text" => COLUMN_DESCRIPTION)
158
+ column.sort_column_id = COLUMN_DESCRIPTION
159
+ treeview.append_column(column)
160
+ end
161
+
162
+ @window.set_default_size(280, 500)
163
+ puts "SelectUpdateWindow"
164
+ end
165
+
166
+ def run
167
+ if !@window.visible?
168
+ @window.show_all
169
+ # add_spinner
170
+ else
171
+ @window.destroy
172
+ # GLib::Source.remove(@tiemout) unless @timeout.zero?
173
+ @timeout = 0
174
+ end
175
+ @window
176
+ end
177
+ end