vimamsa 0.1.4 → 0.1.7

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