tty 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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