ruby-zoom 3.5.0 → 4.0.0
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/bin/z +189 -147
- data/bin/zc +189 -147
- data/bin/zf +189 -147
- data/bin/zg +189 -147
- data/bin/zl +189 -147
- data/bin/zr +189 -147
- data/lib/zoom.rb +48 -604
- data/lib/zoom/cache.rb +253 -0
- data/lib/zoom/cache/result.rb +49 -0
- data/lib/zoom/config.rb +156 -0
- data/lib/zoom/editor.rb +121 -0
- data/lib/zoom/error.rb +6 -6
- data/lib/zoom/error/{executable_not_found_error.rb → executable_not_found.rb} +1 -3
- data/lib/zoom/error/invalid_color.rb +5 -0
- data/lib/zoom/error/{invalid_tag_error.rb → invalid_tag.rb} +1 -3
- data/lib/zoom/error/{profile_class_unknown_error.rb → profile_class_unknown.rb} +1 -3
- data/lib/zoom/error/{profile_does_not_exist_error.rb → profile_does_not_exist.rb} +1 -3
- data/lib/zoom/error/profile_not_named.rb +7 -0
- data/lib/zoom/profile.rb +162 -66
- data/lib/zoom/profile/ack.rb +5 -30
- data/lib/zoom/profile/ag.rb +2 -37
- data/lib/zoom/profile/find.rb +2 -25
- data/lib/zoom/profile/grep.rb +2 -44
- data/lib/zoom/profile/passwords.rb +27 -59
- data/lib/zoom/profile/pt.rb +2 -26
- data/lib/zoom/profile_manager.rb +49 -0
- data/lib/zoom/wish/add_wish.rb +58 -0
- data/lib/zoom/wish/color_wish.rb +147 -0
- data/lib/zoom/wish/copy_wish.rb +57 -0
- data/lib/zoom/wish/delete_wish.rb +51 -0
- data/lib/zoom/wish/edit_wish.rb +130 -0
- data/lib/zoom/wish/editor_wish.rb +31 -0
- data/lib/zoom/wish/list_wish.rb +58 -0
- data/lib/zoom/wish/rename_wish.rb +69 -0
- data/lib/zoom/wish/reset_wish.rb +40 -0
- data/lib/zoom/wish/use_wish.rb +61 -0
- metadata +118 -24
- data/lib/string.rb +0 -48
- data/lib/zoom/error/profile_already_exists_error.rb +0 -8
- data/lib/zoom/error/profile_can_not_be_modified_error.rb +0 -8
data/lib/zoom/editor.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "io/wait"
|
3
|
+
|
4
|
+
class Zoom::Editor
|
5
|
+
def default(results)
|
6
|
+
# First result should never be nil, but better safe than sorry
|
7
|
+
first_result = results.delete_at(0)
|
8
|
+
open_result(first_result) if (first_result)
|
9
|
+
|
10
|
+
results.each do |result|
|
11
|
+
print "Open result #{result.tag} [y]/n/q/l?: "
|
12
|
+
answer = nil
|
13
|
+
while (answer.nil?)
|
14
|
+
begin
|
15
|
+
system("stty raw -echo")
|
16
|
+
if ($stdin.ready?)
|
17
|
+
answer = $stdin.getc
|
18
|
+
else
|
19
|
+
sleep 0.1
|
20
|
+
end
|
21
|
+
ensure
|
22
|
+
system("stty -raw echo")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
puts
|
26
|
+
|
27
|
+
case answer
|
28
|
+
when "n", "N"
|
29
|
+
# Do nothing
|
30
|
+
when "l", "L"
|
31
|
+
# Open this result then exit
|
32
|
+
open_result(result)
|
33
|
+
break
|
34
|
+
when "q", "Q", "\x03"
|
35
|
+
# Quit or ^C
|
36
|
+
break
|
37
|
+
else
|
38
|
+
open_result(result)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
private :default
|
43
|
+
|
44
|
+
def initialize(editor)
|
45
|
+
@editor = editor
|
46
|
+
end
|
47
|
+
|
48
|
+
def open(results)
|
49
|
+
return if (results.nil? || results.empty?)
|
50
|
+
|
51
|
+
case @editor
|
52
|
+
when /vim?$/
|
53
|
+
vim(results)
|
54
|
+
else
|
55
|
+
default(results)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def open_result(result)
|
60
|
+
if (result.grep_like?)
|
61
|
+
filename = result.filename
|
62
|
+
lineno = result.lineno
|
63
|
+
pwd = result.pwd
|
64
|
+
system("#{@editor} +#{lineno} '#{pwd}/#{filename}'")
|
65
|
+
else
|
66
|
+
filename = result.contents
|
67
|
+
pwd = result.pwd
|
68
|
+
system("#{@editor} '#{pwd}/#{filename}'")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
private :open_result
|
72
|
+
|
73
|
+
def vim(results)
|
74
|
+
quickfix = Pathname.new("~/.cache/zoom/quickfix").expand_path
|
75
|
+
source = Pathname.new("~/.cache/zoom/source").expand_path
|
76
|
+
FileUtils.mkdir_p(quickfix.dirname)
|
77
|
+
|
78
|
+
zq = File.open(quickfix, "w")
|
79
|
+
zs = File.open(source, "w")
|
80
|
+
|
81
|
+
vimscript = [
|
82
|
+
"augroup Zoom",
|
83
|
+
" autocmd!",
|
84
|
+
" autocmd FileType qf nnoremap <cr> :.cc<cr>:cclose<cr>",
|
85
|
+
"augroup END",
|
86
|
+
"",
|
87
|
+
"nnoremap <leader>z :copen<cr>",
|
88
|
+
"nnoremap zn :copen<cr>j:.cc<cr>:cclose<cr>",
|
89
|
+
"nnoremap zp :copen<cr>k:.cc<cr>:cclose<cr>",
|
90
|
+
""
|
91
|
+
].join("\n")
|
92
|
+
zs.write(vimscript)
|
93
|
+
|
94
|
+
files = Array.new
|
95
|
+
results.each do |result|
|
96
|
+
filename = result.filename if (result.grep_like?)
|
97
|
+
filename ||= result.contents
|
98
|
+
lineno = result.lineno
|
99
|
+
match = result.match
|
100
|
+
pwd = result.pwd
|
101
|
+
|
102
|
+
if (!files.include?("#{pwd}/#{filename}"))
|
103
|
+
files.push("#{pwd}/#{filename}")
|
104
|
+
zs.write("#{lineno}\nbnext\n") if (result.grep_like?)
|
105
|
+
end
|
106
|
+
|
107
|
+
if (result.grep_like?)
|
108
|
+
zq.write("#{pwd}/#{filename}|#{lineno}| #{match}\n")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
zs.write("silent cfile #{quickfix}\n")
|
112
|
+
|
113
|
+
zq.close
|
114
|
+
zs.close
|
115
|
+
|
116
|
+
system("#{@editor} -S #{source} #{files.join(" ")}")
|
117
|
+
|
118
|
+
FileUtils.rm_f(quickfix)
|
119
|
+
FileUtils.rm_f(source)
|
120
|
+
end
|
121
|
+
end
|
data/lib/zoom/error.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
class Zoom::Error < RuntimeError
|
2
2
|
end
|
3
3
|
|
4
|
-
require "zoom/error/
|
5
|
-
require "zoom/error/
|
6
|
-
require "zoom/error/
|
7
|
-
require "zoom/error/
|
8
|
-
require "zoom/error/
|
9
|
-
require "zoom/error/
|
4
|
+
require "zoom/error/executable_not_found"
|
5
|
+
require "zoom/error/invalid_color"
|
6
|
+
require "zoom/error/invalid_tag"
|
7
|
+
require "zoom/error/profile_class_unknown"
|
8
|
+
require "zoom/error/profile_does_not_exist"
|
9
|
+
require "zoom/error/profile_not_named"
|
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class Zoom::Error::ProfileDoesNotExistError < Zoom::Error
|
1
|
+
class Zoom::Error::ProfileDoesNotExist < Zoom::Error
|
4
2
|
def initialize(profile = nil)
|
5
3
|
super("Profile does not exist: #{profile}") if (profile)
|
6
4
|
super("Profile does not exist") if (profile.nil?)
|
data/lib/zoom/profile.rb
CHANGED
@@ -1,97 +1,171 @@
|
|
1
|
+
require "hilighter"
|
1
2
|
require "scoobydoo"
|
2
3
|
require "shellwords"
|
3
|
-
require "zoom/error/profile_class_unknown_error"
|
4
4
|
|
5
5
|
class Zoom::Profile < Hash
|
6
|
-
|
7
|
-
|
6
|
+
attr_reader :pattern
|
7
|
+
attr_reader :taggable
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
self["append"] = append if (append)
|
13
|
-
return self["append"]
|
9
|
+
def after(a = nil)
|
10
|
+
self["after"] = a if (a)
|
11
|
+
return self["after"].strip
|
14
12
|
end
|
15
13
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
14
|
+
def before(b = nil)
|
15
|
+
self["before"] = b if (b)
|
16
|
+
return self["before"].strip
|
19
17
|
end
|
20
18
|
|
21
|
-
def
|
22
|
-
|
23
|
-
""
|
19
|
+
def class_name
|
20
|
+
return self["class"]
|
24
21
|
end
|
25
22
|
|
26
23
|
def exe(args, pattern)
|
27
|
-
|
24
|
+
# Use hard-coded pattern if defined
|
25
|
+
pattern = @pattern if (@pattern && !@pattern.empty?)
|
26
|
+
|
27
|
+
# If not pattern and no after, then return nothing
|
28
|
+
if (pattern.nil? || pattern.empty?)
|
29
|
+
return "" if (after.nil? || after.empty? || after == ".")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Emulate grep
|
33
|
+
case operator.split("/")[-1]
|
34
|
+
when "ack", "ack-grep"
|
35
|
+
str = [
|
36
|
+
before,
|
37
|
+
operator,
|
38
|
+
"-H --nobreak --nocolor --noheading -s",
|
39
|
+
flags
|
40
|
+
].join(" ").strip
|
41
|
+
return %x(#{str} #{args} #{pattern.shellescape} #{after})
|
42
|
+
when "ag"
|
43
|
+
str = [
|
44
|
+
before,
|
45
|
+
operator,
|
46
|
+
"--filename --nobreak --nocolor --noheading --silent",
|
47
|
+
flags
|
48
|
+
].join(" ").strip
|
49
|
+
return %x(#{str} #{args} #{pattern.shellescape} #{after})
|
50
|
+
when "find"
|
51
|
+
str = [before, operator, flags].join(" ").strip
|
52
|
+
return %x(#{str} #{args} \"#{pattern}\" #{after})
|
53
|
+
when "grep"
|
54
|
+
str = [
|
55
|
+
before,
|
56
|
+
operator,
|
57
|
+
"--color=never -EHnRs",
|
58
|
+
"--exclude-dir=.bzr",
|
59
|
+
"--exclude-dir=.git",
|
60
|
+
"--exclude-dir=.svn",
|
61
|
+
flags
|
62
|
+
].join(" ").strip
|
63
|
+
return %x(#{str} #{args} #{pattern.shellescape} #{after})
|
64
|
+
when "pt"
|
65
|
+
str = [
|
66
|
+
before,
|
67
|
+
operator,
|
68
|
+
"-e --nocolor --nogroup",
|
69
|
+
flags
|
70
|
+
].join(" ").strip
|
71
|
+
return %x(#{str} #{args} #{pattern.shellescape} #{after})
|
72
|
+
else
|
73
|
+
str = [before, operator, flags].join(" ").strip
|
74
|
+
return %x(#{str} #{args} #{pattern} #{after})
|
75
|
+
end
|
28
76
|
end
|
29
77
|
|
30
|
-
def flags(
|
31
|
-
self["flags"] =
|
32
|
-
return self["flags"]
|
78
|
+
def flags(f = nil)
|
79
|
+
self["flags"] = f if (f)
|
80
|
+
return self["flags"].strip
|
33
81
|
end
|
34
82
|
|
35
83
|
def self.from_json(json)
|
36
84
|
begin
|
37
85
|
return profile_by_name(json["class"]).new(
|
86
|
+
json["name"],
|
38
87
|
json["operator"].nil? ? "" : json["operator"],
|
39
88
|
json["flags"].nil? ? "" : json["flags"],
|
40
|
-
json["
|
41
|
-
json["
|
42
|
-
)
|
43
|
-
rescue NameError => e
|
44
|
-
raise Zoom::Error::ProfileClassUnknownError.new(
|
45
|
-
json["class"]
|
89
|
+
json["before"].nil? ? "" : json["before"],
|
90
|
+
json["after"].nil? ? "" : json["after"]
|
46
91
|
)
|
92
|
+
rescue NoMethodError
|
93
|
+
raise Zoom::Error::ProfileNotNamed.new(json)
|
94
|
+
rescue NameError
|
95
|
+
raise Zoom::Error::ProfileClassUnknown.new(json["class"])
|
47
96
|
end
|
48
97
|
end
|
49
98
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
99
|
+
def go(editor, results)
|
100
|
+
Zoom::Editor.new(editor).open(results)
|
101
|
+
end
|
102
|
+
|
103
|
+
def hilight_after(str)
|
104
|
+
return str if (!Zoom.hilight?)
|
105
|
+
return str.yellow
|
106
|
+
end
|
107
|
+
private :hilight_after
|
108
|
+
|
109
|
+
def hilight_before(str)
|
110
|
+
return str if (!Zoom.hilight?)
|
111
|
+
return str.yellow
|
112
|
+
end
|
113
|
+
private :hilight_before
|
114
|
+
|
115
|
+
def hilight_class
|
116
|
+
return class_name if (!Zoom.hilight?)
|
117
|
+
return class_name.cyan
|
118
|
+
end
|
119
|
+
private :hilight_class
|
120
|
+
|
121
|
+
def hilight_flags(str)
|
122
|
+
return str if (!Zoom.hilight?)
|
123
|
+
return str.magenta
|
124
|
+
end
|
125
|
+
private :hilight_flags
|
126
|
+
|
127
|
+
def hilight_name
|
128
|
+
return name if (!Zoom.hilight?)
|
129
|
+
return name.white
|
130
|
+
end
|
131
|
+
private :hilight_name
|
132
|
+
|
133
|
+
def hilight_operator(str)
|
134
|
+
return str if (!Zoom.hilight?)
|
135
|
+
return str.green
|
136
|
+
end
|
137
|
+
private :hilight_operator
|
138
|
+
|
139
|
+
def hilight_pattern(str)
|
140
|
+
return str if (!Zoom.hilight?)
|
141
|
+
return str
|
58
142
|
end
|
143
|
+
private :hilight_pattern
|
59
144
|
|
60
|
-
def initialize(
|
61
|
-
operator = "echo",
|
62
|
-
flags = "#",
|
63
|
-
envprepend = "",
|
64
|
-
append = ""
|
65
|
-
)
|
145
|
+
def initialize(n, o = "echo", f = "#", b = "", a = "")
|
66
146
|
self["class"] = self.class.to_s
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
147
|
+
after(a)
|
148
|
+
before(b)
|
149
|
+
flags(f.split(" ").uniq.join(" "))
|
150
|
+
name(n)
|
151
|
+
operator(o)
|
71
152
|
|
72
|
-
@
|
73
|
-
@pager = "z --pager --cache-file #{@@cache_file}"
|
153
|
+
@pattern = "" # Setting this will override user input
|
74
154
|
@taggable = false
|
75
155
|
end
|
76
156
|
|
77
|
-
def
|
78
|
-
if (
|
79
|
-
|
80
|
-
if (op)
|
81
|
-
self["operator"] = op
|
82
|
-
else
|
83
|
-
self["operator"] = ScoobyDoo.where_are_you("echo")
|
84
|
-
flags("")
|
85
|
-
prepend("")
|
86
|
-
append("#{operator} is not installed!")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
return self["operator"]
|
157
|
+
def name(n = nil)
|
158
|
+
self["name"] = n if (n)
|
159
|
+
return self["name"].strip
|
90
160
|
end
|
91
161
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
162
|
+
def operator(o = nil)
|
163
|
+
if (o)
|
164
|
+
op = ScoobyDoo.where_are_you(o)
|
165
|
+
raise Zoom::Error::ExecutableNotFound.new(o) if (op.nil?)
|
166
|
+
self["operator"] = o
|
167
|
+
end
|
168
|
+
return self["operator"].strip
|
95
169
|
end
|
96
170
|
|
97
171
|
def self.profile_by_name(clas)
|
@@ -100,13 +174,35 @@ class Zoom::Profile < Hash
|
|
100
174
|
end
|
101
175
|
end
|
102
176
|
|
177
|
+
def self.subclasses
|
178
|
+
ObjectSpace.each_object(Class).select do |clas|
|
179
|
+
if (clas < self)
|
180
|
+
begin
|
181
|
+
clas.new(clas.to_s)
|
182
|
+
true
|
183
|
+
rescue Zoom::Error::ExecutableNotFound
|
184
|
+
false
|
185
|
+
end
|
186
|
+
else
|
187
|
+
false
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
103
192
|
def to_s
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
193
|
+
ret = Array.new
|
194
|
+
ret.push(hilight_name)
|
195
|
+
ret.push("#{hilight_class}\n")
|
196
|
+
ret.push(hilight_before(before)) if (!before.empty?)
|
197
|
+
ret.push(hilight_operator(operator)) if (!operator.empty?)
|
198
|
+
ret.push(hilight_flags(flags)) if (!flags.empty?)
|
199
|
+
if (@pattern.nil? || @pattern.empty?)
|
200
|
+
ret.push(hilight_pattern("PATTERN"))
|
201
|
+
else
|
202
|
+
ret.push(hilight_pattern("\"#{@pattern}\""))
|
203
|
+
end
|
204
|
+
ret.push(hilight_after(after)) if (!after.empty?)
|
205
|
+
return ret.join(" ").strip
|
110
206
|
end
|
111
207
|
end
|
112
208
|
|