vimamsa 0.1.4 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vimamsa/rbvma.rb CHANGED
@@ -7,17 +7,24 @@ require "pathname"
7
7
  require "date"
8
8
  require "ripl/multi_line"
9
9
  require "json"
10
-
11
- puts "INIT rbvma"
10
+ require "listen"
12
11
 
13
12
  require "vimamsa/util"
14
- # require "rbvma/rbvma"
15
- require "vimamsa/main" #
16
- require "vimamsa/key_binding_tree" #
17
- require "vimamsa/actions" #
18
- require "vimamsa/macro" #
19
- require "vimamsa/buffer" #
20
- require "vimamsa/debug" #
13
+ require "vimamsa/main"
14
+
15
+ require "vimamsa/actions"
16
+ require "vimamsa/key_binding_tree"
17
+ require "vimamsa/key_actions"
18
+
19
+
20
+ require "vimamsa/gui"
21
+ require "vimamsa/gui_menu"
22
+ require "vimamsa/gui_select_window"
23
+ require "vimamsa/gui_sourceview"
24
+
25
+ require "vimamsa/macro"
26
+ require "vimamsa/buffer"
27
+ require "vimamsa/debug"
21
28
  require "vimamsa/constants"
22
29
  require "vimamsa/easy_jump"
23
30
  require "vimamsa/hook"
@@ -40,418 +47,12 @@ def vma()
40
47
  return $vma
41
48
  end
42
49
 
43
- $idle_scroll_to_mark = false
44
-
45
- def idle_func
46
- # puts "IDLEFUNC"
47
- if $idle_scroll_to_mark
48
- # Ripl.start :binding => binding
49
- # $view.get_visible_rect
50
- vr = $view.visible_rect
51
-
52
- # iter = b.get_iter_at(:offset => i)
53
-
54
- b = $view.buffer
55
- iter = b.get_iter_at(:offset => b.cursor_position)
56
- iterxy = $view.get_iter_location(iter)
57
- # puts "ITERXY" + iterxy.inspect
58
- # Ripl.start :binding => binding
59
-
60
- intr = iterxy.intersect(vr)
61
- if intr.nil?
62
- $view.set_cursor_pos($view.buffer.cursor_position)
63
- else
64
- $idle_scroll_to_mark = false
65
- end
66
-
67
- sleep(0.1)
68
- end
69
- sleep(0.01)
70
- return true
71
- end
72
-
73
- # qt_select_update_window(l, $select_keys.collect { |x| x.upcase },
74
- # "gui_find_macro_select_callback",
75
- # "gui_find_macro_update_callback")
76
- class SelectUpdateWindow
77
- COLUMN_JUMP_KEY = 0
78
- COLUMN_DESCRIPTION = 1
79
-
80
- def update_item_list(item_list)
81
- # puts item_list.inspect
82
- # Ripl.start :binding => binding
83
- @model.clear
84
- for item in item_list
85
- iter = @model.append
86
- v = ["", item[0]]
87
- puts v.inspect
88
- iter.set_values(v)
89
- end
90
-
91
- set_selected_row(0)
92
- end
93
-
94
- def set_selected_row(rownum)
95
- rownum = 0 if rownum < 0
96
- @selected_row = rownum
97
-
98
- if @model.count > 0
99
- path = Gtk::TreePath.new(@selected_row.to_s)
100
- iter = @model.get_iter(path)
101
- @tv.selection.select_iter(iter)
102
- end
103
- end
104
-
105
- def initialize(main_window, item_list, jump_keys, select_callback, update_callback)
106
- @window = Gtk::Window.new(:toplevel)
107
- # @window.screen = main_window.screen
108
- @window.title = "List Store"
109
-
110
- @selected_row = 0
111
-
112
- puts item_list.inspect
113
- @update_callback = method(update_callback)
114
- @select_callback = method(select_callback)
115
- # puts @update_callback_m.call("").inspect
116
-
117
- vbox = Gtk::Box.new(:vertical, 8)
118
- vbox.margin = 8
119
- @window.add(vbox)
120
-
121
- @entry = Gtk::SearchEntry.new
122
- @entry.width_chars = 45
123
- container = Gtk::Box.new(:horizontal, 10)
124
- # container.halign = :start
125
- container.halign = :center
126
- container.pack_start(@entry,
127
- :expand => false, :fill => false, :padding => 0)
128
-
129
- # create tree view
130
- @model = Gtk::ListStore.new(String, String)
131
- treeview = Gtk::TreeView.new(@model)
132
- treeview.search_column = COLUMN_DESCRIPTION
133
- @tv = treeview
134
- # item_list = @update_callback.call("")
135
- update_item_list(item_list)
136
-
137
- # Ripl.start :binding => binding
138
- @window.signal_connect("key-press-event") do |_widget, event|
139
- # puts "KEYPRESS 1"
140
- @entry.handle_event(event)
141
- end
142
-
143
- @entry.signal_connect("key_press_event") do |widget, event|
144
- # puts "KEYPRESS 2"
145
- if event.keyval == Gdk::Keyval::KEY_Down
146
- puts "DOWN"
147
- set_selected_row(@selected_row + 1)
148
- # fixed = iter[COLUMN_FIXED]
149
-
150
- true
151
- elsif event.keyval == Gdk::Keyval::KEY_Up
152
- set_selected_row(@selected_row - 1)
153
- puts "UP"
154
- true
155
- elsif event.keyval == Gdk::Keyval::KEY_Return
156
- path = Gtk::TreePath.new(@selected_row.to_s)
157
- iter = @model.get_iter(path)
158
- ret = iter[1]
159
- @select_callback.call(ret, @selected_row)
160
- @window.destroy
161
- # puts iter[1].inspect
162
- true
163
- elsif event.keyval == Gdk::Keyval::KEY_Escape
164
- @window.destroy
165
- true
166
- else
167
- false
168
- end
169
- end
170
-
171
- @entry.signal_connect("search-changed") do |widget|
172
- puts "search changed: #{widget.text || ""}"
173
- item_list = @update_callback.call(widget.text)
174
- update_item_list(item_list)
175
- # label.text = widget.text || ""
176
- end
177
- @entry.signal_connect("changed") { puts "[changed] " }
178
- @entry.signal_connect("next-match") { puts "[next-match] " }
179
-
180
- label = Gtk::Label.new(<<-EOF)
181
-
182
- Search:
183
- EOF
184
- vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
185
-
186
- vbox.pack_start(container, :expand => false, :fill => false, :padding => 0)
187
- sw = Gtk::ScrolledWindow.new(nil, nil)
188
- sw.shadow_type = :etched_in
189
- sw.set_policy(:never, :automatic)
190
- vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
191
-
192
- sw.add(treeview)
193
-
194
- renderer = Gtk::CellRendererText.new
195
- column = Gtk::TreeViewColumn.new("JMP",
196
- renderer,
197
- "text" => COLUMN_JUMP_KEY)
198
- column.sort_column_id = COLUMN_JUMP_KEY
199
- treeview.append_column(column)
200
-
201
- renderer = Gtk::CellRendererText.new
202
- column = Gtk::TreeViewColumn.new("Description",
203
- renderer,
204
- "text" => COLUMN_DESCRIPTION)
205
- column.sort_column_id = COLUMN_DESCRIPTION
206
- treeview.append_column(column)
207
-
208
- @window.set_default_size(280, 500)
209
- puts "SelectUpdateWindow"
210
- end
211
-
212
- def run
213
- if !@window.visible?
214
- @window.show_all
215
- # add_spinner
216
- else
217
- @window.destroy
218
- # GLib::Source.remove(@tiemout) unless @timeout.zero?
219
- @timeout = 0
220
- end
221
- @window
222
- end
223
- end
224
-
225
- def center_on_current_line()
226
- b = $view.buffer
227
- iter = b.get_iter_at(:offset => b.cursor_position)
228
- within_margin = 0.0 #margin as a [0.0,0.5) fraction of screen size
229
- use_align = true
230
- xalign = 0.0 #0.0=top 1.0=bottom, 0.5=center
231
- yalign = 0.5
232
- $view.scroll_to_iter(iter, within_margin, use_align, xalign, yalign)
233
- end
234
-
235
- def qt_select_update_window(item_list, jump_keys, select_callback, update_callback)
236
- $selup = SelectUpdateWindow.new(nil, item_list, jump_keys, select_callback, update_callback)
237
- $selup.run
238
- end
239
-
240
- # ~/Drive/code/ruby-gnome/gtk3/sample/gtk-demo/search_entry2.rb
241
- # ~/Drive/code/ruby-gnome/gtk3/sample/gtk-demo/list_store.rb
242
-
243
- def qt_open_file_dialog(dirpath)
244
- dialog = Gtk::FileChooserDialog.new(:title => "Open file",
245
- :action => :open,
246
- :buttons => [[Gtk::Stock::OPEN, :accept],
247
- [Gtk::Stock::CANCEL, :cancel]])
248
- dialog.set_current_folder(dirpath)
249
-
250
- dialog.signal_connect("response") do |dialog, response_id|
251
- if response_id == Gtk::ResponseType::ACCEPT
252
- open_new_file(dialog.filename)
253
- # puts "uri = #{dialog.uri}"
254
- end
255
- dialog.destroy
256
- end
257
- dialog.run
258
- end
259
-
260
- def qt_file_saveas(dirpath)
261
- dialog = Gtk::FileChooserDialog.new(:title => "Save as",
262
- :action => :save,
263
- :buttons => [[Gtk::Stock::SAVE, :accept],
264
- [Gtk::Stock::CANCEL, :cancel]])
265
- dialog.set_current_folder(dirpath)
266
- dialog.signal_connect("response") do |dialog, response_id|
267
- if response_id == Gtk::ResponseType::ACCEPT
268
- file_saveas(dialog.filename)
269
- end
270
- dialog.destroy
271
- end
272
-
273
- dialog.run
274
- end
275
-
276
- def qt_create_buffer(id)
277
- puts "qt_create_buffer(#{id})"
278
- buf1 = GtkSource::Buffer.new()
279
- view = VSourceView.new()
280
-
281
- view.set_highlight_current_line(true)
282
- view.set_show_line_numbers(true)
283
- view.set_buffer(buf1)
284
-
285
- ssm = GtkSource::StyleSchemeManager.new
286
- ssm.set_search_path(ssm.search_path << ppath("styles/"))
287
- # sty = ssm.get_scheme("dark")
288
- sty = ssm.get_scheme("molokai_edit")
289
- # puts ssm.scheme_ids
290
-
291
- view.buffer.highlight_matching_brackets = true
292
- view.buffer.style_scheme = sty
293
-
294
- provider = Gtk::CssProvider.new
295
- provider.load(data: "textview { font-family: Monospace; font-size: 11pt; }")
296
- # provider.load(data: "textview { font-family: Arial; font-size: 12pt; }")
297
- view.style_context.add_provider(provider)
298
- view.wrap_mode = :char
299
-
300
- $vmag.buffers[id] = view
301
- end
302
-
303
- def gui_set_file_lang(id, lname)
304
- view = $vmag.buffers[id]
305
- lm = GtkSource::LanguageManager.new
306
- lang = nil
307
- lm.set_search_path(lm.search_path << ppath("lang/"))
308
- lang = lm.get_language(lname)
309
-
310
- view.buffer.language = lang
311
- view.buffer.highlight_syntax = true
312
- end
313
-
314
- def qt_process_deltas
315
- end
316
-
317
- def qt_add_image(imgpath, pos)
318
- end
319
-
320
- def qt_process_deltas
321
- end
322
-
323
- def qt_process_events
324
- end
325
-
326
- def qt_select_window_close(arg = nil)
327
- end
328
-
329
- def set_window_title(str)
330
- unimplemented
331
- end
332
-
333
- def render_text(tmpbuf, pos, selection_start, reset)
334
- unimplemented
335
- end
336
-
337
- def qt_set_buffer_contents(id, txt)
338
- # $vbuf.set_text(txt)
339
- puts "qt_set_buffer_contents(#{id}, txt)"
340
-
341
- $vmag.buffers[id].buffer.set_text(txt)
342
- end
343
-
344
- def qt_set_cursor_pos(id, pos)
345
- $view.set_cursor_pos(pos)
346
- # Ripl.start :binding => binding
347
- end
348
-
349
- def qt_set_selection_start(id, selection_start)
350
- end
351
-
352
- def qt_set_current_buffer(id)
353
- view = $vmag.buffers[id]
354
- puts "qt_set_current_buffer(#{id}), view=#{view}"
355
- buf1 = view.buffer
356
- $vmag.view = view
357
- $vmag.buf1 = buf1
358
- $view = view
359
- $vbuf = buf1
360
-
361
- $vmag.sw.remove($vmag.sw.child) if !$vmag.sw.child.nil?
362
- $vmag.sw.add(view)
363
-
364
- view.grab_focus
365
- #view.set_focus(10)
366
- view.set_cursor_visible(true)
367
- #view.move_cursor(1, 1, false)
368
- view.place_cursor_onscreen
369
-
370
- #TODO:
371
- # itr = view.buffer.get_iter_at(:offset => 0)
372
- # view.buffer.place_cursor(itr)
373
-
374
- wtitle = ""
375
- wtitle = buf.fname if !buf.fname.nil?
376
- $vmag.window.title = wtitle
377
- $vmag.sw.show_all
378
- end
379
-
380
50
  def unimplemented
381
51
  puts "unimplemented"
382
52
  end
383
53
 
384
- def center_where_cursor
385
- unimplemented
386
- end
387
-
388
- def paste_system_clipboard()
389
- # clipboard = $vmag.window.get_clipboard(Gdk::Selection::CLIPBOARD)
390
- utf8_string = Gdk::Atom.intern("UTF8_STRING")
391
- # x = clipboard.request_contents(utf8_string)
392
-
393
- widget = Gtk::Invisible.new
394
- clipboard = Gtk::Clipboard.get_default($vmag.window.display)
395
- received_text = ""
396
54
 
397
- target_string = Gdk::Selection::TARGET_STRING
398
- ti = clipboard.request_contents(target_string)
399
-
400
- # clipboard.request_contents(target_string) do |_clipboard, selection_data|
401
- # received_text = selection_data.text
402
- # puts "received_text=#{received_text}"
403
- # end
404
- if clipboard.wait_is_text_available?
405
- received_text = clipboard.wait_for_text
406
- end
407
-
408
- if received_text != "" and !received_text.nil?
409
- max_clipboard_items = 100
410
- if received_text != $clipboard[-1]
411
- #TODO: HACK
412
- $paste_lines = false
413
- end
414
- $clipboard << received_text
415
- # puts $clipboard[-1]
416
- $clipboard = $clipboard[-([$clipboard.size, max_clipboard_items].min)..-1]
417
- end
418
- return received_text
419
- end
420
-
421
- def set_system_clipboard(arg)
422
- # return if arg.class != String
423
- # return if s.size < 1
424
- # utf8_string = Gdk::Atom.intern("UTF8_STRING")
425
- widget = Gtk::Invisible.new
426
- clipboard = Gtk::Clipboard.get_default($vmag.window.display)
427
- clipboard.text = arg
428
- end
429
-
430
- def get_visible_area()
431
- view = $view
432
- vr = view.visible_rect
433
- startpos = view.get_iter_at_position_raw(vr.x, vr.y)[1].offset
434
- endpos = view.get_iter_at_position_raw(vr.x + vr.width, vr.y + vr.height)[1].offset
435
- return [startpos, endpos]
436
- end
437
-
438
- def page_up
439
- $view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), -1, false)
440
- return true
441
- end
442
-
443
- def page_down
444
- $view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), 1, false)
445
- return true
446
- end
447
-
448
- # module Rbvma
449
- # # Your code goes here...
450
- # def foo
451
- # puts "BAR"
452
- # end
453
- # end
454
- $debug = true
55
+ $debug = false
455
56
 
