vimamsa 0.1.0 → 0.1.1

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