vimamsa 0.1.0 → 0.1.5
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/.vma_project +0 -0
- data/README.md +110 -16
- data/exe/vimamsa +40 -0
- data/ext/vmaext/vmaext.c +0 -3
- data/lang/hyperplaintext.lang +129 -0
- data/lib/vimamsa.rb +3 -1
- data/lib/vimamsa/ack.rb +35 -0
- data/lib/vimamsa/actions.rb +125 -0
- data/lib/vimamsa/buffer.rb +1760 -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 +448 -0
- data/lib/vimamsa/easy_jump.rb +161 -0
- data/lib/vimamsa/editor.rb +667 -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 +1072 -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
- data/vimamsa.gemspec +4 -2
- metadata +66 -10
- data/ext/vimamsa/extconf.rb +0 -11
- data/ext/vimamsa/vimamsa.c +0 -174
@@ -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
|