vimamsa 0.1.5 → 0.1.8

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