vimamsa 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,161 @@
1
+
2
+ # Similar feature as Vim EasyMotion https://github.com/easymotion/vim-easymotion
3
+ class EasyJump
4
+ def initialize()
5
+ make_jump_sequence
6
+ end
7
+ end
8
+
9
+ def easy_jump(direction)
10
+ # message "EASY JUMP"
11
+ visible_range = get_visible_area()
12
+ visible_text = $buffer[visible_range[0]..visible_range[1]]
13
+ wsmarks = scan_word_start_marks(visible_text)
14
+ line_starts = scan_indexes(visible_text, /^/)
15
+ lsh = Hash[line_starts.collect { |x| [x, true] }]
16
+ wsmh = Hash[wsmarks.collect { |x| [x, true] }]
17
+
18
+ wsmarks.select! { |x|
19
+ r = true
20
+ r = false if lsh[x] or lsh[x - 1] or lsh[x - 2]
21
+ r
22
+ }
23
+
24
+ linestart_buf = (line_starts).collect { |x| x + visible_range[0] }
25
+ wsmarks_buf = (wsmarks).collect { |x| x + visible_range[0] }
26
+
27
+ # All line starts should be accessible with just two key presses, so put them first in order
28
+ # Other word start positions ordered by distance from current pos
29
+ wsmarks_buf.sort_by! { |x| (x - $buffer.pos).abs }
30
+ $easy_jump_wsmarks = linestart_buf + wsmarks_buf
31
+
32
+ $jump_sequence = make_jump_sequence($easy_jump_wsmarks.size)
33
+
34
+ $input_char_call_func = method(:easy_jump_input_char)
35
+ $kbd.set_mode(:readchar)
36
+ $easy_jump_input = ""
37
+ easy_jump_draw
38
+ end
39
+
40
+ def easy_jump_input_char(c)
41
+ # vma.paint_stack = []
42
+ puts "EASY JUMP: easy_jump_input_char [#{c}]"
43
+ $easy_jump_input << c.upcase
44
+ if $jump_sequence.include?($easy_jump_input)
45
+ jshash = Hash[$jump_sequence.map.with_index.to_a]
46
+ nthword = jshash[$easy_jump_input]
47
+ puts "nthword:#{nthword} #{[$easy_jump_wsmarks[nthword],$jump_sequence[nthword]]}"
48
+ $buffer.set_pos($easy_jump_wsmarks[nthword])
49
+ $kbd.set_mode(:command)
50
+ $input_char_call_func = nil
51
+ $jump_sequence = []
52
+ $vmag.clear_overlay()
53
+ end
54
+ if $easy_jump_input.size > 2
55
+ $kbd.set_mode(:command)
56
+ $input_char_call_func = nil
57
+ $jump_sequence = []
58
+ $vmag.clear_overlay()
59
+ end
60
+ end
61
+
62
+ def easy_jump_draw()
63
+ # puts $jump_sequence.inspect
64
+ # puts $easy_jump_wsmarks.inspect
65
+ $vmag.start_overlay_draw
66
+ for i in 0..($easy_jump_wsmarks.size - 1)
67
+ $vmag.overlay_draw_text($jump_sequence[i], $easy_jump_wsmarks[i])
68
+ end
69
+ $vmag.end_overlay_draw
70
+
71
+ return
72
+ return if $jump_sequence.empty?
73
+ puts "EASY JUMP DRAW"
74
+ screen_cord = cpp_function_wrapper(0, [$easy_jump_wsmarks])
75
+ screen_cord = screen_cord[1..$jump_sequence.size]
76
+ screen_cord.each_with_index { |point, i|
77
+ mark_str = $jump_sequence[i]
78
+ #puts "draw #{point[0]}x#{point[1]}"
79
+ draw_text(mark_str, point[0] + 3, point[1])
80
+ #break if m > $cpos
81
+ }
82
+ end
83
+
84
+ def make_jump_sequence(num_items)
85
+ left_hand = "asdfvgbqwertzxc123".upcase.split("")
86
+ right_hand = "jklhnnmyuiop890".upcase.split("")
87
+
88
+ sequence = []
89
+ left_hand_fast = "asdf".upcase.split("")
90
+ right_hand_fast = "jkl;".upcase.split("")
91
+
92
+ left_hand_slow = "wergc".upcase.split("") # v
93
+ right_hand_slow = "uiophnm,".upcase.split("")
94
+
95
+ left_hand_slow2 = "tzx23".upcase.split("")
96
+ right_hand_slow2 = "yb9'".upcase.split("")
97
+
98
+ # Rmoved characters that can be mixed: O0Q, 8B, I1, VY
99
+
100
+ left_fast_slow = Array.new(left_hand_fast).concat(left_hand_slow)
101
+ right_fast_slow = Array.new(right_hand_fast).concat(right_hand_slow)
102
+
103
+ left_hand_all = Array.new(left_hand_fast).concat(left_hand_slow).concat(left_hand_slow2)
104
+ right_hand_all = Array.new(right_hand_fast).concat(right_hand_slow).concat(right_hand_slow2)
105
+
106
+ left_hand_fast.each { |x|
107
+ left_hand_fast.each { |y|
108
+ sequence << "#{x}#{y}"
109
+ }
110
+ }
111
+
112
+ right_hand_fast.each { |x|
113
+ right_hand_fast.each { |y|
114
+ sequence << "#{x}#{y}"
115
+ }
116
+ }
117
+
118
+ right_hand_fast.each { |x|
119
+ left_hand_fast.each { |y|
120
+ sequence << "#{x}#{y}"
121
+ }
122
+ }
123
+
124
+ left_hand_fast.each { |x|
125
+ right_hand_fast.each { |y|
126
+ sequence << "#{x}#{y}"
127
+ }
128
+ }
129
+
130
+ left_hand_slow.each { |x|
131
+ right_fast_slow.each { |y|
132
+ sequence << "#{x}#{y}"
133
+ }
134
+ }
135
+
136
+ right_hand_slow.each { |x|
137
+ left_fast_slow.each { |y|
138
+ sequence << "#{x}#{y}"
139
+ }
140
+ }
141
+
142
+ left_hand_slow2.each { |x|
143
+ right_hand_all.each { |y|
144
+ left_hand_all.each { |z|
145
+ sequence << "#{x}#{y}#{z}"
146
+ }
147
+ }
148
+ }
149
+
150
+ right_hand_slow2.each { |x|
151
+ left_hand_all.each { |y|
152
+ right_hand_all.each { |z|
153
+ sequence << "#{x}#{y}#{z}"
154
+ }
155
+ }
156
+ }
157
+
158
+ #printf("Size of sequence: %d\n",sequence.size)
159
+ #puts sequence.inspect
160
+ return sequence
161
+ end
@@ -0,0 +1,645 @@
1
+ require "pty"
2
+
3
+ def exec_in_terminal(cmd)
4
+ # puts "CMD:#{cmd}"
5
+
6
+ # global to prevent garbage collect unlink
7
+ $initf = Tempfile.new("bashinit")
8
+ # puts $initf.path
9
+ $initf.write(cmd)
10
+ $initf.write("rm #{$initf.path}\n")
11
+ $initf.write("\nexec bash\n")
12
+ $initf.close
13
+ # PTY.spawn("gnome-terminal", "--tab", "--", "bash", "-i", $initf.path, "-c", "exec bash")
14
+ fork { exec "gnome-terminal", "--tab", "--", "bash", "-i", $initf.path, "-c", "exec bash" }
15
+ end
16
+
17
+ def handle_drag_and_drop(fname)
18
+ debug "EDITOR:handle_drag_and_drop"
19
+ buf.handle_drag_and_drop(fname)
20
+ end
21
+
22
+ class Editor
23
+ attr_reader :file_content_search_paths, :file_name_search_paths
24
+ attr_accessor :converters, :fh, :paint_stack
25
+ #attr_writer :call_func, :update_highlight
26
+
27
+ def initialize()
28
+ # Thread.new{10000.times{|x|sleep(3);10000.times{|y|y+2};puts "FOOTHREAD #{x}"}}
29
+
30
+ # Search for content inside files (e.g. using ack/grep) in:
31
+ @file_content_search_paths = []
32
+
33
+ # Search for files based on filenames in:
34
+ @file_name_search_paths = []
35
+
36
+ #Regexp gsubs or other small modifiers of text
37
+ @converters = {}
38
+ @paint_stack = []
39
+ @_plugins = {}
40
+ end
41
+
42
+ def start
43
+ # $highlight = {}
44
+
45
+ # GLib::Idle.add
46
+ # Ripl.start :binding => binding
47
+ # GLib::Idle.add(proc{ puts "IDLEFUNC"})
48
+ # GLib::Idle.add(proc { idle_func })
49
+
50
+ $hook = Hook.new
51
+ register_plugin(:Hook, $hook)
52
+ $macro = Macro.new
53
+ register_plugin(:Macro, $macro)
54
+ $search = Search.new
55
+ register_plugin(:Search, $search)
56
+
57
+ $buffers = BufferList.new
58
+ $minibuffer = Buffer.new(">", "")
59
+
60
+ require "vimamsa/text_transforms"
61
+
62
+ debug "ARGV: " + ARGV.inspect
63
+ # build_key_bindings_tree
64
+ $kbd = KeyBindingTree.new()
65
+ $kbd.add_mode("C", :command)
66
+ $kbd.add_mode("I", :insert)
67
+ $kbd.add_mode("V", :visual)
68
+ $kbd.add_mode("M", :minibuffer)
69
+ $kbd.add_mode("R", :readchar)
70
+ $kbd.add_mode("B", :browse)
71
+ $kbd.set_default_mode(:command)
72
+ require "vimamsa/default_key_bindings"
73
+ sleep(0.03)
74
+
75
+ FileManager.init
76
+
77
+ dot_dir = File.expand_path("~/.vimamsa")
78
+ Dir.mkdir(dot_dir) unless File.exist?(dot_dir)
79
+
80
+ $cnf[:theme] = "Twilight_edit"
81
+ $cnf[:syntax_highlight] = true
82
+ settings_path = get_dot_path("settings.rb")
83
+ if File.exist?(settings_path)
84
+ $cnf = eval(IO.read(settings_path))
85
+ end
86
+
87
+ # set_qt_style(1)
88
+
89
+ # Limit file search to these extensions:
90
+ $find_extensions = [".txt", ".h", ".c", ".cpp", ".hpp", ".rb"]
91
+
92
+ dotfile = read_file("", "~/.vimamsarc")
93
+ eval(dotfile) if dotfile
94
+
95
+ # build_options
96
+
97
+ fname = nil
98
+ if conf(:startup_file)
99
+ fname_ = File.expand_path(conf(:startup_file))
100
+ if File.exist?(fname_)
101
+ fname = fname_
102
+ end
103
+ end
104
+ fname = ARGV[0] if ARGV.size >= 1 and File.file?(File.expand_path(ARGV[0]))
105
+ # vma.add_content_search_path(Dir.pwd)
106
+ for fn in ARGV
107
+ fn = File.expand_path(fn)
108
+ if File.directory?(fn)
109
+ vma.add_content_search_path(fn)
110
+ $search_dirs << fn
111
+ end
112
+ end
113
+
114
+ if fname
115
+ buffer = Buffer.new(read_file("", fname), fname)
116
+ else
117
+ buffer = Buffer.new("INIT\n")
118
+ end
119
+ $buffers << buffer
120
+
121
+ # load_theme($cnf[:theme])
122
+
123
+ # render_buffer($buffer, 1) #TODO
124
+
125
+ # gui_select_buffer_init #TODO
126
+ # gui_file_finder_init #TODO
127
+
128
+ #Load plugins
129
+ require "vimamsa/file_history.rb"
130
+ @fh = FileHistory.new
131
+ # @_plugins[:FileFinder] = FileFinder.new
132
+ @_plugins[:FileHistory] = @fh
133
+
134
+ register_plugin(:FileHistory, @fh)
135
+ register_plugin(:FileFinder, FileFinder.new)
136
+ # To access via vma.FileFinder
137
+ # self.define_singleton_method(:FileFinder) { @_plugins[:FileFinder] }
138
+
139
+ $hook.call(:after_init)
140
+ end
141
+
142
+ def register_plugin(name, obj)
143
+ @_plugins[name] = obj
144
+ # To access via e.g. vma.FileFinder
145
+ self.define_singleton_method(name) { obj }
146
+ end
147
+
148
+ def buf()
149
+ return $buffer
150
+ end
151
+
152
+ def marshal_save(varname, vardata)
153
+ save_var_to_file(varname, Marshal.dump(vardata))
154
+ end
155
+
156
+ def marshal_load(varname, default_data = nil)
157
+ mdata = load_var_from_file(varname)
158
+ if mdata
159
+ return Marshal.load(mdata)
160
+ else
161
+ return default_data
162
+ end
163
+ end
164
+
165
+ def save_var_to_file(varname, vardata)
166
+ fn = get_dot_path(varname)
167
+ f = File.open(fn, "w")
168
+ File.binwrite(f, vardata)
169
+ f.close
170
+ end
171
+
172
+ def load_var_from_file(varname)
173
+ fn = get_dot_path(varname)
174
+ if File.exist?(fn)
175
+ vardata = IO.binread(fn)
176
+ if vardata
177
+ debug("Successfully red #{varname} from file #{fn}")
178
+ return vardata
179
+ end
180
+ end
181
+ return nil
182
+ end
183
+
184
+ def plug()
185
+ return @_plugins
186
+ end
187
+
188
+ def shutdown()
189
+ $hook.call(:shutdown)
190
+ save_state
191
+ end
192
+
193
+ def save_state
194
+ end
195
+
196
+ def add_content_search_path(pathstr)
197
+ p = File.expand_path(pathstr)
198
+ if !@file_content_search_paths.include?(p)
199
+ @file_content_search_paths << p
200
+ end
201
+ end
202
+
203
+ # Register converter
204
+ def reg_conv(converter, converter_id)
205
+ @converters[converter_id] = converter
206
+ reg_act(converter_id, proc { $buffer.convert_selected_text(converter_id) }, "Converter #{converter_id}", [:selection])
207
+ # reg_act(converter_id, "$buffer.convert_selected_text(:#{converter_id})", "Converter #{converter_id}", [:selection])
208
+ end
209
+
210
+ def apply_conv(converter_id, txt)
211
+ @converters[converter_id].apply(txt)
212
+ end
213
+
214
+ def get_content_search_paths()
215
+ r = @file_content_search_paths.clone
216
+ p = find_project_dir_of_cur_buffer()
217
+
218
+ if p and !@file_content_search_paths.include?(p)
219
+ r.insert(0, p)
220
+ end
221
+ return r
222
+ end
223
+
224
+ def can_open_extension?(filepath)
225
+ exts = $cnf[:extensions_to_open]
226
+ extname = Pathname.new(filepath).extname.downcase
227
+ can_open = exts.include?(extname)
228
+ puts "CAN OPEN?: #{can_open}"
229
+ return can_open
230
+ end
231
+ end
232
+
233
+ def _quit()
234
+ # Shut down the Qt thread before the ruby thread
235
+ vma.shutdown
236
+ qt_quit
237
+ exit
238
+ end
239
+
240
+ def fatal_error(msg)
241
+ puts msg
242
+ exit!
243
+ end
244
+
245
+ def file_saveas(filename)
246
+ $buffer.set_filename(filename)
247
+ $buffer.save()
248
+ end
249
+
250
+ def open_file_dialog()
251
+ path = ""
252
+ path = $buffer.fname if $buffer.fname
253
+ qt_open_file_dialog(File.dirname(path))
254
+ end
255
+
256
+ def system_clipboard_changed(clipboard_contents)
257
+ max_clipboard_items = 100
258
+ if clipboard_contents != $clipboard[-1]
259
+ #TODO: HACK
260
+ $paste_lines = false
261
+ end
262
+ $clipboard << clipboard_contents
263
+ # puts $clipboard[-1]
264
+ $clipboard = $clipboard[-([$clipboard.size, max_clipboard_items].min)..-1]
265
+ end
266
+
267
+ def set_clipboard(s)
268
+ if !(s.class <= String) or s.size == 0
269
+ puts s.inspect
270
+ puts [s, s.class, s.size]
271
+ log_error("s.class != String or s.size == 0")
272
+ Ripl.start :binding => binding
273
+ return
274
+ end
275
+ $clipboard << s
276
+ set_system_clipboard(s)
277
+ $register[$cur_register] = s
278
+ debug "SET CLIPBOARD: [#{s}]"
279
+ debug "REGISTER: #{$cur_register}:#{$register[$cur_register]}"
280
+ end
281
+
282
+ def set_cursor_pos(new_pos)
283
+ buf.set_pos(new_pos)
284
+ #render_buffer($buffer)
285
+ debug "New pos: #{new_pos}lpos:#{$buffer.lpos} cpos:#{$buffer.cpos}"
286
+ end
287
+
288
+ def set_last_command(cmd)
289
+ $command_history << cmd
290
+ end
291
+
292
+ def can_save_to_directory?(dpath)
293
+ return false if !File.exist?(dpath)
294
+ return false if !File.directory?(dpath)
295
+ return false if !File.writable?(dpath)
296
+ return true
297
+ end
298
+
299
+ def repeat_last_action()
300
+ cmd = $command_history.last
301
+ cmd[:method].call *cmd[:params] if cmd != nil
302
+ end
303
+
304
+ def repeat_last_find()
305
+ return if !defined? $last_find_command
306
+ $buffer.jump_to_next_instance_of_char($last_find_command[:char],
307
+ $last_find_command[:direction])
308
+ end
309
+
310
+ def set_next_command_count(num)
311
+ if $next_command_count != nil
312
+ $next_command_count = $next_command_count * 10 + num.to_i
313
+ else
314
+ $next_command_count = num.to_i
315
+ end
316
+ debug("NEXT COMMAND COUNT: #{$next_command_count}")
317
+ end
318
+
319
+ def start_minibuffer_cmd(bufname, bufstr, cmd)
320
+ $kbd.set_mode(:minibuffer)
321
+ $minibuffer = Buffer.new(bufstr, "")
322
+ $minibuffer.call_func = method(cmd)
323
+ end
324
+
325
+ def show_key_bindings()
326
+ kbd_s = "❙Key bindings❙\n"
327
+ kbd_s << "=======================================\n"
328
+ kbd_s << $kbd.to_s
329
+ kbd_s << "\n=======================================\n"
330
+ create_new_file(nil, kbd_s)
331
+ end
332
+
333
+ def diff_buffer()
334
+ bufstr = ""
335
+ orig_path = $buffer.fname
336
+ infile = Tempfile.new("out")
337
+ infile = Tempfile.new("in")
338
+ infile.write($buffer.to_s)
339
+ infile.flush
340
+ cmd = "diff -w '#{orig_path}' #{infile.path}"
341
+ # puts cmd
342
+ bufstr << run_cmd(cmd)
343
+ # puts bufstr
344
+ infile.close; infile.unlink
345
+ create_new_file(nil, bufstr)
346
+ end
347
+
348
+ def invoke_command()
349
+ start_minibuffer_cmd("", "", :execute_command)
350
+ end
351
+
352
+ def execute_command(input_str)
353
+ begin
354
+ out_str = eval(input_str, TOPLEVEL_BINDING) #TODO: Other binding?
355
+ $minibuffer.clear
356
+ $minibuffer << out_str.to_s #TODO: segfaults, why?
357
+ rescue SyntaxError
358
+ debug("SYNTAX ERROR with eval cmd #{action}: " + $!.to_s)
359
+ end
360
+ end
361
+
362
+ def minibuffer_end()
363
+ debug "minibuffer_end"
364
+ $kbd.set_mode(:command)
365
+ minibuffer_input = $minibuffer.to_s[0..-2]
366
+ return $minibuffer.call_func.call(minibuffer_input)
367
+ end
368
+
369
+ def minibuffer_cancel()
370
+ debug "minibuffer_cancel"
371
+ $kbd.set_mode(:command)
372
+ minibuffer_input = $minibuffer.to_s[0..-2]
373
+ # $minibuffer.call_func.call('')
374
+ end
375
+
376
+ def minibuffer_new_char(c)
377
+ if c == "\r"
378
+ raise "Should not come here"
379
+ debug "MINIBUFFER END"
380
+ else
381
+ $minibuffer.insert_txt(c)
382
+ debug "MINIBUFFER: #{c}"
383
+ end
384
+ #$buffer = $minibuffer
385
+ end
386
+
387
+ def readchar_new_char(c)
388
+ $input_char_call_func.call(c)
389
+ end
390
+
391
+ def minibuffer_delete()
392
+ $minibuffer.delete(BACKWARD_CHAR)
393
+ end
394
+
395
+ def message(s)
396
+ s = "[#{DateTime.now().strftime("%H:%M")}] #{s}"
397
+ puts s
398
+
399
+ $vmag.add_to_minibuf(s)
400
+ # $minibuffer = Buffer.new(s, "")
401
+ # $minibuffer[0..-1] = s # TODO
402
+ #render_minibuffer
403
+ end
404
+
405
+ GUESS_ENCODING_ORDER = [
406
+ Encoding::US_ASCII,
407
+ Encoding::UTF_8,
408
+ Encoding::Shift_JIS,
409
+ Encoding::EUC_JP,
410
+ Encoding::EucJP_ms,
411
+ Encoding::Big5,
412
+ Encoding::UTF_16BE,
413
+ Encoding::UTF_16LE,
414
+ Encoding::UTF_32BE,
415
+ Encoding::UTF_32LE,
416
+ Encoding::CP949,
417
+ Encoding::Emacs_Mule,
418
+ Encoding::EUC_KR,
419
+ Encoding::EUC_TW,
420
+ Encoding::GB18030,
421
+ Encoding::GBK,
422
+ Encoding::Stateless_ISO_2022_JP,
423
+ Encoding::CP51932,
424
+ Encoding::EUC_CN,
425
+ Encoding::GB12345,
426
+ Encoding::Windows_31J,
427
+ Encoding::MacJapanese,
428
+ Encoding::UTF8_MAC,
429
+ Encoding::BINARY,
430
+ ]
431
+
432
+ def create_new_file(filename = nil, file_contents = "\n")
433
+ debug "NEW FILE CREATED"
434
+ buffer = Buffer.new(file_contents)
435
+ qt_set_current_buffer(buffer.id) #TODO: remove?
436
+ $buffers << buffer
437
+ return buffer
438
+ end
439
+
440
+ def filter_buffer(buf)
441
+ i = 0
442
+ while i < buf.size
443
+ if buf[i].ord == 160
444
+ buf[i] = " "
445
+ #TODO: hack. fix properly
446
+ end
447
+ i += 1
448
+ end
449
+ return buf
450
+ end
451
+
452
+ def load_buffer(fname)
453
+ return if !File.exist?(fname)
454
+ existing_buffer = $buffers.get_buffer_by_filename(fname)
455
+ if existing_buffer != nil
456
+ $buffer_history << existing_buffer
457
+ return
458
+ end
459
+ debug("LOAD BUFFER: #{fname}")
460
+ buffer = Buffer.new(read_file("", fname), fname)
461
+ # qt_set_current_buffer(buffer.id)
462
+ buffer.set_active
463
+ debug("DONE LOAD: #{fname}")
464
+ #buf = filter_buffer(buffer)
465
+ # debug("END FILTER: #{fname}")
466
+ $buffers << buffer
467
+ #$buffer_history << $buffers.size - 1
468
+ end
469
+
470
+ def jump_to_file(filename, linenum = 0)
471
+ open_new_file(filename)
472
+ if linenum > 0
473
+ $buffer.jump_to_line(linenum)
474
+ center_on_current_line
475
+ end
476
+ end
477
+
478
+ #TODO: needed?
479
+ def open_existing_file(filename)
480
+ open_new_file(filename)
481
+ end
482
+
483
+ def open_new_file(filename, file_contents = "")
484
+ #TODO: expand path
485
+ filename = File.expand_path(filename)
486
+ b = $buffers.get_buffer_by_filename(filename)
487
+ # File is already opened to existing buffer
488
+ if b != nil
489
+ message "Switching to: #{filename}"
490
+ $buffers.set_current_buffer(b)
491
+ else
492
+ message "New file opened: #{filename}"
493
+ fname = filename
494
+ load_buffer(fname)
495
+ end
496
+ set_window_title("Vimamsa - #{File.basename(filename)}")
497
+ end
498
+
499
+ def scan_word_start_marks(search_str)
500
+ # \Z = end of string, just before last newline.
501
+ wsmarks = scan_indexes(search_str, /(?<=[^\p{Word}])\p{Word}|\Z/)
502
+ return wsmarks
503
+ end
504
+
505
+ def draw_text(str, x, y)
506
+ vma.paint_stack << [4, x, y, str]
507
+ end
508
+
509
+ def center_on_current_line__2del()
510
+ center_where_cursor
511
+ end
512
+
513
+ def hook_draw()
514
+ # TODO: as hook.register
515
+ # easy_jump_draw()
516
+ end
517
+
518
+ def render_buffer(buffer = 0, reset = 0)
519
+ tmpbuf = $buffer.to_s
520
+ debug "pos:#{$buffer.pos} L:#{$buffer.lpos} C:#{$buffer.cpos}"
521
+ pos = $buffer.pos
522
+ selection_start = $buffer.selection_start
523
+
524
+ if $buffer.need_redraw?
525
+ reset = 1
526
+ end
527
+ t1 = Time.now
528
+ hook_draw()
529
+
530
+ render_text(tmpbuf, pos, selection_start, reset) #TODO: remove?
531
+
532
+ if $buffer.need_redraw?
533
+ hpt_scan_images() if $debug #experimental
534
+ end
535
+
536
+ $buffer.highlight
537
+ if Time.now - t1 > 1 / 100.0
538
+ debug "SLOW render"
539
+ debug "Render time: #{Time.now - t1}"
540
+ end
541
+ $buffer.set_redrawed if reset == 1
542
+ end
543
+
544
+ def get_dot_path(sfx)
545
+ dot_dir = File.expand_path("~/.vimamsa")
546
+ Dir.mkdir(dot_dir) unless File.exist?(dot_dir)
547
+ dpath = "#{dot_dir}/#{sfx}"
548
+ return dpath
549
+ end
550
+
551
+ def get_file_line_pointer(s)
552
+ #"/code/vimamsa/lib/vimamsa/buffer_select.rb:31:def"
553
+ # m = s.match(/(~[a-z]*)?\/.*\//)
554
+ m = s.match(/((~[a-z]*)?\/.*\/\S+):(\d+)/)
555
+ if m != nil
556
+ if File.exist?(File.expand_path(m[1]))
557
+ return [m[1], m[3].to_i]
558
+ end
559
+ end
560
+ return nil
561
+ end
562
+
563
+ def open_url(url)
564
+ system("xdg-open", url)
565
+ end
566
+
567
+ def open_with_default_program(url)
568
+ system("xdg-open", url)
569
+ end
570
+
571
+ def run_cmd(cmd)
572
+ tmpf = Tempfile.new("vmarun", "/tmp").path
573
+ cmd = "#{cmd} > #{tmpf}"
574
+ puts "CMD:\n#{cmd}"
575
+ system("bash", "-c", cmd)
576
+ res_str = File.read(tmpf)
577
+ return res_str
578
+ end
579
+
580
+ require "open3"
581
+
582
+ def exec_cmd(bin_name, arg1 = nil, arg2 = nil, arg3 = nil, arg4 = nil, arg5 = nil)
583
+ assert_binary_exists(bin_name)
584
+ if !arg5.nil?
585
+ p = Open3.popen2(bin_name, arg1, arg2, arg3, arg4, arg5)
586
+ elsif !arg4.nil?
587
+ p = Open3.popen2(bin_name, arg1, arg2, arg3, arg4)
588
+ elsif !arg3.nil?
589
+ p = Open3.popen2(bin_name, arg1, arg2, arg3)
590
+ elsif !arg2.nil?
591
+ p = Open3.popen2(bin_name, arg1, arg2)
592
+ elsif !arg1.nil?
593
+ p = Open3.popen2(bin_name, arg1)
594
+ else
595
+ p = Open3.popen2(bin_name)
596
+ end
597
+
598
+ ret_str = p[1].read
599
+ return ret_str
600
+ end
601
+
602
+ def file_is_text_file(fpath)
603
+ puts "file_is_text_file(#{fpath})"
604
+ fpath = File.expand_path(fpath)
605
+ return false if !File.exist?(fpath)
606
+ r = exec_cmd("file", fpath)
607
+ puts "DEBUG:#{r}"
608
+ return true if r.match(/UTF-8.*text/)
609
+ return true if r.match(/ASCII.*text/)
610
+ return false
611
+ end
612
+
613
+ def set_register(char)
614
+ $cur_register = char
615
+ message("Set register #{char}")
616
+ end
617
+
618
+ def paste_register(char)
619
+ $c = $register[char]
620
+ message("Paste: #{$c}")
621
+ end
622
+
623
+ def find_project_dir_of_fn(fn)
624
+ pcomp = Pathname.new(fn).each_filename.to_a
625
+ parent_dirs = (0..(pcomp.size - 2)).collect { |x| "/" + pcomp[0..x].join("/") }.reverse
626
+ projdir = nil
627
+ for pdir in parent_dirs
628
+ candfn = "#{pdir}/.vma_project"
629
+ if File.exist?(candfn)
630
+ projdir = pdir
631
+ break
632
+ end
633
+ end
634
+ return projdir
635
+ end
636
+
637
+ def find_project_dir_of_cur_buffer()
638
+ # Find "project dir" of current file. If currently editing file in path "/foo/bar/baz/fn.txt" and file named "/foo/bar/.vma_project" exists, then dir /foo/bar is treated as project dir and subject to e.g. ack search.
639
+ pdir = nil
640
+ if $buffer.fname
641
+ pdir = find_project_dir_of_fn($buffer.fname)
642
+ end
643
+ # puts "Proj dir of current file: #{pdir}"
644
+ return pdir
645
+ end