456
57
  def scan_indexes(txt, regex)
457
58
  # indexes = txt.enum_for(:scan, regex).map { Regexp.last_match.begin(0) + 1 }
@@ -461,553 +62,4 @@ end
461
62
 
462
63
  $update_cursor = false
463
64
 
464
- class VSourceView < GtkSource::View
465
- def initialize(title = nil)
466
- # super(:toplevel)
467
- super()
468
- puts "vsource init"
469
- @last_keyval = nil
470
- @last_event = [nil, nil]
471
-
472
- signal_connect("key_press_event") do |widget, event|
473
- handle_key_event(event, :key_press_event)
474
- true
475
- end
476
-
477
- signal_connect("key_release_event") do |widget, event|
478
- handle_key_event(event, :key_release_event)
479
- true
480
- end
481
-
482
- signal_connect("move-cursor") do |widget, event|
483
- $update_cursor = true
484
- false
485
- end
486
-
487
- signal_connect "button-release-event" do |widget, event|
488
- $buffer.set_pos(buffer.cursor_position)
489
- false
490
- end
491
- @curpos_mark = nil
492
- end
493
-
494
- def handle_key_event(event, sig)
495
- if $update_cursor
496
- curpos = buffer.cursor_position
497
- puts "MOVE CURSOR: #{curpos}"
498
- buf.set_pos(curpos)
499
- $update_cursor = false
500
- end
501
- puts $view.visible_rect.inspect
502
-
503
- puts "key event"
504
- puts event
505
-
506
- key_name = event.string
507
- if event.state.control_mask?
508
- key_name = Gdk::Keyval.to_name(event.keyval)
509
- # Gdk::Keyval.to_name()
510
- end
511
-
512
- keyval_trans = {}
513
- keyval_trans[Gdk::Keyval::KEY_Control_L] = "ctrl"
514
- keyval_trans[Gdk::Keyval::KEY_Control_R] = "ctrl"
515
-
516
- keyval_trans[Gdk::Keyval::KEY_Escape] = "esc"
517
-
518
- keyval_trans[Gdk::Keyval::KEY_Return] = "enter"
519
- keyval_trans[Gdk::Keyval::KEY_ISO_Enter] = "enter"
520
- keyval_trans[Gdk::Keyval::KEY_KP_Enter] = "enter"
521
- keyval_trans[Gdk::Keyval::KEY_Alt_L] = "alt"
522
- keyval_trans[Gdk::Keyval::KEY_Alt_R] = "alt"
523
-
524
- keyval_trans[Gdk::Keyval::KEY_BackSpace] = "backspace"
525
- keyval_trans[Gdk::Keyval::KEY_KP_Page_Down] = "pagedown"
526
- keyval_trans[Gdk::Keyval::KEY_KP_Page_Up] = "pageup"
527
- keyval_trans[Gdk::Keyval::KEY_Page_Down] = "pagedown"
528
- keyval_trans[Gdk::Keyval::KEY_Page_Up] = "pageup"
529
- keyval_trans[Gdk::Keyval::KEY_Left] = "left"
530
- keyval_trans[Gdk::Keyval::KEY_Right] = "right"
531
- keyval_trans[Gdk::Keyval::KEY_Down] = "down"
532
- keyval_trans[Gdk::Keyval::KEY_Up] = "up"
533
- keyval_trans[Gdk::Keyval::KEY_space] = "space"
534
-
535
- keyval_trans[Gdk::Keyval::KEY_Shift_L] = "shift"
536
- keyval_trans[Gdk::Keyval::KEY_Shift_R] = "shift"
537
- keyval_trans[Gdk::Keyval::KEY_Tab] = "tab"
538
-
539
- key_trans = {}
540
- key_trans["\e"] = "esc"
541
- tk = keyval_trans[event.keyval]
542
- key_name = tk if !tk.nil?
543
-
544
- key_str_parts = []
545
- key_str_parts << "ctrl" if event.state.control_mask? and key_name != "ctrl"
546
- key_str_parts << "alt" if event.state.mod1_mask? and key_name != "alt"
547
-
548
- key_str_parts << key_name
549
- key_str = key_str_parts.join("-")
550
- keynfo = { :key_str => key_str, :key_name => key_name, :keyval => event.keyval }
551
- puts keynfo.inspect
552
- # $kbd.match_key_conf(key_str, nil, :key_press)
553
- # puts "key_str=#{key_str} key_"
554
-
555
- if key_str != "" # or prefixed_key_str != ""
556
- if sig == :key_release_event and event.keyval == @last_keyval
557
- $kbd.match_key_conf(key_str + "!", nil, :key_release)
558
- @last_event = [event, :key_release]
559
- elsif sig == :key_press_event
560
- $kbd.match_key_conf(key_str, nil, :key_press)
561
- @last_event = [event, key_str, :key_press]
562
- end
563
- @last_keyval = event.keyval #TODO: outside if?
564
- end
565
-
566
- handle_deltas
567
-
568
- # set_focus(5)
569
- # false
570
-
571
- end
572
-
573
- def pos_to_coord(i)
574
- b = buffer
575
- iter = b.get_iter_at(:offset => i)
576
- iterxy = get_iter_location(iter)
577
- winw = parent_window.width
578
- view_width = visible_rect.width
579
- gutter_width = winw - view_width
580
-
581
- x = iterxy.x + gutter_width
582
- y = iterxy.y
583
-
584
- # buffer_to_window_coords(Gtk::TextWindowType::TEXT, iterxy.x, iterxy.y).inspect
585
- # puts buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y).inspect
586
- (x, y) = buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y)
587
- # Ripl.start :binding => binding
588
-
589
- return [x, y]
590
- end
591
-
592
- def handle_deltas()
593
- any_change = false
594
- while d = buf.deltas.shift
595
- any_change = true
596
- pos = d[0]
597
- op = d[1]
598
- num = d[2]
599
- txt = d[3]
600
- if op == DELETE
601
- startiter = buffer.get_iter_at(:offset => pos)
602
- enditer = buffer.get_iter_at(:offset => pos + num)
603
- buffer.delete(startiter, enditer)
604
- elsif op == INSERT
605
- startiter = buffer.get_iter_at(:offset => pos)
606
- buffer.insert(startiter, txt)
607
- end
608
- end
609
- if any_change
610
- qt_set_cursor_pos($buffer.id, $buffer.pos) #TODO: only when necessary
611
- end
612
-
613
- # sanity_check #TODO
614
- end
615
-
616
- def sanity_check()
617
- a = buffer.text
618
- b = buf.to_s
619
- # puts "===================="
620
- # puts a.lines[0..10].join()
621
- # puts "===================="
622
- # puts b.lines[0..10].join()
623
- # puts "===================="
624
- if a == b
625
- puts "Buffers match"
626
- else
627
- puts "ERROR: Buffer's don't match."
628
- end
629
- end
630
-
631
- def set_cursor_pos(pos)
632
- # return
633
- itr = buffer.get_iter_at(:offset => pos)
634
- itr2 = buffer.get_iter_at(:offset => pos + 1)
635
- buffer.place_cursor(itr)
636
-
637
- # $view.signal_emit("extend-selection", Gtk::MovementStep.new(:PAGES), -1, false)
638
-
639
- within_margin = 0.075 #margin as a [0.0,0.5) fraction of screen size
640
- use_align = false
641
- xalign = 0.5 #0.0=top 1.0=bottom, 0.5=center
642
- yalign = 0.5
643
-
644
- if @curpos_mark.nil?
645
- @curpos_mark = buffer.create_mark("cursor", itr, false)
646
- else
647
- buffer.move_mark(@curpos_mark, itr)
648
- end
649
- scroll_to_mark(@curpos_mark, within_margin, use_align, xalign, yalign)
650
- $idle_scroll_to_mark = true
651
- ensure_cursor_visible
652
-
653
- # scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
654
-
655
- # $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
656
- # Ripl.start :binding => binding
657
- draw_cursor
658
-
659
- return true
660
- end
661
-
662
- def cursor_visible_idle_func
663
- puts "cursor_visible_idle_func"
664
- # From https://picheta.me/articles/2013/08/gtk-plus--a-method-to-guarantee-scrolling.html
665
- # vr = visible_rect
666
-
667
- # b = $view.buffer
668
- # iter = buffer.get_iter_at(:offset => buffer.cursor_position)
669
- # iterxy = get_iter_location(iter)
670
-
671
- sleep(0.01)
672
- # intr = iterxy.intersect(vr)
673
- if is_cursor_visible == false
674
- # set_cursor_pos(buffer.cursor_position)
675
-
676
- itr = buffer.get_iter_at(:offset => buffer.cursor_position)
677
-
678
- within_margin = 0.075 #margin as a [0.0,0.5) fraction of screen size
679
- use_align = false
680
- xalign = 0.5 #0.0=top 1.0=bottom, 0.5=center
681
- yalign = 0.5
682
-
683
- scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
684
-
685
- # return true # Call this func again
686
- else
687
- return false # Don't call this idle func again
688
- end
689
- end
690
-
691
- def is_cursor_visible
692
- vr = visible_rect
693
- iter = buffer.get_iter_at(:offset => buffer.cursor_position)
694
- iterxy = get_iter_location(iter)
695
- iterxy.width = 1 if iterxy.width == 0
696
- iterxy.height = 1 if iterxy.height == 0
697
-
698
- intr = iterxy.intersect(vr)
699
- if intr.nil?
700
- puts iterxy.inspect
701
- puts vr.inspect
702
- # Ripl.start :binding => binding
703
-
704
- # exit!
705
- return false
706
- else
707
- return true
708
- end
709
- end
710
65
 
