highline 2.0.0.pre.develop.6 → 2.0.0.pre.develop.9
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +8 -2
- data/Changelog.md +22 -0
- data/Gemfile +21 -1
- data/README.md +16 -2
- data/appveyor.yml +1 -1
- data/examples/menus.rb +3 -0
- data/lib/highline.rb +16 -12
- data/lib/highline/import.rb +2 -1
- data/lib/highline/menu.rb +84 -54
- data/lib/highline/menu/item.rb +30 -0
- data/lib/highline/question.rb +11 -5
- data/lib/highline/version.rb +1 -1
- data/test/test_helper.rb +2 -6
- data/test/test_highline.rb +176 -8
- data/test/test_menu.rb +99 -4
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c639e0a0e863970d33dd5f04f0503770980f79cb
|
4
|
+
data.tar.gz: 4e23a7f040b753da355772655775c3a66e6dced3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d5f0ce4b01d5d777dbf46c01b4f5276aa1aaa1a1411240b690ad137fb9dc4c676dc4bf399eb90dfd1572aa1549d18afcb74e8c211d423b5c9b38bd5ab5ad2e4
|
7
|
+
data.tar.gz: 97f72ad639d2b0b2bd40cc828ff4d10d552b0932e2fb946e8755a2c5c52dcdce957ac2db0a5e53a596f2e128db45878a314e202a1b6a6e70ac77010b8d7481e6
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Bellow the changes to default Rubocop behavior.
|
2
|
+
|
3
|
+
# See options at:
|
4
|
+
# https://github.com/bbatsov/rubocop/tree/master/config
|
5
|
+
|
6
|
+
# General
|
7
|
+
|
8
|
+
# Multi-line method chaining should be done with leading dots.
|
9
|
+
Style/DotPosition:
|
10
|
+
EnforcedStyle: trailing
|
11
|
+
SupportedStyles:
|
12
|
+
- leading
|
13
|
+
- trailing
|
14
|
+
|
15
|
+
# Enabling!
|
16
|
+
|
17
|
+
Style/CollectionMethods:
|
18
|
+
Description: 'Preferred collection methods.'
|
19
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size'
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Style/StringMethods:
|
23
|
+
Description: 'Checks if configured preferred methods are used over non-preferred.'
|
24
|
+
Enabled: true
|
25
|
+
|
26
|
+
# Disabling!
|
27
|
+
|
28
|
+
Style/StringLiterals:
|
29
|
+
Description: 'Checks if uses of quotes match the configured preference.'
|
30
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals'
|
31
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
---
|
2
2
|
language: ruby
|
3
|
+
dist: trusty
|
3
4
|
sudo: false
|
4
5
|
script: "bundle exec rake test"
|
5
6
|
rvm:
|
@@ -8,7 +9,7 @@ rvm:
|
|
8
9
|
- 2.1
|
9
10
|
- 2.2
|
10
11
|
- ruby-head
|
11
|
-
- rbx-
|
12
|
+
- rbx-3.81
|
12
13
|
- jruby-19mode # JRuby in 1.9 mode
|
13
14
|
- jruby-head
|
14
15
|
|
@@ -16,7 +17,12 @@ notifications:
|
|
16
17
|
email: false
|
17
18
|
matrix:
|
18
19
|
allow_failures:
|
20
|
+
- rvm: 1.9
|
19
21
|
- rvm: ruby-head
|
20
|
-
- rvm: rbx-
|
22
|
+
- rvm: rbx-3.81
|
21
23
|
- rvm: jruby-19mode # JRuby in 1.9 mode
|
22
24
|
- rvm: jruby-head
|
25
|
+
include:
|
26
|
+
- rvm: 2.3
|
27
|
+
script: "bundle exec rake test && bundle exec codeclimate-test-reporter" # Run only for 2.3
|
28
|
+
bundler_args: --without development
|
data/Changelog.md
CHANGED
@@ -2,7 +2,27 @@
|
|
2
2
|
|
3
3
|
Below is a complete listing of changes for each revision of HighLine.
|
4
4
|
|
5
|
+
### 2.0.0-develop.9 / 2017-06-24
|
6
|
+
|
7
|
+
* PR #211 / PR #212 - HighLine#use_color= and use_color? as instance methods (@abinoam, @phiggins)
|
8
|
+
* PR #203 / I #191 - Default values are shown in menus by Frederico (@fredrb)
|
9
|
+
* PR #201 / I #198 - Confirm in question now accepts Proc (@mmihira)
|
10
|
+
* PR #197 - Some HighLine::Menu improvements
|
11
|
+
* Move Menu::MenuItem to Menu::Item with its own file
|
12
|
+
* Some small refactorings
|
13
|
+
|
14
|
+
### 2.0.0-develop.8 / 2016-06-03
|
15
|
+
|
16
|
+
* PR #195 - Add PRONTO to development group at Gemfile by Abinoam Jr. (@abinoam)
|
17
|
+
|
18
|
+
### 2.0.0-develop.7 / 2016-05-31
|
19
|
+
|
20
|
+
* PR #194 - Indices coloring on HighLine::Menu by Aregic (@aregic)
|
21
|
+
* PR #190 - Add Ruby 2.3.0 to travis matrix by Koichi (@koic/ruby-23)
|
22
|
+
* PR #189 - Improve #agree tests by @kevinoid
|
23
|
+
|
5
24
|
### 2.0.0-develop.6 / 2016-02-01
|
25
|
+
|
6
26
|
* PR #184 - Menu improvements, bug fixes, and more tests by Geoff Lee (@matrinox)
|
7
27
|
* Add third arg to menu that overides the choice displayed to the user
|
8
28
|
* FIX: autocomplete prompt does not include menu choices after the first
|
@@ -10,9 +30,11 @@ Below is a complete listing of changes for each revision of HighLine.
|
|
10
30
|
* PR #183 - Fix menu example in README.md by Fabien Foerster (@fabienfoerster)
|
11
31
|
|
12
32
|
### 2.0.0-develop.5 / 2015-12-27
|
33
|
+
|
13
34
|
* Fix #180 with PR #181 - Make it possible to overwrite the menu prompt shown on errors.
|
14
35
|
|
15
36
|
### 2.0.0-develop.4 / 2015-12-14
|
37
|
+
|
16
38
|
This versions makes the code documentation 100% 'A' grade on inch.
|
17
39
|
We have used inch and http://inch-ci.org to guide the priorities
|
18
40
|
on documentation production.
|
data/Gemfile
CHANGED
@@ -8,5 +8,25 @@ group :development, :test do
|
|
8
8
|
gem "minitest", require: false
|
9
9
|
end
|
10
10
|
|
11
|
+
|
12
|
+
# Reporting only at one ruby version of travis matrix (no repetition)
|
11
13
|
gem "codeclimate-test-reporter", group: :test, require: false
|
12
|
-
|
14
|
+
|
15
|
+
platform :ruby do
|
16
|
+
# Running only on MRI
|
17
|
+
gem "simplecov", group: :test
|
18
|
+
end
|
19
|
+
|
20
|
+
group :development do
|
21
|
+
gem 'pronto'
|
22
|
+
gem 'pronto-reek', require: false
|
23
|
+
gem 'pronto-rubocop', require: false
|
24
|
+
gem 'pronto-poper', require: false
|
25
|
+
|
26
|
+
# Using strict versions of flay and pronto-flay while
|
27
|
+
# PR https://github.com/mmozuras/pronto-flay/pull/11/files
|
28
|
+
# is not merged
|
29
|
+
gem 'flay', '2.7.0'
|
30
|
+
gem 'pronto-flay', '0.6.1', require: false
|
31
|
+
gem 'flog'
|
32
|
+
end
|
data/README.md
CHANGED
@@ -74,6 +74,19 @@ cli.choose do |menu|
|
|
74
74
|
menu.prompt = "Please choose your favorite programming language? "
|
75
75
|
menu.choice(:ruby) { cli.say("Good choice!") }
|
76
76
|
menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
|
77
|
+
menu.default = :ruby
|
78
|
+
end
|
79
|
+
|
80
|
+
## Using colored indices on Menus
|
81
|
+
|
82
|
+
HighLine::Menu.index_color = :rgb_77bbff # set default index color
|
83
|
+
|
84
|
+
cli.choose do |menu|
|
85
|
+
menu.index_color = :rgb_999999 # override default color of index
|
86
|
+
# you can also use constants like :blue
|
87
|
+
menu.prompt = "Please choose your favorite programming language? "
|
88
|
+
menu.choice(:ruby) { cli.say("Good choice!") }
|
89
|
+
menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
|
77
90
|
end
|
78
91
|
```
|
79
92
|
|
@@ -143,7 +156,7 @@ Contributing
|
|
143
156
|
|
144
157
|
4. Add the main HighLine repository as the __upstream__ remote
|
145
158
|
- ```cd highline``` # to enter the cloned repository directory.
|
146
|
-
- ```git remote add
|
159
|
+
- ```git remote add upstream https://github.com/JEG2/highline```
|
147
160
|
|
148
161
|
5. Keep your fork in sync with __upstream__
|
149
162
|
- ```git fetch upstream```
|
@@ -153,9 +166,10 @@ Contributing
|
|
153
166
|
6. Create your feature branch
|
154
167
|
- ```git checkout -b your_branch```
|
155
168
|
|
156
|
-
7. Hack the source code
|
169
|
+
7. Hack the source code, run the tests and __pronto__
|
157
170
|
- ```rake test```
|
158
171
|
- ```rake acceptance```
|
172
|
+
- ```pronto run```
|
159
173
|
|
160
174
|
8. Commit your changes
|
161
175
|
- ```git commit -am "Your commit message"```
|
data/appveyor.yml
CHANGED
data/examples/menus.rb
CHANGED
data/lib/highline.rb
CHANGED
@@ -44,17 +44,17 @@ class HighLine
|
|
44
44
|
include BuiltinStyles
|
45
45
|
include CustomErrors
|
46
46
|
|
47
|
-
#
|
48
|
-
|
47
|
+
# Set it to false to disable ANSI coloring
|
48
|
+
attr_writer :use_color
|
49
49
|
|
50
|
-
#
|
51
|
-
def
|
52
|
-
@use_color
|
50
|
+
# Returns true if HighLine instance is currently using color escapes.
|
51
|
+
def use_color?
|
52
|
+
@use_color
|
53
53
|
end
|
54
54
|
|
55
|
-
#
|
56
|
-
def
|
57
|
-
@use_color
|
55
|
+
# Resets the use of color.
|
56
|
+
def reset_use_color
|
57
|
+
@use_color = true
|
58
58
|
end
|
59
59
|
|
60
60
|
# For checking if the current version of HighLine supports RGB colors
|
@@ -101,10 +101,11 @@ class HighLine
|
|
101
101
|
end
|
102
102
|
|
103
103
|
# Reset HighLine to default.
|
104
|
-
# Clears Style index and
|
104
|
+
# Clears Style index and resets color_scheme and use_color settings.
|
105
105
|
def self.reset
|
106
106
|
Style.clear_index
|
107
107
|
reset_color_scheme
|
108
|
+
reset_use_color
|
108
109
|
end
|
109
110
|
|
110
111
|
# Reset color scheme to default (+nil+)
|
@@ -138,6 +139,7 @@ class HighLine
|
|
138
139
|
@header = nil
|
139
140
|
@prompt = nil
|
140
141
|
@key = nil
|
142
|
+
@use_color = true
|
141
143
|
|
142
144
|
@terminal = HighLine::Terminal.get_terminal(input, output)
|
143
145
|
end
|
@@ -190,7 +192,7 @@ class HighLine
|
|
190
192
|
# @see Question#character
|
191
193
|
def agree( yes_or_no_question, character = nil )
|
192
194
|
ask(yes_or_no_question, lambda { |yn| yn.downcase[0] == ?y}) do |q|
|
193
|
-
q.validate = /\
|
195
|
+
q.validate = /\A(?:y(?:es)?|no?)\Z/i
|
194
196
|
q.responses[:not_valid] = 'Please enter "yes" or "no".'
|
195
197
|
q.responses[:ask_on_error] = :question
|
196
198
|
q.character = character
|
@@ -307,9 +309,11 @@ class HighLine
|
|
307
309
|
end
|
308
310
|
|
309
311
|
# (see .color)
|
310
|
-
#
|
312
|
+
# This method is a clone of the HighLine.color class method.
|
313
|
+
# But it checks for use_color? per instance
|
311
314
|
def color(string, *colors)
|
312
|
-
|
315
|
+
return string unless use_color?
|
316
|
+
HighLine.Style(*colors).color(string)
|
313
317
|
end
|
314
318
|
|
315
319
|
# In case you just want the color code, without the embedding and
|
data/lib/highline/import.rb
CHANGED
@@ -24,7 +24,8 @@ $terminal = HighLine.new
|
|
24
24
|
#
|
25
25
|
module Kernel
|
26
26
|
extend Forwardable
|
27
|
-
def_delegators :$terminal, :agree, :ask, :choose, :say
|
27
|
+
def_delegators :$terminal, :agree, :ask, :choose, :say,
|
28
|
+
:use_color=, :use_color?, :reset_use_color
|
28
29
|
end
|
29
30
|
|
30
31
|
# When requiring 'highline/import' HighLine adds {#or_ask} to Object so
|
data/lib/highline/menu.rb
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
# This is Free Software. See LICENSE and COPYING for details.
|
10
10
|
|
11
11
|
require "highline/question"
|
12
|
+
require "highline/menu/item"
|
12
13
|
|
13
14
|
class HighLine
|
14
15
|
#
|
@@ -17,6 +18,21 @@ class HighLine
|
|
17
18
|
# to {HighLine#choose} can detail all aspects of menu display and control.
|
18
19
|
#
|
19
20
|
class Menu < Question
|
21
|
+
# Pass +false+ to _color_ to turn off HighLine::Menu's
|
22
|
+
# index coloring.
|
23
|
+
# Pass a color and the Menu's indices will be colored.
|
24
|
+
def self.index_color=(color = :rgb_77bbff)
|
25
|
+
@index_color = color
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initialize it
|
29
|
+
self.index_color = false
|
30
|
+
|
31
|
+
# Returns color used for coloring Menu's indices
|
32
|
+
def self.index_color
|
33
|
+
@index_color
|
34
|
+
end
|
35
|
+
|
20
36
|
#
|
21
37
|
# Create an instance of HighLine::Menu. All customization is done
|
22
38
|
# through the passed block, which should call accessors, {#choice} and
|
@@ -32,7 +48,7 @@ class HighLine
|
|
32
48
|
# menu.choices(:python, :perl) { say("Not from around here, are you?") }
|
33
49
|
# end
|
34
50
|
|
35
|
-
def initialize
|
51
|
+
def initialize
|
36
52
|
#
|
37
53
|
# Initialize Question objects with ignored values, we'll
|
38
54
|
# adjust ours as needed.
|
@@ -54,6 +70,10 @@ class HighLine
|
|
54
70
|
@shell = false
|
55
71
|
@nil_on_handled = false
|
56
72
|
|
73
|
+
# Used for coloring Menu indices.
|
74
|
+
# Set it to default. But you may override it.
|
75
|
+
@index_color = self.class.index_color
|
76
|
+
|
57
77
|
# Override Questions responses, we'll set our own.
|
58
78
|
@responses = { }
|
59
79
|
# Context for action code.
|
@@ -130,6 +150,11 @@ class HighLine
|
|
130
150
|
# Defaults to +false+.
|
131
151
|
#
|
132
152
|
attr_accessor :nil_on_handled
|
153
|
+
#
|
154
|
+
# The color of the index when displaying the menu. See Style class for
|
155
|
+
# available colors.
|
156
|
+
#
|
157
|
+
attr_accessor :index_color
|
133
158
|
|
134
159
|
#
|
135
160
|
# Adds _name_ to the list of available menu items. Menu items will be
|
@@ -162,7 +187,7 @@ class HighLine
|
|
162
187
|
# end
|
163
188
|
|
164
189
|
def choice( name, help = nil, text = nil, &action )
|
165
|
-
item =
|
190
|
+
item = Menu::Item.new(name, text: text, help: help, action: action)
|
166
191
|
@items << item
|
167
192
|
@help.merge!(item.item_help)
|
168
193
|
update_responses # rebuild responses based on our settings
|
@@ -170,21 +195,21 @@ class HighLine
|
|
170
195
|
|
171
196
|
#
|
172
197
|
# This method helps reduce the namespaces in the original call, which would look
|
173
|
-
# like this: HighLine::Menu::
|
198
|
+
# like this: HighLine::Menu::Item.new(...)
|
174
199
|
# With #build_item, it looks like this: menu.build_item(...)
|
175
200
|
# @param *args splat args, the same args you would pass to an initialization of
|
176
|
-
# HighLine::Menu::
|
177
|
-
# @return [HighLine::Menu::
|
201
|
+
# HighLine::Menu::Item
|
202
|
+
# @return [HighLine::Menu::Item] the menu item
|
178
203
|
|
179
204
|
def build_item(*args)
|
180
|
-
|
205
|
+
Menu::Item.new(*args)
|
181
206
|
end
|
182
207
|
|
183
208
|
#
|
184
209
|
# Adds an item directly to the menu. If you want more configuraiton or options,
|
185
210
|
# use this method
|
186
211
|
#
|
187
|
-
# @param item [Menu::
|
212
|
+
# @param item [Menu::Item] item containing choice fields and more
|
188
213
|
# @return [void]
|
189
214
|
|
190
215
|
def add_item(item)
|
@@ -218,7 +243,7 @@ class HighLine
|
|
218
243
|
# @return (see #choice)
|
219
244
|
|
220
245
|
def hidden( name, help = nil, &action )
|
221
|
-
item =
|
246
|
+
item = Menu::Item.new(name, text: name, help: help, action: action)
|
222
247
|
@hidden_items << item
|
223
248
|
@help.merge!(item.item_help)
|
224
249
|
end
|
@@ -329,29 +354,30 @@ class HighLine
|
|
329
354
|
# This method returns all possible options for auto-completion, based
|
330
355
|
# on the settings of _index_ and _select_by_.
|
331
356
|
#
|
332
|
-
def options
|
333
|
-
# add in any hidden menu commands
|
334
|
-
items = all_items
|
335
|
-
|
357
|
+
def options
|
336
358
|
case @select_by
|
337
|
-
when :index
|
338
|
-
map_items_by_index
|
359
|
+
when :index
|
360
|
+
map_items_by_index
|
339
361
|
when :name
|
340
|
-
|
362
|
+
map_items_by_name
|
341
363
|
else
|
342
|
-
map_items_by_index
|
364
|
+
map_items_by_index + map_items_by_name
|
343
365
|
end
|
344
366
|
end
|
345
367
|
|
346
|
-
def map_items_by_index
|
347
|
-
if index == :letter
|
368
|
+
def map_items_by_index
|
369
|
+
if @index == :letter
|
348
370
|
l_index = "`"
|
349
|
-
|
371
|
+
all_items.map { l_index.succ!.dup }
|
350
372
|
else
|
351
|
-
(1
|
373
|
+
(1..all_items.size).map(&:to_s)
|
352
374
|
end
|
353
375
|
end
|
354
376
|
|
377
|
+
def map_items_by_name
|
378
|
+
all_items.map(&:name)
|
379
|
+
end
|
380
|
+
|
355
381
|
def all_items
|
356
382
|
@items + @hidden_items
|
357
383
|
end
|
@@ -447,22 +473,38 @@ class HighLine
|
|
447
473
|
end
|
448
474
|
end
|
449
475
|
|
476
|
+
def decorate_index(index)
|
477
|
+
if index_color
|
478
|
+
HighLine.color(index, index_color)
|
479
|
+
else
|
480
|
+
index
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
450
484
|
#
|
451
485
|
# Allows Menu objects to pass as Arrays, for use with HighLine.list().
|
452
486
|
# This method returns all menu items to be displayed, complete with
|
453
487
|
# indexes.
|
454
488
|
#
|
455
|
-
def to_ary
|
489
|
+
def to_ary
|
490
|
+
@items.map.with_index { |item, ix| decorate_item(item.text.to_s, ix) }
|
491
|
+
end
|
492
|
+
|
493
|
+
def decorate_item(text, ix)
|
494
|
+
decorated, non_decorated = mark_for_decoration(text, ix)
|
495
|
+
decorate_index(decorated) + non_decorated
|
496
|
+
end
|
497
|
+
|
498
|
+
def mark_for_decoration(text, ix)
|
456
499
|
case @index
|
457
500
|
when :number
|
458
|
-
|
501
|
+
["#{ix + 1}#{@index_suffix}", text]
|
459
502
|
when :letter
|
460
|
-
|
461
|
-
@items.map { |i| "#{l_index.succ!}#{@index_suffix}#{i.text}" }
|
503
|
+
["#{('a'.ord + ix).chr}#{@index_suffix}", text]
|
462
504
|
when :none
|
463
|
-
|
505
|
+
[text, ""]
|
464
506
|
else
|
465
|
-
|
507
|
+
["#{index}#{@index_suffix}", text]
|
466
508
|
end
|
467
509
|
end
|
468
510
|
|
@@ -474,23 +516,33 @@ class HighLine
|
|
474
516
|
case @layout
|
475
517
|
when :list
|
476
518
|
%(<%= header ? "#{header}:\n" : '' %>) +
|
477
|
-
|
478
|
-
|
519
|
+
parse_list +
|
520
|
+
show_default_if_any +
|
479
521
|
"<%= prompt %>"
|
480
522
|
when :one_line
|
481
523
|
%(<%= header ? "#{header}: " : '' %>) +
|
482
524
|
"<%= prompt %>" +
|
483
|
-
"(
|
484
|
-
|
525
|
+
"(" + parse_list + ")" +
|
526
|
+
show_default_if_any +
|
485
527
|
"<%= prompt[/\s*$/] %>"
|
486
528
|
when :menu_only
|
487
|
-
|
488
|
-
|
529
|
+
parse_list +
|
530
|
+
show_default_if_any +
|
531
|
+
"<%= prompt %>"
|
489
532
|
else
|
490
533
|
@layout
|
491
534
|
end
|
492
535
|
end
|
493
536
|
|
537
|
+
def parse_list
|
538
|
+
"<%= list( menu, #{@flow.inspect},
|
539
|
+
#{@list_option.inspect} ) %>"
|
540
|
+
end
|
541
|
+
|
542
|
+
def show_default_if_any
|
543
|
+
return default.to_s.empty? ? "" : "(#{default}) "
|
544
|
+
end
|
545
|
+
|
494
546
|
#
|
495
547
|
# This method will update the intelligent responses to account for
|
496
548
|
# Menu specific differences. Calls the superclass' (Question's)
|
@@ -500,27 +552,5 @@ class HighLine
|
|
500
552
|
def update_responses
|
501
553
|
build_responses(options)
|
502
554
|
end
|
503
|
-
|
504
|
-
class MenuItem
|
505
|
-
attr_reader :name, :text, :help, :action
|
506
|
-
|
507
|
-
#
|
508
|
-
# @param name [String] The name that is matched against the user input
|
509
|
-
# @param text: [String] The text that displays for that choice (defaults to name)
|
510
|
-
# @param help: [String] help, see above (not sure how it works)
|
511
|
-
# @param action: [Block] a block that gets called when choice is selected
|
512
|
-
#
|
513
|
-
def initialize(name, attributes)
|
514
|
-
@name = name
|
515
|
-
@text = attributes[:text] || @name
|
516
|
-
@help = attributes[:help]
|
517
|
-
@action = attributes[:action]
|
518
|
-
end
|
519
|
-
|
520
|
-
def item_help
|
521
|
-
return {} unless help
|
522
|
-
{ name.to_s.downcase => help }
|
523
|
-
end
|
524
|
-
end
|
525
555
|
end
|
526
556
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class HighLine
|
2
|
+
class Menu < Question
|
3
|
+
# Represents an Item of a HighLine::Menu.
|
4
|
+
#
|
5
|
+
class Item
|
6
|
+
attr_reader :name, :text, :help, :action
|
7
|
+
|
8
|
+
#
|
9
|
+
# @param name [String] The name that is matched against the user input
|
10
|
+
# @param attributes [Hash] options Hash to tailor menu item to your needs
|
11
|
+
# @option attributes text: [String] The text that displays for that
|
12
|
+
# choice (defaults to name)
|
13
|
+
# @option attributes help: [String] help/hint string to be displayed.
|
14
|
+
# @option attributes action: [Block] a block that gets called when choice
|
15
|
+
# is selected
|
16
|
+
#
|
17
|
+
def initialize(name, attributes)
|
18
|
+
@name = name
|
19
|
+
@text = attributes[:text] || @name
|
20
|
+
@help = attributes[:help]
|
21
|
+
@action = attributes[:action]
|
22
|
+
end
|
23
|
+
|
24
|
+
def item_help
|
25
|
+
return {} unless help
|
26
|
+
{ name.to_s.downcase => help }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/highline/question.rb
CHANGED
@@ -147,11 +147,15 @@ class HighLine
|
|
147
147
|
attr_accessor :in
|
148
148
|
#
|
149
149
|
# Asks a yes or no confirmation question, to ensure a user knows what
|
150
|
-
# they have just agreed to.
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
150
|
+
# they have just agreed to. The confirm attribute can be set to :
|
151
|
+
# +true+ : In this case the question will be, "Are you sure?".
|
152
|
+
# Proc : The Proc is yielded the answer given. The Proc must
|
153
|
+
# output a string which is then used as the confirm
|
154
|
+
# question.
|
155
|
+
# String : The String must use ERB syntax. The String is
|
156
|
+
# evaluated with access to question and answer and
|
157
|
+
# is then used as the confirm question.
|
158
|
+
# When set to +false+ or +nil+ (the default), answers are not confirmed.
|
155
159
|
attr_accessor :confirm
|
156
160
|
#
|
157
161
|
# When set, the user will be prompted for multiple answers which will
|
@@ -529,6 +533,8 @@ class HighLine
|
|
529
533
|
def confirm_question(highline)
|
530
534
|
if confirm == true
|
531
535
|
"Are you sure? "
|
536
|
+
elsif confirm.is_a?(Proc)
|
537
|
+
confirm.call(self.answer)
|
532
538
|
else
|
533
539
|
# evaluate ERb under initial scope, so it will have
|
534
540
|
# access to question and answer
|
data/lib/highline/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
if ENV['CODECLIMATE_REPO_TOKEN']
|
7
|
-
require "codeclimate-test-reporter"
|
8
|
-
CodeClimate::TestReporter.start
|
9
|
-
end
|
4
|
+
# Run code coverage only for mri
|
5
|
+
require 'simplecov' if RUBY_ENGINE == 'ruby'
|
10
6
|
|
11
7
|
# Compatibility module for StringIO, File
|
12
8
|
# and Tempfile. Necessary for some tests.
|
data/test/test_highline.rb
CHANGED
@@ -34,15 +34,55 @@ class TestHighLine < Minitest::Test
|
|
34
34
|
@terminal = HighLine.new(@input, @output)
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
|
39
|
-
@input.rewind
|
37
|
+
def test_agree_valid_yes_answers
|
38
|
+
valid_yes_answers = %w{ y yes Y YES }
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
valid_yes_answers.each do |user_input|
|
41
|
+
@input << "#{user_input}\n"
|
42
|
+
@input.rewind
|
43
|
+
|
44
|
+
assert_equal true, @terminal.agree("Yes or no? ")
|
45
|
+
assert_equal "Yes or no? ", @output.string
|
46
|
+
|
47
|
+
@input.truncate(@input.rewind)
|
48
|
+
@output.truncate(@output.rewind)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_agree_valid_no_answers
|
53
|
+
valid_no_answers = %w{ n no N NO }
|
54
|
+
|
55
|
+
valid_no_answers.each do |user_input|
|
56
|
+
@input << "#{user_input}\n"
|
57
|
+
@input.rewind
|
58
|
+
|
59
|
+
assert_equal false, @terminal.agree("Yes or no? ")
|
60
|
+
assert_equal "Yes or no? ", @output.string
|
61
|
+
|
62
|
+
@input.truncate(@input.rewind)
|
63
|
+
@output.truncate(@output.rewind)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_agree_invalid_answers
|
68
|
+
invalid_answers = [ "ye", "yuk", "nope", "Oh yes", "Oh no", "Hell no!"]
|
69
|
+
|
70
|
+
invalid_answers.each do |user_input|
|
71
|
+
# Each invalid answer, should be followed by a 'y' (as the question is reasked)
|
72
|
+
@input << "#{user_input}\ny\n"
|
73
|
+
@input.rewind
|
74
|
+
|
75
|
+
assert_equal true, @terminal.agree("Yes or no? ")
|
76
|
+
|
77
|
+
# It reasks the question if the answer is invalid
|
78
|
+
assert_equal "Yes or no? Please enter \"yes\" or \"no\".\nYes or no? ", @output.string
|
79
|
+
|
80
|
+
@input.truncate(@input.rewind)
|
81
|
+
@output.truncate(@output.rewind)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_agree_with_getc
|
46
86
|
@input.truncate(@input.rewind)
|
47
87
|
@input << "yellow"
|
48
88
|
@input.rewind
|
@@ -462,9 +502,119 @@ class TestHighLine < Minitest::Test
|
|
462
502
|
# turn off color
|
463
503
|
old_setting = HighLine.use_color?
|
464
504
|
HighLine.use_color = false
|
505
|
+
@terminal.use_color = false
|
465
506
|
@terminal.say("This should be <%= color('cyan', CYAN) %>!")
|
466
507
|
assert_equal("This should be cyan!\n", @output.string)
|
467
508
|
HighLine.use_color = old_setting
|
509
|
+
@terminal.use_color = old_setting
|
510
|
+
end
|
511
|
+
|
512
|
+
def test_color_setting_per_instance
|
513
|
+
require 'highline/import'
|
514
|
+
old_glob_term = $terminal
|
515
|
+
old_setting = HighLine.use_color?
|
516
|
+
|
517
|
+
gterm_input = StringIO.new
|
518
|
+
gterm_output = StringIO.new
|
519
|
+
$terminal = HighLine.new(gterm_input, gterm_output)
|
520
|
+
|
521
|
+
# It can set coloring at HighLine class
|
522
|
+
cli_input = StringIO.new
|
523
|
+
cli_output = StringIO.new
|
524
|
+
|
525
|
+
cli = HighLine.new(cli_input, cli_output)
|
526
|
+
|
527
|
+
# Testing with both use_color setted to true
|
528
|
+
HighLine.use_color = true
|
529
|
+
@terminal.use_color = true
|
530
|
+
cli.use_color = true
|
531
|
+
|
532
|
+
say("This should be <%= color('cyan', CYAN) %>!")
|
533
|
+
assert_equal("This should be \e[36mcyan\e[0m!\n", gterm_output.string)
|
534
|
+
|
535
|
+
@terminal.say("This should be <%= color('cyan', CYAN) %>!")
|
536
|
+
assert_equal("This should be \e[36mcyan\e[0m!\n", @output.string)
|
537
|
+
|
538
|
+
cli.say("This should be <%= color('cyan', CYAN) %>!")
|
539
|
+
assert_equal("This should be \e[36mcyan\e[0m!\n", cli_output.string)
|
540
|
+
|
541
|
+
gterm_output.truncate(gterm_output.rewind)
|
542
|
+
@output.truncate(@output.rewind)
|
543
|
+
cli_output.truncate(cli_output.rewind)
|
544
|
+
|
545
|
+
# Testing with both use_color setted to false
|
546
|
+
HighLine.use_color = false
|
547
|
+
@terminal.use_color = false
|
548
|
+
cli.use_color = false
|
549
|
+
|
550
|
+
say("This should be <%= color('cyan', CYAN) %>!")
|
551
|
+
assert_equal("This should be cyan!\n", gterm_output.string)
|
552
|
+
|
553
|
+
@terminal.say("This should be <%= color('cyan', CYAN) %>!")
|
554
|
+
assert_equal("This should be cyan!\n", @output.string)
|
555
|
+
|
556
|
+
cli.say("This should be <%= color('cyan', CYAN) %>!")
|
557
|
+
assert_equal("This should be cyan!\n", cli_output.string)
|
558
|
+
|
559
|
+
gterm_output.truncate(gterm_output.rewind)
|
560
|
+
@output.truncate(@output.rewind)
|
561
|
+
cli_output.truncate(cli_output.rewind)
|
562
|
+
|
563
|
+
# Now check when class and instance doesn't agree about use_color
|
564
|
+
|
565
|
+
# Class false, instance true
|
566
|
+
HighLine.use_color = false
|
567
|
+
@terminal.use_color = false
|
568
|
+
cli.use_color = true
|
569
|
+
|
570
|
+
say("This should be <%= color('cyan', CYAN) %>!")
|
571
|
+
assert_equal("This should be cyan!\n", gterm_output.string)
|
572
|
+
|
573
|
+
@terminal.say("This should be <%= color('cyan', CYAN) %>!")
|
574
|
+
assert_equal("This should be cyan!\n", @output.string)
|
575
|
+
|
576
|
+
cli.say("This should be <%= color('cyan', CYAN) %>!")
|
577
|
+
assert_equal("This should be \e[36mcyan\e[0m!\n", cli_output.string)
|
578
|
+
|
579
|
+
gterm_output.truncate(gterm_output.rewind)
|
580
|
+
@output.truncate(@output.rewind)
|
581
|
+
cli_output.truncate(cli_output.rewind)
|
582
|
+
|
583
|
+
# Class true, instance false
|
584
|
+
HighLine.use_color = true
|
585
|
+
@terminal.use_color = true
|
586
|
+
cli.use_color = false
|
587
|
+
|
588
|
+
say("This should be <%= color('cyan', CYAN) %>!")
|
589
|
+
assert_equal("This should be \e[36mcyan\e[0m!\n", gterm_output.string)
|
590
|
+
|
591
|
+
@terminal.say("This should be <%= color('cyan', CYAN) %>!")
|
592
|
+
assert_equal("This should be \e[36mcyan\e[0m!\n", @output.string)
|
593
|
+
|
594
|
+
cli.say("This should be <%= color('cyan', CYAN) %>!")
|
595
|
+
assert_equal("This should be cyan!\n", cli_output.string )
|
596
|
+
|
597
|
+
gterm_output.truncate(gterm_output.rewind)
|
598
|
+
@output.truncate(@output.rewind)
|
599
|
+
cli_output.truncate(cli_output.rewind)
|
600
|
+
|
601
|
+
HighLine.use_color = old_setting
|
602
|
+
@terminal.use_color = old_setting
|
603
|
+
$terminal = old_glob_term
|
604
|
+
end
|
605
|
+
|
606
|
+
def test_reset_use_color
|
607
|
+
HighLine.use_color = false
|
608
|
+
refute HighLine.use_color?
|
609
|
+
HighLine.reset_use_color
|
610
|
+
assert HighLine.use_color?
|
611
|
+
end
|
612
|
+
|
613
|
+
def test_reset_use_color_when_highline_reset
|
614
|
+
HighLine.use_color = false
|
615
|
+
refute HighLine.use_color?
|
616
|
+
HighLine.reset
|
617
|
+
assert HighLine.use_color?
|
468
618
|
end
|
469
619
|
|
470
620
|
def test_uncolor
|
@@ -539,6 +689,24 @@ class TestHighLine < Minitest::Test
|
|
539
689
|
assert_equal( "Enter a filename: " +
|
540
690
|
"Are you sure you want to overwrite junk.txt? ",
|
541
691
|
@output.string )
|
692
|
+
|
693
|
+
@input.truncate(@input.rewind)
|
694
|
+
@input << "junk.txt\nyes\nsave.txt\nn\n"
|
695
|
+
@input.rewind
|
696
|
+
@output.truncate(@output.rewind)
|
697
|
+
|
698
|
+
scoped_variable = { "junk.txt" => '20mb' }
|
699
|
+
answer = @terminal.ask("Enter a filename: ") do |q|
|
700
|
+
q.confirm = Proc.new do |answer|
|
701
|
+
"Are you sure you want to overwrite #{answer} with size " +
|
702
|
+
"of #{scoped_variable[answer]}? "
|
703
|
+
end
|
704
|
+
end
|
705
|
+
assert_equal("junk.txt", answer)
|
706
|
+
assert_equal( "Enter a filename: " +
|
707
|
+
"Are you sure you want to overwrite junk.txt " +
|
708
|
+
"with size of 20mb? ",
|
709
|
+
@output.string )
|
542
710
|
end
|
543
711
|
|
544
712
|
def test_generic_confirm_with_true
|
data/test/test_menu.rb
CHANGED
@@ -31,6 +31,18 @@ class TestMenu < Minitest::Test
|
|
31
31
|
assert_equal("Sample2", output)
|
32
32
|
end
|
33
33
|
|
34
|
+
def test_default
|
35
|
+
@input << "\n"
|
36
|
+
@input.rewind
|
37
|
+
|
38
|
+
output = @terminal.choose do |menu|
|
39
|
+
menu.choices("Sample1", "Sample2", "Sample3")
|
40
|
+
menu.default = "Sample1"
|
41
|
+
end
|
42
|
+
|
43
|
+
assert_equal("Sample1", output)
|
44
|
+
end
|
45
|
+
|
34
46
|
def test_flow
|
35
47
|
@input << "Sample1\n"
|
36
48
|
@input.rewind
|
@@ -114,8 +126,8 @@ class TestMenu < Minitest::Test
|
|
114
126
|
@input.rewind
|
115
127
|
|
116
128
|
selected = @terminal.choose do |menu|
|
117
|
-
menu.add_item(HighLine::Menu::
|
118
|
-
menu.add_item(HighLine::Menu::
|
129
|
+
menu.add_item(HighLine::Menu::Item.new("Sample1", text: "Sample2"))
|
130
|
+
menu.add_item(HighLine::Menu::Item.new("Sample2", text: "Sample1"))
|
119
131
|
end
|
120
132
|
assert_equal(selected, "Sample1")
|
121
133
|
assert_equal("1. Sample2\n" +
|
@@ -128,8 +140,8 @@ class TestMenu < Minitest::Test
|
|
128
140
|
@input.rewind
|
129
141
|
|
130
142
|
selected = @terminal.choose do |menu|
|
131
|
-
menu.add_item(HighLine::Menu::
|
132
|
-
menu.add_item(HighLine::Menu::
|
143
|
+
menu.add_item(HighLine::Menu::Item.new("Sample1", text: "Sample2"))
|
144
|
+
menu.add_item(HighLine::Menu::Item.new("Sample2", text: "Sample1"))
|
133
145
|
end
|
134
146
|
assert_equal(selected, "Sample2")
|
135
147
|
assert_equal("1. Sample2\n" +
|
@@ -235,6 +247,89 @@ class TestMenu < Minitest::Test
|
|
235
247
|
assert_equal("* Sample1\n* Sample2\n* Sample3\n? ", @output.string)
|
236
248
|
end
|
237
249
|
|
250
|
+
def test_index_with_color
|
251
|
+
index_color = :rgb_77bbff
|
252
|
+
|
253
|
+
@input << "Sample1\n"
|
254
|
+
@input.rewind
|
255
|
+
|
256
|
+
@terminal.choose do |menu|
|
257
|
+
# Default: menu.index = :number
|
258
|
+
menu.index_color = index_color
|
259
|
+
|
260
|
+
menu.choice "Sample1"
|
261
|
+
menu.choice "Sample2"
|
262
|
+
menu.choice "Sample3"
|
263
|
+
end
|
264
|
+
|
265
|
+
assert_equal(
|
266
|
+
HighLine.color("1. ", index_color) + "Sample1\n" +
|
267
|
+
HighLine.color("2. ", index_color) + "Sample2\n" +
|
268
|
+
HighLine.color("3. ", index_color) + "Sample3\n" +
|
269
|
+
"? ",
|
270
|
+
@output.string
|
271
|
+
)
|
272
|
+
|
273
|
+
@output.truncate(@output.rewind)
|
274
|
+
@input.rewind
|
275
|
+
|
276
|
+
@terminal.choose do |menu|
|
277
|
+
menu.index = :letter
|
278
|
+
menu.index_suffix = ") "
|
279
|
+
menu.index_color = index_color
|
280
|
+
|
281
|
+
menu.choice "Sample1"
|
282
|
+
menu.choice "Sample2"
|
283
|
+
menu.choice "Sample3"
|
284
|
+
end
|
285
|
+
|
286
|
+
assert_equal(
|
287
|
+
HighLine.color("a) ", index_color) + "Sample1\n" +
|
288
|
+
HighLine.color("b) ", index_color) + "Sample2\n" +
|
289
|
+
HighLine.color("c) ", index_color) + "Sample3\n? ",
|
290
|
+
@output.string
|
291
|
+
)
|
292
|
+
|
293
|
+
@output.truncate(@output.rewind)
|
294
|
+
@input.rewind
|
295
|
+
|
296
|
+
@terminal.choose do |menu|
|
297
|
+
menu.index = :none
|
298
|
+
menu.index_color = index_color
|
299
|
+
|
300
|
+
menu.choice "Sample1"
|
301
|
+
menu.choice "Sample2"
|
302
|
+
menu.choice "Sample3"
|
303
|
+
end
|
304
|
+
|
305
|
+
assert_equal(
|
306
|
+
HighLine.color("Sample1", index_color) + "\n" +
|
307
|
+
HighLine.color("Sample2", index_color) + "\n" +
|
308
|
+
HighLine.color("Sample3", index_color) + "\n? ",
|
309
|
+
@output.string
|
310
|
+
)
|
311
|
+
|
312
|
+
@output.truncate(@output.rewind)
|
313
|
+
@input.rewind
|
314
|
+
|
315
|
+
@terminal.choose do |menu|
|
316
|
+
menu.index = "*"
|
317
|
+
menu.index_color = index_color
|
318
|
+
|
319
|
+
menu.choice "Sample1"
|
320
|
+
menu.choice "Sample2"
|
321
|
+
menu.choice "Sample3"
|
322
|
+
end
|
323
|
+
|
324
|
+
colored_asterix = HighLine.color("* ", index_color)
|
325
|
+
assert_equal(
|
326
|
+
"#{colored_asterix}Sample1\n" +
|
327
|
+
"#{colored_asterix}Sample2\n" +
|
328
|
+
"#{colored_asterix}Sample3\n? ",
|
329
|
+
@output.string
|
330
|
+
)
|
331
|
+
end
|
332
|
+
|
238
333
|
def test_layouts
|
239
334
|
@input << "save\n"
|
240
335
|
@input.rewind
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: highline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.pre.develop.
|
4
|
+
version: 2.0.0.pre.develop.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Edward Gray II
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: code_statistics
|
@@ -39,6 +39,7 @@ extra_rdoc_files:
|
|
39
39
|
- LICENSE
|
40
40
|
files:
|
41
41
|
- ".gitignore"
|
42
|
+
- ".rubocop.yml"
|
42
43
|
- ".simplecov"
|
43
44
|
- ".travis.yml"
|
44
45
|
- AUTHORS
|
@@ -74,6 +75,7 @@ files:
|
|
74
75
|
- lib/highline/list.rb
|
75
76
|
- lib/highline/list_renderer.rb
|
76
77
|
- lib/highline/menu.rb
|
78
|
+
- lib/highline/menu/item.rb
|
77
79
|
- lib/highline/paginator.rb
|
78
80
|
- lib/highline/question.rb
|
79
81
|
- lib/highline/question/answer_converter.rb
|
@@ -135,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
137
|
version: 1.3.1
|
136
138
|
requirements: []
|
137
139
|
rubyforge_project: highline
|
138
|
-
rubygems_version: 2.
|
140
|
+
rubygems_version: 2.6.11
|
139
141
|
signing_key:
|
140
142
|
specification_version: 4
|
141
143
|
summary: HighLine is a high-level command-line IO library.
|