ruby-zoom 3.5.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/bin/z +189 -147
  3. data/bin/zc +189 -147
  4. data/bin/zf +189 -147
  5. data/bin/zg +189 -147
  6. data/bin/zl +189 -147
  7. data/bin/zr +189 -147
  8. data/lib/zoom.rb +48 -604
  9. data/lib/zoom/cache.rb +253 -0
  10. data/lib/zoom/cache/result.rb +49 -0
  11. data/lib/zoom/config.rb +156 -0
  12. data/lib/zoom/editor.rb +121 -0
  13. data/lib/zoom/error.rb +6 -6
  14. data/lib/zoom/error/{executable_not_found_error.rb → executable_not_found.rb} +1 -3
  15. data/lib/zoom/error/invalid_color.rb +5 -0
  16. data/lib/zoom/error/{invalid_tag_error.rb → invalid_tag.rb} +1 -3
  17. data/lib/zoom/error/{profile_class_unknown_error.rb → profile_class_unknown.rb} +1 -3
  18. data/lib/zoom/error/{profile_does_not_exist_error.rb → profile_does_not_exist.rb} +1 -3
  19. data/lib/zoom/error/profile_not_named.rb +7 -0
  20. data/lib/zoom/profile.rb +162 -66
  21. data/lib/zoom/profile/ack.rb +5 -30
  22. data/lib/zoom/profile/ag.rb +2 -37
  23. data/lib/zoom/profile/find.rb +2 -25
  24. data/lib/zoom/profile/grep.rb +2 -44
  25. data/lib/zoom/profile/passwords.rb +27 -59
  26. data/lib/zoom/profile/pt.rb +2 -26
  27. data/lib/zoom/profile_manager.rb +49 -0
  28. data/lib/zoom/wish/add_wish.rb +58 -0
  29. data/lib/zoom/wish/color_wish.rb +147 -0
  30. data/lib/zoom/wish/copy_wish.rb +57 -0
  31. data/lib/zoom/wish/delete_wish.rb +51 -0
  32. data/lib/zoom/wish/edit_wish.rb +130 -0
  33. data/lib/zoom/wish/editor_wish.rb +31 -0
  34. data/lib/zoom/wish/list_wish.rb +58 -0
  35. data/lib/zoom/wish/rename_wish.rb +69 -0
  36. data/lib/zoom/wish/reset_wish.rb +40 -0
  37. data/lib/zoom/wish/use_wish.rb +61 -0
  38. metadata +118 -24
  39. data/lib/string.rb +0 -48
  40. data/lib/zoom/error/profile_already_exists_error.rb +0 -8
  41. data/lib/zoom/error/profile_can_not_be_modified_error.rb +0 -8
data/bin/zc CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require "djinni"
4
+ require "fileutils"
5
+ require "hilighter"
3
6
  require "optparse"
4
7
  require "zoom"
5
8
 
@@ -8,7 +11,9 @@ class ZoomExit
8
11
  INVALID_OPTION = 1
9
12
  INVALID_ARGUMENT = 2
10
13
  MISSING_ARGUMENT = 3
11
- EXCEPTION = 4
14
+ EXTRA_ARGUMENTS = 4
15
+ EXCEPTION = 5
16
+ AMBIGUOUS_ARGUMENT = 6
12
17
  end
13
18
 
14
19
  def parse(args)
@@ -16,76 +21,50 @@ def parse(args)
16
21
  options["action"] = "exec"
17
22
  options["cache_file"] = nil
18
23
  options["use"] = nil
24
+ options["verbose"] = false
19
25
 
