highline 2.0.0.pre.develop.6 → 2.0.0.pre.develop.9
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|