711
- def ensure_cursor_visible
712
- if is_cursor_visible == false
713
- Thread.new {
714
- sleep 0.01
715
- GLib::Idle.add(proc { cursor_visible_idle_func })
716
- }
717
- end
718
- end
719
-
720
- def draw_cursor
721
- if is_command_mode
722
- itr = buffer.get_iter_at(:offset => buf.pos)
723
- itr2 = buffer.get_iter_at(:offset => buf.pos + 1)
724
- $view.buffer.select_range(itr, itr2)
725
- elsif buf.visual_mode?
726
- puts "VISUAL MODE"
727
- (_start, _end) = buf.get_visual_mode_range2
728
- puts "#{_start}, #{_end}"
729
- itr = buffer.get_iter_at(:offset => _start)
730
- itr2 = buffer.get_iter_at(:offset => _end + 1)
731
- $view.buffer.select_range(itr, itr2)
732
- else # Insert mode
733
- itr = buffer.get_iter_at(:offset => buf.pos)
734
- $view.buffer.select_range(itr, itr)
735
- puts "INSERT MODE"
736
- end
737
- end
738
-
739
- # def quit
740
- # destroy
741
- # true
742
- # end
743
- end
744
-
745
- class VMAg
746
- attr_accessor :buffers, :sw, :view, :buf1, :window
747
-
748
- VERSION = "1.0"
749
-
750
- HEART = "♥"
751
- RADIUS = 150
752
- N_WORDS = 5
753
- FONT = "Serif 18"
754
- TEXT = "I ♥ GTK+"
755
-
756
- def initialize()
757
- @show_overlay = true
758
- @da = nil
759
- @buffers = {}
760
- @view = nil
761
- @buf1 = nil
762
- end
763
-
764
- def run
765
- init_window
766
- # init_rtext
767
- Gtk.main
768
- end
769
-
770
- def start_overlay_draw()
771
- @da = Gtk::Fixed.new
772
- @overlay.add_overlay(@da)
773
- @overlay.set_overlay_pass_through(@da, true)
774
- end
775
-
776
- def clear_overlay()
777
- if @da != nil
778
- @overlay.remove(@da)
779
- end
780
- end
781
-
782
- def overlay_draw_text(text, textpos)
783
- # puts "overlay_draw_text #{[x,y]}"
784
- (x, y) = @view.pos_to_coord(textpos)
785
- # puts "overlay_draw_text #{[x,y]}"
786
- label = Gtk::Label.new("<span background='#00000088' foreground='#ff0000' weight='ultrabold'>#{text}</span>")
787
- label.use_markup = true
788
- @da.put(label, x, y)
789
- end
790
-
791
- def end_overlay_draw()
792
- @da.show_all
793
- end
794
-
795
- def toggle_overlay
796
- @show_overlay = @show_overlay ^ 1
797
- if !@show_overlay
798
- if @da != nil
799
- @overlay.remove(@da)
800
- end
801
- return
802
- else
803
- @da = Gtk::Fixed.new
804
- @overlay.add_overlay(@da)
805
- @overlay.set_overlay_pass_through(@da, true)
806
- end
807
-
808
- (startpos, endpos) = get_visible_area
809
- s = @view.buffer.text
810
- wpos = s.enum_for(:scan, /\W(\w)/).map { Regexp.last_match.begin(0) + 1 }
811
- wpos = wpos[0..130]
812
-
813
- # vr = @view.visible_rect
814
- # # gtk_text_view_get_line_at_y
815
- # # gtk_text_view_get_iter_at_position
816
- # gtk_text_view_get_iter_at_position(vr.
817
- # istart = @view.get_iter_at_position(vr.x,vr.y)
818
- # istart = @view.get_iter_at_y(vr.y)
819
- # startpos = @view.get_iter_at_position_raw(vr.x,vr.y)[1].offset
820
- # endpos = @view.get_iter_at_position_raw(vr.x+vr.width,vr.y+vr.height)[1].offset
821
- # puts "startpos,endpos:#{[startpos, endpos]}"
822
-
823
- da = @da
824
- if false
825
- da.signal_connect "draw" do |widget, cr|
826
- cr.save
827
- for pos in wpos
828
- (x, y) = @view.pos_to_coord(pos)
829
-
830
- layout = da.create_pango_layout("XY")
831
- desc = Pango::FontDescription.new("sans bold 11")
832
- layout.font_description = desc
833
-
834
- cr.move_to(x, y)
835
- # cr.move_to(gutter_width, 300)
836
- cr.pango_layout_path(layout)
837
-
838
- cr.set_source_rgb(1.0, 0.0, 0.0)
839
- cr.fill_preserve
840
- end
841
- cr.restore
842
- false # = draw other
843
- # true # = Don't draw others
844
- end
845
- end
846
-
847
- for pos in wpos
848
- (x, y) = @view.pos_to_coord(pos)
849
- # da.put(Gtk::Label.new("AB"), x, y)
850
- label = Gtk::Label.new("<span background='#00000088' foreground='#ff0000' weight='ultrabold'>AB</span>")
851
- label.use_markup = true
852
- da.put(label, x, y)
853
- end
854
-
855
- # puts @view.pos_to_coord(300).inspect
856
-
857
- @da.show_all
858
- end
859
-
860
- def init_keybindings
861
- $kbd = KeyBindingTree.new()
862
- $kbd.add_mode("C", :command)
863
- $kbd.add_mode("I", :insert)
864
- $kbd.add_mode("V", :visual)
865
- $kbd.add_mode("M", :minibuffer)
866
- $kbd.add_mode("R", :readchar)
867
- $kbd.add_mode("B", :browse)
868
- $kbd.set_default_mode(:command)
869
- require "default_key_bindings"
870
-
871
- $macro = Macro.new
872
-
873
- # bindkey "VC j", "buf.move(FORWARD_LINE)"
874
- bindkey "VC j", "puts('j_key_action')"
875
- bindkey "VC ctrl-j", "puts('ctrl_j_key_action')"
876
-
877
- bindkey "VC l", "buf.move(FORWARD_CHAR)"
878
- bindkey "C x", "buf.delete(CURRENT_CHAR_FORWARD)"
879
- # bindkey "C r <char>", "buf.replace_with_char(<char>)"
880
- bindkey "I space", 'buf.insert_txt(" ")'
881
-
882
- bindkey "VC l", "buf.move(FORWARD_CHAR)"
883
- bindkey "VC j", "buf.move(FORWARD_LINE)"
884
- bindkey "VC k", "buf.move(BACKWARD_LINE)"
885
- bindkey "VC h", "buf.move(BACKWARD_CHAR)"
886
- end
887
-
888
- def handle_deltas()
889
- while d = buf.deltas.shift
890
- pos = d[0]
891
- op = d[1]
892
- num = d[2]
893
- txt = d[3]
894
- if op == DELETE
895
- startiter = @buf1.get_iter_at(:offset => pos)
896
- enditer = @buf1.get_iter_at(:offset => pos + num)
897
- @buf1.delete(startiter, enditer)
898
- elsif op == INSERT
899
- startiter = @buf1.get_iter_at(:offset => pos)
900
- @buf1.insert(startiter, txt)
901
- end
902
- end
903
- end
904
-
905
- def add_to_minibuf(msg)
906
- startiter = @minibuf.buffer.get_iter_at(:offset => 0)
907
- @minibuf.buffer.insert(startiter, "#{msg}\n")
908
- @minibuf.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), -1, false)
909
- end
910
-
911
- def init_minibuffer()
912
- # Init minibuffer
913
- sw = Gtk::ScrolledWindow.new
914
- sw.set_policy(:automatic, :automatic)
915
- overlay = Gtk::Overlay.new
916
- overlay.add(sw)
917
- @vpaned.pack2(overlay, :resize => false)
918
- # overlay.set_size_request(-1, 50)
919
- # $ovrl = overlay
920
- # $ovrl.set_size_request(-1, 30)
921
- $sw2 = sw
922
- sw.set_size_request(-1, 12)
923
-
924
- view = VSourceView.new()
925
- view.set_highlight_current_line(false)
926
- view.set_show_line_numbers(false)
927
- # view.set_buffer(buf1)
928
- ssm = GtkSource::StyleSchemeManager.new
929
- ssm.set_search_path(ssm.search_path << ppath("styles/"))
930
- sty = ssm.get_scheme("molokai_edit")
931
- view.buffer.highlight_matching_brackets = false
932
- view.buffer.style_scheme = sty
933
- provider = Gtk::CssProvider.new
934
- # provider.load(data: "textview { font-family: Monospace; font-size: 11pt; }")
935
- provider.load(data: "textview { font-family: Arial; font-size: 10pt; color:#ff0000}")
936
- view.style_context.add_provider(provider)
937
- view.wrap_mode = :char
938
- @minibuf = view
939
- # Ripl.start :binding => binding
940
- # startiter = view.buffer.get_iter_at(:offset => 0)
941
- message("STARTUP")
942
- sw.add(view)
943
- end
944
-
945
- def init_header_bar()
946
- # @window = Gtk::Window.new(:toplevel)
947
- # @window.screen = main_window.screen
948
- # @window.set_default_size(600, 400)
949
-
950
- header = Gtk::HeaderBar.new
951
- header.show_close_button = true
952
- header.title = "Welcome to Facebook - Log in, sign up or learn more"
953
- header.has_subtitle = false
954
-
955
- # icon = Gio::ThemedIcon.new("mail-send-receive-symbolic")
956
- # icon = Gio::ThemedIcon.new("document-open-symbolic")
957
- # icon = Gio::ThemedIcon.new("dialog-password")
958
-
959
- #edit-redo edit-paste edit-find-replace edit-undo edit-find edit-cut edit-copy
960
- #document-open document-save document-save-as document-properties document-new
961
- button = Gtk::Button.new
962
- icon = Gio::ThemedIcon.new("open-menu-symbolic")
963
- image = Gtk::Image.new(:icon => icon, :size => :button)
964
- button.add(image)
965
- header.pack_end(button)
966
-
967
- button = Gtk::Button.new
968
- icon = Gio::ThemedIcon.new("document-revert-symbolic")
969
- image = Gtk::Image.new(:icon => icon, :size => :button)
970
- button.add(image)
971
- header.pack_end(button)
972
-
973
- box = Gtk::Box.new(:horizontal, 0)
974
- box.style_context.add_class("linked")
975
-
976
- button = Gtk::Button.new
977
- image = Gtk::Image.new(:icon_name => "pan-start-symbolic", :size => :button)
978
- button.add(image)
979
- box.add(button)
980
-
981
- button = Gtk::Button.new
982
- image = Gtk::Image.new(:icon_name => "pan-end-symbolic", :size => :button)
983
- button.add(image)
984
- box.add(button)
985
-
986
- header.pack_start(box)
987
- @window.titlebar = header
988
- @window.add(Gtk::TextView.new)
989
- end
990
-
991
- def init_window
992
- @window = Gtk::Window.new(:toplevel)
993
- @window.set_default_size(650, 850)
994
- @window.title = "Multiple Views"
995
- @window.show_all
996
- # vpaned = Gtk::Paned.new(:horizontal)
997
- @vpaned = Gtk::Paned.new(:vertical)
998
- @window.add(@vpaned)
999
-
1000
- @sw = Gtk::ScrolledWindow.new
1001
- @sw.set_policy(:automatic, :automatic)
1002
- @overlay = Gtk::Overlay.new
1003
- @overlay.add(@sw)
1004
- @vpaned.pack1(@overlay, :resize => true)
1005
-
1006
- init_minibuffer
1007
- init_header_bar
1008
-
1009
- @window.show_all
1010
-
1011
- vma.start
1012
- end
1013
- end