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,49 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- class Shell
5
- # A class responsible for string comparison
6
- class Distance
7
- # Calculate the optimal string alignment distance
8
- #
9
- # @api public
10
- def distance(first, second)
11
- distances = []
12
- rows = first.to_s.length
13
- cols = second.to_s.length
14
-
15
- 0.upto(rows) do |index|
16
- distances << [index] + [0] * cols
17
- end
18
- distances[0] = 0.upto(cols).to_a
19
-
20
- 1.upto(rows) do |first_index|
21
- 1.upto(cols) do |second_index|
22
- first_char = first[first_index - 1]
23
- second_char = second[second_index - 1]
24
- cost = first_char == second_char ? 0 : 1
25
-
26
- distances[first_index][second_index] = [
27
- distances[first_index - 1][second_index], # deletion
28
- distances[first_index][second_index - 1], # insertion
29
- distances[first_index - 1][second_index - 1] # substitution
30
- ].min + cost
31
-
32
- if first_index > 1 && second_index > 1
33
- first_previous_char = first[first_index - 2]
34
- second_previous_char = second[second_index - 2]
35
- if first_char == second_previous_char && second_char == first_previous_char
36
- distances[first_index][second_index] = [
37
- distances[first_index][second_index],
38
- distances[first_index - 2][second_index - 2] + 1 # transposition
39
- ].min
40
- end
41
- end
42
-
43
- end
44
- end
45
- distances[rows][cols]
46
- end
47
- end # Distance
48
- end # Text
49
- end # TTY
@@ -1,335 +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 command line question
9
- class Question
10
- include TTY::Shell::ResponseDelegation
11
-
12
- PREFIX = ' + '
13
- MULTIPLE_PREFIX = ' * '
14
- ERROR_PREFIX = ' ERROR:'
15
-
16
- # Store statement.
17
- #
18
- # @api private
19
- attr_accessor :statement
20
-
21
- # Store default value.
22
- #
23
- # @api private
24
- attr_reader :default_value
25
-
26
- attr_reader :required
27
- private :required
28
-
29
- attr_reader :validation
30
-
31
- # Controls character processing of the answer
32
- #
33
- # @api public
34
- attr_reader :modifier
35
-
36
- # Returns valid answers
37
- #
38
- # @api public
39
- attr_reader :valid_values
40
-
41
- attr_reader :error
42
-
43
- # Returns character mode
44
- #
45
- # @api public
46
- attr_reader :character
47
-
48
- # @api private
49
- attr_reader :shell
50
- private :shell
51
-
52
- # Initialize a Question
53
- #
54
- # @api public
55
- def initialize(shell, options = {})
56
- @shell = shell || Shell.new
57
- @required = options.fetch(:required) { false }
58
- @echo = options.fetch(:echo) { true }
59
- @raw = options.fetch(:raw) { false }
60
- @mask = options.fetch(:mask) { false }
61
- @character = options.fetch(:character) { false }
62
- @in = options.fetch(:in) { false }
63
- @modifier = Modifier.new options.fetch(:modifier) { [] }
64
- @valid_values = options.fetch(:valid) { [] }
65
- @validation = Validation.new options.fetch(:validation) { nil }
66
- @default_value = nil
67
- @error = false
68
- @converter = Necromancer.new
69
- end
70
-
71
- # Set a new prompt
72
- #
73
- # @param [String] message
74
- #
75
- # @return [self]
76
- #
77
- # @api public
78
- def prompt(message)
79
- self.statement = message
80
- shell.say shell.prefix + statement
81
- self
82
- end
83
-
84
- # Set default value.
85
- #
86
- # @api public
87
- def default(value)
88
- return self if value == ''
89
- @default_value = value
90
- self
91
- end
92
-
93
- # Check if default value is set
94
- #
95
- # @return [Boolean]
96
- #
97
- # @api public
98
- def default?
99
- !!@default_value
100
- end
101
-
102
- # Ensure that passed argument is present if required option
103
- #
104
- # @return [Question]
105
- #
106
- # @api public
107
- def argument(value)
108
- case value
109
- when :required
110
- @required = true
111
- when :optional
112
- @required = false
113
- end
114
- self
115
- end
116
-
117
- # Check if required argument present.
118
- #
119
- # @return [Boolean]
120
- #
121
- # @api private
122
- def required?
123
- required
124
- end
125
-
126
- # Set validation rule for an argument
127
- #
128
- # @param [Object] value
129
- #
130
- # @return [Question]
131
- #
132
- # @api public
133
- def validate(value = nil, &block)
134
- @validation = Validation.new(value || block)
135
- self
136
- end
137
-
138
- # Set expected values
139
- #
140
- # @param [Array] values
141
- #
142
- # @return [self]
143
- #
144
- # @api public
145
- def valid(values)
146
- @valid_values = values
147
- self
148
- end
149
-
150
- # Reset question object.
151
- #
152
- # @api public
153
- def clean
154
- @statement = nil
155
- @default_value = nil
156
- @required = false
157
- @modifier = nil
158
- end
159
-
160
- # Modify string according to the rule given.
161
- #
162
- # @param [Symbol] rule
163
- #
164
- # @api public
165
- def modify(*rules)
166
- @modifier = Modifier.new(*rules)
167
- self
168
- end
169
-
170
- # Setup behaviour when error(s) occur
171
- #
172
- # @api public
173
- def on_error(action = nil)
174
- @error = action
175
- self
176
- end
177
-
178
- # Check if error behaviour is set
179
- #
180
- # @api public
181
- def error?
182
- !!@error
183
- end
184
-
185
- # Turn terminal echo on or off. This is used to secure the display so
186
- # that the entered characters are not echoed back to the screen.
187
- #
188
- # @api public
189
- def echo(value = nil)
190
- return @echo if value.nil?
191
- @echo = value
192
- self
193
- end
194
-
195
- # Chec if echo is set
196
- #
197
- # @api public
198
- def echo?
199
- !!@echo
200
- end
201
-
202
- # Turn raw mode on or off. This enables character-based input.
203
- #
204
- # @api public
205
- def raw(value = nil)
206
- return @raw if value.nil?
207
- @raw = value
208
- self
209
- end
210
-
211
- # Check if raw mode is set
212
- #
213
- # @api public
214
- def raw?
215
- !!@raw
216
- end
217
-
218
- # Set character for masking the STDIN input
219
- #
220
- # @param [String] character
221
- #
222
- # @return [self]
223
- #
224
- # @api public
225
- def mask(char = nil)
226
- return @mask if char.nil?
227
- @mask = char
228
- self
229
- end
230
-
231
- # Check if character mask is set
232
- #
233
- # @return [Boolean]
234
- #
235
- # @api public
236
- def mask?
237
- !!@mask
238
- end
239
-
240
- # Set if the input is character based or not
241
- #
242
- # @param [Boolean] value
243
- #
244
- # @return [self]
245
- #
246
- # @api public
247
- def char(value = nil)
248
- return @character if value.nil?
249
- @character = value
250
- self
251
- end
252
-
253
- # Check if character intput is set
254
- #
255
- # @return [Boolean]
256
- #
257
- # @api public
258
- def character?
259
- !!@character
260
- end
261
-
262
- # Set expect range of values
263
- #
264
- # @param [String] value
265
- #
266
- # @api public
267
- def in(value = nil)
268
- return @in if value.nil?
269
- @in = @converter.convert(value).to(:range, strict: true)
270
- self
271
- end
272
-
273
- # Check if range is set
274
- #
275
- # @return [Boolean]
276
- #
277
- # @api public
278
- def in?
279
- !!@in
280
- end
281
-
282
- # Check if response matches all the requirements set by the question
283
- #
284
- # @param [Object] value
285
- #
286
- # @return [Object]
287
- #
288
- # @api private
289
- def evaluate_response(value)
290
- return default_value if !value && default?
291
- check_required(value)
292
- return if value.nil?
293
-
294
- check_valid(value) unless valid_values.empty?
295
- within?(value)
296
- validation.valid_value?(value)
297
- modifier.apply_to(value)
298
- end
299
-
300
- private
301
-
302
- # Check if value is present
303
- #
304
- # @api private
305
- def check_required(value)
306
- if required? && !default? && value.nil?
307
- fail ArgumentRequired, 'No value provided for required'
308
- end
309
- end
310
-
311
- # Check if value matches any of the expected values
312
- #
313
- # @api private
314
- def check_valid(value)
315
- if Array(value).all? { |val| valid_values.include? val }
316
- return value
317
- else
318
- fail InvalidArgument, "Valid values are: #{valid_values.join(', ')}"
319
- end
320
- end
321
-
322
- # Check if value is within expected range
323
- #
324
- # @api private
325
- def within?(value)
326
- if in? && value
327
- if @in.include?(value)
328
- else
329
- fail InvalidArgument, "Value #{value} is not included in the range #{@in}"
330
- end
331
- end
332
- end
333
- end # Question
334
- end # Shell
335
- end # TTY
@@ -1,93 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- class Shell
5
- class Question
6
- # A class representing String modifications.
7
- class Modifier
8
- attr_reader :modifiers
9
- private :modifiers
10
-
11
- # Initialize a Modifier
12
- #
13
- # @api public
14
- def initialize(*modifiers)
15
- @modifiers = Array(modifiers)
16
- end
17
-
18
- # Change supplied value according to the given string transformation.
19
- # Valid settings are:
20
- #
21
- # @param [String] value
22
- # the string to be modified
23
- #
24
- # @return [String]
25
- #
26
- # @api private
27
- def apply_to(value)
28
- modifiers.reduce(value) do |result, mod|
29
- result = Modifier.letter_case mod, result
30
- Modifier.whitespace mod, result
31
- end
32
- end
33
-
34
- # Changes letter casing in a string according to valid modifications.
35
- # For invalid modification option the string is preserved.
36
- #
37
- # @param [Symbol] mod
38
- # the modification to change the string
39
- #
40
- # @option mod [Symbol] :up change to upper case
41
- # @option mod [Symbol] :upcase change to upper case
42
- # @option mod [Symbol] :uppercase change to upper case
43
- # @option mod [Symbol] :down change to lower case
44
- # @option mod [Symbol] :downcase change to lower case
45
- # @option mod [Symbol] :capitalize change all words to start
46
- # with uppercase case letter
47
- #
48
- # @return [String]
49
- #
50
- # @api public
51
- def self.letter_case(mod, value)
52
- case mod
53
- when :up, :upcase, :uppercase
54
- value.upcase
55
- when :down, :downcase, :lowercase
56
- value.downcase
57
- when :capitalize
58
- value.capitalize
59
- else
60
- value
61
- end
62
- end
63
-
64
- # Changes whitespace in a string according to valid modifications.
65
- #
66
- # @param [Symbol] mod
67
- # the modification to change the string
68
- #
69
- # @option mod [String] :trim, :strip
70
- # remove whitespace for the start and end
71
- # @option mod [String] :chomp remove record separator from the end
72
- # @option mod [String] :collapse remove any duplicate whitespace
73
- # @option mod [String] :remove remove all whitespace
74
- #
75
- # @api public
76
- def self.whitespace(mod, value)
77
- case mod
78
- when :trim, :strip
79
- value.strip
80
- when :chomp
81
- value.chomp
82
- when :collapse
83
- value.gsub(/\s+/, ' ')
84
- when :remove
85
- value.gsub(/\s+/, '')
86
- else
87
- value
88
- end
89
- end
90
- end # Modifier
91
- end # Question
92
- end # Shell
93
- end # TTY