yap-shell-addon-keyboard-macros 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9affe23c7af6a446231e3531cad0d653f3316e19
4
+ data.tar.gz: 5bba5b658d2411d800c61ef0c4b3285011f8f124
5
+ SHA512:
6
+ metadata.gz: e40c3ae748194c46a4fa6e227a25bea2daefb29e999933ffba9d5b20dd2d0ebcf858e7f061e81ed4fb5a6f0694a9c23a180b3b6a1b27b0c7f10fd541469dea5a
7
+ data.tar.gz: 32381095ad4898d0224ae2a936f790668011b16de52b6178e2024e3dc0f9a4a08c50726913c954af89f5c8c663c8acbb015e452b7cb4770e44947fbb3d0b1496
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1 @@
1
+ 2.3.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in yap-shell-addon-keyboard-macros.gemspec
4
+ gemspec
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ yap-shell-addon-keyboard-macros (0.1.0)
5
+ yap-shell (~> 0.6)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ byebug (8.2.5)
11
+ chronic (0.10.2)
12
+ coderay (1.1.1)
13
+ diff-lcs (1.2.5)
14
+ highline (1.7.8)
15
+ method_source (0.8.2)
16
+ pry (0.10.3)
17
+ coderay (~> 1.1.0)
18
+ method_source (~> 0.8.1)
19
+ slop (~> 3.4)
20
+ pry-byebug (3.3.0)
21
+ byebug (~> 8.0)
22
+ pry (~> 0.10)
23
+ rake (11.2.2)
24
+ rspec (3.4.0)
25
+ rspec-core (~> 3.4.0)
26
+ rspec-expectations (~> 3.4.0)
27
+ rspec-mocks (~> 3.4.0)
28
+ rspec-core (3.4.4)
29
+ rspec-support (~> 3.4.0)
30
+ rspec-expectations (3.4.0)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.4.0)
33
+ rspec-mocks (3.4.1)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.4.0)
36
+ rspec-support (3.4.1)
37
+ ruby-terminfo (0.1.1)
38
+ ruby-termios (0.9.6)
39
+ slop (3.6.0)
40
+ term-ansicolor (1.3.2)
41
+ tins (~> 1.0)
42
+ terminal-layout (0.4.0)
43
+ highline (~> 1.7, >= 1.7.8)
44
+ ruby-terminfo (~> 0.1.1)
45
+ ruby-termios (~> 0.9.6)
46
+ treefell (~> 0.2.3)
47
+ tins (1.10.2)
48
+ treefell (0.2.3)
49
+ term-ansicolor (~> 1.3)
50
+ yap-rawline (0.5.0)
51
+ highline (~> 1.7, >= 1.7.2)
52
+ term-ansicolor (~> 1.3.0)
53
+ terminal-layout (~> 0.4.0)
54
+ treefell (~> 0.2.3)
55
+ yap-shell (0.6.0)
56
+ chronic (~> 0.10.2)
57
+ pry-byebug (~> 3.3.0)
58
+ ruby-terminfo (~> 0.1.1)
59
+ ruby-termios (~> 0.9.6)
60
+ term-ansicolor (~> 1.3)
61
+ treefell (~> 0.2.3)
62
+ yap-rawline (~> 0.5.0)
63
+ yap-shell-parser (~> 0.7.0)
64
+ yap-shell-parser (0.7.0)
65
+ term-ansicolor (~> 1.3.0)
66
+ treefell (~> 0.2.3)
67
+
68
+ PLATFORMS
69
+ ruby
70
+
71
+ DEPENDENCIES
72
+ bundler (~> 1.12)
73
+ rake (~> 11.2)
74
+ rspec (~> 3.4)
75
+ yap-shell-addon-keyboard-macros!
76
+
77
+ BUNDLED WITH
78
+ 1.12.5
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Zach Dennis
4
+
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ # keyboard-macros for yap-shell
2
+
3
+ Welcome to your new yap addon! In this directory, you'll find the files you need to be able to package up your addon into a gem. Put your Ruby code in the file `lib/yap-shell-addon-keyboard-macros`.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'yap-shell-addon-keyboard-macros'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install yap-shell-addon-keyboard-macros
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/yap-shell-addon-keyboard-macros.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "yap/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,415 @@
1
+ require 'yap/addon'
2
+ require 'yap-shell-addon-keyboard-macros/version'
3
+ require 'yap-shell-addon-keyboard-macros/cycle'
4
+ require 'yap-shell-addon-keyboard-macros/pretty_print_key'
5
+
6
+ module YapShellAddonKeyboardMacros
7
+ class Addon < ::Yap::Addon::Base
8
+ self.export_as :'keyboard-macros'
9
+
10
+ include PrettyPrintKey
11
+
12
+ DEFAULT_TRIGGER_KEY = :ctrl_g
13
+ DEFAULT_CANCEL_KEY = " "
14
+ DEFAULT_TIMEOUT_IN_MS = 500
15
+
16
+ attr_reader :world
17
+ attr_accessor :timeout_in_ms
18
+ attr_accessor :cancel_key, :trigger_key
19
+ attr_accessor :cancel_on_unknown_sequences
20
+
21
+ def initialize_world(world)
22
+ @world = world
23
+ @configurations = []
24
+ @stack = []
25
+ @timeout_in_ms = DEFAULT_TIMEOUT_IN_MS
26
+ @cancel_key = DEFAULT_CANCEL_KEY
27
+ @trigger_key = DEFAULT_TRIGGER_KEY
28
+ @cancel_on_unknown_sequences = false
29
+ end
30
+
31
+ def cancel_key=(key)
32
+ logger.puts "setting default cancel_key key=#{ppk(key)}"
33
+ @cancel_key = key
34
+ end
35
+
36
+ def cancel_on_unknown_sequences=(true_or_false)
37
+ logger.puts "setting default cancel_on_unknown_sequences=#{true_or_false}"
38
+ @cancel_on_unknown_sequences = true_or_false
39
+ end
40
+
41
+ def timeout_in_ms=(milliseconds)
42
+ logger.puts "setting default timeout_in_ms milliseconds=#{milliseconds.inspect}"
43
+ @timeout_in_ms = milliseconds
44
+ end
45
+
46
+ def trigger_key=(key)
47
+ logger.puts "setting default trigger_key key=#{ppk(key)}"
48
+ @trigger_key = key
49
+ end
50
+
51
+ def configure(cancel_key: nil, trigger_key: nil, &blk)
52
+ logger.puts "configure cancel_key=#{ppk(cancel_key)} trigger_key=#{ppk(trigger_key)} block_given?=#{block_given?}"
53
+
54
+ cancel_key ||= @cancel_key
55
+ trigger_key ||= @trigger_key
56
+
57
+ cancel_blk = lambda do
58
+ world.editor.event_loop.clear @event_id
59
+ cancel_processing
60
+ nil
61
+ end
62
+
63
+ configuration = Configuration.new(
64
+ keymap: world.editor.terminal.keys,
65
+ trigger_key: trigger_key,
66
+ cancellation: Cancellation.new(cancel_key: cancel_key, &cancel_blk),
67
+ editor: world.editor,
68
+ )
69
+
70
+ blk.call configuration if blk
71
+
72
+ world.unbind(trigger_key)
73
+ world.bind(trigger_key) do
74
+ logger.puts "macro triggered key=#{ppk(trigger_key)}"
75
+
76
+ begin
77
+ @previous_result = nil
78
+ @stack << OpenStruct.new(configuration: configuration)
79
+ configuration.start.call if configuration.start
80
+
81
+ logger.puts "taking over keyboard input processing from editor"
82
+ world.editor.push_keyboard_input_processor(self)
83
+
84
+ wait_timeout_in_seconds = 0.1
85
+ world.editor.input.wait_timeout_in_seconds = wait_timeout_in_seconds
86
+ ensure
87
+ queue_up_remove_input_processor(&configuration.stop)
88
+ end
89
+ end
90
+
91
+ @configurations << configuration
92
+ end
93
+
94
+ def cycle(name, &cycle_thru_blk)
95
+ logger.puts "defining cycle name=#{name.inspect}"
96
+
97
+ @cycles ||= {}
98
+ if block_given?
99
+ cycle = YapShellAddonKeyboardMacros::Cycle.new(
100
+ cycle_proc: cycle_thru_blk,
101
+ on_cycle_proc: -> (old_value, new_value) {
102
+ @world.editor.delete_n_characters(old_value.to_s.length)
103
+ process_result(new_value)
104
+ }
105
+ )
106
+ @cycles[name] = cycle
107
+ else
108
+ @cycles.fetch(name)
109
+ end
110
+ end
111
+
112
+ #
113
+ # InputProcessor Methods
114
+ #
115
+
116
+ def read_bytes(bytes)
117
+ if @stack.last
118
+ current_definition = @stack.last
119
+ configuration = current_definition.configuration
120
+ end
121
+
122
+ bytes.each_with_index do |byte, i|
123
+ definition = configuration[byte]
124
+ if !definition
125
+ cancel_processing if cancel_on_unknown_sequences
126
+ break
127
+ end
128
+
129
+ configuration = definition.configuration
130
+ configuration.start.call if configuration.start
131
+ @stack << definition
132
+
133
+ result = definition.process
134
+
135
+ if result =~ /\n$/
136
+ world.editor.write result.chomp, add_to_line_history: false
137
+ world.editor.event_loop.clear @event_id if @event_id
138
+ cancel_processing
139
+ world.editor.newline # add_to_history
140
+ world.editor.process_line
141
+ break
142
+ end
143
+
144
+ if i == bytes.length - 1
145
+ while @stack.last && @stack.last.fragment?
146
+ @stack.pop
147
+ end
148
+ end
149
+
150
+ if @event_id
151
+ world.editor.event_loop.clear @event_id
152
+ @event_id = queue_up_remove_input_processor
153
+ end
154
+
155
+ process_result(result)
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ def process_result(result)
162
+ if result.is_a?(String)
163
+ @world.editor.write result, add_to_line_history: false
164
+ @previous_result = result
165
+ end
166
+ end
167
+
168
+ def queue_up_remove_input_processor(&blk)
169
+ return unless @timeout_in_ms
170
+
171
+ event_args = {
172
+ name: 'remove_input_processor',
173
+ source: self,
174
+ interval_in_ms: @timeout_in_ms,
175
+ }
176
+ @event_id = world.editor.event_loop.once(event_args) do
177
+ cancel_processing
178
+ end
179
+ end
180
+
181
+ def cancel_processing
182
+ logger.puts "cancel_processing"
183
+ @event_id = nil
184
+ @stack.reverse.each do |definition|
185
+ definition.configuration.stop.call if definition.configuration.stop
186
+ end
187
+ @stack.clear
188
+ if world.editor.keyboard_input_processor == self
189
+ logger.puts "giving keyboard input processing control back"
190
+ world.editor.pop_keyboard_input_processor
191
+
192
+ logger.puts "restoring default editor input timeout"
193
+ world.editor.input.restore_default_timeout
194
+ end
195
+ end
196
+
197
+ class Cancellation
198
+ attr_reader :cancel_key
199
+
200
+ def initialize(cancel_key: , &blk)
201
+ @cancel_key = cancel_key
202
+ @blk = blk
203
+ end
204
+
205
+ def call
206
+ @blk.call
207
+ end
208
+ end
209
+
210
+ class Configuration
211
+ include PrettyPrintKey
212
+
213
+ attr_reader :cancellation, :trigger_key, :keymap
214
+
215
+ def logger
216
+ Addon.logger
217
+ end
218
+
219
+ def initialize(cancellation: nil, editor:, keymap: {}, trigger_key: nil)
220
+ @cancellation = cancellation
221
+ @editor = editor
222
+ @keymap = keymap
223
+ @trigger_key = trigger_key
224
+ @storage = {}
225
+ @on_start_blk = nil
226
+ @on_stop_blk = nil
227
+ @cycles = {}
228
+
229
+ logger.puts "configuring a macro trigger_key=#{ppk(trigger_key)}"
230
+
231
+ if @cancellation
232
+ define @cancellation.cancel_key, -> { @cancellation.call }
233
+ end
234
+ end
235
+
236
+ def start(&blk)
237
+ @on_start_blk = blk if blk
238
+ @on_start_blk
239
+ end
240
+
241
+ def stop(&blk)
242
+ @on_stop_blk = blk if blk
243
+ @on_stop_blk
244
+ end
245
+
246
+ def cycle(name, &cycle_thru_blk)
247
+ logger.puts "defining a cycle on macro name=#{name.inspect}"
248
+
249
+ if block_given?
250
+ cycle = YapShellAddonKeyboardMacros::Cycle.new(
251
+ cycle_proc: cycle_thru_blk,
252
+ on_cycle_proc: -> (old_value, new_value) {
253
+ @editor.delete_n_characters(old_value.to_s.length)
254
+ }
255
+ )
256
+ @cycles[name] = cycle
257
+ else
258
+ @cycles.fetch(name)
259
+ end
260
+ end
261
+
262
+ def fragment(sequence, result)
263
+ define(sequence, result, fragment: true)
264
+ end
265
+
266
+ def define(sequence, result=nil, fragment: false, &blk)
267
+ logger.puts "defining macro sequence=#{sequence.inspect} result=#{result.inspect} fragment=#{fragment.inspect} under macro #{ppk(trigger_key)}"
268
+ unless result.respond_to?(:call)
269
+ string_result = result
270
+ result = -> { string_result }
271
+ end
272
+
273
+ case sequence
274
+ when String
275
+ recursively_define_sequence_for_bytes(
276
+ self,
277
+ sequence.bytes,
278
+ result,
279
+ fragment: fragment,
280
+ &blk
281
+ )
282
+ when Symbol
283
+ recursively_define_sequence_for_bytes(
284
+ self,
285
+ @keymap.fetch(sequence){
286
+ fail "Cannot bind unknown sequence #{sequence.inspect}"
287
+ },
288
+ result,
289
+ fragment: fragment,
290
+ &blk
291
+ )
292
+ when Regexp
293
+ define_sequence_for_regex(sequence, result, fragment: fragment, &blk)
294
+ else
295
+ raise NotImplementedError, <<-EOT.gsub(/^\s*/, '')
296
+ Don't know how to define macro for sequence: #{sequence.inspect}
297
+ EOT
298
+ end
299
+ end
300
+
301
+ def [](byte)
302
+ @storage.values.detect { |definition| definition.matches?(byte) }
303
+ end
304
+
305
+ def []=(key, definition)
306
+ @storage[key] = definition
307
+ end
308
+
309
+ def inspect
310
+ str = @storage.map{ |k,v| "#{k}=#{v.inspect}" }.join("\n ")
311
+ num_items = @storage.reduce(0) { |s, arr| s + arr.length }
312
+ "<Configuration num_items=#{num_items} stored_keys=#{str}>"
313
+ end
314
+
315
+ private
316
+
317
+ def define_sequence_for_regex(regex, result, fragment: false, &blk)
318
+ @storage[regex] = Definition.new(
319
+ configuration: Configuration.new(
320
+ cancellation: @cancellation,
321
+ keymap: @keymap,
322
+ editor: @editor
323
+ ),
324
+ fragment: fragment,
325
+ sequence: regex,
326
+ result: result,
327
+ &blk
328
+ )
329
+ end
330
+
331
+ def recursively_define_sequence_for_bytes(configuration, bytes, result, fragment: false, &blk)
332
+ byte, rest = bytes[0], bytes[1..-1]
333
+ if rest.any?
334
+ definition = if configuration[byte]
335
+ configuration[byte]
336
+ else
337
+ Definition.new(
338
+ configuration: Configuration.new(
339
+ cancellation: @cancellation,
340
+ keymap: @keymap,
341
+ editor: @editor
342
+ ),
343
+ fragment: fragment,
344
+ sequence: byte,
345
+ result: nil
346
+ )
347
+ end
348
+ blk.call(definition.configuration) if blk
349
+ configuration[byte] = definition
350
+ recursively_define_sequence_for_bytes(
351
+ definition.configuration,
352
+ rest,
353
+ result,
354
+ fragment: fragment,
355
+ &blk
356
+ )
357
+ else
358
+ definition = Definition.new(
359
+ configuration: Configuration.new(
360
+ keymap: @keymap,
361
+ editor: @editor
362
+ ),
363
+ fragment: fragment,
364
+ sequence: byte,
365
+ result: result
366
+ )
367
+ configuration[byte] = definition
368
+ blk.call(definition.configuration) if blk
369
+ definition
370
+ end
371
+ end
372
+ end
373
+
374
+ class Definition
375
+ attr_reader :configuration, :result, :sequence
376
+
377
+ def initialize(configuration: nil, fragment: false, sequence:, result: nil)
378
+ @fragment = fragment
379
+ @configuration = configuration
380
+ @sequence = sequence
381
+ @result = result
382
+ end
383
+
384
+ def inspect
385
+ "<Definition fragment=#{@fragment.inspect} sequence=#{@sequence.inspect} result=#{@result.inspect} configuration=#{@configuration.inspect}>"
386
+ end
387
+
388
+ def fragment?
389
+ @fragment
390
+ end
391
+
392
+ def matches?(byte)
393
+ if @sequence.is_a?(Regexp)
394
+ @match_data = @sequence.match(byte.chr)
395
+ else
396
+ @sequence == byte
397
+ end
398
+ end
399
+
400
+ def process
401
+ if @result
402
+ if @match_data
403
+ if @match_data.captures.empty?
404
+ @result.call(@match_data[0])
405
+ else
406
+ @result.call(*@match_data.captures)
407
+ end
408
+ else
409
+ @result.call
410
+ end
411
+ end
412
+ end
413
+ end
414
+ end
415
+ end
@@ -0,0 +1,38 @@
1
+ module YapShellAddonKeyboardMacros
2
+ class Cycle
3
+ def initialize(cycle_proc:, on_cycle_proc: nil)
4
+ @cycle_proc = cycle_proc
5
+ @on_cycle_proc = on_cycle_proc
6
+ @previous_result = nil
7
+ reset
8
+ end
9
+
10
+ def next
11
+ @index = -1 if @index >= cycle_values.length - 1
12
+ on_cycle cycle_values[@index += 1]
13
+ end
14
+
15
+ def previous
16
+ @index = cycle_values.length if @index < 0
17
+ on_cycle cycle_values[@index -= 1]
18
+ end
19
+
20
+ def reset
21
+ @index = -1
22
+ @previous_result = nil
23
+ @cycle_values = nil
24
+ end
25
+
26
+ private
27
+
28
+ def cycle_values
29
+ @cycle_values ||= @cycle_proc.call
30
+ end
31
+
32
+ def on_cycle(new_value)
33
+ @on_cycle_proc.call(@previous_result, new_value) if @on_cycle_proc
34
+ @previous_result = new_value
35
+ new_value
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ module YapShellAddonKeyboardMacros
2
+ module PrettyPrintKey
3
+ # ppk means "pretty print key". For example, it returns \C-g if the given
4
+ # byte is 7.
5
+ def ppk(byte)
6
+ if byte && byte.ord <= 26
7
+ '\C-' + ('a'..'z').to_a[byte.ord - 1]
8
+ else
9
+ byte.inspect
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module YapShellAddonKeyboardMacros
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/lib/yap-shell-addon-keyboard-macros/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'yap-shell-addon-keyboard-macros'
5
+ spec.version = YapShellAddonKeyboardMacros::VERSION
6
+ spec.authors = ['Zach Dennis']
7
+ spec.email = 'zach.dennis@gmail.com'
8
+ spec.date = Date.today.to_s
9
+
10
+ spec.summary = 'Keyboard macro library for yap-shell'
11
+ spec.description = 'An amazing keyboard macro library for yap-shell'
12
+ spec.homepage = 'http://github.com/zdennis/yap-shell-keyboard-macros-addon'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(/^(test|spec|features)\//) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(/^exe\//) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "yap-shell", "~> 0.6"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.12"
23
+ spec.add_development_dependency "rake", "~> 11.2"
24
+ spec.add_development_dependency "rspec", "~> 3.4"
25
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yap-shell-addon-keyboard-macros
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Zach Dennis
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: yap-shell
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '11.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '11.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.4'
69
+ description: An amazing keyboard macro library for yap-shell
70
+ email: zach.dennis@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - ".ruby-version"
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/yap-shell-addon-keyboard-macros.rb
83
+ - lib/yap-shell-addon-keyboard-macros/cycle.rb
84
+ - lib/yap-shell-addon-keyboard-macros/pretty_print_key.rb
85
+ - lib/yap-shell-addon-keyboard-macros/version.rb
86
+ - yap-shell-addon-keyboard-macros.gemspec
87
+ homepage: http://github.com/zdennis/yap-shell-keyboard-macros-addon
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.5.1
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Keyboard macro library for yap-shell
111
+ test_files: []
112
+ has_rdoc: