ruby-zoom 3.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 +7 -0
- data/bin/z +275 -0
- data/bin/zc +275 -0
- data/bin/zf +275 -0
- data/bin/zg +275 -0
- data/bin/zl +275 -0
- data/bin/zr +275 -0
- data/lib/ack_profile.rb +48 -0
- data/lib/ag_profile.rb +41 -0
- data/lib/find_profile.rb +28 -0
- data/lib/grep_profile.rb +48 -0
- data/lib/passwords_profile.rb +67 -0
- data/lib/string.rb +26 -0
- data/lib/zoom.rb +621 -0
- data/lib/zoom_error.rb +34 -0
- data/lib/zoom_profile.rb +91 -0
- metadata +112 -0
data/lib/ack_profile.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
require "zoom_profile"
|
3
|
+
|
4
|
+
class AckProfile < ZoomProfile
|
5
|
+
def colors
|
6
|
+
'ACK_COLOR_LINENO=white ACK_COLOR_MATCH="black on_white"'
|
7
|
+
end
|
8
|
+
|
9
|
+
def exe(args, pattern)
|
10
|
+
if (pattern.nil? || pattern.empty?)
|
11
|
+
system(
|
12
|
+
"#{self.to_s} --pager \"#{@pager}\" #{args} " \
|
13
|
+
"#{self.append}"
|
14
|
+
)
|
15
|
+
else
|
16
|
+
system(
|
17
|
+
"#{self.to_s} --pager \"#{@pager}\" #{args} " \
|
18
|
+
"#{pattern.shellescape} #{self.append}"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(
|
24
|
+
operator = nil,
|
25
|
+
flags = "--smart-case",
|
26
|
+
envprepend = "",
|
27
|
+
append = ""
|
28
|
+
)
|
29
|
+
# Special case because of debian
|
30
|
+
operator = nil
|
31
|
+
if (ScoobyDoo.where_are_you("ack"))
|
32
|
+
operator = "ack"
|
33
|
+
elsif (ScoobyDoo.where_are_you("ack-grep"))
|
34
|
+
operator = "ack-grep"
|
35
|
+
else
|
36
|
+
# Oops
|
37
|
+
operator = "echo"
|
38
|
+
if (operator == "echo")
|
39
|
+
flags = "#"
|
40
|
+
envprepend = ""
|
41
|
+
append = ""
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
super(operator, flags, envprepend, append)
|
46
|
+
@taggable = true
|
47
|
+
end
|
48
|
+
end
|
data/lib/ag_profile.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
require "zoom_profile"
|
3
|
+
|
4
|
+
class AgProfile < ZoomProfile
|
5
|
+
def colors
|
6
|
+
'--color-match "47;1;30" --color-line-number "0;37"'
|
7
|
+
end
|
8
|
+
|
9
|
+
def exe(args, pattern)
|
10
|
+
if (pattern.nil? || pattern.empty?)
|
11
|
+
system(
|
12
|
+
"#{self.to_s} --pager \"#{@pager}\" #{args} " \
|
13
|
+
"#{self.append}"
|
14
|
+
)
|
15
|
+
else
|
16
|
+
system(
|
17
|
+
"#{self.to_s} --pager \"#{@pager}\" #{args} " \
|
18
|
+
"#{pattern.shellescape} #{self.append}"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(
|
24
|
+
operator = nil,
|
25
|
+
flags = "-S",
|
26
|
+
envprepend = "",
|
27
|
+
append = ""
|
28
|
+
)
|
29
|
+
super("ag", flags, envprepend, append)
|
30
|
+
@taggable = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
[
|
35
|
+
self["prepend"],
|
36
|
+
self["operator"],
|
37
|
+
self.colors,
|
38
|
+
self["flags"]
|
39
|
+
].join(" ").strip
|
40
|
+
end
|
41
|
+
end
|
data/lib/find_profile.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
require "zoom_profile"
|
3
|
+
|
4
|
+
class FindProfile < ZoomProfile
|
5
|
+
def exe(args, pattern)
|
6
|
+
if (pattern.nil? || pattern.empty?)
|
7
|
+
system(
|
8
|
+
"#{self.to_s} #{args} \"*\" #{self.append} | " \
|
9
|
+
"#{@pager}"
|
10
|
+
)
|
11
|
+
else
|
12
|
+
system(
|
13
|
+
"#{self.to_s} #{args} \"#{pattern}\" " \
|
14
|
+
"#{self.append} | #{@pager}"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(
|
20
|
+
operator = nil,
|
21
|
+
flags = ". -name",
|
22
|
+
envprepend = "",
|
23
|
+
append = ""
|
24
|
+
)
|
25
|
+
super("find", flags, envprepend, append)
|
26
|
+
@taggable = true
|
27
|
+
end
|
28
|
+
end
|
data/lib/grep_profile.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
require "zoom_profile"
|
3
|
+
|
4
|
+
class GrepProfile < ZoomProfile
|
5
|
+
def colors
|
6
|
+
[
|
7
|
+
'GREP_COLORS="',
|
8
|
+
"fn=1;32:",
|
9
|
+
"ln=0;37:",
|
10
|
+
"ms=47;1;30:",
|
11
|
+
"mc=47;1;30:",
|
12
|
+
"sl=:cx=:bn=:se=",
|
13
|
+
'"'
|
14
|
+
].join.strip
|
15
|
+
end
|
16
|
+
|
17
|
+
def exe(args, pattern)
|
18
|
+
# Emulate ag/ack as much as possible
|
19
|
+
if (pattern.nil? || pattern.empty?)
|
20
|
+
system(
|
21
|
+
"#{self.to_s} #{args} #{self.append} | " \
|
22
|
+
"sed \"s|\\[K[:-]|\\[K\\n|\" | #{@pager}"
|
23
|
+
)
|
24
|
+
else
|
25
|
+
system(
|
26
|
+
"#{self.to_s} #{args} #{pattern.shellescape} " \
|
27
|
+
"#{self.append} | sed \"s|\\[K[:-]|\\[K\\n|\" | " \
|
28
|
+
"#{@pager}"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(
|
34
|
+
operator = nil,
|
35
|
+
flags = [
|
36
|
+
"--color=always",
|
37
|
+
"-EHIinR",
|
38
|
+
"--exclude-dir=.bzr",
|
39
|
+
"--exclude-dir=.git",
|
40
|
+
"--exclude-dir=.svn"
|
41
|
+
].join(" ").strip,
|
42
|
+
envprepend = "",
|
43
|
+
append = "."
|
44
|
+
)
|
45
|
+
super("grep", flags, envprepend, append)
|
46
|
+
@taggable = true
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "ag_profile"
|
2
|
+
require "ack_profile"
|
3
|
+
require "grep_profile"
|
4
|
+
require "shellwords"
|
5
|
+
require "zoom_profile"
|
6
|
+
|
7
|
+
class PasswordsProfile < ZoomProfile
|
8
|
+
def colors
|
9
|
+
return @profile.colors
|
10
|
+
end
|
11
|
+
|
12
|
+
def exe(args, pattern)
|
13
|
+
@profile.exe(args, pattern)
|
14
|
+
end
|
15
|
+
|
16
|
+
def info
|
17
|
+
[
|
18
|
+
"Class : #{self.class.to_s}",
|
19
|
+
"Prepend : #{@profile.prepend}",
|
20
|
+
"Operator: #{@profile.operator}",
|
21
|
+
"Flags : #{@profile.flags}",
|
22
|
+
"Append : #{@profile.append}"
|
23
|
+
].join("\n").strip
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(
|
27
|
+
operator = nil,
|
28
|
+
flags = "",
|
29
|
+
envprepend = "",
|
30
|
+
append = ""
|
31
|
+
)
|
32
|
+
@passwd_regex = "\"pass(word|wd)?[^:=,>]? *[:=,>]\""
|
33
|
+
|
34
|
+
if (ScoobyDoo.where_are_you("ag"))
|
35
|
+
@profile = AgProfile.new(nil, "-uS", "", @passwd_regex)
|
36
|
+
elsif (
|
37
|
+
ScoobyDoo.where_are_you("ack") ||
|
38
|
+
ScoobyDoo.where_are_you("ack-grep")
|
39
|
+
)
|
40
|
+
@profile = AckProfile.new(
|
41
|
+
nil,
|
42
|
+
"--smart-case",
|
43
|
+
"",
|
44
|
+
@passwd_regex
|
45
|
+
)
|
46
|
+
else
|
47
|
+
@profile = GrepProfile.new(
|
48
|
+
nil,
|
49
|
+
"--color=always -EHinR",
|
50
|
+
"",
|
51
|
+
@passwd_regex
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
super(
|
56
|
+
@profile.operator,
|
57
|
+
@profile.flags,
|
58
|
+
@profile.prepend,
|
59
|
+
@profile.append
|
60
|
+
)
|
61
|
+
@taggable = true
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_s
|
65
|
+
return @porfile.to_s
|
66
|
+
end
|
67
|
+
end
|
data/lib/string.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Redefine String class to allow for colorizing and rsplit
|
2
|
+
class String
|
3
|
+
def blue
|
4
|
+
return colorize(36)
|
5
|
+
end
|
6
|
+
|
7
|
+
def colorize(color)
|
8
|
+
return "\e[#{color}m#{self}\e[0m"
|
9
|
+
end
|
10
|
+
|
11
|
+
def green
|
12
|
+
return colorize(32)
|
13
|
+
end
|
14
|
+
|
15
|
+
def red
|
16
|
+
return colorize(31)
|
17
|
+
end
|
18
|
+
|
19
|
+
def white
|
20
|
+
return colorize(37)
|
21
|
+
end
|
22
|
+
|
23
|
+
def word_wrap(width = 70)
|
24
|
+
return scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/).join("\n")
|
25
|
+
end
|
26
|
+
end
|
data/lib/zoom.rb
ADDED
@@ -0,0 +1,621 @@
|
|
1
|
+
require "ack_profile"
|
2
|
+
require "ag_profile"
|
3
|
+
require "find_profile"
|
4
|
+
require "grep_profile"
|
5
|
+
require "io/wait"
|
6
|
+
require "json"
|
7
|
+
require "pathname"
|
8
|
+
require "passwords_profile"
|
9
|
+
require "singleton"
|
10
|
+
require "string"
|
11
|
+
require "zoom_error"
|
12
|
+
require "zoom_profile"
|
13
|
+
|
14
|
+
class Zoom
|
15
|
+
include Singleton
|
16
|
+
include ZoomError
|
17
|
+
|
18
|
+
def add_profile(
|
19
|
+
name,
|
20
|
+
clas,
|
21
|
+
operator = nil,
|
22
|
+
flags = nil,
|
23
|
+
envprepend = nil,
|
24
|
+
append = nil
|
25
|
+
)
|
26
|
+
if (@profiles.has_key?(name))
|
27
|
+
raise ZoomError::ProfileAlreadyExistsError.new(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
default_class = nil
|
31
|
+
begin
|
32
|
+
default_class = Object::const_get(clas).new
|
33
|
+
rescue NameError => e
|
34
|
+
raise ZoomError::ProfileClassUnknownError.new(clas)
|
35
|
+
end
|
36
|
+
|
37
|
+
edit_profile(
|
38
|
+
name,
|
39
|
+
default_class,
|
40
|
+
operator,
|
41
|
+
flags,
|
42
|
+
envprepend,
|
43
|
+
append
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def clear_cache
|
48
|
+
@cache_file.delete if (@cache_file.exist?)
|
49
|
+
end
|
50
|
+
|
51
|
+
def configure_editor(editor)
|
52
|
+
e = ScoobyDoo.where_are_you(editor)
|
53
|
+
if (e.nil?)
|
54
|
+
raise ZoomError::ExecutableNotFoundError.new(editor)
|
55
|
+
end
|
56
|
+
|
57
|
+
@rc["editor"] = e
|
58
|
+
write_zoomrc
|
59
|
+
end
|
60
|
+
|
61
|
+
def default
|
62
|
+
default_zoominfo
|
63
|
+
default_zoomrc
|
64
|
+
end
|
65
|
+
|
66
|
+
def default_zoominfo
|
67
|
+
@info = Hash.new
|
68
|
+
@info["profile"] = "default"
|
69
|
+
|
70
|
+
# Reset last command to be empty
|
71
|
+
@info["last_command"] = Hash.new
|
72
|
+
|
73
|
+
write_zoominfo
|
74
|
+
end
|
75
|
+
private :default_zoominfo
|
76
|
+
|
77
|
+
def default_zoomrc
|
78
|
+
@rc = Hash.new
|
79
|
+
@profiles = Hash.new
|
80
|
+
|
81
|
+
all = nil
|
82
|
+
|
83
|
+
# Default ag profiles
|
84
|
+
if (ScoobyDoo.where_are_you("ag"))
|
85
|
+
ag = AgProfile.new
|
86
|
+
all = AgProfile.new(nil, "-uS")
|
87
|
+
else
|
88
|
+
ag = nil
|
89
|
+
end
|
90
|
+
|
91
|
+
# Default ack profile
|
92
|
+
if (
|
93
|
+
ScoobyDoo.where_are_you("ack") ||
|
94
|
+
ScoobyDoo.where_are_you("ack-grep")
|
95
|
+
)
|
96
|
+
ack = AckProfile.new
|
97
|
+
else
|
98
|
+
ack = nil
|
99
|
+
end
|
100
|
+
|
101
|
+
# Default grep profile (emulate ag/ack as much as possible)
|
102
|
+
grep = GrepProfile.new
|
103
|
+
if (all.nil?)
|
104
|
+
all = GrepProfile.new
|
105
|
+
all.flags("--color=always -EHinR")
|
106
|
+
end
|
107
|
+
|
108
|
+
# Create default profile
|
109
|
+
if (ag)
|
110
|
+
default = ag
|
111
|
+
elsif (ack)
|
112
|
+
default = ack
|
113
|
+
else
|
114
|
+
default = grep
|
115
|
+
end
|
116
|
+
|
117
|
+
# Create find profile
|
118
|
+
find = FindProfile.new
|
119
|
+
|
120
|
+
# Put profiles into rc
|
121
|
+
@profiles["ack"] = ack if (ack)
|
122
|
+
@profiles["ag"] = ag if (ag)
|
123
|
+
@profiles["all"] = all if (all)
|
124
|
+
@profiles["default"] = default
|
125
|
+
@profiles["grep"] = grep
|
126
|
+
@profiles["passwords"] = PasswordsProfile.new
|
127
|
+
@profiles["zoom_find"] = find
|
128
|
+
|
129
|
+
# Default editor (use $EDITOR)
|
130
|
+
@rc["editor"] = ""
|
131
|
+
|
132
|
+
write_zoomrc
|
133
|
+
end
|
134
|
+
private :default_zoomrc
|
135
|
+
|
136
|
+
def delete_profile(name)
|
137
|
+
if (name == "default")
|
138
|
+
raise ZoomError::ProfileCanNotBeModifiedError.new(name)
|
139
|
+
end
|
140
|
+
|
141
|
+
if (name == "zoom_find")
|
142
|
+
raise ZoomError::ProfileCanNotBeModifiedError.new(name)
|
143
|
+
end
|
144
|
+
|
145
|
+
if (!@profiles.has_key?(name))
|
146
|
+
raise ZoomError::ProfileDoesNotExistError.new(name)
|
147
|
+
end
|
148
|
+
|
149
|
+
@profiles.delete(name)
|
150
|
+
write_zoomrc
|
151
|
+
|
152
|
+
if (name == @info["profile"])
|
153
|
+
@info["profile"] = "default"
|
154
|
+
write_zoominfo
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def edit_profile(
|
159
|
+
name,
|
160
|
+
profile = nil,
|
161
|
+
operator = nil,
|
162
|
+
flags = nil,
|
163
|
+
envprepend = nil,
|
164
|
+
append = nil
|
165
|
+
)
|
166
|
+
if (name == "zoom_find")
|
167
|
+
raise ZoomError::ProfileCanNotBeModified.new(name)
|
168
|
+
end
|
169
|
+
|
170
|
+
profile = @profiles[name] if (profile.nil?)
|
171
|
+
|
172
|
+
if (profile.nil?)
|
173
|
+
raise ZoomError::ProfileDoesNotExists.new(name)
|
174
|
+
end
|
175
|
+
|
176
|
+
profile.operator(operator) if (operator)
|
177
|
+
profile.flags(flags) if (flags)
|
178
|
+
profile.prepend(envprepend) if (envprepend)
|
179
|
+
profile.append(append) if (append)
|
180
|
+
|
181
|
+
@profiles[name] = profile
|
182
|
+
write_zoomrc
|
183
|
+
end
|
184
|
+
|
185
|
+
def exec_profile(name, args, pattern)
|
186
|
+
name = @info["profile"] if (name.nil?)
|
187
|
+
|
188
|
+
if (!@profiles.has_key?(name))
|
189
|
+
raise ZoomError::ProfileDoesNotExistError.new(name)
|
190
|
+
end
|
191
|
+
|
192
|
+
@info["last_command"] = {
|
193
|
+
"profile" => name,
|
194
|
+
"subargs" => args.nil? ? "": args,
|
195
|
+
"pattern" => pattern.nil? ? "" : pattern
|
196
|
+
}
|
197
|
+
write_zoominfo
|
198
|
+
|
199
|
+
profile = @profiles[name]
|
200
|
+
begin
|
201
|
+
clear_cache if (profile.taggable)
|
202
|
+
profile.exe(args, pattern)
|
203
|
+
shortcut_cache(profile) if (profile.taggable)
|
204
|
+
rescue Interrupt
|
205
|
+
# ^C
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def get_location_of_result(result)
|
210
|
+
count = 0
|
211
|
+
File.open(@shortcut_file) do |file|
|
212
|
+
file.each do |line|
|
213
|
+
count += 1
|
214
|
+
if (count == result)
|
215
|
+
return line
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
return nil
|
220
|
+
end
|
221
|
+
private :get_location_of_result
|
222
|
+
|
223
|
+
def get_new_value(val, default)
|
224
|
+
return default if (val.nil? || val.empty?)
|
225
|
+
return "" if (val.downcase == "empty")
|
226
|
+
return "" if (val.downcase == "\"empty\"")
|
227
|
+
return val
|
228
|
+
end
|
229
|
+
private :get_new_value
|
230
|
+
|
231
|
+
def initialize
|
232
|
+
# Load custom profiles
|
233
|
+
custom_profs = Pathname.new("~/.zoom_profiles.rb").expand_path
|
234
|
+
require_relative custom_profs if (custom_profs.exist?)
|
235
|
+
|
236
|
+
@cache_file = Pathname.new("~/.zoom_cache").expand_path
|
237
|
+
@info_file = Pathname.new("~/.zoominfo").expand_path
|
238
|
+
@rc_file = Pathname.new("~/.zoomrc").expand_path
|
239
|
+
@shortcut_file = Pathname.new("~/.zoom_shortcuts").expand_path
|
240
|
+
|
241
|
+
read_zoomrc
|
242
|
+
read_zoominfo
|
243
|
+
|
244
|
+
# Setup editor
|
245
|
+
@editor = @rc["editor"]
|
246
|
+
@editor = ENV["EDITOR"] if (@editor.nil? || @editor.empty?)
|
247
|
+
@editor = "vim" if (@editor.nil? || @editor.empty?)
|
248
|
+
@editor = ScoobyDoo.where_are_you(@editor)
|
249
|
+
@editor = ScoobyDoo.where_are_you("vi") if (@editor.nil?)
|
250
|
+
end
|
251
|
+
|
252
|
+
def interactive_add_profile(name)
|
253
|
+
if (@profiles.has_key?(name))
|
254
|
+
raise ZoomError::ProfileAlreadyExistsError.new(name)
|
255
|
+
end
|
256
|
+
|
257
|
+
default_op = "grep"
|
258
|
+
if (ScoobyDoo.where_are_you("ag"))
|
259
|
+
default_op = "ag"
|
260
|
+
elsif (ScoobyDoo.where_are_you("ack"))
|
261
|
+
default_op = "ack"
|
262
|
+
elsif (ScoobyDoo.where_are_you("ack-grep"))
|
263
|
+
default_op = "ack-grep"
|
264
|
+
end
|
265
|
+
|
266
|
+
case default_op
|
267
|
+
when "ack", "ack-grep"
|
268
|
+
puts "Enter class (default AckProfile):"
|
269
|
+
when "ag"
|
270
|
+
puts "Enter class (default AgProfile):"
|
271
|
+
when "grep"
|
272
|
+
puts "Enter class (default GrepProfile):"
|
273
|
+
end
|
274
|
+
|
275
|
+
clas = gets.chomp
|
276
|
+
puts if (clas && !clas.empty?)
|
277
|
+
|
278
|
+
case default_op
|
279
|
+
when "ack", "ack-grep"
|
280
|
+
clas = "AckProfile" if (clas.nil? || clas.empty?)
|
281
|
+
when "ag"
|
282
|
+
clas = "AgProfile" if (clas.nil? || clas.empty?)
|
283
|
+
when "grep"
|
284
|
+
clas = "GrepProfile" if (clas.nil? || clas.empty?)
|
285
|
+
end
|
286
|
+
|
287
|
+
add_profile(name, clas)
|
288
|
+
interactive_edit_profile(name)
|
289
|
+
end
|
290
|
+
|
291
|
+
def interactive_edit_profile(name, profile = nil)
|
292
|
+
if (name == "zoom_find")
|
293
|
+
raise ZoomError::ProfileCanNotBeModifiedError.new(name)
|
294
|
+
end
|
295
|
+
|
296
|
+
profile = @profiles[name] if (profile.nil?)
|
297
|
+
|
298
|
+
if (profile.nil?)
|
299
|
+
raise ZoomError::ProfileDoesNotExistError.new(name)
|
300
|
+
end
|
301
|
+
|
302
|
+
# Get new operator
|
303
|
+
puts "Enter operator (default #{profile.operator}):"
|
304
|
+
|
305
|
+
op = ScoobyDoo.where_are_you(gets.chomp)
|
306
|
+
puts if (op && !op.empty?)
|
307
|
+
op = profile.operator if (op.nil? || op.empty?)
|
308
|
+
|
309
|
+
# Get new flags
|
310
|
+
puts "For empty string put \"empty\""
|
311
|
+
puts "Enter flags (default \"#{profile.flags}\"):"
|
312
|
+
|
313
|
+
flags = gets.chomp
|
314
|
+
puts if (flags && !flags.empty?)
|
315
|
+
flags = get_new_value(flags, profile.flags)
|
316
|
+
|
317
|
+
# Get new prepend
|
318
|
+
puts "For empty string put \"empty\""
|
319
|
+
puts "Enter prepend (default \"#{profile.prepend}\"):"
|
320
|
+
|
321
|
+
envprepend = gets.chomp
|
322
|
+
puts if (envprepend && !envprepend.empty?)
|
323
|
+
envprepend = get_new_value(envprepend, profile.prepend)
|
324
|
+
|
325
|
+
# Get new append
|
326
|
+
puts "For empty string put \"empty\""
|
327
|
+
puts "Enter append (default \"#{profile.append}\"):"
|
328
|
+
|
329
|
+
append = gets.chomp
|
330
|
+
puts if (append && !append.empty?)
|
331
|
+
append = get_new_value(append, profile.append)
|
332
|
+
|
333
|
+
edit_profile(name, profile, op, flags, envprepend, append)
|
334
|
+
end
|
335
|
+
|
336
|
+
def list_profile_names
|
337
|
+
@profiles.keys.sort.each do |name|
|
338
|
+
puts name
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def list_profiles
|
343
|
+
@profiles.keys.sort.each do |name|
|
344
|
+
if (name == @info["profile"])
|
345
|
+
puts "### #{name} ###".green
|
346
|
+
else
|
347
|
+
puts "### #{name} ###"
|
348
|
+
end
|
349
|
+
puts @profiles[name].info
|
350
|
+
puts
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def list_tags
|
355
|
+
return if (!@cache_file.exist?)
|
356
|
+
|
357
|
+
# Open shortcut file for writing
|
358
|
+
shct = File.open(@shortcut_file, "r")
|
359
|
+
|
360
|
+
# Read in cache
|
361
|
+
File.open(@cache_file) do |cache|
|
362
|
+
count = 1
|
363
|
+
|
364
|
+
cache.each do |line|
|
365
|
+
line.chomp!
|
366
|
+
plain = remove_colors(line)
|
367
|
+
if (line.start_with?("ZOOM_EXE_DIR="))
|
368
|
+
# Ignore this line
|
369
|
+
elsif ((line == "-") || (line == "--") || line.empty?)
|
370
|
+
# Ignore dividers when searching with context and
|
371
|
+
# empty lines
|
372
|
+
elsif (plain.scan(/^[0-9]+[:-]/).empty?)
|
373
|
+
if (!plain.scan(/^\.\//).empty?)
|
374
|
+
# Operator was probably find
|
375
|
+
puts count
|
376
|
+
count += 1
|
377
|
+
end
|
378
|
+
else
|
379
|
+
puts count
|
380
|
+
count += 1
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def loop_through_results(results)
|
387
|
+
tags = parse_tags(results)
|
388
|
+
return if (tags.empty?)
|
389
|
+
|
390
|
+
tag = tags.delete_at(0)
|
391
|
+
open_editor_to_result(tag)
|
392
|
+
|
393
|
+
tags.each do |tag|
|
394
|
+
print "Do you want to open result #{tag} [y]/n/q/l?: "
|
395
|
+
|
396
|
+
answer = nil
|
397
|
+
while (answer.nil?)
|
398
|
+
begin
|
399
|
+
system("stty raw -echo")
|
400
|
+
if ($stdin.ready?)
|
401
|
+
answer = $stdin.getc
|
402
|
+
else
|
403
|
+
sleep 0.1
|
404
|
+
end
|
405
|
+
ensure
|
406
|
+
system("stty -raw echo")
|
407
|
+
end
|
408
|
+
end
|
409
|
+
puts
|
410
|
+
|
411
|
+
case answer
|
412
|
+
when "n", "N"
|
413
|
+
# Do nothing
|
414
|
+
when "l", "L"
|
415
|
+
# Open this result then exit
|
416
|
+
open_editor_to_result(tag)
|
417
|
+
return
|
418
|
+
when "q", "Q", "\x03"
|
419
|
+
# Quit or ^C
|
420
|
+
return
|
421
|
+
else
|
422
|
+
open_editor_to_result(tag)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def open_editor_to_result(result)
|
428
|
+
loc = get_location_of_result(result.to_i)
|
429
|
+
if (loc)
|
430
|
+
system("#{@editor} #{loc}")
|
431
|
+
else
|
432
|
+
puts "Invalid tag \"#{result}\"!"
|
433
|
+
end
|
434
|
+
end
|
435
|
+
private :open_editor_to_result
|
436
|
+
|
437
|
+
def pager
|
438
|
+
File.open(@cache_file, "w") do |f|
|
439
|
+
f.write("ZOOM_EXE_DIR=#{Dir.pwd}\n")
|
440
|
+
begin
|
441
|
+
$stdin.each_line do |line|
|
442
|
+
f.write(line)
|
443
|
+
end
|
444
|
+
rescue Interrupt
|
445
|
+
# ^C
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
def parse_tags(results)
|
451
|
+
tags = Array.new
|
452
|
+
results.split(",").each do |num|
|
453
|
+
if (!num.scan(/^[0-9]+$/).empty?)
|
454
|
+
tags.push(num.to_i)
|
455
|
+
elsif (!num.scan(/^[0-9]+-[0-9]+$/).empty?)
|
456
|
+
range = num.split("-")
|
457
|
+
(range[0].to_i..range[1].to_i).each do |i|
|
458
|
+
tags.push(i)
|
459
|
+
end
|
460
|
+
else
|
461
|
+
puts "Tag #{num} not formatted properly. Ignoring."
|
462
|
+
end
|
463
|
+
end
|
464
|
+
return tags
|
465
|
+
end
|
466
|
+
private :parse_tags
|
467
|
+
|
468
|
+
def read_zoominfo
|
469
|
+
if (!@info_file.exist? && !@info_file.symlink?)
|
470
|
+
default_zoominfo
|
471
|
+
end
|
472
|
+
|
473
|
+
@info = JSON.parse(File.read(@info_file))
|
474
|
+
end
|
475
|
+
private :read_zoominfo
|
476
|
+
|
477
|
+
def read_zoomrc
|
478
|
+
default_zoomrc if (!@rc_file.exist? && !@rc_file.symlink?)
|
479
|
+
|
480
|
+
@rc = JSON.parse(File.read(@rc_file))
|
481
|
+
@profiles = Hash.new
|
482
|
+
@rc["profiles"].each do |name, prof|
|
483
|
+
@profiles[name] = ZoomProfile.from_json(prof)
|
484
|
+
end
|
485
|
+
@rc["profiles"] = @profiles
|
486
|
+
end
|
487
|
+
private :read_zoomrc
|
488
|
+
|
489
|
+
def rename_profile(rename, name = nil)
|
490
|
+
name = @info["profile"] if (name.nil?)
|
491
|
+
|
492
|
+
if ((name == "default") || (name == "zoom_find"))
|
493
|
+
raise ZoomError::ProfileCanNotBeModifiedError.new(name)
|
494
|
+
end
|
495
|
+
|
496
|
+
if (!@profiles.has_key?(name))
|
497
|
+
raise ZoomError::ProfileDoesNotExistError.new(name)
|
498
|
+
end
|
499
|
+
|
500
|
+
if (@profiles.has_key?(rename))
|
501
|
+
raise ZoomError::ProfileAlreadyExistsError.new(rename)
|
502
|
+
end
|
503
|
+
|
504
|
+
@profiles[rename] = @profiles[name]
|
505
|
+
@profiles.delete(name)
|
506
|
+
write_zoomrc
|
507
|
+
|
508
|
+
if (name == @info["profile"])
|
509
|
+
@info["profile"] = rename
|
510
|
+
write_zoominfo
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
def repeat
|
515
|
+
return if (@info["last_command"].empty?)
|
516
|
+
|
517
|
+
exe_command(
|
518
|
+
@info["last_command"]["profile"],
|
519
|
+
@info["last_command"]["subargs"],
|
520
|
+
@info["last_command"]["pattern"]
|
521
|
+
)
|
522
|
+
end
|
523
|
+
|
524
|
+
def remove_colors(str)
|
525
|
+
str.unpack("C*").pack("U*").gsub(/\e\[([0-9;]*m|K)/, "")
|
526
|
+
end
|
527
|
+
private :remove_colors
|
528
|
+
|
529
|
+
def shortcut_cache(profile = nil)
|
530
|
+
return if (!@cache_file.exist?)
|
531
|
+
return if (@info["last_command"].empty?)
|
532
|
+
|
533
|
+
if (profile.nil?)
|
534
|
+
profile = @profiles[@info["last_command"]["profile"]]
|
535
|
+
end
|
536
|
+
|
537
|
+
# Open shortcut file for writing
|
538
|
+
shct = File.open(@shortcut_file, "w")
|
539
|
+
|
540
|
+
# Read in cache
|
541
|
+
File.open(@cache_file) do |cache|
|
542
|
+
start_dir = ""
|
543
|
+
file = nil
|
544
|
+
filename = ""
|
545
|
+
first_time = true
|
546
|
+
count = 1
|
547
|
+
|
548
|
+
cache.each do |line|
|
549
|
+
line.chomp!
|
550
|
+
plain = remove_colors(line)
|
551
|
+
if (line.start_with?("ZOOM_EXE_DIR="))
|
552
|
+
# Get directory where search was ran
|
553
|
+
start_dir = line.gsub("ZOOM_EXE_DIR=", "")
|
554
|
+
elsif ((line == "-") || (line == "--") || line.empty?)
|
555
|
+
# Ignore dividers when searching with context and
|
556
|
+
# empty lines
|
557
|
+
elsif (plain.scan(/^[0-9]+[:-]/).empty?)
|
558
|
+
operator = profile.operator.split("/").last
|
559
|
+
if (operator != "find")
|
560
|
+
if (file != line)
|
561
|
+
# Filename
|
562
|
+
file = line
|
563
|
+
filename = remove_colors(file)
|
564
|
+
|
565
|
+
puts if (!first_time)
|
566
|
+
first_time = false
|
567
|
+
|
568
|
+
puts "\e[0m#{file}"
|
569
|
+
end
|
570
|
+
else
|
571
|
+
# Operator was find
|
572
|
+
puts "\e[1;31m[#{count}]\e[0m #{line}"
|
573
|
+
shct.write("'#{start_dir}/#{line}'\n")
|
574
|
+
count += 1
|
575
|
+
end
|
576
|
+
elsif (file)
|
577
|
+
# Match
|
578
|
+
sanitized = line.unpack("C*").pack("U*")
|
579
|
+
.gsub(/[\u0080-\u00ff]+/, "\1".dump[1..-2])
|
580
|
+
puts "\e[1;31m[#{count}]\e[0m #{sanitized}"
|
581
|
+
|
582
|
+
lineno = remove_colors(line).split(/[:-]/)[0]
|
583
|
+
shct.write(
|
584
|
+
"+#{lineno} '#{start_dir}/#{filename}'\n"
|
585
|
+
)
|
586
|
+
|
587
|
+
count += 1
|
588
|
+
end
|
589
|
+
end
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
def show_current
|
594
|
+
puts "### #{@info["profile"]} ###".green
|
595
|
+
puts @profiles[@info["profile"]].info
|
596
|
+
end
|
597
|
+
|
598
|
+
def switch_profile(name)
|
599
|
+
if (!@profiles.has_key?(name))
|
600
|
+
raise ZoomError::ProfileDoesNotExistError.new(name)
|
601
|
+
end
|
602
|
+
|
603
|
+
@info["profile"] = name
|
604
|
+
write_zoominfo
|
605
|
+
end
|
606
|
+
|
607
|
+
def write_zoominfo
|
608
|
+
File.open(@info_file, "w") do |file|
|
609
|
+
file.write(JSON.pretty_generate(@info))
|
610
|
+
end
|
611
|
+
end
|
612
|
+
private :write_zoominfo
|
613
|
+
|
614
|
+
def write_zoomrc
|
615
|
+
@rc["profiles"] = @profiles
|
616
|
+
File.open(@rc_file, "w") do |file|
|
617
|
+
file.write(JSON.pretty_generate(@rc))
|
618
|
+
end
|
619
|
+
end
|
620
|
+
private :write_zoomrc
|
621
|
+
end
|