austb-tty-prompt 0.13.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.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +25 -0
  5. data/CHANGELOG.md +218 -0
  6. data/CODE_OF_CONDUCT.md +49 -0
  7. data/Gemfile +19 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +1132 -0
  10. data/Rakefile +8 -0
  11. data/appveyor.yml +23 -0
  12. data/benchmarks/speed.rb +27 -0
  13. data/examples/ask.rb +15 -0
  14. data/examples/collect.rb +19 -0
  15. data/examples/echo.rb +11 -0
  16. data/examples/enum.rb +8 -0
  17. data/examples/enum_paged.rb +9 -0
  18. data/examples/enum_select.rb +7 -0
  19. data/examples/expand.rb +29 -0
  20. data/examples/in.rb +9 -0
  21. data/examples/inputs.rb +10 -0
  22. data/examples/key_events.rb +11 -0
  23. data/examples/keypress.rb +9 -0
  24. data/examples/mask.rb +13 -0
  25. data/examples/multi_select.rb +8 -0
  26. data/examples/multi_select_paged.rb +9 -0
  27. data/examples/multiline.rb +9 -0
  28. data/examples/pause.rb +7 -0
  29. data/examples/select.rb +18 -0
  30. data/examples/select_paginated.rb +9 -0
  31. data/examples/slider.rb +6 -0
  32. data/examples/validation.rb +9 -0
  33. data/examples/yes_no.rb +7 -0
  34. data/lib/tty-prompt.rb +4 -0
  35. data/lib/tty/prompt.rb +535 -0
  36. data/lib/tty/prompt/answers_collector.rb +59 -0
  37. data/lib/tty/prompt/choice.rb +90 -0
  38. data/lib/tty/prompt/choices.rb +110 -0
  39. data/lib/tty/prompt/confirm_question.rb +129 -0
  40. data/lib/tty/prompt/converter_dsl.rb +22 -0
  41. data/lib/tty/prompt/converter_registry.rb +64 -0
  42. data/lib/tty/prompt/converters.rb +77 -0
  43. data/lib/tty/prompt/distance.rb +49 -0
  44. data/lib/tty/prompt/enum_list.rb +337 -0
  45. data/lib/tty/prompt/enum_paginator.rb +56 -0
  46. data/lib/tty/prompt/evaluator.rb +29 -0
  47. data/lib/tty/prompt/expander.rb +292 -0
  48. data/lib/tty/prompt/keypress.rb +94 -0
  49. data/lib/tty/prompt/list.rb +317 -0
  50. data/lib/tty/prompt/mask_question.rb +91 -0
  51. data/lib/tty/prompt/multi_list.rb +108 -0
  52. data/lib/tty/prompt/multiline.rb +71 -0
  53. data/lib/tty/prompt/paginator.rb +88 -0
  54. data/lib/tty/prompt/question.rb +333 -0
  55. data/lib/tty/prompt/question/checks.rb +87 -0
  56. data/lib/tty/prompt/question/modifier.rb +94 -0
  57. data/lib/tty/prompt/question/validation.rb +72 -0
  58. data/lib/tty/prompt/reader.rb +352 -0
  59. data/lib/tty/prompt/reader/codes.rb +121 -0
  60. data/lib/tty/prompt/reader/console.rb +57 -0
  61. data/lib/tty/prompt/reader/history.rb +145 -0
  62. data/lib/tty/prompt/reader/key_event.rb +91 -0
  63. data/lib/tty/prompt/reader/line.rb +162 -0
  64. data/lib/tty/prompt/reader/mode.rb +44 -0
  65. data/lib/tty/prompt/reader/win_api.rb +29 -0
  66. data/lib/tty/prompt/reader/win_console.rb +53 -0
  67. data/lib/tty/prompt/result.rb +42 -0
  68. data/lib/tty/prompt/slider.rb +182 -0
  69. data/lib/tty/prompt/statement.rb +55 -0
  70. data/lib/tty/prompt/suggestion.rb +115 -0
  71. data/lib/tty/prompt/symbols.rb +61 -0
  72. data/lib/tty/prompt/timeout.rb +69 -0
  73. data/lib/tty/prompt/utils.rb +44 -0
  74. data/lib/tty/prompt/version.rb +7 -0
  75. data/lib/tty/test_prompt.rb +20 -0
  76. data/tasks/console.rake +11 -0
  77. data/tasks/coverage.rake +11 -0
  78. data/tasks/spec.rake +29 -0
  79. data/tty-prompt.gemspec +32 -0
  80. metadata +243 -0
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ module TTY
4
+ class Prompt
5
+ # Cross platform common Unicode symbols.
6
+ #
7
+ # @api public
8
+ module Symbols
9
+ KEYS = {
10
+ tick: '✓',
11
+ cross: '✘',
12
+ star: '★',
13
+ dot: '•',
14
+ pointer: '‣',
15
+ line: '─',
16
+ pipe: '|',
17
+ handle: 'O',
18
+ ellipsis: '…',
19
+ radio_on: '⬢',
20
+ radio_off: '⬡',
21
+ checkbox_on: '☒',
22
+ checkbox_off: '☐',
23
+ circle_on: 'ⓧ',
24
+ circle_off: 'Ⓘ'
25
+ }.freeze
26
+
27
+ WIN_KEYS = {
28
+ tick: '√',
29
+ cross: '×',
30
+ star: '*',
31
+ dot: '.',
32
+ pointer: '>',
33
+ line: '-',
34
+ pipe: '|',
35
+ handle: 'O',
36
+ ellipsis: '...',
37
+ radio_on: '(*)',
38
+ radio_off: '( )',
39
+ checkbox_on: '[×]',
40
+ checkbox_off: '[ ]',
41
+ circle_on: '(x)',
42
+ circle_off: '( )'
43
+ }.freeze
44
+
45
+ def symbols
46
+ @symbols ||= windows? ? WIN_KEYS : KEYS
47
+ end
48
+ module_function :symbols
49
+
50
+ # Check if Windowz
51
+ #
52
+ # @return [Boolean]
53
+ #
54
+ # @api public
55
+ def windows?
56
+ ::File::ALT_SEPARATOR == "\\"
57
+ end
58
+ module_function :windows?
59
+ end # Symbols
60
+ end # Prompt
61
+ end # TTY
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ require 'timers'
4
+
5
+ module TTY
6
+ class Prompt
7
+ class Timeout
8
+ Error = Class.new(RuntimeError)
9
+
10
+ TIMEOUT_HANDLER = proc { |t| t.raise Error, 'timeout expired' }
11
+
12
+ def initialize(options = {})
13
+ @timeout_handler = options.fetch(:timeout_handler) { TIMEOUT_HANDLER }
14
+ @interval_handler = options.fetch(:interval_handler) { proc {} }
15
+ @lock = Mutex.new
16
+ @running = true
17
+ @timers = Timers::Group.new
18
+ end
19
+
20
+ def self.timeout(time, interval, &block)
21
+ (@scheduler ||= new).timeout(time, interval, &block)
22
+ end
23
+
24
+ # Evalute block and time it
25
+ #
26
+ # @param [Float] time
27
+ # the time by which to stop
28
+ # @param [Float] interval
29
+ # the interval time for each tick
30
+ #
31
+ # @api public
32
+ def timeout(time, interval, &block)
33
+ @runner = async_run(time, interval)
34
+ @running = block.()
35
+ @runner.join
36
+ end
37
+
38
+ def async_run(time, interval)
39
+ Thread.new do
40
+ Thread.current.abort_on_exception = true
41
+ start = Time.now
42
+
43
+ interval_timer = @timers.every(interval) do
44
+ runtime = Time.now - start
45
+ delta = time - runtime
46
+ if delta.round >= 0
47
+ @interval_handler.(delta.round)
48
+ end
49
+ end
50
+
51
+ while @running
52
+ @lock.synchronize {
53
+ @timers.wait
54
+ runtime = Time.now - start
55
+ delta = time - runtime
56
+
57
+ if delta <= 0.0
58
+ @timeout_handler.(Thread.current)
59
+ break
60
+ end
61
+ }
62
+ end
63
+
64
+ interval_timer.cancel
65
+ end
66
+ end
67
+ end # Scheduler
68
+ end # Prompt
69
+ end # TTY
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ module TTY
4
+ module Utils
5
+ module_function
6
+
7
+ BLANK_REGEX = /\A[[:space:]]*\z/o.freeze
8
+
9
+ # Extract options hash from array argument
10
+ #
11
+ # @param [Array[Object]] args
12
+ #
13
+ # @api public
14
+ def extract_options(args)
15
+ options = args.last
16
+ options.respond_to?(:to_hash) ? options.to_hash.dup : {}
17
+ end
18
+
19
+ def extract_options!(args)
20
+ args.last.respond_to?(:to_hash) ? args.pop : {}
21
+ end
22
+
23
+ # Check if value is nil or an empty string
24
+ #
25
+ # @param [Object] value
26
+ # the value to check
27
+ #
28
+ # @return [Boolean]
29
+ #
30
+ # @api public
31
+ def blank?(value)
32
+ value.nil? ||
33
+ value.respond_to?(:empty?) && value.empty? ||
34
+ BLANK_REGEX === value
35
+ end
36
+
37
+ # Deep copy object
38
+ #
39
+ # @api public
40
+ def deep_copy(object)
41
+ Marshal.load(Marshal.dump(object))
42
+ end
43
+ end # Utils
44
+ end # TTY
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module TTY
4
+ class Prompt
5
+ VERSION = "0.13.0"
6
+ end # Prompt
7
+ end # TTY
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'prompt'
4
+
5
+ module TTY
6
+ # Used for initializing test cases
7
+ class TestPrompt < Prompt
8
+ def initialize(options = {})
9
+ @input = StringIO.new
10
+ @output = StringIO.new
11
+ options.merge!({
12
+ input: @input,
13
+ output: @output,
14
+ env: { "TTY_TEST" => true },
15
+ enable_color: options.fetch(:enable_color) { true }
16
+ })
17
+ super(options)
18
+ end
19
+ end # TestPrompt
20
+ end # TTY
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Load gem inside irb console'
4
+ task :console do
5
+ require 'irb'
6
+ require 'irb/completion'
7
+ require File.join(__FILE__, '../../lib/tty-prompt')
8
+ ARGV.clear
9
+ IRB.start
10
+ end
11
+ task c: %w[ console ]
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Measure code coverage'
4
+ task :coverage do
5
+ begin
6
+ original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
7
+ Rake::Task['spec'].invoke
8
+ ensure
9
+ ENV['COVERAGE'] = original
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run all specs'
7
+ RSpec::Core::RakeTask.new(:spec) do |task|
8
+ task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
9
+ end
10
+
11
+ namespace :spec do
12
+ desc 'Run unit specs'
13
+ RSpec::Core::RakeTask.new(:unit) do |task|
14
+ task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
15
+ end
16
+
17
+ desc 'Run integration specs'
18
+ RSpec::Core::RakeTask.new(:integration) do |task|
19
+ task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
20
+ end
21
+ end
22
+
23
+ rescue LoadError
24
+ %w[spec spec:unit spec:integration].each do |name|
25
+ task name do
26
+ $stderr.puts "In order to run #{name}, do `gem install rspec`"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tty/prompt/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "austb-tty-prompt"
8
+ spec.version = TTY::Prompt::VERSION
9
+ spec.authors = ["Piotr Murach", "Austin Blatt"]
10
+ spec.email = ["austinblatt@gmail.com"]
11
+ spec.summary = %q{A beautiful and powerful interactive command line prompt.}
12
+ spec.description = %q{A beautiful and powerful interactive command line prompt with a robust API for getting and validating complex inputs.}
13
+ spec.homepage = "https://github.com/austb/tty-prompt"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency 'necromancer', '~> 0.4.0'
24
+ spec.add_dependency 'pastel', '~> 0.7.0'
25
+ spec.add_dependency 'tty-cursor', '~> 0.5.0'
26
+ spec.add_dependency 'wisper', '~> 2.0.0'
27
+ spec.add_dependency 'timers', '~> 4.1.2'
28
+
29
+ spec.add_development_dependency 'bundler', '>= 1.5.0', '< 2.0'
30
+ spec.add_development_dependency 'rake'
31
+ spec.add_development_dependency 'rspec', '~> 3.5.0'
32
+ end
metadata ADDED
@@ -0,0 +1,243 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: austb-tty-prompt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.13.0
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Murach
8
+ - Austin Blatt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-08-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: necromancer
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.4.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.4.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: pastel
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 0.7.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 0.7.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: tty-cursor
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 0.5.0
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 0.5.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: wisper
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 2.0.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 2.0.0
70
+ - !ruby/object:Gem::Dependency
71
+ name: timers
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 4.1.2
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 4.1.2
84
+ - !ruby/object:Gem::Dependency
85
+ name: bundler
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.5.0
91
+ - - "<"
92
+ - !ruby/object:Gem::Version
93
+ version: '2.0'
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 1.5.0
101
+ - - "<"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ - !ruby/object:Gem::Dependency
105
+ name: rake
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ - !ruby/object:Gem::Dependency
119
+ name: rspec
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 3.5.0
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 3.5.0
132
+ description: A beautiful and powerful interactive command line prompt with a robust
133
+ API for getting and validating complex inputs.
134
+ email:
135
+ - austinblatt@gmail.com
136
+ executables: []
137
+ extensions: []
138
+ extra_rdoc_files: []
139
+ files:
140
+ - ".gitignore"
141
+ - ".rspec"
142
+ - ".travis.yml"
143
+ - CHANGELOG.md
144
+ - CODE_OF_CONDUCT.md
145
+ - Gemfile
146
+ - LICENSE.txt
147
+ - README.md
148
+ - Rakefile
149
+ - appveyor.yml
150
+ - benchmarks/speed.rb
151
+ - examples/ask.rb
152
+ - examples/collect.rb
153
+ - examples/echo.rb
154
+ - examples/enum.rb
155
+ - examples/enum_paged.rb
156
+ - examples/enum_select.rb
157
+ - examples/expand.rb
158
+ - examples/in.rb
159
+ - examples/inputs.rb
160
+ - examples/key_events.rb
161
+ - examples/keypress.rb
162
+ - examples/mask.rb
163
+ - examples/multi_select.rb
164
+ - examples/multi_select_paged.rb
165
+ - examples/multiline.rb
166
+ - examples/pause.rb
167
+ - examples/select.rb
168
+ - examples/select_paginated.rb
169
+ - examples/slider.rb
170
+ - examples/validation.rb
171
+ - examples/yes_no.rb
172
+ - lib/tty-prompt.rb
173
+ - lib/tty/prompt.rb
174
+ - lib/tty/prompt/answers_collector.rb
175
+ - lib/tty/prompt/choice.rb
176
+ - lib/tty/prompt/choices.rb
177
+ - lib/tty/prompt/confirm_question.rb
178
+ - lib/tty/prompt/converter_dsl.rb
179
+ - lib/tty/prompt/converter_registry.rb
180
+ - lib/tty/prompt/converters.rb
181
+ - lib/tty/prompt/distance.rb
182
+ - lib/tty/prompt/enum_list.rb
183
+ - lib/tty/prompt/enum_paginator.rb
184
+ - lib/tty/prompt/evaluator.rb
185
+ - lib/tty/prompt/expander.rb
186
+ - lib/tty/prompt/keypress.rb
187
+ - lib/tty/prompt/list.rb
188
+ - lib/tty/prompt/mask_question.rb
189
+ - lib/tty/prompt/multi_list.rb
190
+ - lib/tty/prompt/multiline.rb
191
+ - lib/tty/prompt/paginator.rb
192
+ - lib/tty/prompt/question.rb
193
+ - lib/tty/prompt/question/checks.rb
194
+ - lib/tty/prompt/question/modifier.rb
195
+ - lib/tty/prompt/question/validation.rb
196
+ - lib/tty/prompt/reader.rb
197
+ - lib/tty/prompt/reader/codes.rb
198
+ - lib/tty/prompt/reader/console.rb
199
+ - lib/tty/prompt/reader/history.rb
200
+ - lib/tty/prompt/reader/key_event.rb
201
+ - lib/tty/prompt/reader/line.rb
202
+ - lib/tty/prompt/reader/mode.rb
203
+ - lib/tty/prompt/reader/win_api.rb
204
+ - lib/tty/prompt/reader/win_console.rb
205
+ - lib/tty/prompt/result.rb
206
+ - lib/tty/prompt/slider.rb
207
+ - lib/tty/prompt/statement.rb
208
+ - lib/tty/prompt/suggestion.rb
209
+ - lib/tty/prompt/symbols.rb
210
+ - lib/tty/prompt/timeout.rb
211
+ - lib/tty/prompt/utils.rb
212
+ - lib/tty/prompt/version.rb
213
+ - lib/tty/test_prompt.rb
214
+ - tasks/console.rake
215
+ - tasks/coverage.rake
216
+ - tasks/spec.rake
217
+ - tty-prompt.gemspec
218
+ homepage: https://github.com/austb/tty-prompt
219
+ licenses:
220
+ - MIT
221
+ metadata: {}
222
+ post_install_message:
223
+ rdoc_options: []
224
+ require_paths:
225
+ - lib
226
+ required_ruby_version: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - ">="
229
+ - !ruby/object:Gem::Version
230
+ version: '0'
231
+ required_rubygems_version: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ requirements: []
237
+ rubyforge_project:
238
+ rubygems_version: 2.5.1
239
+ signing_key:
240
+ specification_version: 4
241
+ summary: A beautiful and powerful interactive command line prompt.
242
+ test_files: []
243
+ has_rdoc: