tty 0.2.1 → 0.3.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +45 -115
  4. data/lib/tty.rb +3 -31
  5. data/lib/tty/plugins/plugin.rb +2 -2
  6. data/lib/tty/terminal.rb +2 -58
  7. data/lib/tty/terminal/home.rb +27 -9
  8. data/lib/tty/version.rb +1 -1
  9. data/spec/tty/plugins/plugin/load_spec.rb +10 -18
  10. data/spec/tty/system/editor/open_spec.rb +1 -1
  11. data/spec/tty/terminal/home_spec.rb +18 -26
  12. data/spec/tty/tty_spec.rb +1 -1
  13. data/spec/tty/vector/new_spec.rb +1 -1
  14. metadata +2 -83
  15. data/lib/tty/shell.rb +0 -211
  16. data/lib/tty/shell/distance.rb +0 -49
  17. data/lib/tty/shell/question.rb +0 -335
  18. data/lib/tty/shell/question/modifier.rb +0 -93
  19. data/lib/tty/shell/question/validation.rb +0 -92
  20. data/lib/tty/shell/reader.rb +0 -110
  21. data/lib/tty/shell/response.rb +0 -249
  22. data/lib/tty/shell/response_delegation.rb +0 -55
  23. data/lib/tty/shell/statement.rb +0 -60
  24. data/lib/tty/shell/suggestion.rb +0 -126
  25. data/lib/tty/support/utils.rb +0 -16
  26. data/lib/tty/terminal/echo.rb +0 -38
  27. data/lib/tty/terminal/raw.rb +0 -38
  28. data/spec/tty/shell/ask_spec.rb +0 -77
  29. data/spec/tty/shell/distance/distance_spec.rb +0 -75
  30. data/spec/tty/shell/distance/initialize_spec.rb +0 -14
  31. data/spec/tty/shell/error_spec.rb +0 -30
  32. data/spec/tty/shell/print_table_spec.rb +0 -24
  33. data/spec/tty/shell/question/argument_spec.rb +0 -30
  34. data/spec/tty/shell/question/character_spec.rb +0 -24
  35. data/spec/tty/shell/question/default_spec.rb +0 -25
  36. data/spec/tty/shell/question/in_spec.rb +0 -23
  37. data/spec/tty/shell/question/initialize_spec.rb +0 -24
  38. data/spec/tty/shell/question/modifier/apply_to_spec.rb +0 -34
  39. data/spec/tty/shell/question/modifier/letter_case_spec.rb +0 -27
  40. data/spec/tty/shell/question/modifier/whitespace_spec.rb +0 -33
  41. data/spec/tty/shell/question/modify_spec.rb +0 -44
  42. data/spec/tty/shell/question/valid_spec.rb +0 -46
  43. data/spec/tty/shell/question/validate_spec.rb +0 -30
  44. data/spec/tty/shell/question/validation/coerce_spec.rb +0 -24
  45. data/spec/tty/shell/question/validation/valid_value_spec.rb +0 -28
  46. data/spec/tty/shell/reader/getc_spec.rb +0 -42
  47. data/spec/tty/shell/response/read_bool_spec.rb +0 -40
  48. data/spec/tty/shell/response/read_char_spec.rb +0 -16
  49. data/spec/tty/shell/response/read_date_spec.rb +0 -20
  50. data/spec/tty/shell/response/read_email_spec.rb +0 -42
  51. data/spec/tty/shell/response/read_multiple_spec.rb +0 -23
  52. data/spec/tty/shell/response/read_number_spec.rb +0 -28
  53. data/spec/tty/shell/response/read_range_spec.rb +0 -31
  54. data/spec/tty/shell/response/read_spec.rb +0 -68
  55. data/spec/tty/shell/response/read_string_spec.rb +0 -19
  56. data/spec/tty/shell/say_spec.rb +0 -67
  57. data/spec/tty/shell/statement/initialize_spec.rb +0 -15
  58. data/spec/tty/shell/suggest_spec.rb +0 -50
  59. data/spec/tty/shell/warn_spec.rb +0 -30
  60. data/spec/tty/terminal/color_spec.rb +0 -16
  61. data/spec/tty/terminal/echo_spec.rb +0 -21
@@ -1,92 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- class Shell
5
- class Question
6
- # A class representing question validation.
7
- class Validation
8
- # @api private
9
- attr_reader :validation
10
- private :validation
11
-
12
- # Initialize a Validation
13
- #
14
- # @param [Object] validation
15
- #
16
- # @return [undefined]
17
- #
18
- # @api private
19
- def initialize(validation = nil)
20
- @validation = validation ? coerce(validation) : validation
21
- end
22
-
23
- # Convert validation into known type.
24
- #
25
- # @param [Object] validation
26
- #
27
- # @raise [TTY::ValidationCoercion] failed to convert validation
28
- #
29
- # @api private
30
- def coerce(validation)
31
- case validation
32
- when Proc
33
- validation
34
- when Regexp, String
35
- Regexp.new(validation.to_s)
36
- else
37
- fail TTY::ValidationCoercion, "Wrong type, got #{validation.class}"
38
- end
39
- end
40
-
41
- # Check if validation is required
42
- #
43
- # @return [Boolean]
44
- #
45
- # @api public
46
- def validate?
47
- !!validation
48
- end
49
-
50
- # Test if the value matches the validation
51
- #
52
- # @example
53
- # validation.valid_value?(value) # => true or false
54
- #
55
- # @param [Object] value
56
- # the value to validate
57
- #
58
- # @return [undefined]
59
- #
60
- # @api public
61
- def valid_value?(value)
62
- check_validation(value)
63
- end
64
-
65
- private
66
-
67
- # Check if provided value passes validation
68
- #
69
- # @param [String] value
70
- #
71
- # @raise [TTY::InvalidArgument] unkown type of argument
72
- #
73
- # @return [undefined]
74
- #
75
- # @api private
76
- def check_validation(value)
77
- if validate? && value
78
- value = value.to_s
79
- if validation.is_a?(Regexp) && validation =~ value
80
- elsif validation.is_a?(Proc) && validation.call(value)
81
- else
82
- fail TTY::InvalidArgument, "Invalid input for #{value}"
83
- end
84
- true
85
- else
86
- false
87
- end
88
- end
89
- end # Validation
90
- end # Question
91
- end # Shell
92
- end # TTY
@@ -1,110 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- # A class responsible for shell prompt interactions.
5
- class Shell
6
- # A class responsible for reading character input from STDIN
7
- class Reader
8
- # @api private
9
- attr_reader :shell
10
- private :shell
11
-
12
- # Key input constants for decimal codes
13
- CARRIAGE_RETURN = 13.freeze
14
- NEWLINE = 10.freeze
15
- BACKSPACE = 127.freeze
16
- DELETE = 8.freeze
17
-
18
- # Initialize a Reader
19
- #
20
- # @api public
21
- def initialize(shell = Shell.new)
22
- @shell = shell
23
- end
24
-
25
- # Get input in unbuffered mode.
26
- #
27
- # @example
28
- # buffer do
29
- # ...
30
- # end
31
- #
32
- # @return [String]
33
- #
34
- # @api public
35
- def buffer(&block)
36
- bufferring = shell.output.sync
37
- # Immediately flush output
38
- shell.output.sync = true
39
-
40
- value = block.call if block_given?
41
-
42
- shell.output.sync = bufferring
43
- value
44
- end
45
-
46
- # Get a value from STDIN one key at a time. Each key press is echoed back
47
- # to the shell masked with character(if given). The input finishes when
48
- # enter key is pressed.
49
- #
50
- # @param [String] mask
51
- # the character to use as mask
52
- #
53
- # @return [String]
54
- #
55
- # @api public
56
- def getc(mask = (not_set = true))
57
- value = ''
58
- buffer do
59
- begin
60
- while (char = shell.input.getbyte) &&
61
- !(char == CARRIAGE_RETURN || char == NEWLINE)
62
- value = handle_char value, char, not_set, mask
63
- end
64
- ensure
65
- TTY.terminal.echo_on
66
- end
67
- end
68
- value
69
- end
70
-
71
- # Get a value from STDIN using line input.
72
- #
73
- # @api public
74
- def gets
75
- shell.input.gets
76
- end
77
-
78
- # Reads at maximum +maxlen+ characters.
79
- #
80
- # @param [Integer] maxlen
81
- #
82
- # @api public
83
- def readpartial(maxlen)
84
- shell.input.readpartial(maxlen)
85
- end
86
-
87
- private
88
-
89
- # Handle single character by appending to or removing from output
90
- #
91
- # @api private
92
- def handle_char(value, char, not_set, mask)
93
- if char == BACKSPACE || char == DELETE
94
- value.slice!(-1, 1) unless value.empty?
95
- else
96
- print_char char, not_set, mask
97
- value << char
98
- end
99
- value
100
- end
101
-
102
- # Print out character back to shell STDOUT
103
- #
104
- # @api private
105
- def print_char(char, not_set, mask)
106
- shell.output.putc((not_set || !mask) ? char : mask)
107
- end
108
- end # Reader
109
- end # Shell
110
- end # TTY
@@ -1,249 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'date'
4
-
5
- module TTY
6
- # A class responsible for shell prompt interactions
7
- class Shell
8
- # A class representing a shell response
9
- class Response
10
- VALID_TYPES = [
11
- :boolean,
12
- :string,
13
- :symbol,
14
- :integer,
15
- :float,
16
- :date,
17
- :datetime
18
- ]
19
-
20
- attr_reader :reader
21
- private :reader
22
-
23
- attr_reader :shell
24
- private :shell
25
-
26
- attr_reader :question
27
- private :question
28
-
29
- # Initialize a Response
30
- #
31
- # @api public
32
- def initialize(question, shell = Shell.new)
33
- @question = question
34
- @shell = shell
35
- @converter = Necromancer.new
36
- @reader = Reader.new(shell)
37
- end
38
-
39
- # Read input from STDIN either character or line
40
- #
41
- # @param [Symbol] type
42
- #
43
- # @return [undefined]
44
- #
45
- # @api public
46
- def read(type = nil)
47
- question.evaluate_response read_input
48
- end
49
-
50
- # @api private
51
- def read_input
52
- reader = Reader.new(shell)
53
-
54
- if question.mask? && question.echo?
55
- reader.getc(question.mask)
56
- else
57
- TTY.terminal.echo(question.echo) do
58
- TTY.terminal.raw(question.raw) do
59
- if question.raw?
60
- reader.readpartial(10)
61
- elsif question.character?
62
- reader.getc(question.mask)
63
- else
64
- reader.gets
65
- end
66
- end
67
- end
68
- end
69
- end
70
-
71
- # Read answer and cast to String type
72
- #
73
- # @param [String] error
74
- # error to display on failed conversion to string type
75
- #
76
- # @api public
77
- def read_string(error = nil)
78
- question.evaluate_response(String(read_input).strip)
79
- end
80
-
81
- # Read answer's first character
82
- #
83
- # @api public
84
- def read_char
85
- question.char(true)
86
- question.evaluate_response String(read_input).chars.to_a[0]
87
- end
88
-
89
- # Read multiple line answer and cast to String type
90
- #
91
- # @api public
92
- def read_text
93
- question.evaluate_response String(read_input)
94
- end
95
-
96
- # Read ansewr and cast to Symbol type
97
- #
98
- # @api public
99
- def read_symbol(error = nil)
100
- question.evaluate_response(read_input.to_sym)
101
- end
102
-
103
- # Read answer from predifined choicse
104
- #
105
- # @api public
106
- def read_choice(type = nil)
107
- question.argument(:required) unless question.default?
108
- question.evaluate_response read_input
109
- end
110
-
111
- # Read integer value
112
- #
113
- # @api public
114
- def read_int(error = nil)
115
- response = @converter.convert(read_input).to(:integer)
116
- question.evaluate_response(response)
117
- end
118
-
119
- # Read float value
120
- #
121
- # @api public
122
- def read_float(error = nil)
123
- response = @converter.convert(read_input).to(:float)
124
- question.evaluate_response(response)
125
- end
126
-
127
- # Read regular expression
128
- #
129
- # @api public
130
- def read_regex(error = nil)
131
- question.evaluate_response Kernel.send(:Regex, read_input)
132
- end
133
-
134
- # Read range expression
135
- #
136
- # @api public
137
- def read_range
138
- response = @converter.convert(read_input).to(:range, strict: true)
139
- question.evaluate_response(response)
140
- end
141
-
142
- # Read date
143
- #
144
- # @api public
145
- def read_date
146
- response = @converter.convert(read_input).to(:date)
147
- question.evaluate_response(response)
148
- end
149
-
150
- # Read datetime
151
- #
152
- # @api public
153
- def read_datetime
154
- response = @converter.convert(read_input).to(:datetime)
155
- question.evaluate_response(response)
156
- end
157
-
158
- # Read boolean
159
- #
160
- # @api public
161
- def read_bool(error = nil)
162
- response = @converter.convert(read_input).to(:boolean, strict: true)
163
- question.evaluate_response(response)
164
- end
165
-
166
- # Read file contents
167
- #
168
- # @api public
169
- def read_file(error = nil)
170
- question.evaluate_response File.open(File.join(directory, read_input))
171
- end
172
-
173
- # Read string answer and validate against email regex
174
- #
175
- # @return [String]
176
- #
177
- # @api public
178
- def read_email
179
- question.validate(/^[a-z0-9._%+-]+@([a-z0-9-]+\.)+[a-z]{2,6}$/i)
180
- question.prompt(question.statement) if question.error
181
- with_exception { read_string }
182
- end
183
-
184
- # Read answer provided on multiple lines
185
- #
186
- # @api public
187
- def read_multiple
188
- response = ''
189
- loop do
190
- value = question.evaluate_response read_input
191
- break if !value || value == ''
192
- next if value !~ /\S/
193
- response << value
194
- end
195
- response
196
- end
197
-
198
- # Read password
199
- #
200
- # @api public
201
- def read_password
202
- question.echo false
203
- question.evaluate_response read_input
204
- end
205
-
206
- # Read a single keypress
207
- #
208
- # @api public
209
- def read_keypress
210
- question.echo false
211
- question.raw true
212
- question.evaluate_response(read_input).tap do |key|
213
- raise Interrupt if key == "\x03" # Ctrl-C
214
- end
215
- end
216
-
217
- private
218
-
219
- # Ignore exception
220
- #
221
- # @api private
222
- def with_exception(&block)
223
- yield
224
- rescue
225
- question.error? ? block.call : raise
226
- end
227
-
228
- # @param [Symbol] type
229
- # :boolean, :string, :numeric, :array
230
- #
231
- # @api private
232
- def read_type(class_or_name)
233
- raise TypeError, "Type #{type} is not valid" if type && !valid_type?(type)
234
- case type
235
- when :string, ::String
236
- read_string
237
- when :symbol, ::Symbol
238
- read_symbol
239
- when :float, ::Float
240
- read_float
241
- end
242
- end
243
-
244
- def valid_type?(type)
245
- self.class::VALID_TYPES.include? type.to_sym
246
- end
247
- end # Response
248
- end # Shell
249
- end # TTY