20
- info = "Do you like to search through code using ag, ack, or " \
21
- "grep? Good! This tool is for you! Zoom adds some " \
22
- "convenience to ag/ack/grep by allowing you to quickly " \
23
- "open your search results in your editor of choice. When " \
24
- "looking at large code-bases, it can be a pain to have to " \
25
- "scroll to find the filename of each result. Zoom prints a " \
26
- "tag number in front of each result that ag/ack/grep " \
27
- "outputs. Then you can quickly open that tag number with " \
28
- "Zoom to jump straight to the source. Zoom is even " \
29
- "persistent across all your sessions! You can search in " \
30
- "one terminal and jump to a tag in another terminal from " \
31
- "any directory!"
26
+ info = [
27
+ "Do you like to search through code using ag, ack, grep, or",
28
+ "pt? Good! This tool is for you! Zoom adds some convenience",
29
+ "to ag/ack/grep/pt by allowing you to quickly open your",
30
+ "search results in your editor of choice. When looking at",
31
+ "large code-bases, it can be a pain to have to scroll to",
32
+ "find the filename of each result. Zoom prints a tag number",
33
+ "in front of each result that ag/ack/grep/pt outputs. Then",
34
+ "you can quickly open that tag number with Zoom to jump",
35
+ "straight to the source. Zoom is even persistent across all",
36
+ "your sessions! You can search in one terminal and jump to a",
37
+ "tag in another terminal from any directory!"
38
+ ].join(" ")
32
39
 
33
40
  parser = OptionParser.new do |opts|
41
+ opts.summary_width = 25
42
+
34
43
  opts.banner =
35
- "Usage: #{File.basename($0)} [OPTIONS] <pattern>"
44
+ "Usage: #{File.basename($0)} [OPTIONS] [pattern]"
36
45
 
37
- opts.on(
38
- "-a",
39
- "--add=NAME",
40
- "Add a new profile with specified name"
41
- ) do |name|
42
- options["action"] = "add"
43
- options["use"] = name
46
+ opts.on("", "DESCRIPTION")
47
+
48
+ info.scan(/\S.{0,76}\S(?=\s|$)|\S+/).each do |line|
49
+ opts.on(" #{line}")
44
50
  end
45
51
 
52
+ opts.on("", "OPTIONS")
53
+
46
54
  opts.on("-c", "--cache", "Show previous results") do
47
55
  options["action"] = "cache"
48
56
  end
49
57
 
50
58
  opts.on(
59
+ "-o",
51
60
  "--cache-file=FILE",
52
- "Use the specified cache file"
61
+ "Use alternate cache"
53
62
  ) do |file|
54
63
  options["cache_file"] = file
55
64
  end
56
65
 
57
- opts.on(
58
- "-d",
59
- "--delete=NAME",
60
- "Delete profile with specified name"
61
- ) do |name|
62
- options["action"] = "delete"
63
- options["use"] = name
64
- end
65
-
66
- opts.on(
67
- "-e",
68
- "--edit=NAME",
69
- "Edit profile with specified name"
70
- ) do |name|
71
- options["action"] = "edit"
72
- options["use"] = name
73
- end
74
-
75
- opts.on(
76
- "--editor=EDITOR",
77
- "Use the specified editor"
78
- ) do |editor|
79
- options["action"] = "editor"
80
- options["use"] = editor
81
- end
82
-
83
- opts.on("--examples", "Show some examples") do
84
- options["action"] = "examples"
85
- end
86
-
87
- opts.on("--find", "Use the zoom_find profile") do
88
- options["use"] = "zoom_find"
66
+ opts.on("--find", "Use built-in find profile") do
67
+ options["use"] = "find"
89
68
  end
90
69
 
91
70
  opts.on(
@@ -106,65 +85,78 @@ def parse(args)
106
85
  options["action"] = "list_profiles"
107
86
  end
108
87
 
109
- opts.on(
110
- "--list-profile-names",
111
- "List profile names for completion functions"
112
- ) do
113
- options["action"] = "list_profile_names"
88
+ opts.on("-r", "--repeat", "Repeat last Zoom command") do
89
+ options["action"] = "repeat"
114
90
  end
115
91
 
116
- opts.on(
117
- "--list-tags",
118
- "List tags for completion functions"
119
- ) do
120
- options["action"] = "list_tags"
92
+ opts.on("-u", "--use=NAME", "Run specified profile") do |name|
93
+ options["use"] = name
121
94
  end
122
95
 
123
- opts.on(
124
- "--pager",
125
- "Treat Zoom as a pager (internal use only)"
126
- ) do
127
- options["action"] = "pager"
96
+ opts.on("-w", "--which", "Display current profile") do
97
+ options["action"] = "which"
128
98
  end
129
99
 
130
- opts.on("-r", "--repeat", "Repeat the last Zoom command") do
131
- options["action"] = "repeat"
100
+ opts.on("", "CONFIGURE_OPTIONS")
101
+
102
+ opts.on(
103
+ "--configure",
104
+ "Open prompt to edit profiles"
105
+ ) do
106
+ options["action"] = "configure"
132
107
  end
133
108
 
134
- opts.on("--rc", "Create default .zoomrc file") do
109
+ opts.on("--rc", "Create default config file") do
135
110
  options["action"] = "rc"
136
111
  end
137
112
 
113
+ opts.on("", "MISC_OPTIONS")
114
+
138
115
  opts.on(
139
- "--rename=NAME",
140
- "Rename the current profile"
141
- ) do |name|
142
- options["action"] = "rename"
143
- options["rename"] = name
116
+ "--list-profile-names",
117
+ "List profile names for completion functions"
118
+ ) do
119
+ options["action"] = "list_profile_names"
144
120
  end
