vimamsa 0.1.4 → 0.1.7

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.
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