ffast 0.1.6 → 0.1.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c664b4d8bafbac99cd9814bcdf77e730184c6e9a38a01ab52d21369bc9c52f8d
4
- data.tar.gz: 3f761262fc7db1a9ab856fcdab4bfe1580187d882f253f03cd82138b745a43d9
3
+ metadata.gz: d1ae41b9a66311eb3308fd3ca3f69f5a06943a337f9907d502f1a2ed27342a46
4
+ data.tar.gz: 80e545ae2769ab27ba39d8338b57c60626ca3f79ec5e73139c12f3cb01dfd5fb
5
5
  SHA512:
6
- metadata.gz: 742d1f586ede35f47ecdcd27013d9e2082641a7809edc6ea43e1538954a805d9d8aadd2f3c6772161bcad2df6223ba2920a71d745a067e3a6ca91c8ef220c2f4
7
- data.tar.gz: 7cb8e4d954d2ecea9e8a5d3f6f94a7b08ecaed80df1b6ee72bcb8e2b0ca58ce1fd20a84166f884fe8d38f4c692ae1da129ec3276a46d3f6a820efde903e830fd
6
+ metadata.gz: fbcb874fb1c2916d0fa89d687fd9e320f248c8cc64c5193244b8d007b39cffb86b23db2ff7c3134c4d43baba1d4d99b6526831a20b3c630867691d5076ae33bc
7
+ data.tar.gz: de6c3a1e706f6a3e39791a413584dc227af3ee8810628145b0844d9b4d2ac1f9d7f631c9db859a7cb6d8c7f56313b3f0aff2be4b9868627c31ece3924e79379c
data/Fastfile CHANGED
@@ -8,6 +8,9 @@
8
8
  # Let's say you'd like to show the version that is over the version file
9
9
  Fast.shortcut(:version, '(casgn nil VERSION (str _))', 'lib/fast/version.rb')
10
10
 
11
+ # Show all classes that inherits Fast::Find
12
+ Fast.shortcut(:finders, '(class ... (const nil Find)', 'lib')
13
+
11
14
  # You can run shortcuts appending a dot to the shortcut.
12
15
  # $ fast .version
13
16
  # # lib/fast/version.rb:4
data/README.md CHANGED
@@ -421,6 +421,7 @@ The CLI tool takes the following flags
421
421
  - Use `--pry` to jump debugging the first result with pry
422
422
  - Use `-c` to search from code example
423
423
  - Use `-s` to search similar code
424
+ - Use `-p` or `--parallel` to parallelize the search
424
425
 
425
426
  ### Define your `Fastfile`
426
427
 
@@ -11,6 +11,7 @@ $ fast '(def match?)' lib/fast.rb
11
11
  - Use `--pry` to jump debugging the first result with pry
12
12
  - Use `-c` to search from code example
13
13
  - Use `-s` to search similar code
14
+ - Use `-p` to or `--parallel` to use multi core search
14
15
 
15
16
  ## `--pry`
16
17
 