145
121
 
146
122
  opts.on(
147
- "-s",
148
- "--switch=NAME",
149
- "Switch to profile with specified name"
150
- ) do |name|
151
- options["action"] = "switch"
152
- options["use"] = name
123
+ "--list-tags",
124
+ "List tags for completion functions"
125
+ ) do
126
+ options["action"] = "list_tags"
127
+ end
128
+
129
+ opts.on("--nocolor", "Disable colorized output") do
130
+ Hilighter.disable
153
131
  end
154
132
 
155
133
  opts.on(
156
- "-u",
157
- "--use=NAME",
158
- "Use specified profile one time only"
159
- ) do |name|
160
- options["use"] = name
134
+ "-v",
135
+ "--verbose",
136
+ "Show backtrace when error occurs"
137
+ ) do
138
+ options["verbose"] = true
161
139
  end
162
140
 
163
- opts.on("-w", "--which", "Display the current profile") do
164
- options["action"] = "which"
141
+ opts.on("--version", "Show version") do
142
+ options["action"] = "version"
165
143
  end
166
144
 
167
- opts.on("", info.word_wrap(80))
145
+ opts.on(
146
+ "",
147
+ "EXAMPLES",
148
+ " Execute default profile:",
149
+ " $ z PATTERN",
150
+ "",
151
+ " Execute specified profile:",
152
+ " $ z -u grep PATTERN",
153
+ "",
154
+ " Pass additional flags to default profile:",
155
+ " $ z -- -A 3 PATTERN",
156
+ "",
157
+ " Open tags:",
158
+ " $ zg 10,20,30-40"
159
+ )
168
160
  end
169
161
 
170
162
  begin
@@ -181,13 +173,17 @@ def parse(args)
181
173
  puts e.message
182
174
  puts parser
183
175
  exit ZoomExit::MISSING_ARGUMENT
176
+ rescue OptionParser::AmbiguousOption => e
177
+ puts e.message
178
+ puts parser
179
+ exit ZoomExit::AMBIGUOUS_ARGUMENT
184
180
  end
185
181
 
186
182
  case File.basename($0)
187
183
  when "zc"
188
184
  options["action"] = "cache"
189
185
  when "zf"
190
- options["use"] = "zoom_find"
186
+ options["use"] = "find"
191
187
  when "zg"
192
188
  options["action"] = "go"
193
189
  options["use"] = args[0]
@@ -196,7 +192,7 @@ def parse(args)
196
192
  when "zr"
197
193
  options["action"] = "repeat"
198
194
  when "z"
199
- # do nothing, this is the normal usage
195
+ # Do nothing, this is the normal usage
200
196
  else
201
197
  options["use"] = File.basename($0)
202
198
  end
@@ -208,80 +204,126 @@ end
208
204
 
209
205
  options = parse(ARGV)
210
206
 
211
- zoom = Zoom.new(options["cache_file"])
212
207
  begin
208
+ if (options["action"] == "rc")
209
+ FileUtils.rm_f(Pathname.new("~/.zoomrc").expand_path)
210
+ end
211
+
212
+ zoom = Zoom.new(options["cache_file"], nil, !Hilighter.disable?)
213
+
213
214
  case options["action"]
214
- when "add"
215
- zoom.interactive_add_profile(options["use"])
216
215
  when "cache"
