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