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,47 @@
|
|
1
|
+
|
2
|
+
require "openssl"
|
3
|
+
|
4
|
+
class Encrypt
|
5
|
+
def initialize(pass_phrase)
|
6
|
+
salt = "uvgixEtU"
|
7
|
+
@enc = OpenSSL::Cipher.new "AES-128-CBC"
|
8
|
+
@enc.encrypt
|
9
|
+
@enc.pkcs5_keyivgen pass_phrase, salt
|
10
|
+
@dec = OpenSSL::Cipher.new "AES-128-CBC"
|
11
|
+
@dec.decrypt
|
12
|
+
@dec.pkcs5_keyivgen pass_phrase, salt
|
13
|
+
end
|
14
|
+
|
15
|
+
def encrypt(text)
|
16
|
+
cipher=@enc
|
17
|
+
encrypted = cipher.update text
|
18
|
+
encrypted << cipher.final
|
19
|
+
encrypted = encrypted.unpack('H*')[0].upcase
|
20
|
+
@enc.reset
|
21
|
+
return encrypted
|
22
|
+
end
|
23
|
+
|
24
|
+
def decrypt(encrypted)
|
25
|
+
cipher=@dec
|
26
|
+
encrypted = [encrypted].pack("H*").unpack("C*").pack("c*")
|
27
|
+
plain = cipher.update encrypted
|
28
|
+
plain << cipher.final
|
29
|
+
plain.force_encoding("utf-8")
|
30
|
+
@dec.reset
|
31
|
+
return plain
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def decrypt_cur_buffer(password, b = nil)
|
36
|
+
$buffer.decrypt(password)
|
37
|
+
end
|
38
|
+
|
39
|
+
def encrypt_cur_buffer()
|
40
|
+
callback = proc{|x|encrypt_cur_buffer_callback(x)}
|
41
|
+
gui_one_input_action("Encrypt", "Password:", "Encrypt", callback)
|
42
|
+
end
|
43
|
+
|
44
|
+
def encrypt_cur_buffer_callback(password,b=nil)
|
45
|
+
$buffer.set_encrypted(password)
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "parallel"
|
2
|
+
|
3
|
+
class FileFinder
|
4
|
+
def initialize()
|
5
|
+
$hook.register(:shutdown, self.method("save"))
|
6
|
+
$dir_list = vma.marshal_load("file_index")
|
7
|
+
end
|
8
|
+
|
9
|
+
def save()
|
10
|
+
vma.marshal_save("file_index", $dir_list)
|
11
|
+
end
|
12
|
+
|
13
|
+
def start_gui()
|
14
|
+
if $search_dirs.empty?
|
15
|
+
message("FileFinder: No $search_dirs defined")
|
16
|
+
return
|
17
|
+
end
|
18
|
+
l = []
|
19
|
+
$select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
|
20
|
+
if $dir_list == nil
|
21
|
+
Thread.new { recursively_find_files() }
|
22
|
+
end
|
23
|
+
|
24
|
+
qt_select_update_window(l, $select_keys.collect { |x| x.upcase },
|
25
|
+
"gui_file_finder_select_callback",
|
26
|
+
"gui_file_finder_update_callback")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_file_index()
|
31
|
+
message("Start updating file index")
|
32
|
+
Thread.new {
|
33
|
+
recursively_find_files()
|
34
|
+
message("Finnish updating file index")
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def recursively_find_files()
|
39
|
+
debug("START find files")
|
40
|
+
dlist = []
|
41
|
+
|
42
|
+
for d in $search_dirs
|
43
|
+
debug("FIND FILEs IN #{d}")
|
44
|
+
dlist = dlist + Dir.glob("#{d}/**/*").select { |e| File.file?(e) and $find_extensions.include?(File.extname(e)) }
|
45
|
+
debug("FIND FILEs IN #{d} END")
|
46
|
+
end
|
47
|
+
#$dir_list = Dir.glob('./**/*').select { |e| File.file? e }
|
48
|
+
debug("END find files2")
|
49
|
+
$dir_list = dlist
|
50
|
+
debug("END find files")
|
51
|
+
return $dir_list
|
52
|
+
end
|
53
|
+
|
54
|
+
def filter_files(search_str)
|
55
|
+
dir_hash = {}
|
56
|
+
scores = Parallel.map($dir_list, in_threads: 8) do |file|
|
57
|
+
[file, srn_dst(search_str, file)]
|
58
|
+
end
|
59
|
+
for s in scores
|
60
|
+
dir_hash[s[0]] = s[1] if s[1] > 0
|
61
|
+
end
|
62
|
+
# puts scores
|
63
|
+
dir_hash = dir_hash.sort_by { |k, v| -v }
|
64
|
+
dir_hash = dir_hash[0..20]
|
65
|
+
dir_hash.map do |file, d|
|
66
|
+
puts "D:#{d} #{file}"
|
67
|
+
end
|
68
|
+
return dir_hash
|
69
|
+
end
|
70
|
+
|
71
|
+
def gui_file_finder_update_callback(search_str = "")
|
72
|
+
puts "FILE FINDER UPDATE CALLBACK: #{search_str}"
|
73
|
+
if (search_str.size > 1)
|
74
|
+
files = filter_files(search_str)
|
75
|
+
$file_search_list = files
|
76
|
+
return files
|
77
|
+
#puts files.inspect
|
78
|
+
#return files.values
|
79
|
+
end
|
80
|
+
return []
|
81
|
+
end
|
82
|
+
|
83
|
+
def gui_file_finder_select_callback(search_str, idx)
|
84
|
+
selected_file = $file_search_list[idx][0]
|
85
|
+
debug "FILE FINDER SELECT CALLBACK: s=#{search_str},i=#{idx}: #{selected_file}"
|
86
|
+
qt_select_window_close(0)
|
87
|
+
open_new_file(selected_file)
|
88
|
+
end
|
89
|
+
|
90
|
+
def gui_file_finder_handle_char(c)
|
91
|
+
puts "BUFFER SELECTOR INPUT CHAR: #{c}"
|
92
|
+
buffer_i = $select_keys.index(c)
|
93
|
+
if buffer_i != nil
|
94
|
+
gui_file_finder_callback(buffer_i)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# TODO: delete?
|
99
|
+
def gui_file_finder_init()
|
100
|
+
$kbd.add_mode("Z", :filefinder)
|
101
|
+
bindkey "Z enter", "$kbd.set_mode(:command)"
|
102
|
+
bindkey "Z return", "$kbd.set_mode(:command)"
|
103
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# History of previously opened files
|
2
|
+
|
3
|
+
class FileHistory
|
4
|
+
attr_accessor :history
|
5
|
+
|
6
|
+
def initialize()
|
7
|
+
# puts self.method("update")
|
8
|
+
# x = self.method("update")
|
9
|
+
# x.call("ASFASF")
|
10
|
+
|
11
|
+
$hook.register(:change_buffer, self.method("update"))
|
12
|
+
$hook.register(:shutdown, self.method("save"))
|
13
|
+
|
14
|
+
reg_act(:fhist_remove_nonexisting, proc { remove_nonexisting }, "Cleanup history, remove non-existing files")
|
15
|
+
|
16
|
+
@history = vma.marshal_load("file_history", {})
|
17
|
+
$search_list = []
|
18
|
+
end
|
19
|
+
|
20
|
+
# def self.init()
|
21
|
+
# end
|
22
|
+
|
23
|
+
def update(buf)
|
24
|
+
puts "FileHistory.update(buf=#{buf.fname})"
|
25
|
+
return if !buf.fname
|
26
|
+
@history[buf.fname] if !@history[buf.fname]
|
27
|
+
if !@history[buf.fname]
|
28
|
+
@history[buf.fname] = 1
|
29
|
+
else
|
30
|
+
@history[buf.fname] += 1
|
31
|
+
end
|
32
|
+
puts @history
|
33
|
+
|
34
|
+
# puts "FileHistory.update(buf=#{buf})"
|
35
|
+
end
|
36
|
+
|
37
|
+
def save()
|
38
|
+
vma.marshal_save("file_history", @history)
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_nonexisting()
|
42
|
+
size_orig = @history.size
|
43
|
+
for k, v in @history
|
44
|
+
if !File.exist?(k)
|
45
|
+
@history.delete(k)
|
46
|
+
log_message("Delete #{k} from history")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
size_new = @history.size
|
50
|
+
message("History size #{size_orig} => #{size_new}")
|
51
|
+
end
|
52
|
+
|
53
|
+
def start_gui()
|
54
|
+
return if $vma.fh.history.empty?
|
55
|
+
l = []
|
56
|
+
$select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
|
57
|
+
|
58
|
+
qt_select_update_window(l, $select_keys.collect { |x| x.upcase },
|
59
|
+
"gui_file_history_select_callback",
|
60
|
+
"gui_file_history_update_callback")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def fuzzy_filter(search_str, list, maxfinds)
|
65
|
+
h = {}
|
66
|
+
scores = Parallel.map(list, in_threads: 8) do |l|
|
67
|
+
[l, srn_dst(search_str, l)]
|
68
|
+
end
|
69
|
+
for s in scores
|
70
|
+
h[s[0]] = s[1] if s[1] > 0
|
71
|
+
end
|
72
|
+
h = h.sort_by { |k, v| -v }
|
73
|
+
h = h[0..maxfinds]
|
74
|
+
# h.map do |i, d|
|
75
|
+
# puts "D:#{d} #{i}"
|
76
|
+
# end
|
77
|
+
return h
|
78
|
+
end
|
79
|
+
|
80
|
+
def gui_file_history_update_callback(search_str = "")
|
81
|
+
puts "gui_file_history_update_callback: #{search_str}"
|
82
|
+
return [] if $vma.fh.history.empty?
|
83
|
+
$search_list = []
|
84
|
+
files = $vma.fh.history.keys.sort.collect { |x| [x, 0] }
|
85
|
+
|
86
|
+
if (search_str.size > 1)
|
87
|
+
files = fuzzy_filter(search_str, $vma.fh.history.keys, 40)
|
88
|
+
end
|
89
|
+
$search_list = files
|
90
|
+
return files
|
91
|
+
end
|
92
|
+
|
93
|
+
def gui_file_history_select_callback(search_str, idx)
|
94
|
+
# selected_file = $file_search_list[idx][0]
|
95
|
+
selected_file = $search_list[idx][0]
|
96
|
+
|
97
|
+
debug "FILE HISTORY SELECT CALLBACK: s=#{search_str},i=#{idx}: #{selected_file}"
|
98
|
+
qt_select_window_close(0)
|
99
|
+
open_new_file(selected_file)
|
100
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
class FileManager
|
2
|
+
@@cur
|
3
|
+
|
4
|
+
def initialize()
|
5
|
+
@buf = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.chdir_parent()
|
9
|
+
@@cur.chdir_parent
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.cur()
|
13
|
+
return @@cur
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.init()
|
17
|
+
reg_act(:start_file_selector, proc { FileManager.new.run; $kbd.set_mode(:file_exp) }, "File selector")
|
18
|
+
|
19
|
+
reg_act(:fexp_chdir_parent, proc { FileManager.chdir_parent }, "File selector")
|
20
|
+
reg_act(:fexp_select, proc { buf.module.select_line }, "")
|
21
|
+
|
22
|
+
reg_act(:fexp_sort_mtime, proc { FileManager.cur.sort_mtime }, "Sort based on time")
|
23
|
+
reg_act(:fexp_sort_fname, proc { FileManager.cur.sort_fname }, "Sort based on file name")
|
24
|
+
|
25
|
+
bindkey "C , j f", :start_file_selector
|
26
|
+
bindkey "C , f", :start_file_selector
|
27
|
+
|
28
|
+
# bindkey "C o", :delete_state
|
29
|
+
|
30
|
+
$kbd.add_minor_mode("fexp", :file_exp, :command)
|
31
|
+
|
32
|
+
bindkey "fexp o m", :fexp_sort_mtime
|
33
|
+
bindkey "fexp o f", :fexp_sort_fname
|
34
|
+
|
35
|
+
# bindkey "fexp l", [:fexp_right, proc { puts "==fexp_right==" }, ""]
|
36
|
+
bindkey "fexp h", :fexp_chdir_parent
|
37
|
+
bindkey "fexp esc", [:fexp_quit, proc { $kbd.set_mode(:command) }, ""]
|
38
|
+
bindkey "fexp enter", :fexp_select
|
39
|
+
bindkey "fexp l", :fexp_select
|
40
|
+
|
41
|
+
@sort_by = :name
|
42
|
+
end
|
43
|
+
|
44
|
+
def chdir_parent
|
45
|
+
dir_to_buf(fullp(".."))
|
46
|
+
end
|
47
|
+
|
48
|
+
def run
|
49
|
+
@@cur = self
|
50
|
+
ld = buflist.get_last_dir
|
51
|
+
dir_to_buf(ld)
|
52
|
+
# puts "ld=#{ld}"
|
53
|
+
# dlist = Dir["#{ld}/*"]
|
54
|
+
end
|
55
|
+
|
56
|
+
def sort_mtime
|
57
|
+
@sort_by = :mtime
|
58
|
+
dir_to_buf(@ld)
|
59
|
+
end
|
60
|
+
|
61
|
+
def sort_fname
|
62
|
+
@sort_by = :name
|
63
|
+
dir_to_buf(@ld)
|
64
|
+
end
|
65
|
+
|
66
|
+
def dir_to_buf(dirpath, b = nil)
|
67
|
+
# File.stat("testfile").mtime
|
68
|
+
dirpath = File.expand_path(dirpath)
|
69
|
+
@header = []
|
70
|
+
@header << "#{dirpath}"
|
71
|
+
@header << "=" * 40
|
72
|
+
@ld = dirpath
|
73
|
+
@dlist = Dir.children(@ld).sort
|
74
|
+
@cdirs = []
|
75
|
+
@cfiles = []
|
76
|
+
for x in @dlist
|
77
|
+
fpath = fullp(x)
|
78
|
+
|
79
|
+
ok = true
|
80
|
+
begin
|
81
|
+
fstat = File.stat(fpath)
|
82
|
+
rescue Errno::ENOENT # Broken link or something
|
83
|
+
next
|
84
|
+
end
|
85
|
+
next if x[0] == "."
|
86
|
+
if File.directory?(fpath)
|
87
|
+
# if f.directory?(fpath)
|
88
|
+
@cdirs << x
|
89
|
+
else
|
90
|
+
@cfiles << [x, fstat]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# sort_by = :mtime
|
95
|
+
# sort_by = :name
|
96
|
+
# Ripl.start :binding => binding
|
97
|
+
@cfiles.sort_by! { |x| x[1].mtime }.reverse! if @sort_by == :mtime
|
98
|
+
@cfiles.sort_by! { |x| x[1].size }.reverse! if @sort_by == :size
|
99
|
+
@cfiles.sort_by! { |x| x[0] } if @sort_by == :name
|
100
|
+
|
101
|
+
s = ""
|
102
|
+
s << @header.join("\n")
|
103
|
+
s << "\n"
|
104
|
+
s << "..\n"
|
105
|
+
s << @cdirs.join("\n")
|
106
|
+
s << "\n"
|
107
|
+
s << "\n"
|
108
|
+
for f in @cfiles
|
109
|
+
s << "#{f[0]}\n"
|
110
|
+
# s << @cfiles.join("\n")
|
111
|
+
end
|
112
|
+
|
113
|
+
if @buf.nil?
|
114
|
+
@buf = create_new_file(nil, s)
|
115
|
+
@buf.module = self
|
116
|
+
@buf.active_kbd_mode = :file_exp
|
117
|
+
else
|
118
|
+
@buf.set_content(s)
|
119
|
+
end
|
120
|
+
@buf.set_line_and_column_pos(@header.size, 0)
|
121
|
+
end
|
122
|
+
|
123
|
+
def fullp(fn)
|
124
|
+
"#{@ld}/#{fn}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def select_line
|
128
|
+
return if @buf.lpos < @header.size
|
129
|
+
# puts "def select_line"
|
130
|
+
fn = fullp(@buf.get_current_line[0..-2])
|
131
|
+
if File.directory?(fn)
|
132
|
+
puts "CHDIR: #{fn}"
|
133
|
+
dir_to_buf(fn)
|
134
|
+
# elsif vma.can_open_extension?(fn)
|
135
|
+
# jump_to_file(fn)
|
136
|
+
elsif file_is_text_file(fn)
|
137
|
+
bufs.close_current_buffer
|
138
|
+
jump_to_file(fn)
|
139
|
+
else
|
140
|
+
open_with_default_program(fn)
|
141
|
+
end
|
142
|
+
# puts l.inspect
|
143
|
+
end
|
144
|
+
end
|
data/lib/vimamsa/hook.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
class HookItem
|
3
|
+
attr_writer :method_name, :weight
|
4
|
+
|
5
|
+
def initialize(hook_method, weight)
|
6
|
+
@method_name = hook_method.to_s
|
7
|
+
|
8
|
+
if hook_method.class == Method
|
9
|
+
@call_func = hook_method
|
10
|
+
elsif hook_method.class == String
|
11
|
+
@call_func = method(hook_method)
|
12
|
+
end
|
13
|
+
@weight = weight
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(x = nil)
|
17
|
+
@call_func.call(x) if x != nil
|
18
|
+
@call_func.call() if x == nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
#$hook.register(:puts,"puts")
|
23
|
+
#$hook.call(:puts,"AAAA")
|
24
|
+
|
25
|
+
class Hook < Hash
|
26
|
+
|
27
|
+
#attr_reader :pos,
|
28
|
+
#attr_writer :call_func
|
29
|
+
|
30
|
+
def initialize()
|
31
|
+
end
|
32
|
+
|
33
|
+
def register(hook_id, hook_method, weight = 0)
|
34
|
+
self[hook_id] = [] if self[hook_id] == nil
|
35
|
+
self[hook_id] << HookItem.new(hook_method, weight)
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(hook_id, x = nil)
|
39
|
+
if self[hook_id]
|
40
|
+
self[hook_id].each { |hi|
|
41
|
+
hi.call(x) if x != nil
|
42
|
+
hi.call() if x == nil
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
def hpt_open_link()
|
4
|
+
end
|
5
|
+
|
6
|
+
def hpt_check_cur_word(w)
|
7
|
+
puts "check_cur_word(w)"
|
8
|
+
m = w.match(/⟦(.*)⟧/)
|
9
|
+
if m
|
10
|
+
fpfx = m[1]
|
11
|
+
if $buffer.fname
|
12
|
+
dn = File.dirname($buffer.fname)
|
13
|
+
|
14
|
+
fcands = []
|
15
|
+
fcands << "#{dn}/#{fpfx}"
|
16
|
+
fcands << "#{dn}/#{fpfx}.txt"
|
17
|
+
fcands << File.expand_path("#{fpfx}")
|
18
|
+
fcands << File.expand_path("#{fpfx}.txt")
|
19
|
+
|
20
|
+
fn = nil
|
21
|
+
for fc in fcands
|
22
|
+
if File.exists?(fc)
|
23
|
+
fn = fc
|
24
|
+
break
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if fn
|
29
|
+
message "HPT opening file #{fn}"
|
30
|
+
return fn
|
31
|
+
# open_existing_file(fn)
|
32
|
+
# return true
|
33
|
+
else
|
34
|
+
message "File not found: #{fpfx}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def hpt_scan_images()
|
42
|
+
return if !buf.fname
|
43
|
+
return if !buf.fname.match(/.*txt$/)
|
44
|
+
imgpos = scan_indexes(buf, /⟦img:.+?⟧/)
|
45
|
+
imgtags = buf.scan(/(⟦img:(.+?)⟧)/)
|
46
|
+
# i = 0
|
47
|
+
c = 0
|
48
|
+
imgpos.each.with_index { |x, i|
|
49
|
+
a = imgpos[i]
|
50
|
+
t = imgtags[i]
|
51
|
+
insert_pos = a + t[0].size + c
|
52
|
+
imgfn = File.expand_path(t[1])
|
53
|
+
# Ripl.start :binding => binding
|
54
|
+
next if !File.exist?(imgfn)
|
55
|
+
if buf[insert_pos..(insert_pos + 2)] != "\n \n"
|
56
|
+
buf.insert_txt_at("\n \n", insert_pos)
|
57
|
+
c += 3
|
58
|
+
end
|
59
|
+
buf.add_image(imgfn, insert_pos + 1)
|
60
|
+
}
|
61
|
+
end
|