217
- zoom.shortcut_cache
218
- when "delete"
219
- zoom.delete_profile(options["use"])
220
- when "edit"
221
- zoom.interactive_edit_profile(options["use"])
222
- when "editor"
223
- zoom.configure_editor(options["use"])
224
- when "examples"
225
- puts [
226
- "EXAMPLES:",
227
- "",
228
- "Add a profile named test:",
229
- " $ z --add test",
230
- "",
231
- "Edit a profile named test:",
232
- " $ z --edit test",
233
- "",
234
- "Execute the current profile:",
235
- " $ z PATTERN",
236
- "",
237
- "Repeat the previous Zoom command:",
238
- " $ z --repeat",
239
- "",
240
- "Pass additional flags to the choosen operator:",
241
- " $ z -- -A 3 PATTERN",
242
- "",
243
- "Open a tag:",
244
- " $ z --go 10",
245
- "",
246
- "Open multiple tags:",
247
- " $ z --go 10,20,30-40"
248
- ].join("\n")
216
+ zoom.cache.shortcut(zoom.config)
217
+ when "configure"
218
+ Zoom.hilight(false)
219
+ djinni = Djinni.new
220
+ djinni.load_wishes(
221
+ "#{File.dirname(__FILE__)}/../lib/zoom/wish"
222
+ )
223
+ djinni.prompt(
224
+ {
225
+ "cache" => zoom.cache,
226
+ "config" => zoom.config,
227
+ "prompt_color" => "white",
228
+ "zoom" => zoom
229
+ },
230
+ "zoom(#{zoom.config.current_profile_name})> ".white
231
+ )
249
232
  when "go"
250
- zoom.loop_through_results(options["use"])
233
+ if (options["use"])
234
+ results = zoom.cache.get_results(options["use"])
235
+ zoom.open(results)
236
+ end
251
237
  when "list_profiles"
252
- zoom.list_profiles
238
+ profiles = zoom.config.get_profiles
239
+ profiles.keys.sort do |a, b|
240
+ a.downcase <=> b.downcase
241
+ end.each do |name|
242
+ if (name == zoom.config.current_profile_name)
243
+ print "*".red if (Zoom.hilight?)
244
+ print "*" if (!Zoom.hilight?)
245
+ end
246
+
247
+ lines = profiles[name].to_s.scan(
248
+ /\S.{0,76}\S(?=\s|$)|\S+/
249
+ )
250
+ puts lines.delete_at(0)
251
+ lines.each do |line|
252
+ puts " #{line}"
253
+ end
254
+ end
253
255
  when "list_profile_names"
254
- zoom.list_profile_names
256
+ puts zoom.config.get_profile_names
255
257
  when "list_tags"
256
- zoom.list_tags
257
- when "pager"
258
- zoom.pager
258
+ puts zoom.cache.available_tags
259
259
  when "repeat"
260
260
  zoom.repeat
261
261
  when "rc"
262
- zoom.default
263
- when "rename"
264
- zoom.rename_profile(
265
- options["rename"],
266
- options["use"]
267
- )
268
- when "switch"
269
- zoom.switch_profile(options["use"])
262
+ zoom.config.default_config
263
+ zoom.cache.clear
264
+ when "version"
265
+ __FILE__.match(/ruby-zoom-(\d+\.\d+\.\d+)/) do |m|
266
+ puts m[1]
267
+ end
270
268
  when "which"
271
- zoom.show_current
269
+ name = zoom.config.current_profile_name
270
+ profile = zoom.config.get_profiles[name]
271
+
272
+ print "*".red if (Zoom.hilight?)
273
+ print "*" if (!Zoom.hilight?)
274
+
275
+ lines = profile.to_s.scan(/\S.{0,76}\S(?=\s|$)|\S+/)
276
+ puts lines.delete_at(0)
277
+ lines.each do |line|
278
+ puts " #{line}"
279
+ end
272
280
  else
