yap-shell-addon-tab-completion 0.1.0

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 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: