vimamsa 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/vimamsa +34 -0
- data/lang/hyperplaintext.lang +129 -0
- data/lib/vimamsa.rb +32 -0
- data/lib/vimamsa/ack.rb +35 -0
- data/lib/vimamsa/actions.rb +125 -0
- data/lib/vimamsa/buffer.rb +1731 -0
- data/lib/vimamsa/buffer_list.rb +207 -0
- data/lib/vimamsa/constants.rb +44 -0
- data/lib/vimamsa/debug.rb +142 -0
- data/lib/vimamsa/default_key_bindings.rb +445 -0
- data/lib/vimamsa/easy_jump.rb +161 -0
- data/lib/vimamsa/editor.rb +645 -0
- data/lib/vimamsa/encrypt.rb +47 -0
- data/lib/vimamsa/file_finder.rb +103 -0
- data/lib/vimamsa/file_history.rb +100 -0
- data/lib/vimamsa/file_manager.rb +144 -0
- data/lib/vimamsa/hook.rb +46 -0
- data/lib/vimamsa/hyper_plain_text.rb +61 -0
- data/lib/vimamsa/key_binding_tree.rb +603 -0
- data/lib/vimamsa/macro.rb +177 -0
- data/lib/vimamsa/main.rb +71 -0
- data/lib/vimamsa/rbvma.rb +1014 -0
- data/lib/vimamsa/search.rb +100 -0
- data/lib/vimamsa/search_replace.rb +333 -0
- data/lib/vimamsa/text_transforms.rb +32 -0
- data/lib/vimamsa/util.rb +101 -0
- data/lib/vimamsa/version.rb +1 -1
- data/styles/134272-molokai.xml +33 -0
- data/styles/dark.xml +152 -0
- data/styles/molokai_edit.xml +49 -0
- metadata +31 -2
@@ -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
|