273
- # Search and save results
274
- zoom.exec_profile(
281
+ # Search and cache results
282
+ zoom.run(
275
283
  options["use"],
276
284
  options["subargs"],
277
285
  options["pattern"]
278
286
  )
279
287
  end
288
+ rescue SystemExit
289
+ # Quit from djinni
290
+ # Exit gracefully
280
291
  rescue Zoom::Error => e
281
- puts e.message
292
+ $stderr.puts e.message
293
+ if (options["verbose"])
294
+ e.backtrace.each do |line|
295
+ $stderr.puts line.yellow
296
+ end
297
+ end
282
298
  exit ZoomExit::EXCEPTION
299
+ rescue Interrupt
300
+ # ^C
301
+ # Exit gracefully
302
+ rescue Errno::EPIPE
303
+ # Do nothing. This can happen if piping to another program such as
304
+ # less. Usually if less is closed before Zoom is done with STDOUT.
283
305
  rescue Exception => e
284
- puts e.message
306
+ $stderr.puts
307
+ $stderr.puts "Oops! Looks like an error has occured! Try " \
308
+ "resetting your configs with the"
309
+ $stderr.puts "following comand:"
310
+ $stderr.puts
311
+ $stderr.puts " z --rc"
312
+ $stderr.puts
313
+ $stderr.puts "If the error persists, file a bug at:"
314
+ $stderr.puts
315
+ $stderr.puts " https://gitlab.com/mjwhitta/zoom/issues"
316
+ $stderr.puts
317
+ $stderr.puts "Maybe the message below will help. If not, you " \
318
+ "can use the --verbose flag to get"
319
+ $stderr.puts "a backtrace."
320
+
321
+ $stderr.puts e.message.white.on_red
322
+ if (options["verbose"])
323
+ e.backtrace.each do |line|
324
+ $stderr.puts line.yellow
325
+ end
326
+ end
285
327
  exit ZoomExit::EXCEPTION
286
328
  end
287
329
  exit ZoomExit::GOOD
data/bin/zf CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require "djinni"
4
+ require "fileutils"
5
+ require "hilighter"
3
6
  require "optparse"
4
7
  require "zoom"
5
8
 
@@ -8,7 +11,9 @@ class ZoomExit
8
11
  INVALID_OPTION = 1
9
12
  INVALID_ARGUMENT = 2
10
13
  MISSING_ARGUMENT = 3
11
- EXCEPTION = 4
14
+ EXTRA_ARGUMENTS = 4
15
+ EXCEPTION = 5
16
+ AMBIGUOUS_ARGUMENT = 6
12
17
  end
13
18
 
14
19
  def parse(args)
@@ -16,76 +21,50 @@ def parse(args)
16
21
  options["action"] = "exec"
17
22
  options["cache_file"] = nil
18
23
  options["use"] = nil
24
+ options["verbose"] = false
19
25
 
20
- info = "Do you like to search through code using ag, ack, or " \
21
- "grep? Good! This tool is for you! Zoom adds some " \
22
- "convenience to ag/ack/grep by allowing you to quickly " \
23
- "open your search results in your editor of choice. When " \
24
- "looking at large code-bases, it can be a pain to have to " \
25
- "scroll to find the filename of each result. Zoom prints a " \
26
- "tag number in front of each result that ag/ack/grep " \
27
- "outputs. Then you can quickly open that tag number with " \
28
- "Zoom to jump straight to the source. Zoom is even " \
29
- "persistent across all your sessions! You can search in " \
30
- "one terminal and jump to a tag in another terminal from " \
31
- "any directory!"
26
+ info = [
27
+ "Do you like to search through code using ag, ack, grep, or",
28
+ "pt? Good! This tool is for you! Zoom adds some convenience",
29
+ "to ag/ack/grep/pt by allowing you to quickly open your",
30
+ "search results in your editor of choice. When looking at",
31
+ "large code-bases, it can be a pain to have to scroll to",
32
+ "find the filename of each result. Zoom prints a tag number",
33
+ "in front of each result that ag/ack/grep/pt outputs. Then",
34
+ "you can quickly open that tag number with Zoom to jump",
35
+ "straight to the source. Zoom is even persistent across all",
36
+ "your sessions! You can search in one terminal and jump to a",
37
+ "tag in another terminal from any directory!"
38
+ ].join(" ")
32
39
 
33
40
  parser = OptionParser.new do |opts|
41
+ opts.summary_width = 25
42
+
34
43
  opts.banner =
35
- "Usage: #{File.basename($0)} [OPTIONS] <pattern>"
44
+ "Usage: #{File.basename($0)} [OPTIONS] [pattern]"
36
45
 
37
- opts.on(
38
- "-a",
39
- "--add=NAME",
40
- "Add a new profile with specified name"
41
- ) do |name|
42
- options["action"] = "add"
43
- options["use"] = name
46
+ opts.on("", "DESCRIPTION")
47
+
48
+ info.scan(/\S.{0,76}\S(?=\s|$)|\S+/).each do |line|
49
+ opts.on(" #{line}")
44
50
  end
45
51
 
52
+ opts.on("", "OPTIONS")
53
+
46
54
  opts.on("-c", "--cache", "Show previous results") do
47
55
  options["action"] = "cache"
48
56
  end
49
57
 
50
58
  opts.on(
59
+ "-o",
51
60
  "--cache-file=FILE",
52
- "Use the specified cache file"
61
+ "Use alternate cache"
53
62
  ) do |file|
54
63
  options["cache_file"] = file
55
64
  end
56
65
 
57
- opts.on(
58
- "-d",
59
- "--delete=NAME",
60
- "Delete profile with specified name"
61
- ) do |name|
62
- options["action"] = "delete"
63
- options["use"] = name
64
- end
65
-
66
- opts.on(
67
- "-e",
68
- "--edit=NAME",
69
- "Edit profile with specified name"
70
- ) do |name|
71
- options["action"] = "edit"
72
- options["use"] = name
73
- end
74
-
75
- opts.on(
76
- "--editor=EDITOR",
77
- "Use the specified editor"
78
- ) do |editor|
79
- options["action"] = "editor"
80
- options["use"] = editor
81
- end
82
-
83
- opts.on("--examples", "Show some examples") do
84
- options["action"] = "examples"
85
- end
86
-
87
- opts.on("--find", "Use the zoom_find profile") do
88
- options["use"] = "zoom_find"
66
+ opts.on("--find", "Use built-in find profile") do
67
+ options["use"] = "find"
89
68
  end
90
69
 
91
70
  opts.on(
@@ -106,65 +85,78 @@ def parse(args)
106
85
  options["action"] = "list_profiles"
107
86
  end
108
87
 
109
- opts.on(
110
- "--list-profile-names",
111
- "List profile names for completion functions"
112
- ) do
113
- options["action"] = "list_profile_names"
88
+ opts.on("-r", "--repeat", "Repeat last Zoom command") do
89
+ options["action"] = "repeat"
114
90
  end
115
91
 
116
- opts.on(
117
- "--list-tags",
118
- "List tags for completion functions"
119
- ) do
120
- options["action"] = "list_tags"
92
+ opts.on("-u", "--use=NAME", "Run specified profile") do |name|
93
+ options["use"] = name
121
94
  end
122
95
 
123
- opts.on(
124
- "--pager",
125
- "Treat Zoom as a pager (internal use only)"
126
- ) do
127
- options["action"] = "pager"
96
+ opts.on("-w", "--which", "Display current profile") do
97
+ options["action"] = "which"
128
98
  end
129
99
 
130
- opts.on("-r", "--repeat", "Repeat the last Zoom command") do
131
- options["action"] = "repeat"
100
+ opts.on("", "CONFIGURE_OPTIONS")
101
+
102
+ opts.on(
103
+ "--configure",
104
+ "Open prompt to edit profiles"
105
+ ) do
106
+ options["action"] = "configure"
132
107
  end
133
108
 
134
- opts.on("--rc", "Create default .zoomrc file") do
109
+ opts.on("--rc", "Create default config file") do
135
110
  options["action"] = "rc"
136
111
  end
137
112
 
113
+ opts.on("", "MISC_OPTIONS")
114
+
138
115
  opts.on(
139
- "--rename=NAME",
140
- "Rename the current profile"
141
- ) do |name|
142
- options["action"] = "rename"
143
- options["rename"] = name
116
+ "--list-profile-names",
117
+ "List profile names for completion functions"
118
+ ) do
119
+ options["action"] = "list_profile_names"
144
120
  end
145
121
 
146
122
  opts.on(
147
- "-s",
148
- "--switch=NAME",
149
- "Switch to profile with specified name"
150
- ) do |name|
151
- options["action"] = "switch"
152
- options["use"] = name
123
+ "--list-tags",
124
+ "List tags for completion functions"
125
+ ) do
126
+ options["action"] = "list_tags"
127
+ end
128
+
129
+ opts.on("--nocolor", "Disable colorized output") do
130
+ Hilighter.disable
153
131
  end
