vimamsa 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/vimamsa +4 -2
- data/lib/vimamsa/ack.rb +0 -4
- data/lib/vimamsa/actions.rb +20 -32
- data/lib/vimamsa/buffer.rb +23 -16
- data/lib/vimamsa/buffer_list.rb +3 -3
- data/lib/vimamsa/debug.rb +6 -6
- data/lib/vimamsa/easy_jump.rb +129 -125
- data/lib/vimamsa/editor.rb +29 -28
- data/lib/vimamsa/file_finder.rb +2 -2
- data/lib/vimamsa/file_history.rb +12 -5
- data/lib/vimamsa/gui.rb +561 -0
- data/lib/vimamsa/gui_gtk_sourceview.rb +294 -0
- data/lib/vimamsa/gui_menu.rb +100 -0
- data/lib/vimamsa/gui_select_window.rb +177 -0
- data/lib/vimamsa/gui_sourceview.rb +294 -0
- data/lib/vimamsa/{default_key_bindings.rb → key_actions.rb} +64 -189
- data/lib/vimamsa/key_binding_tree.rb +21 -9
- data/lib/vimamsa/key_bindings_vimlike.rb +259 -0
- data/lib/vimamsa/macro.rb +1 -1
- data/lib/vimamsa/main.rb +1 -2
- data/lib/vimamsa/rbvma.rb +16 -1023
- data/lib/vimamsa/search.rb +0 -4
- data/lib/vimamsa/search_replace.rb +1 -2
- data/lib/vimamsa/version.rb +1 -1
- metadata +9 -3
data/lib/vimamsa/editor.rb
CHANGED
@@ -19,9 +19,14 @@ def handle_drag_and_drop(fname)
|
|
19
19
|
buf.handle_drag_and_drop(fname)
|
20
20
|
end
|
21
21
|
|
22
|
+
def mkdir_if_not_exists(_dirpath)
|
23
|
+
dirpath = File.expand_path(_dirpath)
|
24
|
+
Dir.mkdir(dirpath) unless File.exist?(dirpath)
|
25
|
+
end
|
26
|
+
|
22
27
|
class Editor
|
23
|
-
attr_reader :file_content_search_paths, :file_name_search_paths
|
24
|
-
attr_accessor :converters, :fh, :paint_stack
|
28
|
+
attr_reader :file_content_search_paths, :file_name_search_paths, :gui
|
29
|
+
attr_accessor :converters, :fh, :paint_stack, :kbd
|
25
30
|
#attr_writer :call_func, :update_highlight
|
26
31
|
|
27
32
|
def initialize()
|
@@ -37,12 +42,13 @@ class Editor
|
|
37
42
|
@converters = {}
|
38
43
|
@paint_stack = []
|
39
44
|
@_plugins = {}
|
45
|
+
|
40
46
|
end
|
41
47
|
|
42
48
|
def open_file_listener(added)
|
43
49
|
if !added.empty?
|
44
50
|
for fp in added
|
45
|
-
|
51
|
+
sleep 0.1
|
46
52
|
x = IO.read(fp)
|
47
53
|
File.delete(fp)
|
48
54
|
for f in x.lines
|
@@ -65,6 +71,8 @@ class Editor
|
|
65
71
|
# GLib::Idle.add(proc{ puts "IDLEFUNC"})
|
66
72
|
# GLib::Idle.add(proc { idle_func })
|
67
73
|
|
74
|
+
@gui = $vmag #TODO
|
75
|
+
|
68
76
|
$hook = Hook.new
|
69
77
|
register_plugin(:Hook, $hook)
|
70
78
|
$macro = Macro.new
|
@@ -79,7 +87,8 @@ class Editor
|
|
79
87
|
|
80
88
|
debug "ARGV: " + ARGV.inspect
|
81
89
|
# build_key_bindings_tree
|
82
|
-
|
90
|
+
@kbd = KeyBindingTree.new()
|
91
|
+
$kbd = @kbd
|
83
92
|
$kbd.add_mode("C", :command)
|
84
93
|
$kbd.add_mode("I", :insert)
|
85
94
|
$kbd.add_mode("V", :visual)
|
@@ -87,15 +96,15 @@ class Editor
|
|
87
96
|
$kbd.add_mode("R", :readchar)
|
88
97
|
$kbd.add_mode("B", :browse)
|
89
98
|
$kbd.set_default_mode(:command)
|
90
|
-
require "vimamsa/
|
99
|
+
require "vimamsa/key_bindings_vimlike"
|
91
100
|
sleep(0.03)
|
92
101
|
|
93
102
|
FileManager.init
|
94
103
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
104
|
+
mkdir_if_not_exists("~/.vimamsa")
|
105
|
+
mkdir_if_not_exists("~/.vimamsa/backup")
|
106
|
+
mkdir_if_not_exists("~/.vimamsa/listen")
|
107
|
+
listen_dir = File.expand_path "~/.vimamsa/listen"
|
99
108
|
listener = Listen.to(listen_dir) do |modified, added, removed|
|
100
109
|
puts(modified: modified, added: added, removed: removed)
|
101
110
|
open_file_listener(added)
|
@@ -109,7 +118,7 @@ class Editor
|
|
109
118
|
$cnf = eval(IO.read(settings_path))
|
110
119
|
end
|
111
120
|
|
112
|
-
#
|
121
|
+
# set_gui_style(1)
|
113
122
|
|
114
123
|
# Limit file search to these extensions:
|
115
124
|
$find_extensions = [".txt", ".h", ".c", ".cpp", ".hpp", ".rb"]
|
@@ -139,7 +148,7 @@ class Editor
|
|
139
148
|
if fname
|
140
149
|
buffer = Buffer.new(read_file("", fname), fname)
|
141
150
|
else
|
142
|
-
buffer = Buffer.new("
|
151
|
+
buffer = Buffer.new(" \n")
|
143
152
|
end
|
144
153
|
$buffers << buffer
|
145
154
|
|
@@ -228,8 +237,7 @@ class Editor
|
|
228
237
|
# Register converter
|
229
238
|
def reg_conv(converter, converter_id)
|
230
239
|
@converters[converter_id] = converter
|
231
|
-
reg_act(converter_id, proc { $buffer.convert_selected_text(converter_id) }, "Converter #{converter_id}", [:selection])
|
232
|
-
# reg_act(converter_id, "$buffer.convert_selected_text(:#{converter_id})", "Converter #{converter_id}", [:selection])
|
240
|
+
reg_act(converter_id, proc { $buffer.convert_selected_text(converter_id) }, "Converter #{converter_id}", { :scope => [:selection] })
|
233
241
|
end
|
234
242
|
|
235
243
|
def apply_conv(converter_id, txt)
|
@@ -257,7 +265,7 @@ end
|
|
257
265
|
|
258
266
|
def _quit()
|
259
267
|
vma.shutdown
|
260
|
-
|
268
|
+
Gtk.main_quit
|
261
269
|
end
|
262
270
|
|
263
271
|
def fatal_error(msg)
|
@@ -266,14 +274,13 @@ def fatal_error(msg)
|
|
266
274
|
end
|
267
275
|
|
268
276
|
def file_saveas(filename)
|
269
|
-
|
270
|
-
$buffer.save()
|
277
|
+
buf.save_as_callback(filename)
|
271
278
|
end
|
272
279
|
|
273
280
|
def open_file_dialog()
|
274
281
|
path = ""
|
275
282
|
path = $buffer.fname if $buffer.fname
|
276
|
-
|
283
|
+
gui_open_file_dialog(File.dirname(path))
|
277
284
|
end
|
278
285
|
|
279
286
|
def system_clipboard_changed(clipboard_contents)
|
@@ -407,9 +414,9 @@ def minibuffer_new_char(c)
|
|
407
414
|
#$buffer = $minibuffer
|
408
415
|
end
|
409
416
|
|
410
|
-
def readchar_new_char(c)
|
411
|
-
$input_char_call_func.call(c)
|
412
|
-
end
|
417
|
+
# def readchar_new_char(c)
|
418
|
+
# $input_char_call_func.call(c)
|
419
|
+
# end
|
413
420
|
|
414
421
|
def minibuffer_delete()
|
415
422
|
$minibuffer.delete(BACKWARD_CHAR)
|
@@ -455,7 +462,7 @@ GUESS_ENCODING_ORDER = [
|
|
455
462
|
def create_new_file(filename = nil, file_contents = "\n")
|
456
463
|
debug "NEW FILE CREATED"
|
457
464
|
buffer = Buffer.new(file_contents)
|
458
|
-
#
|
465
|
+
# gui_set_current_buffer(buffer.id) #TODO: remove?
|
459
466
|
$buffers << buffer
|
460
467
|
return buffer
|
461
468
|
end
|
@@ -481,7 +488,7 @@ def load_buffer(fname)
|
|
481
488
|
end
|
482
489
|
debug("LOAD BUFFER: #{fname}")
|
483
490
|
buffer = Buffer.new(read_file("", fname), fname)
|
484
|
-
#
|
491
|
+
# gui_set_current_buffer(buffer.id)
|
485
492
|
buffer.set_active
|
486
493
|
debug("DONE LOAD: #{fname}")
|
487
494
|
#buf = filter_buffer(buffer)
|
@@ -528,10 +535,6 @@ def draw_text(str, x, y)
|
|
528
535
|
vma.paint_stack << [4, x, y, str]
|
529
536
|
end
|
530
537
|
|
531
|
-
def center_on_current_line__2del()
|
532
|
-
center_where_cursor
|
533
|
-
end
|
534
|
-
|
535
538
|
def hook_draw()
|
536
539
|
# TODO: as hook.register
|
537
540
|
# easy_jump_draw()
|
@@ -549,8 +552,6 @@ def render_buffer(buffer = 0, reset = 0)
|
|
549
552
|
t1 = Time.now
|
550
553
|
hook_draw()
|
551
554
|
|
552
|
-
render_text(tmpbuf, pos, selection_start, reset) #TODO: remove?
|
553
|
-
|
554
555
|
if $buffer.need_redraw?
|
555
556
|
hpt_scan_images() if $debug #experimental
|
556
557
|
end
|
data/lib/vimamsa/file_finder.rb
CHANGED
@@ -21,7 +21,7 @@ class FileFinder
|
|
21
21
|
Thread.new { recursively_find_files() }
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
gui_select_update_window(l, $select_keys.collect { |x| x.upcase },
|
25
25
|
"gui_file_finder_select_callback",
|
26
26
|
"gui_file_finder_update_callback")
|
27
27
|
end
|
@@ -83,7 +83,7 @@ end
|
|
83
83
|
def gui_file_finder_select_callback(search_str, idx)
|
84
84
|
selected_file = $file_search_list[idx][0]
|
85
85
|
debug "FILE FINDER SELECT CALLBACK: s=#{search_str},i=#{idx}: #{selected_file}"
|
86
|
-
|
86
|
+
gui_select_window_close(0)
|
87
87
|
open_new_file(selected_file)
|
88
88
|
end
|
89
89
|
|
data/lib/vimamsa/file_history.rb
CHANGED
@@ -55,9 +55,14 @@ class FileHistory
|
|
55
55
|
l = []
|
56
56
|
$select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
opt = { :title => "File history search",
|
59
|
+
:desc => "Search for previously opened files. Fuzzy search." ,
|
60
|
+
:columns => [{:title=>'Filename',:id=>0}]
|
61
|
+
}
|
62
|
+
gui_select_update_window(l, $select_keys.collect { |x| x.upcase },
|
63
|
+
"gui_file_history_select_callback",
|
64
|
+
"gui_file_history_update_callback",
|
65
|
+
opt)
|
61
66
|
end
|
62
67
|
end
|
63
68
|
|
@@ -86,8 +91,10 @@ def gui_file_history_update_callback(search_str = "")
|
|
86
91
|
if (search_str.size > 1)
|
87
92
|
files = fuzzy_filter(search_str, $vma.fh.history.keys, 40)
|
88
93
|
end
|
94
|
+
|
89
95
|
$search_list = files
|
90
|
-
|
96
|
+
ret = files.collect{|x|[x[0]]}
|
97
|
+
return ret
|
91
98
|
end
|
92
99
|
|
93
100
|
def gui_file_history_select_callback(search_str, idx)
|
@@ -95,6 +102,6 @@ def gui_file_history_select_callback(search_str, idx)
|
|
95
102
|
selected_file = $search_list[idx][0]
|
96
103
|
|
97
104
|
debug "FILE HISTORY SELECT CALLBACK: s=#{search_str},i=#{idx}: #{selected_file}"
|
98
|
-
|
105
|
+
gui_select_window_close(0)
|
99
106
|
open_new_file(selected_file)
|
100
107
|
end
|
data/lib/vimamsa/gui.rb
ADDED
@@ -0,0 +1,561 @@
|
|
1
|
+
$idle_scroll_to_mark = false
|
2
|
+
|
3
|
+
def gui_open_file_dialog(dirpath)
|
4
|
+
dialog = Gtk::FileChooserDialog.new(:title => "Open file",
|
5
|
+
:action => :open,
|
6
|
+
:buttons => [[Gtk::Stock::OPEN, :accept],
|
7
|
+
[Gtk::Stock::CANCEL, :cancel]])
|
8
|
+
dialog.set_current_folder(dirpath)
|
9
|
+
|
10
|
+
dialog.signal_connect("response") do |dialog, response_id|
|
11
|
+
if response_id == Gtk::ResponseType::ACCEPT
|
12
|
+
open_new_file(dialog.filename)
|
13
|
+
# puts "uri = #{dialog.uri}"
|
14
|
+
end
|
15
|
+
dialog.destroy
|
16
|
+
end
|
17
|
+
dialog.run
|
18
|
+
end
|
19
|
+
|
20
|
+
def gui_file_saveas(dirpath)
|
21
|
+
dialog = Gtk::FileChooserDialog.new(:title => "Save as",
|
22
|
+
:action => :save,
|
23
|
+
:buttons => [[Gtk::Stock::SAVE, :accept],
|
24
|
+
[Gtk::Stock::CANCEL, :cancel]])
|
25
|
+
dialog.set_current_folder(dirpath)
|
26
|
+
dialog.signal_connect("response") do |dialog, response_id|
|
27
|
+
if response_id == Gtk::ResponseType::ACCEPT
|
28
|
+
file_saveas(dialog.filename)
|
29
|
+
end
|
30
|
+
dialog.destroy
|
31
|
+
end
|
32
|
+
|
33
|
+
dialog.run
|
34
|
+
end
|
35
|
+
|
36
|
+
def idle_func
|
37
|
+
# puts "IDLEFUNC"
|
38
|
+
if $idle_scroll_to_mark
|
39
|
+
# Ripl.start :binding => binding
|
40
|
+
# $view.get_visible_rect
|
41
|
+
vr = $view.visible_rect
|
42
|
+
|
43
|
+
# iter = b.get_iter_at(:offset => i)
|
44
|
+
|
45
|
+
b = $view.buffer
|
46
|
+
iter = b.get_iter_at(:offset => b.cursor_position)
|
47
|
+
iterxy = $view.get_iter_location(iter)
|
48
|
+
# puts "ITERXY" + iterxy.inspect
|
49
|
+
# Ripl.start :binding => binding
|
50
|
+
|
51
|
+
intr = iterxy.intersect(vr)
|
52
|
+
if intr.nil?
|
53
|
+
$view.set_cursor_pos($view.buffer.cursor_position)
|
54
|
+
else
|
55
|
+
$idle_scroll_to_mark = false
|
56
|
+
end
|
57
|
+
|
58
|
+
sleep(0.1)
|
59
|
+
end
|
60
|
+
sleep(0.01)
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
|
64
|
+
def center_on_current_line()
|
65
|
+
b = $view.buffer
|
66
|
+
iter = b.get_iter_at(:offset => b.cursor_position)
|
67
|
+
within_margin = 0.0 #margin as a [0.0,0.5) fraction of screen size
|
68
|
+
use_align = true
|
69
|
+
xalign = 0.0 #0.0=top 1.0=bottom, 0.5=center
|
70
|
+
yalign = 0.5
|
71
|
+
$view.scroll_to_iter(iter, within_margin, use_align, xalign, yalign)
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_visible_area()
|
75
|
+
view = $view
|
76
|
+
vr = view.visible_rect
|
77
|
+
startpos = view.get_iter_at_position_raw(vr.x, vr.y)[1].offset
|
78
|
+
endpos = view.get_iter_at_position_raw(vr.x + vr.width, vr.y + vr.height)[1].offset
|
79
|
+
return [startpos, endpos]
|
80
|
+
end
|
81
|
+
|
82
|
+
def page_up
|
83
|
+
$view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), -1, false)
|
84
|
+
return true
|
85
|
+
end
|
86
|
+
|
87
|
+
def page_down
|
88
|
+
$view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), 1, false)
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
|
92
|
+
def paste_system_clipboard()
|
93
|
+
# clipboard = $vmag.window.get_clipboard(Gdk::Selection::CLIPBOARD)
|
94
|
+
utf8_string = Gdk::Atom.intern("UTF8_STRING")
|
95
|
+
# x = clipboard.request_contents(utf8_string)
|
96
|
+
|
97
|
+
widget = Gtk::Invisible.new
|
98
|
+
clipboard = Gtk::Clipboard.get_default($vmag.window.display)
|
99
|
+
received_text = ""
|
100
|
+
|
101
|
+
target_string = Gdk::Selection::TARGET_STRING
|
102
|
+
ti = clipboard.request_contents(target_string)
|
103
|
+
|
104
|
+
# clipboard.request_contents(target_string) do |_clipboard, selection_data|
|
105
|
+
# received_text = selection_data.text
|
106
|
+
# puts "received_text=#{received_text}"
|
107
|
+
# end
|
108
|
+
if clipboard.wait_is_text_available?
|
109
|
+
received_text = clipboard.wait_for_text
|
110
|
+
end
|
111
|
+
|
112
|
+
if received_text != "" and !received_text.nil?
|
113
|
+
max_clipboard_items = 100
|
114
|
+
if received_text != $clipboard[-1]
|
115
|
+
#TODO: HACK
|
116
|
+
$paste_lines = false
|
117
|
+
end
|
118
|
+
$clipboard << received_text
|
119
|
+
# puts $clipboard[-1]
|
120
|
+
$clipboard = $clipboard[-([$clipboard.size, max_clipboard_items].min)..-1]
|
121
|
+
end
|
122
|
+
return received_text
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_system_clipboard(arg)
|
126
|
+
# return if arg.class != String
|
127
|
+
# return if s.size < 1
|
128
|
+
# utf8_string = Gdk::Atom.intern("UTF8_STRING")
|
129
|
+
widget = Gtk::Invisible.new
|
130
|
+
clipboard = Gtk::Clipboard.get_default($vmag.window.display)
|
131
|
+
clipboard.text = arg
|
132
|
+
end
|
133
|
+
|
134
|
+
def gui_create_buffer(id)
|
135
|
+
puts "gui_create_buffer(#{id})"
|
136
|
+
buf1 = GtkSource::Buffer.new()
|
137
|
+
view = VSourceView.new()
|
138
|
+
|
139
|
+
view.set_highlight_current_line(true)
|
140
|
+
view.set_show_line_numbers(true)
|
141
|
+
view.set_buffer(buf1)
|
142
|
+
|
143
|
+
ssm = GtkSource::StyleSchemeManager.new
|
144
|
+
ssm.set_search_path(ssm.search_path << ppath("styles/"))
|
145
|
+
# sty = ssm.get_scheme("dark")
|
146
|
+
sty = ssm.get_scheme("molokai_edit")
|
147
|
+
# puts ssm.scheme_ids
|
148
|
+
|
149
|
+
view.buffer.highlight_matching_brackets = true
|
150
|
+
view.buffer.style_scheme = sty
|
151
|
+
|
152
|
+
provider = Gtk::CssProvider.new
|
153
|
+
provider.load(data: "textview { font-family: Monospace; font-size: 11pt; }")
|
154
|
+
# provider.load(data: "textview { font-family: Arial; font-size: 12pt; }")
|
155
|
+
view.style_context.add_provider(provider)
|
156
|
+
view.wrap_mode = :char
|
157
|
+
|
158
|
+
$vmag.buffers[id] = view
|
159
|
+
end
|
160
|
+
|
161
|
+
def gui_set_file_lang(id, lname)
|
162
|
+
view = $vmag.buffers[id]
|
163
|
+
lm = GtkSource::LanguageManager.new
|
164
|
+
lang = nil
|
165
|
+
lm.set_search_path(lm.search_path << ppath("lang/"))
|
166
|
+
lang = lm.get_language(lname)
|
167
|
+
|
168
|
+
view.buffer.language = lang
|
169
|
+
view.buffer.highlight_syntax = true
|
170
|
+
end
|
171
|
+
|
172
|
+
def gui_add_image(imgpath, pos)
|
173
|
+
end
|
174
|
+
|
175
|
+
# TODO:?
|
176
|
+
def gui_select_window_close(arg = nil)
|
177
|
+
end
|
178
|
+
|
179
|
+
# def set_window_title(str)
|
180
|
+
# unimplemented
|
181
|
+
# end
|
182
|
+
|
183
|
+
def gui_set_buffer_contents(id, txt)
|
184
|
+
# $vbuf.set_text(txt)
|
185
|
+
puts "gui_set_buffer_contents(#{id}, txt)"
|
186
|
+
|
187
|
+
$vmag.buffers[id].buffer.set_text(txt)
|
188
|
+
end
|
189
|
+
|
190
|
+
def gui_set_cursor_pos(id, pos)
|
191
|
+
$view.set_cursor_pos(pos)
|
192
|
+
# Ripl.start :binding => binding
|
193
|
+
end
|
194
|
+
|
195
|
+
def gui_set_current_buffer(id)
|
196
|
+
view = $vmag.buffers[id]
|
197
|
+
puts "gui_set_current_buffer(#{id}), view=#{view}"
|
198
|
+
buf1 = view.buffer
|
199
|
+
$vmag.view = view
|
200
|
+
$vmag.buf1 = buf1
|
201
|
+
$view = view
|
202
|
+
$vbuf = buf1
|
203
|
+
|
204
|
+
$vmag.sw.remove($vmag.sw.child) if !$vmag.sw.child.nil?
|
205
|
+
$vmag.sw.add(view)
|
206
|
+
|
207
|
+
view.grab_focus
|
208
|
+
#view.set_focus(10)
|
209
|
+
view.set_cursor_visible(true)
|
210
|
+
#view.move_cursor(1, 1, false)
|
211
|
+
view.place_cursor_onscreen
|
212
|
+
|
213
|
+
#TODO:
|
214
|
+
# itr = view.buffer.get_iter_at(:offset => 0)
|
215
|
+
# view.buffer.place_cursor(itr)
|
216
|
+
|
217
|
+
# wtitle = ""
|
218
|
+
# wtitle = buf.fname if !buf.fname.nil?
|
219
|
+
$vmag.sw.show_all
|
220
|
+
end
|
221
|
+
|
222
|
+
def gui_set_window_title(wtitle, subtitle = "")
|
223
|
+
$vmag.window.title = wtitle
|
224
|
+
$vmag.window.titlebar.subtitle = subtitle
|
225
|
+
end
|
226
|
+
|
227
|
+
class VMAgui
|
228
|
+
attr_accessor :buffers, :sw, :view, :buf1, :window
|
229
|
+
|
230
|
+
VERSION = "1.0"
|
231
|
+
|
232
|
+
HEART = "♥"
|
233
|
+
RADIUS = 150
|
234
|
+
N_WORDS = 5
|
235
|
+
FONT = "Serif 18"
|
236
|
+
TEXT = "I ♥ GTK+"
|
237
|
+
|
238
|
+
def initialize()
|
239
|
+
@show_overlay = true
|
240
|
+
@da = nil
|
241
|
+
@buffers = {}
|
242
|
+
@view = nil
|
243
|
+
@buf1 = nil
|
244
|
+
end
|
245
|
+
|
246
|
+
def run
|
247
|
+
init_window
|
248
|
+
# init_rtext
|
249
|
+
Gtk.main
|
250
|
+
end
|
251
|
+
|
252
|
+
def start_overlay_draw()
|
253
|
+
@da = Gtk::Fixed.new
|
254
|
+
@overlay.add_overlay(@da)
|
255
|
+
@overlay.set_overlay_pass_through(@da, true)
|
256
|
+
end
|
257
|
+
|
258
|
+
def clear_overlay()
|
259
|
+
if @da != nil
|
260
|
+
@overlay.remove(@da)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def overlay_draw_text(text, textpos)
|
265
|
+
# puts "overlay_draw_text #{[x,y]}"
|
266
|
+
(x, y) = @view.pos_to_coord(textpos)
|
267
|
+
# puts "overlay_draw_text #{[x,y]}"
|
268
|
+
label = Gtk::Label.new("<span background='#00000088' foreground='#ff0000' weight='ultrabold'>#{text}</span>")
|
269
|
+
label.use_markup = true
|
270
|
+
@da.put(label, x, y)
|
271
|
+
end
|
272
|
+
|
273
|
+
def end_overlay_draw()
|
274
|
+
@da.show_all
|
275
|
+
end
|
276
|
+
|
277
|
+
def toggle_overlay
|
278
|
+
@show_overlay = @show_overlay ^ 1
|
279
|
+
if !@show_overlay
|
280
|
+
if @da != nil
|
281
|
+
@overlay.remove(@da)
|
282
|
+
end
|
283
|
+
return
|
284
|
+
else
|
285
|
+
@da = Gtk::Fixed.new
|
286
|
+
@overlay.add_overlay(@da)
|
287
|
+
@overlay.set_overlay_pass_through(@da, true)
|
288
|
+
end
|
289
|
+
|
290
|
+
(startpos, endpos) = get_visible_area
|
291
|
+
s = @view.buffer.text
|
292
|
+
wpos = s.enum_for(:scan, /\W(\w)/).map { Regexp.last_match.begin(0) + 1 }
|
293
|
+
wpos = wpos[0..130]
|
294
|
+
|
295
|
+
# vr = @view.visible_rect
|
296
|
+
# # gtk_text_view_get_line_at_y
|
297
|
+
# # gtk_text_view_get_iter_at_position
|
298
|
+
# gtk_text_view_get_iter_at_position(vr.
|
299
|
+
# istart = @view.get_iter_at_position(vr.x,vr.y)
|
300
|
+
# istart = @view.get_iter_at_y(vr.y)
|
301
|
+
# startpos = @view.get_iter_at_position_raw(vr.x,vr.y)[1].offset
|
302
|
+
# endpos = @view.get_iter_at_position_raw(vr.x+vr.width,vr.y+vr.height)[1].offset
|
303
|
+
# puts "startpos,endpos:#{[startpos, endpos]}"
|
304
|
+
|
305
|
+
da = @da
|
306
|
+
if false
|
307
|
+
da.signal_connect "draw" do |widget, cr|
|
308
|
+
cr.save
|
309
|
+
for pos in wpos
|
310
|
+
(x, y) = @view.pos_to_coord(pos)
|
311
|
+
|
312
|
+
layout = da.create_pango_layout("XY")
|
313
|
+
desc = Pango::FontDescription.new("sans bold 11")
|
314
|
+
layout.font_description = desc
|
315
|
+
|
316
|
+
cr.move_to(x, y)
|
317
|
+
# cr.move_to(gutter_width, 300)
|
318
|
+
cr.pango_layout_path(layout)
|
319
|
+
|
320
|
+
cr.set_source_rgb(1.0, 0.0, 0.0)
|
321
|
+
cr.fill_preserve
|
322
|
+
end
|
323
|
+
cr.restore
|
324
|
+
false # = draw other
|
325
|
+
# true # = Don't draw others
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
for pos in wpos
|
330
|
+
(x, y) = @view.pos_to_coord(pos)
|
331
|
+
# da.put(Gtk::Label.new("AB"), x, y)
|
332
|
+
label = Gtk::Label.new("<span background='#00000088' foreground='#ff0000' weight='ultrabold'>AB</span>")
|
333
|
+
label.use_markup = true
|
334
|
+
da.put(label, x, y)
|
335
|
+
end
|
336
|
+
|
337
|
+
# puts @view.pos_to_coord(300).inspect
|
338
|
+
|
339
|
+
@da.show_all
|
340
|
+
end
|
341
|
+
|
342
|
+
def handle_deltas()
|
343
|
+
while d = buf.deltas.shift
|
344
|
+
pos = d[0]
|
345
|
+
op = d[1]
|
346
|
+
num = d[2]
|
347
|
+
txt = d[3]
|
348
|
+
if op == DELETE
|
349
|
+
startiter = @buf1.get_iter_at(:offset => pos)
|
350
|
+
enditer = @buf1.get_iter_at(:offset => pos + num)
|
351
|
+
@buf1.delete(startiter, enditer)
|
352
|
+
elsif op == INSERT
|
353
|
+
startiter = @buf1.get_iter_at(:offset => pos)
|
354
|
+
@buf1.insert(startiter, txt)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def add_to_minibuf(msg)
|
360
|
+
startiter = @minibuf.buffer.get_iter_at(:offset => 0)
|
361
|
+
@minibuf.buffer.insert(startiter, "#{msg}\n")
|
362
|
+
@minibuf.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES), -1, false)
|
363
|
+
end
|
364
|
+
|
365
|
+
def init_minibuffer()
|
366
|
+
# Init minibuffer
|
367
|
+
sw = Gtk::ScrolledWindow.new
|
368
|
+
sw.set_policy(:automatic, :automatic)
|
369
|
+
overlay = Gtk::Overlay.new
|
370
|
+
overlay.add(sw)
|
371
|
+
# @vpaned.pack2(overlay, :resize => false)
|
372
|
+
@vbox.attach(overlay, 0, 2, 1, 1)
|
373
|
+
# overlay.set_size_request(-1, 50)
|
374
|
+
# $ovrl = overlay
|
375
|
+
# $ovrl.set_size_request(-1, 30)
|
376
|
+
$sw2 = sw
|
377
|
+
sw.set_size_request(-1, 12)
|
378
|
+
|
379
|
+
view = VSourceView.new()
|
380
|
+
view.set_highlight_current_line(false)
|
381
|
+
view.set_show_line_numbers(false)
|
382
|
+
# view.set_buffer(buf1)
|
383
|
+
ssm = GtkSource::StyleSchemeManager.new
|
384
|
+
ssm.set_search_path(ssm.search_path << ppath("styles/"))
|
385
|
+
sty = ssm.get_scheme("molokai_edit")
|
386
|
+
view.buffer.highlight_matching_brackets = false
|
387
|
+
view.buffer.style_scheme = sty
|
388
|
+
provider = Gtk::CssProvider.new
|
389
|
+
# provider.load(data: "textview { font-family: Monospace; font-size: 11pt; }")
|
390
|
+
provider.load(data: "textview { font-family: Arial; font-size: 10pt; color:#ff0000}")
|
391
|
+
view.style_context.add_provider(provider)
|
392
|
+
view.wrap_mode = :char
|
393
|
+
@minibuf = view
|
394
|
+
# Ripl.start :binding => binding
|
395
|
+
# startiter = view.buffer.get_iter_at(:offset => 0)
|
396
|
+
message("STARTUP")
|
397
|
+
sw.add(view)
|
398
|
+
end
|
399
|
+
|
400
|
+
def init_header_bar()
|
401
|
+
header = Gtk::HeaderBar.new
|
402
|
+
@header = header
|
403
|
+
header.show_close_button = true
|
404
|
+
header.title = ""
|
405
|
+
header.has_subtitle = true
|
406
|
+
header.subtitle = ""
|
407
|
+
# Ripl.start :binding => binding
|
408
|
+
|
409
|
+
# icon = Gio::ThemedIcon.new("mail-send-receive-symbolic")
|
410
|
+
# icon = Gio::ThemedIcon.new("document-open-symbolic")
|
411
|
+
# icon = Gio::ThemedIcon.new("dialog-password")
|
412
|
+
|
413
|
+
#edit-redo edit-paste edit-find-replace edit-undo edit-find edit-cut edit-copy
|
414
|
+
#document-open document-save document-save-as document-properties document-new
|
415
|
+
# document-revert-symbolic
|
416
|
+
#
|
417
|
+
|
418
|
+
#TODO:
|
419
|
+
# button = Gtk::Button.new
|
420
|
+
# icon = Gio::ThemedIcon.new("open-menu-symbolic")
|
421
|
+
# image = Gtk::Image.new(:icon => icon, :size => :button)
|
422
|
+
# button.add(image)
|
423
|
+
# header.pack_end(button)
|
424
|
+
|
425
|
+
button = Gtk::Button.new
|
426
|
+
icon = Gio::ThemedIcon.new("document-open-symbolic")
|
427
|
+
image = Gtk::Image.new(:icon => icon, :size => :button)
|
428
|
+
button.add(image)
|
429
|
+
header.pack_end(button)
|
430
|
+
|
431
|
+
button.signal_connect "clicked" do |_widget|
|
432
|
+
open_file_dialog
|
433
|
+
end
|
434
|
+
|
435
|
+
button = Gtk::Button.new
|
436
|
+
icon = Gio::ThemedIcon.new("document-save-symbolic")
|
437
|
+
image = Gtk::Image.new(:icon => icon, :size => :button)
|
438
|
+
button.add(image)
|
439
|
+
header.pack_end(button)
|
440
|
+
button.signal_connect "clicked" do |_widget|
|
441
|
+
buf.save
|
442
|
+
end
|
443
|
+
|
444
|
+
button = Gtk::Button.new
|
445
|
+
icon = Gio::ThemedIcon.new("document-new-symbolic")
|
446
|
+
image = Gtk::Image.new(:icon => icon, :size => :button)
|
447
|
+
button.add(image)
|
448
|
+
header.pack_end(button)
|
449
|
+
button.signal_connect "clicked" do |_widget|
|
450
|
+
create_new_file
|
451
|
+
end
|
452
|
+
|
453
|
+
box = Gtk::Box.new(:horizontal, 0)
|
454
|
+
box.style_context.add_class("linked")
|
455
|
+
|
456
|
+
button = Gtk::Button.new
|
457
|
+
image = Gtk::Image.new(:icon_name => "pan-start-symbolic", :size => :button)
|
458
|
+
button.add(image)
|
459
|
+
box.add(button)
|
460
|
+
button.signal_connect "clicked" do |_widget|
|
461
|
+
history_switch_backwards
|
462
|
+
end
|
463
|
+
|
464
|
+
button = Gtk::Button.new
|
465
|
+
image = Gtk::Image.new(:icon_name => "pan-end-symbolic", :size => :button)
|
466
|
+
button.add(image)
|
467
|
+
box.add(button)
|
468
|
+
button.signal_connect "clicked" do |_widget|
|
469
|
+
history_switch_forwards
|
470
|
+
end
|
471
|
+
|
472
|
+
button = Gtk::Button.new
|
473
|
+
icon = Gio::ThemedIcon.new("window-close-symbolic")
|
474
|
+
image = Gtk::Image.new(:icon => icon, :size => :button)
|
475
|
+
button.add(image)
|
476
|
+
box.add(button)
|
477
|
+
button.signal_connect "clicked" do |_widget|
|
478
|
+
bufs.close_current_buffer
|
479
|
+
end
|
480
|
+
|
481
|
+
header.pack_start(box)
|
482
|
+
@window.titlebar = header
|
483
|
+
@window.add(Gtk::TextView.new)
|
484
|
+
end
|
485
|
+
|
486
|
+
def create_menu_item(label, depth)
|
487
|
+
menuitem = Gtk::MenuItem.new(:label => label)
|
488
|
+
menuitem.submenu = create_menu(depth)
|
489
|
+
@menubar.append(menuitem)
|
490
|
+
end
|
491
|
+
|
492
|
+
def create_menu(depth)
|
493
|
+
return nil if depth < 1
|
494
|
+
|
495
|
+
menu = Gtk::Menu.new
|
496
|
+
last_item = nil
|
497
|
+
(0..5).each do |i|
|
498
|
+
j = i + 1
|
499
|
+
label = "item #{depth} - #{j}"
|
500
|
+
menu_item = Gtk::RadioMenuItem.new(nil, label)
|
501
|
+
menu_item.join_group(last_item) if last_item
|
502
|
+
last_item = menu_item
|
503
|
+
menu.append(menu_item)
|
504
|
+
menu_item.sensitive = false if i == 3
|
505
|
+
menu_item.submenu = create_menu(depth - 1)
|
506
|
+
end
|
507
|
+
|
508
|
+
menu
|
509
|
+
end
|
510
|
+
|
511
|
+
def init_window
|
512
|
+
@window = Gtk::Window.new(:toplevel)
|
513
|
+
@window.set_default_size(650, 850)
|
514
|
+
@window.title = "Multiple Views"
|
515
|
+
@window.show_all
|
516
|
+
# vpaned = Gtk::Paned.new(:horizontal)
|
517
|
+
@vpaned = Gtk::Paned.new(:vertical)
|
518
|
+
#@vpaned = Gtk::Box.new(:vertical, 0)
|
519
|
+
# @vbox = Gtk::Box.new(:vertical, 0)
|
520
|
+
@vbox = Gtk::Grid.new()
|
521
|
+
@window.add(@vbox)
|
522
|
+
|
523
|
+
@menubar = Gtk::MenuBar.new
|
524
|
+
@menubar.expand = false
|
525
|
+
|
526
|
+
|
527
|
+
@sw = Gtk::ScrolledWindow.new
|
528
|
+
@sw.set_policy(:automatic, :automatic)
|
529
|
+
@overlay = Gtk::Overlay.new
|
530
|
+
@overlay.add(@sw)
|
531
|
+
|
532
|
+
# @vpaned.pack1(@overlay, :resize => true)
|
533
|
+
# @vpaned.pack2(@menubar, :resize => false)
|
534
|
+
# @vbox.add(@menubar, :resize => false)
|
535
|
+
|
536
|
+
init_header_bar
|
537
|
+
|
538
|
+
# @window.show_all
|
539
|
+
|
540
|
+
# @vbox.pack_start(@menubar, :expand => false, :fill => false, :padding => 0 )
|
541
|
+
# @vbox.pack_start(@menubar)
|
542
|
+
# @vbox.pack_start(@overlay, :expand => true, :fill => true, :padding => 0 )
|
543
|
+
# @vbox.pack_start(@overlay, :expand => true, :fill => true, :padding => 0 )
|
544
|
+
@vbox.attach(@menubar, 0, 0, 1, 1)
|
545
|
+
@vbox.attach(@overlay, 0, 1, 1, 1)
|
546
|
+
@overlay.vexpand = true
|
547
|
+
@overlay.hexpand = true
|
548
|
+
|
549
|
+
@menubar.vexpand = false
|
550
|
+
@menubar.hexpand = false
|
551
|
+
|
552
|
+
init_minibuffer
|
553
|
+
|
554
|
+
|
555
|
+
@window.show_all
|
556
|
+
vma.start
|
557
|
+
Vimamsa::Menu.new(@menubar)
|
558
|
+
@window.show_all
|
559
|
+
|
560
|
+
end
|
561
|
+
end
|