yap-shell-addon-tab-completion 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 17f0d28a12033e862e37d1fb8cde3087567f02a8
4
+ data.tar.gz: 931b2fecaad8de83abeb99f497f0d5eca0859a8e
5
+ SHA512:
6
+ metadata.gz: 88a04ac6f611fd87a381ca5bcd8bea6f6a068257d524297826db1d40af302ab95bb19a64d05cc7092b19ae30265722b579f75c47c9249cda51a846f0655a6766
7
+ data.tar.gz: df594f455eb5d59e4b27802edbea32ab0fdaeb10e4f2d5135a0a602a303fdc33113843f5165ac959efaa7dc1bb251673497ab69f8da789de670e10713b0b1ac2
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ wiki/
data/.ruby-version ADDED
@@ -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-tab-completion.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -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.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # tab-completion 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-tab-completion`.
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-tab-completion'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install yap-shell-addon-tab-completion
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-tab-completion.
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).
data/Rakefile ADDED
@@ -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,178 @@
1
+ require 'yap/addon'
2
+ require 'yap-shell-addon-tab-completion/basic_completion'
3
+ require 'yap-shell-addon-tab-completion/completer'
4
+ require 'yap-shell-addon-tab-completion/completion_result'
5
+ require 'yap-shell-addon-tab-completion/custom_completion'
6
+ require 'yap-shell-addon-tab-completion/dsl_methods'
7
+ require 'yap-shell-addon-tab-completion/version'
8
+
9
+ module YapShellAddonTabCompletion
10
+ class Addon < ::Yap::Addon::Base
11
+ self.export_as :'tab-completion'
12
+
13
+ class CompletionResult
14
+ attr_accessor :text, :type, :descriptive_text
15
+
16
+ def initialize(text:, type:, descriptive_text: nil)
17
+ @descriptive_text = descriptive_text || text
18
+ @text = text
19
+ @type = type
20
+ end
21
+
22
+ def ==(other)
23
+ other.is_a?(self.class) && @text == other.text && @type == other.type
24
+ end
25
+
26
+ def <=>(other)
27
+ @text <=> other.text
28
+ end
29
+
30
+ def to_s
31
+ @text.to_s
32
+ end
33
+ alias_method :to_str, :to_s
34
+ alias_method :inspect, :to_s
35
+ end
36
+
37
+ COMPLETIONS = [ BasicCompletion ]
38
+
39
+ Color = Term::ANSIColor
40
+
41
+ DISPLAY_PROCS = Hash.new{ |h,k| h[k] = ->(text){ text } }.merge(
42
+ directory: -> (text){ text + "/" }
43
+ )
44
+
45
+ STYLE_PROCS = Hash.new{ |h,k| h[k] = ->(text){ text } }.merge(
46
+ alias: -> (text){ Color.bold(Color.color("#ff00d7"){ text } ) },
47
+ builtin: -> (text){ Color.bold(Color.color("#d7af00"){ text } ) },
48
+ directory: -> (text){ Color.bold(Color.red(text)) },
49
+ command: -> (text){ Color.bold(Color.green(text)) },
50
+ shell_command: -> (text){ Color.bold(Color.color("#ffafff"){ text } ) },
51
+ symlink: -> (text){ Color.bold(Color.cyan(text)) },
52
+ selected: -> (text){ Color.negative(text) }
53
+ )
54
+
55
+ DECORATION_PROCS = Hash.new{ |h,k| h[k] = ->(text){ text } }.merge(
56
+ directory: -> (text){ text + "/" },
57
+ command: -> (text){ text + "@" },
58
+ shell_command: -> (text) { text + "🐚" }
59
+ )
60
+
61
+ attr_reader :editor, :world
62
+
63
+ def initialize_world(world)
64
+ @world = world
65
+ @world.extend YapShellAddonTabCompletion::DslMethods
66
+ @editor = @world.editor
67
+ @editor.completion_proc = -> (word, line, word_index){
68
+ complete(word, line, word_index)
69
+ }
70
+ @editor.bind(:tab){ @editor.complete }
71
+ @completions = COMPLETIONS.dup
72
+
73
+ @style_procs = STYLE_PROCS.dup
74
+ @decoration_procs = DECORATION_PROCS.dup
75
+ @display_procs = DISPLAY_PROCS.dup
76
+
77
+ editor.on_word_complete do |event|
78
+ logger.puts "on_word_complete event: #{event}"
79
+
80
+ sub_word = event[:payload][:sub_word]
81
+ word = event[:payload][:word]
82
+ actual_completion = event[:payload][:completion]
83
+ possible_completions = event[:payload][:possible_completions]
84
+
85
+ semi_formatted_possibilities = possible_completions.map.with_index do |completion, i|
86
+ if completion == actual_completion
87
+ style_text_for_selected_match(completion) + "\e[0m"
88
+ else
89
+ style_text_for_nonselected_match(completion) + "\e[0m"
90
+ end
91
+ end
92
+
93
+ max_width = @editor.terminal_width
94
+ max_item_width = semi_formatted_possibilities.map(&:length).max + 2
95
+ most_per_line = max_width / max_item_width
96
+ padding_at_the_end = max_width % max_item_width
97
+
98
+ formatted_possibilities = semi_formatted_possibilities.map.with_index do |completion, i|
99
+ spaces_to_pad = max_item_width - completion.length
100
+ completion + (" " * spaces_to_pad)
101
+ end
102
+
103
+ editor.content_box.children = formatted_possibilities.map do |str|
104
+ TerminalLayout::Box.new(content: str, style: { display: :float, float: :left, height: 1, width: max_item_width })
105
+ end
106
+ end
107
+
108
+ editor.on_word_complete_no_match do |event|
109
+ logger.puts "on_word_complete_no_match event: #{event}"
110
+
111
+ sub_word = event[:payload][:sub_word]
112
+ word = event[:payload][:word]
113
+ editor.content_box.children = []
114
+ # editor.content_box.content = "Failed to find a match to complete #{sub_word} portion of #{word}"
115
+ end
116
+
117
+ editor.on_word_complete_done do |event|
118
+ logger.puts "on_word_complete_done event: #{event}"
119
+
120
+ # TODO: add a better way to clear content
121
+ editor.content_box.children = []
122
+ end
123
+ end
124
+
125
+ def add_completion(name, pattern, &blk)
126
+ raise ArgumentError, "Must supply block!" unless block_given?
127
+ logger.puts "NO-OP add_completion for name=#{name.inspect} pattern=#{pattern.inspect} block?=#{block_given?}"
128
+ # @completions.push CustomCompletion.new(name:name, pattern:pattern, world:world, &blk)
129
+ end
130
+
131
+ def set_decoration(type, &blk)
132
+ raise ArgumentError, "Must supply block!" unless block_given?
133
+ logger.puts "set_decoration for type=#{name.inspect}"
134
+ @style_procs[type] = blk
135
+ end
136
+
137
+ def complete(word, words, word_index)
138
+ logger.puts "complete word=#{word.inspect} words=#{words.inspect} word_index=#{word_index.inspect}"
139
+
140
+ matches = @completions.sort_by(&:priority).reverse.map do |completion|
141
+ if completion.respond_to?(:call)
142
+ completion.call
143
+ else
144
+ completions = completion.new(
145
+ world: @world,
146
+ word_break_characters: editor.word_break_characters
147
+ ).completions_for(word, words, word_index)
148
+ completions.each do |completion|
149
+ completion.text = display_text_for_match(completion)
150
+ end
151
+ end
152
+ end.flatten
153
+
154
+ logger.puts "complete possible matches are #{matches.inspect}"
155
+ matches
156
+ end
157
+
158
+ private
159
+
160
+ def display_text_for_match(match)
161
+ ANSIString.new @display_procs[match.type].call(match.text.dup)
162
+ end
163
+
164
+ def style_text_for_selected_match(match)
165
+ styled_text = @style_procs[match.type].call(match.descriptive_text.dup).to_s
166
+ styled_text = @decoration_procs[match.type].call(styled_text).to_s
167
+ uncolored_text = Color.uncolored(styled_text)
168
+ ANSIString.new @style_procs[:selected].call(uncolored_text)
169
+ end
170
+
171
+ def style_text_for_nonselected_match(match)
172
+ str = @decoration_procs[match.type].call(
173
+ @style_procs[match.type].call(match.descriptive_text.dup)
174
+ )
175
+ ANSIString.new str
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,151 @@
1
+ module YapShellAddonTabCompletion
2
+ class BasicCompletion
3
+ class << self
4
+ attr_accessor :priority
5
+ end
6
+ self.priority = 1
7
+
8
+ attr_reader :world
9
+
10
+ def initialize(world:, word_break_characters:, path:nil)
11
+ @world = world
12
+ @word_break_characters = word_break_characters
13
+ path ||= @world.env["PATH"]
14
+ @paths = path.split(":")
15
+ end
16
+
17
+ def completions_for(word, words, word_index)
18
+ completions_by_name = {}
19
+ if looking_for_command?(word, words, word_index)
20
+ # Lowest Priority
21
+ completions_by_name.merge! command_completion_matches_for(word, words)
22
+
23
+ # Low Priority
24
+ completions_by_name.merge! builtin_completion_matches_for(word, words)
25
+
26
+ # Medium Priority
27
+ completions_by_name.merge! executable_filename_completion_matches_for(word, words)
28
+
29
+ # High Priority
30
+ completions_by_name.merge! shell_command_completion_matches_for(word, words)
31
+
32
+ # Highest Priority
33
+ completions_by_name.merge! alias_completion_matches_for(word, words)
34
+ else
35
+ completions_by_name.merge! filename_completion_matches_for(word, words)
36
+ end
37
+ completions_by_name.merge! environment_variable_completions_for(word, words)
38
+ completions_by_name.values
39
+ end
40
+
41
+ private
42
+
43
+ def looking_for_command?(word, words, word_index)
44
+ return false unless word_index
45
+ return true if word_index == 0
46
+ return true if words[word_index - 1] =~ /[;&]/
47
+ false
48
+ end
49
+
50
+ def alias_completion_matches_for(word, words)
51
+ @world.aliases.names.each_with_object({}) do |name, result|
52
+ if name =~ /^#{Regexp.escape(word)}/
53
+ result[name] ||= CompletionResult.new(
54
+ type: :alias,
55
+ text: name
56
+ )
57
+ end
58
+ end
59
+ end
60
+
61
+ def builtin_completion_matches_for(word, words)
62
+ @world.builtins.each_with_object({}) do |builtin, result|
63
+ if builtin =~ /^#{Regexp.escape(word)}/
64
+ result[builtin] ||= CompletionResult.new(
65
+ type: :builtin,
66
+ text: builtin
67
+ )
68
+ end
69
+ end
70
+ end
71
+
72
+ def command_completion_matches_for(word, words)
73
+ @paths.each_with_object({}) do |path, matches|
74
+ glob = File.join(path, "#{word}*")
75
+ arr = Dir[glob].select { |path| File.executable?(path) && File.file?(path) }
76
+ arr.map { |path| File.basename(path) }.uniq.each do |command|
77
+ matches[command] = CompletionResult.new(type: :command, text: command)
78
+ end
79
+ end
80
+ end
81
+
82
+ def environment_variable_completions_for(word, words)
83
+ return {} unless word =~ /^\$/
84
+ prefix, word_sans_prefix = word[0], word[1..-1]
85
+ @world.env.keys.each_with_object({}) do |env_var, result|
86
+ if env_var =~ /^#{Regexp.escape(word_sans_prefix)}/
87
+ result[env_var] ||= CompletionResult.new(
88
+ type: :env_var,
89
+ text: prefix + env_var
90
+ )
91
+ end
92
+ end
93
+ end
94
+
95
+ def executable_filename_completion_matches_for(word, words)
96
+ glob = "#{word}*"
97
+ glob.gsub!("~", world.env["HOME"])
98
+ Dir.glob(glob, File::FNM_CASEFOLD).each_with_object({}) do |path, result|
99
+ text = path.gsub(filtered_work_break_characters_rgx, '\\\\\1')
100
+ descriptive_text = File.basename(text)
101
+ if !File.directory?(path) && File.executable?(path)
102
+ result[path] = CompletionResult.new(
103
+ type: :command,
104
+ text: text,
105
+ descriptive_text: descriptive_text
106
+ )
107
+ end
108
+ end
109
+ end
110
+
111
+ def shell_command_completion_matches_for(word, words)
112
+ @world.shell_commands.each_with_object({}) do |shell_command, result|
113
+ if shell_command =~ /^#{Regexp.escape(word)}/
114
+ result[shell_command] ||= CompletionResult.new(
115
+ type: :shell_command,
116
+ text: shell_command
117
+ )
118
+ end
119
+ end
120
+ end
121
+
122
+ def filename_completion_matches_for(word, line)
123
+ glob = "#{word}*"
124
+ glob.gsub!("~", world.env["HOME"])
125
+ Dir.glob(glob, File::FNM_CASEFOLD).each_with_object({}) do |path, result|
126
+ text = path.gsub(filtered_work_break_characters_rgx, '\\\\\1')
127
+ descriptive_text = File.basename(text)
128
+ result[path] = if File.directory?(path)
129
+ CompletionResult.new(type: :directory, text: text, descriptive_text: descriptive_text)
130
+ elsif File.symlink?(path)
131
+ CompletionResult.new(type: :symlink, text: text, descriptive_text: descriptive_text)
132
+ elsif File.file?(path) && File.executable?(path)
133
+ CompletionResult.new(type: :command, text: text, descriptive_text: descriptive_text)
134
+ else
135
+ CompletionResult.new(type: :file, text: text, descriptive_text: descriptive_text)
136
+ end
137
+ end
138
+ end
139
+
140
+ # Remove file separator and the back-slash from word break characters when determining
141
+ # the pre-word-context
142
+ def filtered_word_break_characters
143
+ @word_break_characters.sub(File::Separator, "").sub('\\', '')
144
+ end
145
+
146
+ def filtered_work_break_characters_rgx
147
+ /([#{Regexp.escape(filtered_word_break_characters)}])/
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,61 @@
1
+ module YapShellAddonTabCompletion
2
+ class Completer
3
+ def initialize(char:, line:, completion:, completion_found:, completion_not_found:, done:)
4
+ @completion_char = char
5
+ @line = line
6
+ @completion_proc = completion
7
+ @completion_found_proc = completion_found
8
+ @completion_not_found_proc = completion_not_found
9
+ @done_proc = done
10
+
11
+ @completion_matches = HistoryBuffer.new(0) do |h|
12
+ h.duplicates = false
13
+ h.cycle = true
14
+ end
15
+ @completion_matches.empty
16
+
17
+ @first_time = true
18
+ @word_start = @line.word[:start]
19
+ end
20
+
21
+ def read_bytes(bytes)
22
+ return unless bytes.any?
23
+
24
+ if bytes.map(&:ord) != @completion_char
25
+ @done_proc.call(bytes)
26
+ elsif @first_time
27
+ matches = @completion_proc.call(sub_word) unless !@completion_proc || @completion_proc == []
28
+ matches = matches.to_a.compact.sort.reverse
29
+
30
+ if matches.any?
31
+ @completion_matches.resize(matches.length)
32
+ matches.each { |w| @completion_matches << w }
33
+
34
+ # Get first match
35
+ @completion_matches.back
36
+ match = @completion_matches.get
37
+
38
+ # completion matches is a history implementation and its in reverse order from what
39
+ # a user would expect
40
+ @completion_found_proc.call(completion: match, possible_completions: @completion_matches.reverse)
41
+ else
42
+ @completion_not_found_proc.call
43
+ @done_proc.call
44
+ end
45
+ @first_time = false
46
+ else
47
+ @completion_matches.back
48
+ match = @completion_matches.get
49
+
50
+ @completion_found_proc.call(completion: match, possible_completions: @completion_matches.reverse)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def sub_word
57
+ @line.text[@line.word[:start]..@line.position-1] || ""
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,25 @@
1
+ module YapShellAddonTabCompletion
2
+ class CompletionResult
3
+ attr_accessor :text, :type, :descriptive_text
4
+
5
+ def initialize(text:, type:, descriptive_text: nil)
6
+ @descriptive_text = descriptive_text || text
7
+ @text = text
8
+ @type = type
9
+ end
10
+
11
+ def ==(other)
12
+ other.is_a?(self.class) && @text == other.text && @type == other.type
13
+ end
14
+
15
+ def <=>(other)
16
+ @text <=> other.text
17
+ end
18
+
19
+ def to_s
20
+ @text.to_s
21
+ end
22
+ alias_method :to_str, :to_s
23
+ alias_method :inspect, :to_s
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ module YapShellAddonTabCompletion
2
+ class CustomCompletion
3
+ PRIORITY = 2
4
+
5
+ attr_reader :name, :pattern, :priority
6
+
7
+ def initialize(world:, name:nil, pattern:nil, priority:PRIORITY, &blk)
8
+ @world = world
9
+ @name = name
10
+ @pattern = pattern
11
+ @priority = priority
12
+ @blk = blk
13
+ end
14
+
15
+ def new(world:)
16
+ @world = world
17
+ self
18
+ end
19
+
20
+ def completions_for(word, line)
21
+ # TODO
22
+ return []
23
+ end
24
+
25
+ private
26
+
27
+ def match_rgx
28
+ return // if pattern.nil?
29
+ return pattern if pattern.is_a?(Regexp)
30
+ /^#{Regexp.escape(pattern.to_s)}\s/
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ module YapShellAddonTabCompletion
2
+ module DslMethods
3
+ def tab_completion(name, pattern, &blk)
4
+ self[:tab_completion].add_completion(name, pattern, &blk)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module YapShellAddonTabCompletion
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/lib/yap-shell-addon-tab-completion/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'yap-shell-addon-tab-completion'
5
+ spec.version = YapShellAddonTabCompletion::VERSION
6
+ spec.authors = ['Your name']
7
+ spec.email = 'you@example.com'
8
+ spec.date = Date.today.to_s
9
+
10
+ spec.summary = 'tab-completion summary goes here.'
11
+ spec.description = 'tab-completion description goes here.'
12
+ spec.homepage = ''
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,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yap-shell-addon-tab-completion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Your name
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: tab-completion description goes here.
70
+ email: you@example.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - ".ruby-version"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - lib/yap-shell-addon-tab-completion.rb
82
+ - lib/yap-shell-addon-tab-completion/basic_completion.rb
83
+ - lib/yap-shell-addon-tab-completion/completer.rb
84
+ - lib/yap-shell-addon-tab-completion/completion_result.rb
85
+ - lib/yap-shell-addon-tab-completion/custom_completion.rb
86
+ - lib/yap-shell-addon-tab-completion/dsl_methods.rb
87
+ - lib/yap-shell-addon-tab-completion/version.rb
88
+ - yap-shell-addon-tab-completion.gemspec
89
+ homepage: ''
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.5.1
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: tab-completion summary goes here.
113
+ test_files: []
114
+ has_rdoc: