ruby-zoom 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|