@@ -0,0 +1,46 @@
1
+ # Editors' integration
2
+
3
+ We don't have any proper integration or official plugins for editors yet.
4
+
5
+ Here are a few ideas you can use to make your own flow.
6
+
7
+ ## Vim
8
+
9
+ Split terminal vertically and open fast focused on build the expression.
10
+
11
+ ```vim
12
+ nnoremap <Leader>ff :vsplit \| terminal fast "()" % <Left><Left><Left><Left><Left>
13
+ ```
14
+
15
+ Or you can build a function:
16
+
17
+ ```vim
18
+ function! s:Fast(args)
19
+ let cmd = ''
20
+ if !empty(b:ruby_project_root)
21
+ let cmd .= 'cd ' . b:ruby_project_root . ' && '
22
+ endif
23
+
24
+ let cmd .= 'fast --no-color ' . a:args
25
+
26
+ let custom_maker = neomake#utils#MakerFromCommand(cmd)
27
+ let custom_maker.name = cmd
28
+ let custom_maker.cwd = b:ruby_project_root
29
+ let custom_maker.remove_invalid_entries = 0
30
+ " e.g.:
31
+ " # path/to/file.rb:1141
32
+ " my_method(
33
+ " :boom,
34
+ " arg1: 1,
35
+ " )
36
+ " %W# %f:%l -> start a multiline warning when the line matches '# path/file.rb:1234'
37
+ " %-Z# end multiline warning on the next line that starts with '#'
38
+ " %C%m continued multiline warning message
39
+ let custom_maker.errorformat = '%W# %f:%l, %-Z#, %C%m'
40
+ let enabled_makers = [custom_maker]
41
+ update | call neomake#Make(0, enabled_makers) | echom "running: " . cmd
42
+ endfunction
43
+ command! -complete=file -nargs=1 Fast call s:Fast(<q-args>)
44
+ ```
45
+
46
+ Check the conversation about vim integration [here](https://github.com/jonatas/fast/pull/16#issuecomment-555115606).
@@ -0,0 +1,288 @@
1
+ # Shortcuts
2
+
3
+ Shortcuts are defined on a `Fastfile` inside any ruby project.
4
+
5
+ !!!info "Use `~/Fastfile`"
6
+ You can also add one extra in your `$HOME` if you want to have something loaded always.
7
+
8
+ By default, the command line interface does not load any `Fastfile` if the
9
+ first param is not a shortcut. It should start with `.`.
10
+
11
+ I'm building several researches and I'll make the examples open here to show
12
+ several interesting cases in action.
13
+
14
+ ## Rails: Show validations from models
15
+
16
+ If the shortcut does not define a block, it works as a holder for arguments from
17
+ the command line.
18
+
19
+ Let's say you always use `fast "(send nil {validate validates})" app/models` to
20
+ check validations in the models. You can define a shortcut to hold the args and
21
+ avoid retyping long lines:
22
+
23
+ ```ruby
24
+ # Show validations from app/models
25
+ Fast.shortcut(:validations, "(send nil {validate validates})", "app/models")
26
+ ```
27
+ And you can reuse the search with the shortcut starting with a `.`:
28
+
29
+ ```
30
+ fast .validations
31
+ ```
32
+ And it will also accept params if you want to filter a specific file:
33
+
34
+ ```
35
+ fast .validations app/models/user.rb
36
+ ```
37
+
38
+ !!! info "Note that you can also use flags in the command line shortcuts"
39
+
40
+ Let's say you also want to use `fast --headless` you can add it to the params:
41
+
42
+ > Fast.shortcut(:validations, "(send nil {validate validates})", "app/models", "--headless")
43
+
44
+ ## Automated Refactor: Bump version
45
+
46
+ Let's start with a [real usage](https://github.com/jonatas/fast/blob/master/Fastfile#L20-L34)
47
+ to bump a new version of the gem.
48
+
49
+ ```ruby
50
+ Fast.shortcut :bump_version do
51
+ rewrite_file('(casgn nil VERSION (str _)', 'lib/fast/version.rb') do |node|
52
+ target = node.children.last.loc.expression
53
+ pieces = target.source.split('.').map(&:to_i)
54
+ pieces.reverse.each_with_index do |fragment, i|
55
+ if fragment < 9
56
+ pieces[-(i + 1)] = fragment + 1
57
+ break
58
+ else
59
+ pieces[-(i + 1)] = 0
60
+ end
61
+ end
62
+ replace(target, "'#{pieces.join('.')}'")
63
+ end
64
+ end
65
+ ```
66
+
67
+ And then the change is done in the `lib/fast/version.rb`:
68
+
69
+ ```diff
70
+ module Fast
71
+ - VERSION = '0.1.6'
72
+ + VERSION = '0.1.7'
73
+ end
74
+ ```
75
+
76
+ ## List Shortcuts
77
+
78
+ As the interface is very rudimentar, let's build a shortcut to print what
79
+ shortcuts are available. This is a good one to your `$HOME/Fastfile`:
80
+
81
+ ```ruby
82
+ # List all shortcut with comments
83
+ Fast.shortcut :shortcuts do
84
+ fast_files.each do |file|
85
+ lines = File.readlines(file).map{|line|line.chomp.gsub(/\s*#/,'').strip}
86
+ result = capture_file('(send ... shortcut $(sym _', file)
87
+ result = [result] unless result.is_a?Array
88
+ result.each do |capture|
89
+ target = capture.loc.expression
90
+ puts "fast .#{target.source[1..-1].ljust(30)} # #{lines[target.line-2]}"
91
+ end
92
+ end
93
+ end
94
+ ```
95
+
96
+ And using it on `fast` project that loads both `~/Fastfile` and the Fastfile from the project:
97
+
98
+ ```
99
+ fast .version # Let's say you'd like to show the version that is over the version file
100
+ fast .parser # Simple shortcut that I used often to show how the expression parser works
101
+ fast .bump_version # Use `fast .bump_version` to rewrite the version file
102
+ fast .shortcuts # List all shortcut with comments
103
+ ```
104
+
105
+ ## RSpec: Find unused shared contexts
106
+
107
+ If you build shared contexts often, probably you can forget some left overs.
108
+
109
+ The objective of the shortcut is find leftovers from shared contexts.
110
+
111
+ First, the objective is capture all names of the `RSpec.shared_context` or
112
+ `shared_context` declared in the `spec/support` folder.
113
+
114
+ ```ruby
115
+ Fast.capture_all('(block (send {nil,_} shared_context (str $_)))', Fast.ruby_files_from('spec/support'))
116
+ ```
117
+
118
+ Then, we need to check all the specs and search for `include_context` usages to
119
+ confirm if all defined contexts are being used:
120
+
121
+ ```ruby
122
+ specs = Fast.ruby_files_from('spec').select{|f|f !~ %r{spec/support/}}
123
+ Fast.search_all("(send nil include_context (str #register_usage)", specs)
124
+ ```
125
+
126
+ Note that we created a new reference to `#register_usage` and we need to define the method too:
127
+
128
+
129
+ ```ruby
130
+ @used = []
131
+ def register_usage context_name
132
+ @used << context_name
133
+ end
134
+ ```
135
+
136
+ Wrapping up everything in a shortcut:
137
+
138
+ ```ruby
139
+ # Show unused shared contexts
140
+ Fast.shortcut(:unused_shared_contexts) do
141
+ puts "Checking shared contexts"
142
+ Kernel.class_eval do
143
+ @used = []
144
+ def register_usage context_name
145
+ @used << context_name
146
+ end
147
+ def show_report! defined_contexts
148
+ unused = defined_contexts.values.flatten - @used
149
+ if unused.any?
150
+ puts "Unused shared contexts", unused
151
+ else
152
+ puts "Good job! all the #{defined_contexts.size} contexts are used!"
153
+ end
154
+ end
155
+ end
156
+ specs = ruby_files_from('spec/').select{|f|f !~ %r{spec/support/}}
157
+ search_all("(send nil include_context (str #register_usage)", specs)
158
+ defined_contexts = capture_all('(block (send {nil,_} shared_context (str $_)))', ruby_files_from('spec'))
159
+ Kernel.public_send(:show_report!, defined_contexts)
160
+ end
161
+ ```
162
+
163
+ !!! faq "Why `#register_usage` is defined on the `Kernel`?"
164
+ Yes! note that the `#register_usage` was forced to be inside `Kernel`
165
+ because of the `shortcut` block that takes the `Fast` context to be easy
166
+ to access in the default functions. As I can define multiple shortcuts
167
+ I don't want to polute my Kernel module with other methods that are not useful.
168
+
169
+
170
+ ## RSpec: Remove unused let
171
+
172
+ !!! hint "First shortcut with experiments"
173
+ If you're not familiar with automated experiments, you can read about it [here](/experiments).
174
+
175
+ The current scenario is similar in terms of search with the previous one, but more advanced
176
+ because we're going to introduce automated refactoring.
177
+
178
+ The idea is simple, if it finds a `let` in a RSpec scenario that is not referenced, it tries to experimentally remove the `let` and run the tests:
179
+
180
+ ```ruby
181
+ # Experimental remove `let` that are not referenced in the spec
182
+ Fast.shortcut(:exp_remove_let) do
183
+ require 'fast/experiment'
184
+ Kernel.class_eval do
185
+ file = ARGV.last
186
+
187
+ defined_lets = Fast.capture_file('(block (send nil let (sym $_)))', file).uniq
188
+ @unreferenced= defined_lets.select do |identifier|
189
+ Fast.search_file("(send nil #{identifier})", file).empty?
190
+ end
191
+
192
+ def unreferenced_let?(identifier)
193
+ @unreferenced.include? identifier
194
+ end
195
+ end
196
+
197
+ experiment('RSpec/RemoveUnreferencedLet') do
198
+ lookup ARGV.last
199
+ search '(block (send nil let (sym #unreferenced_let?)))'
200
+ edit { |node| remove(node.loc.expression) }
201
+ policy { |new_file| system("bundle exec rspec --fail-fast #{new_file}") }
202
+ end.run
203
+ end
204
+ ```
205
+
206
+ And it will run with a single file from command line:
207
+
208
+ ```
209
+ fast .exp_remove_let spec/my_file_spec.rb
210
+ ```
211
+
212
+ ## FactoryBot: Replace `create` with `build_stubbed`
213
+
214
+ For performance reasons, if we can avoid touching the database the test will
215
+ always be faster.
216
+
217
+ ```ruby
218
+ # Experimental switch from `create` to `build_stubbed`
219
+ Fast.shortcut(:exp_build_stubbed) do
220
+ require 'fast/experiment'
221
+ Fast.experiment('FactoryBot/UseBuildStubbed') do
222
+ lookup ARGV.last
223
+ search '(send nil create)'
224
+ edit { |node| replace(node.loc.selector, 'build_stubbed') }
225
+ policy { |new_file| system("bundle exec rspec --fail-fast #{new_file}") }
226
+ end.run
227
+ end
228
+ ```
229
+ ## RSpec: Use `let_it_be` instead of `let`
230
+
231
+ The `let_it_be` is a simple helper from
232
+ [TestProf](https://test-prof.evilmartians.io/#/let_it_be) gem that can speed up
233
+ the specs by caching some factories using like a `before_all` approach.
234
+
235
+ This experiment hunts for `let(...) { create(...) }` and switch the `let` to
236
+ `let_it_be`:
237
+
238
+ ```ruby
239
+ # Experimental replace `let(_)` with `let_it_be` case it calls `create` inside the block
240
+ Fast.shortcut(:exp_let_it_be) do
241
+ require 'fast/experiment'
242
+ Fast.experiment('FactoryBot/LetItBe') do
243
+ lookup ARGV.last
244
+ search '(block (send nil let (sym _)) (args) (send nil create))'
245
+ edit { |node| replace(node.children.first.loc.selector, 'let_it_be') }
246
+ policy { |new_file| system("bin/spring rspec --fail-fast #{new_file}") }
247
+ end.run
248
+ end
249
+ ```
250
+
251
+ ## RSpec: Remove `before` or `after` blocks
252
+
253
+ From time to time, we forget some left overs like `before` or `after` blocks
254
+ that even removing from the code, the tests still passes. This experiment
255
+ removes the before/after blocks and check if the test passes.
256
+
257
+ ```ruby
258
+ # Experimental remove `before` or `after` blocks.
259
+ Fast.shortcut(:exp_remove_before_after) do
260
+ require 'fast/experiment'
261
+ Fast.experiment('RSpec/RemoveBeforeAfter') do
262
+ lookup ARGV.last
263
+ search '(block (send nil {before after}))'
264
+ edit { |node| remove(node.loc.expression) }
265
+ policy { |new_file| system("bin/spring rspec --fail-fast #{new_file}") }
266
+ end.run
267
+ end
268
+ ```
269
+
270
+ ## RSpec: Show message chains
271
+
272
+ I often forget the syntax and need to search for message chains on specs, so I
273
+ created an shortcut for it.
274
+
275
+ ```ruby
276
+ # Show RSpec message chains
277
+ Fast.shortcut(:message_chains, '^^(send nil receive_message_chain)', 'spec')
278
+ ```
279
+
280
+ ## RSpec: Show nested assertions
281
+
282
+ I love to use nested assertions and I often need examples to refer to them:
283
+
284
+ ```ruby
285
+ # Show RSpec nested assertions with .and
286
+ Fast.shortcut(:nested_assertions, '^^(send ... and)', 'spec')
287
+ ```
288
+
@@ -0,0 +1,12 @@
1
+ # Videos
2
+
3
+ - Grepping Ruby code like a boss: [RubyConf Brazil 2019 (Portuguese)](https://www.eventials.com/locaweb/jonatas-paganini-live-coding-grepping-ruby-code-like-a-boss/#_=_)
4
+
5
+ - Introduction to [inline code](https://www.youtube.com/watch?v=KQXglNLUv7o).
6
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/KQXglNLUv7o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
7
+
8
+ - [Making local variables inline](https://www.youtube.com/watch?v=JD44nhegCRs)
9
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/YN0s9kV1A2A" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
10
+
11
+ - [Making methods inline](https://www.youtube.com/watch?v=JD44nhegCRs)
12
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/YN0s9kV1A2A" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_dependency 'astrolabe'
28
28
  spec.add_dependency 'coderay'
29
+ spec.add_dependency 'parallel'
29
30
  spec.add_dependency 'parser'
30
31
  spec.add_dependency 'pry'
31
32
 
@@ -108,25 +108,50 @@ module Fast
108
108
  # @param [String] pattern
109
109
  # @param [Array<String>] *locations where to search. Default is '.'
110
110
  # @return [Hash<String,Array<Astrolabe::Node>>] with files and results
111
- def search_all(pattern, locations = ['.'])
112
- search_pattern = method(:search_file).curry.call(pattern)
113
- group_results(search_pattern, locations)
111
+ def search_all(pattern, locations = ['.'], parallel: true, on_result: nil)
112
+ group_results(build_grouped_search(:search_file, pattern, on_result),
113
+ locations, parallel: parallel)
114
114
  end
115
115
 
116
116
  # Capture with pattern on a directory or multiple files
117
117
  # @param [String] pattern
118
118
  # @param [Array<String>] locations where to search. Default is '.'
119
119
  # @return [Hash<String,Object>] with files and captures
120
- def capture_all(pattern, locations = ['.'])
121
- capture_pattern = method(:capture_file).curry.call(pattern)
122
- group_results(capture_pattern, locations)
120
+ def capture_all(pattern, locations = ['.'], parallel: true, on_result: nil)
121
+ group_results(build_grouped_search(:capture_file, pattern, on_result),
122
+ locations, parallel: parallel)
123
+ end
124
+
125
+ # @return [Proc] binding `pattern` argument from a given `method_name`.
126
+ # @param [Symbol] method_name with `:capture_file` or `:search_file`
127
+ # @param [String] pattern to match in a search to any file
128
+ # @param [Proc] on_result is a callback that can be notified soon it matches
129
+ def build_grouped_search(method_name, pattern, on_result)
130
+ search_pattern = method(method_name).curry.call(pattern)
131
+ proc do |file|
132
+ results = search_pattern.call(file)
133
+ next if results.nil? || results.empty?
134
+
135
+ on_result&.(file, results)
136
+ { file => results }
137
+ end
123
138
  end
124
139
 
125
- def group_results(search_pattern, locations)
126
- ruby_files_from(*locations)
127
- .map { |f| { f => search_pattern.call(f) } }
128
- .reject { |results| results.values.all?(&:empty?) }
129
- .inject(&:merge!)
140
+ # Compact grouped results by file allowing parallel processing.
141
+ # @param [Proc] group_files allows to define a search that can be executed
142
+ # parallel or not.
143
+ # @param [Proc] on_result allows to define a callback for fast feedback
144
+ # while it process several locations in parallel.
145
+ # @param [Boolean] parallel runs the `group_files` in parallel
146
+ # @return [Hash[String, Array]] with files and results
147
+ def group_results(group_files, locations, parallel: true)
148
+ files = ruby_files_from(*locations)
149
+ if parallel
150
+ require 'parallel' unless defined?(Parallel)
151
+ Parallel.map(files, &group_files)
152
+ else
153
+ files.map(&group_files)
154
+ end.compact.inject(&:merge!)
130
155
  end
131
156
 
132
157
  # Capture elements from searches in files. Keep in mind you need to use `$`
@@ -154,19 +179,16 @@ module Fast
154
179
  end
155
180
  end
156
181
 
157
- # Return only captures from a search
182
+ # Only captures from a search
158
183
  # @return [Array<Object>] with all captured elements.
159
- # @return [Object] with single element when single capture.
160
184
  def capture(pattern, node)
161
- res = if (match = match?(pattern, node))
162
- match == true ? node : match
163
- else
164
- node.each_child_node
165
- .flat_map { |child| capture(pattern, child) }
166
- .compact.flatten
167
- end
168
- res = [res] unless res.is_a?(Array)
169
- res.one? ? res.first : res
185
+ if (match = match?(pattern, node))
186
+ match == true ? node : match
187
+ else
188
+ node.each_child_node
189
+ .flat_map { |child| capture(pattern, child) }
190
+ .compact.flatten
191
+ end
170
192
  end
171
193
 
172
194
  def expression(string)
@@ -69,6 +69,10 @@ module Fast
69
69
  @show_sexp = true
70
70
  end
71
71
 
72
+ opts.on('-p', '--parallel', 'Paralelize search') do
73
+ @parallel = true
74
+ end
75
+
72
76
  opts.on('--captures', 'Print only captures of the patterns and skip node results') do
73
77
  @captures = true
74
78
  end
@@ -129,6 +133,8 @@ module Fast
129
133
 
130
134
  # Show help or search for node patterns
131
135
  def run!
136
+ raise 'pry and parallel options are incompatible :(' if @parallel && @pry
137
+
132
138
  if @help || @files.empty? && @pattern.nil?
133
139
  puts option_parser.help
134
140
  else
@@ -137,6 +143,7 @@ module Fast
137
143
  end
138
144
 
139
145
  # Create fast expression from node pattern using the command line
146
+ # @return [Array<Fast::Find>] with the expression from string.
140
147
  def expression
141
148
  Fast.expression(@pattern)
142
149
  end
@@ -146,24 +153,29 @@ module Fast
146
153
  # If capture option is enabled it will only print the captures, otherwise it
147
154
  # prints all the results.
148
155
  def search
149
- if debug_mode?
150
- Fast.debug { execute_search }
151
- else
152
- execute_search do |file, results|
153
- results.each do |result|
154
- binding.pry if @pry # rubocop:disable Lint/Debugger
155
- report(result, file)
156
- end
156
+ return Fast.debug(&method(:execute_search)) if debug_mode?
157
+
158
+ execute_search do |file, results|
159
+ results.each do |result|
160
+ binding.pry if @pry # rubocop:disable Lint/Debugger
161
+ report(file, result)
157
162
  end
158
163
  end
159
164
  end
160
165
 
161
- def execute_search
162
- method_name = @captures ? :capture_all : :search_all
163
- (Fast.public_send(method_name, expression, @files) || []).each do |file, results|
164
- results = [results] unless results.is_a?(Array)
165
- yield file, results
166
- end
166
+ # Executes search for all files yielding the results
167
+ # @yieldparam [String, Array] with file and respective search results
168
+ def execute_search(&on_result)
169
+ Fast.public_send(search_method_name,
170
+ expression,
171
+ @files,
172
+ parallel: parallel?,
173
+ on_result: on_result)
174
+ end
175
+
176
+ # @return [Symbol] with `:capture_all` or `:search_all` depending the command line options
177
+ def search_method_name
178
+ @captures ? :capture_all : :search_all
167
179
  end
168
180
 
169
181
  # @return [Boolean] true when "-d" or "--debug" option is passed
@@ -176,9 +188,13 @@ module Fast
176
188
  puts(info) if debug_mode?
177
189
  end
178
190
 
191
+ def parallel?
192
+ @parallel == true
193
+ end
194
+
179
195
  # Report results using the actual options binded from command line.
180
196
  # @see Fast.report
181
- def report(result, file)
197
+ def report(file, result)
182
198
  Fast.report(result, file: file, show_sexp: @show_sexp, headless: @headless, colorize: @colorize)
183
199
  end
184
200
 
@@ -198,7 +214,10 @@ module Fast
198
214
  # Prints available shortcuts as extra help and exit with code 1.
199
215
  def exit_shortcut_not_found(name)
200
216
  puts "Shortcut \033[1m#{name}\033[0m not found :("
201
- puts "Available shortcuts are: #{Fast.shortcuts.keys.join(', ')}." if Fast.shortcuts.any?
217
+ if Fast.shortcuts.any?
218
+ puts "Available shortcuts are: #{Fast.shortcuts.keys.join(', ')}."
219
+ Fast.load_fast_files!
220
+ end
202
221
  exit 1
203
222
  end
204
223
  end
@@ -66,7 +66,7 @@ module Fast
66
66
  # the options from previous alias and replacing the files with the
67
67
  # @param [Array] extra_args
68
68
  def merge_args(extra_args)
69
- [params[0], *options, *extra_args]
69
+ [params[0], *options, *extra_args.select(&File.method(:exists?))]
70
70
  end
71
71
 
72
72
  # If the shortcut was defined with a single block and no extra arguments, it
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fast
4
- VERSION = '0.1.6'
4
+ VERSION = '0.1.7'
5
5
  end
data/mkdocs.yml CHANGED
@@ -18,5 +18,8 @@ nav:
18
18
  - Syntax: syntax.md
19
19
  - Command Line: command_line.md
20
20
  - Experiments: experiments.md
21
+ - Shortcuts: shortcuts.md
21
22
  - Code Similarity: similarity_tutorial.md
22
23
  - Pry Integration: pry-integration.md
24
+ - Editors' Integration: editors-integration.md
25
+ - Videos: videos.md
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jônatas Davi Paganini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-18 00:00:00.000000000 Z
11
+ date: 2019-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: astrolabe
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: parallel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: parser
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -247,11 +261,14 @@ files:
247
261
  - bin/fast-experiment
248
262
  - bin/setup
249
263
  - docs/command_line.md
264
+ - docs/editors-integration.md
250
265
  - docs/experiments.md
251
266
  - docs/index.md
252
267
  - docs/pry-integration.md
268
+ - docs/shortcuts.md
253
269
  - docs/similarity_tutorial.md
254
270
  - docs/syntax.md
271
+ - docs/videos.md
255
272
  - examples/build_stubbed_and_let_it_be_experiment.rb
256
273
  - examples/experimental_replacement.rb
257
274
  - examples/find_usage.rb
@@ -291,7 +308,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
291
308
  - !ruby/object:Gem::Version
292
309
  version: '0'
293
310
  requirements: []
294
- rubygems_version: 3.0.3
311
+ rubyforge_project:
312
+ rubygems_version: 2.7.6.2
295
313
  signing_key:
296
314
  specification_version: 4
297
315
  summary: 'FAST: Find by AST.'