154
132
 
155
133
  opts.on(
156
- "-u",
157
- "--use=NAME",
158
- "Use specified profile one time only"
159
- ) do |name|
160
- options["use"] = name
134
+ "-v",
135
+ "--verbose",
136
+ "Show backtrace when error occurs"
137
+ ) do
138
+ options["verbose"] = true
161
139
  end
162
140
 
163
- opts.on("-w", "--which", "Display the current profile") do
164
- options["action"] = "which"
141
+ opts.on("--version", "Show version") do
142
+ options["action"] = "version"
165
143
  end
166
144
 
167
- opts.on("", info.word_wrap(80))
145
+ opts.on(
146
+ "",
147
+ "EXAMPLES",
148
+ " Execute default profile:",
149
+ " $ z PATTERN",
150
+ "",
151
+ " Execute specified profile:",
152
+ " $ z -u grep PATTERN",
153
+ "",
154
+ " Pass additional flags to default profile:",
155
+ " $ z -- -A 3 PATTERN",
156
+ "",
157
+ " Open tags:",
158
+ " $ zg 10,20,30-40"
159
+ )
168
160
  end
169
161
 
170
162
  begin
@@ -181,13 +173,17 @@ def parse(args)
181
173
  puts e.message
182
174
  puts parser
183
175
  exit ZoomExit::MISSING_ARGUMENT
176
+ rescue OptionParser::AmbiguousOption => e
177
+ puts e.message
178
+ puts parser
179
+ exit ZoomExit::AMBIGUOUS_ARGUMENT
184
180
  end
185
181
 
186
182
  case File.basename($0)
187
183
  when "zc"
188
184
  options["action"] = "cache"
189
185
  when "zf"
190
- options["use"] = "zoom_find"
186
+ options["use"] = "find"
191
187
  when "zg"
192
188
  options["action"] = "go"
193
189
  options["use"] = args[0]
@@ -196,7 +192,7 @@ def parse(args)
196
192
  when "zr"
197
193
  options["action"] = "repeat"
198
194
  when "z"
199
- # do nothing, this is the normal usage
195
+ # Do nothing, this is the normal usage
200
196
  else
201
197
  options["use"] = File.basename($0)
202
198
  end
@@ -208,80 +204,126 @@ end
208
204
 
209
205
  options = parse(ARGV)
210
206
 
211
- zoom = Zoom.new(options["cache_file"])
212
207
  begin
208
+ if (options["action"] == "rc")
209
+ FileUtils.rm_f(Pathname.new("~/.zoomrc").expand_path)
210
+ end
211
+
212
+ zoom = Zoom.new(options["cache_file"], nil, !Hilighter.disable?)
213
+
213
214
  case options["action"]
214
- when "add"
215
- zoom.interactive_add_profile(options["use"])
216
215
  when "cache"
217
- zoom.shortcut_cache
218
- when "delete"
219
- zoom.delete_profile(options["use"])
220
- when "edit"
221
- zoom.interactive_edit_profile(options["use"])
222
- when "editor"
223
- zoom.configure_editor(options["use"])
224
- when "examples"
225
- puts [
226
- "EXAMPLES:",
227
- "",
228
- "Add a profile named test:",
229
- " $ z --add test",
230
- "",
231
- "Edit a profile named test:",
232
- " $ z --edit test",
233
- "",
234
- "Execute the current profile:",
235
- " $ z PATTERN",
236
- "",
237
- "Repeat the previous Zoom command:",
238
- " $ z --repeat",
239
- "",
240
- "Pass additional flags to the choosen operator:",
241
- " $ z -- -A 3 PATTERN",
242
- "",
243
- "Open a tag:",
244
- " $ z --go 10",
245
- "",
246
- "Open multiple tags:",
247
- " $ z --go 10,20,30-40"
248
- ].join("\n")
216
+ zoom.cache.shortcut(zoom.config)
217
+ when "configure"
218
+ Zoom.hilight(false)
219
+ djinni = Djinni.new
220
+ djinni.load_wishes(
221
+ "#{File.dirname(__FILE__)}/../lib/zoom/wish"
222
+ )
223
+ djinni.prompt(
224
+ {
225
+ "cache" => zoom.cache,
226
+ "config" => zoom.config,
227
+ "prompt_color" => "white",
228
+ "zoom" => zoom
229
+ },
230
+ "zoom(#{zoom.config.current_profile_name})> ".white
231
+ )
249
232
  when "go"
250
- zoom.loop_through_results(options["use"])
233
+ if (options["use"])
234
+ results = zoom.cache.get_results(options["use"])
235
+ zoom.open(results)
236
+ end
251
237
  when "list_profiles"
252
- zoom.list_profiles
238
+ profiles = zoom.config.get_profiles
239
+ profiles.keys.sort do |a, b|
240
+ a.downcase <=> b.downcase
241
+ end.each do |name|
242
+ if (name == zoom.config.current_profile_name)
243
+ print "*".red if (Zoom.hilight?)
244
+ print "*" if (!Zoom.hilight?)
245
+ end
246
+
247
+ lines = profiles[name].to_s.scan(
248
+ /\S.{0,76}\S(?=\s|$)|\S+/
249
+ )
250
+ puts lines.delete_at(0)
251
+ lines.each do |line|
252
+ puts " #{line}"
253
+ end
254
+ end
253
255
  when "list_profile_names"
254
- zoom.list_profile_names
256
+ puts zoom.config.get_profile_names
255
257
  when "list_tags"
256
- zoom.list_tags
257
- when "pager"
258
- zoom.pager
258
+ puts zoom.cache.available_tags
259
259
  when "repeat"
260
260
  zoom.repeat
261
261
  when "rc"
262
- zoom.default
263
- when "rename"
264
- zoom.rename_profile(
265
- options["rename"],
266
- options["use"]
267
- )
268
- when "switch"
269
- zoom.switch_profile(options["use"])
262
+ zoom.config.default_config
263
+ zoom.cache.clear
264
+ when "version"
265
+ __FILE__.match(/ruby-zoom-(\d+\.\d+\.\d+)/) do |m|
266
+ puts m[1]
267
+ end
270
268
  when "which"
271
- zoom.show_current
269
+ name = zoom.config.current_profile_name
270
+ profile = zoom.config.get_profiles[name]
271
+
272
+ print "*".red if (Zoom.hilight?)
273
+ print "*" if (!Zoom.hilight?)
274
+
275
+ lines = profile.to_s.scan(/\S.{0,76}\S(?=\s|$)|\S+/)
276
+ puts lines.delete_at(0)
277
+ lines.each do |line|
278
+ puts " #{line}"
279
+ end
272
280
  else
273
- # Search and save results
274
- zoom.exec_profile(
281
+ # Search and cache results
282
+ zoom.run(
275
283
  options["use"],
276
284
  options["subargs"],
277
285
  options["pattern"]
278
286
  )
279
287
  end
288
+ rescue SystemExit
289
+ # Quit from djinni
290
+ # Exit gracefully
280
291
  rescue Zoom::Error => e
281
- puts e.message
292
+ $stderr.puts e.message
293
+ if (options["verbose"])
294
+ e.backtrace.each do |line|
295
+ $stderr.puts line.yellow
296
+ end
297
+ end
282
298
  exit ZoomExit::EXCEPTION
299
+ rescue Interrupt
300
+ # ^C
301
+ # Exit gracefully
302
+ rescue Errno::EPIPE
303
+ # Do nothing. This can happen if piping to another program such as
304
+ # less. Usually if less is closed before Zoom is done with STDOUT.
283
305
  rescue Exception => e
284
- puts e.message
306
+ $stderr.puts
307
+ $stderr.puts "Oops! Looks like an error has occured! Try " \
308
+ "resetting your configs with the"
309
+ $stderr.puts "following comand:"
310
+ $stderr.puts
311
+ $stderr.puts " z --rc"
312
+ $stderr.puts
313
+ $stderr.puts "If the error persists, file a bug at:"
314
+ $stderr.puts
315
+ $stderr.puts " https://gitlab.com/mjwhitta/zoom/issues"
316
+ $stderr.puts
317
+ $stderr.puts "Maybe the message below will help. If not, you " \
318
+ "can use the --verbose flag to get"
319
+ $stderr.puts "a backtrace."
320
+
321
+ $stderr.puts e.message.white.on_red
322
+ if (options["verbose"])
323
+ e.backtrace.each do |line|
324
+ $stderr.puts line.yellow
325
+ end
326
+ end
285
327
  exit ZoomExit::EXCEPTION
286
328
  end
287
329
  exit ZoomExit::GOOD