highline 1.6.15 → 1.6.16
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +11 -3
- data/INSTALL +1 -1
- data/README.rdoc +2 -2
- data/Rakefile +2 -2
- data/examples/basic_usage.rb +2 -2
- data/examples/color_scheme.rb +2 -2
- data/examples/get_character.rb +12 -0
- data/examples/limit.rb +1 -1
- data/examples/menus.rb +2 -2
- data/examples/overwrite.rb +2 -2
- data/examples/page_and_wrap.rb +11 -11
- data/highline.gemspec +1 -0
- data/lib/highline.rb +156 -112
- data/lib/highline/color_scheme.rb +13 -13
- data/lib/highline/import.rb +4 -4
- data/lib/highline/menu.rb +64 -64
- data/lib/highline/question.rb +61 -58
- data/lib/highline/simulate.rb +1 -1
- data/lib/highline/string_extensions.rb +11 -11
- data/lib/highline/style.rb +21 -21
- data/lib/highline/system_extensions.rb +11 -9
- data/setup.rb +6 -6
- data/site/index.html +1 -1
- data/test/tc_highline.rb +91 -3
- data/test/tc_style.rb +3 -3
- metadata +5 -3
@@ -13,17 +13,17 @@ class HighLine
|
|
13
13
|
#
|
14
14
|
# colors("This is a warning", :warning)
|
15
15
|
#
|
16
|
-
# A ColorScheme contains named sets of HighLine color constants.
|
16
|
+
# A ColorScheme contains named sets of HighLine color constants.
|
17
17
|
#
|
18
18
|
# Example: Instantiating a color scheme, applying it to HighLine,
|
19
|
-
#
|
19
|
+
# and using it:
|
20
20
|
#
|
21
21
|
# ft = HighLine::ColorScheme.new do |cs|
|
22
22
|
# cs[:headline] = [ :bold, :yellow, :on_black ]
|
23
23
|
# cs[:horizontal_line] = [ :bold, :white ]
|
24
24
|
# cs[:even_row] = [ :green ]
|
25
25
|
# cs[:odd_row] = [ :magenta ]
|
26
|
-
# end
|
26
|
+
# end
|
27
27
|
#
|
28
28
|
# HighLine.color_scheme = ft
|
29
29
|
# say("<%= color('Headline', :headline) %>")
|
@@ -34,15 +34,15 @@ class HighLine
|
|
34
34
|
# say("<%= color('#{row}', :even_row ) %>")
|
35
35
|
# else
|
36
36
|
# say("<%= color('#{row}', :odd_row) %>")
|
37
|
-
# end
|
37
|
+
# end
|
38
38
|
# i = !i
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
#
|
42
|
-
class ColorScheme
|
42
|
+
class ColorScheme
|
43
43
|
#
|
44
44
|
# Create an instance of HighLine::ColorScheme. The customization can
|
45
|
-
# happen as a passed in Hash or via the yielded block.
|
45
|
+
# happen as a passed in Hash or via the yielded block. Keys are
|
46
46
|
# converted to <tt>:symbols</tt> and values are converted to HighLine
|
47
47
|
# constants.
|
48
48
|
#
|
@@ -68,13 +68,13 @@ class HighLine
|
|
68
68
|
def []( color_tag )
|
69
69
|
@scheme[to_symbol(color_tag)]
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Retrieve the original form of the scheme
|
73
73
|
def definition( color_tag )
|
74
74
|
style = @scheme[to_symbol(color_tag)]
|
75
75
|
style && style.list
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
# Retrieve the keys in the scheme
|
79
79
|
def keys
|
80
80
|
@scheme.keys
|
@@ -82,15 +82,15 @@ class HighLine
|
|
82
82
|
|
83
83
|
# Allow the scheme to be set like a Hash.
|
84
84
|
def []=( color_tag, constants )
|
85
|
-
@scheme[to_symbol(color_tag)] = HighLine::Style.new(:name=>color_tag.to_s.downcase.to_sym,
|
85
|
+
@scheme[to_symbol(color_tag)] = HighLine::Style.new(:name=>color_tag.to_s.downcase.to_sym,
|
86
86
|
:list=>constants, :no_index=>true)
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
# Retrieve the color scheme hash (in original definition format)
|
90
90
|
def to_hash
|
91
91
|
@scheme.inject({}) { |hsh, pair| key, value = pair; hsh[key] = value.list; hsh }
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
|
95
95
|
private
|
96
96
|
|
@@ -112,11 +112,11 @@ class HighLine
|
|
112
112
|
|
113
113
|
# A sample ColorScheme.
|
114
114
|
class SampleColorScheme < ColorScheme
|
115
|
-
#
|
115
|
+
#
|
116
116
|
# Builds the sample scheme with settings for <tt>:critical</tt>,
|
117
117
|
# <tt>:error</tt>, <tt>:warning</tt>, <tt>:notice</tt>, <tt>:info</tt>,
|
118
118
|
# <tt>:debug</tt>, <tt>:row_even</tt>, and <tt>:row_odd</tt> colors.
|
119
|
-
#
|
119
|
+
#
|
120
120
|
def initialize( h = nil )
|
121
121
|
scheme = {
|
122
122
|
:critical => [ :yellow, :on_red ],
|
data/lib/highline/import.rb
CHANGED
@@ -25,16 +25,16 @@ module Kernel
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class Object
|
28
|
-
#
|
28
|
+
#
|
29
29
|
# Tries this object as a _first_answer_ for a HighLine::Question. See that
|
30
30
|
# attribute for details.
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# *Warning*: This Object will be passed to String() before set.
|
33
|
-
#
|
33
|
+
#
|
34
34
|
def or_ask( *args, &details )
|
35
35
|
ask(*args) do |question|
|
36
36
|
question.first_answer = String(self) unless nil?
|
37
|
-
|
37
|
+
|
38
38
|
details.call(question) unless details.nil?
|
39
39
|
end
|
40
40
|
end
|
data/lib/highline/menu.rb
CHANGED
@@ -8,11 +8,11 @@
|
|
8
8
|
require "highline/question"
|
9
9
|
|
10
10
|
class HighLine
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Menu objects encapsulate all the details of a call to HighLine.choose().
|
13
13
|
# Using the accessors and Menu.choice() and Menu.choices(), the block passed
|
14
14
|
# to HighLine.choose() can detail all aspects of menu display and control.
|
15
|
-
#
|
15
|
+
#
|
16
16
|
class Menu < Question
|
17
17
|
#
|
18
18
|
# Create an instance of HighLine::Menu. All customization is done
|
@@ -20,14 +20,14 @@ class HighLine
|
|
20
20
|
# choices() as needed to define the Menu. Note that Menus are also
|
21
21
|
# Questions, so all that functionality is available to the block as
|
22
22
|
# well.
|
23
|
-
#
|
23
|
+
#
|
24
24
|
def initialize( )
|
25
25
|
#
|
26
26
|
# Initialize Question objects with ignored values, we'll
|
27
27
|
# adjust ours as needed.
|
28
|
-
#
|
28
|
+
#
|
29
29
|
super("Ignored", [ ], &nil) # avoiding passing the block along
|
30
|
-
|
30
|
+
|
31
31
|
@items = [ ]
|
32
32
|
@hidden_items = [ ]
|
33
33
|
@help = Hash.new("There's no help for that topic.")
|
@@ -42,12 +42,12 @@ class HighLine
|
|
42
42
|
@layout = :list
|
43
43
|
@shell = false
|
44
44
|
@nil_on_handled = false
|
45
|
-
|
45
|
+
|
46
46
|
# Override Questions responses, we'll set our own.
|
47
47
|
@responses = { }
|
48
48
|
# Context for action code.
|
49
49
|
@highline = nil
|
50
|
-
|
50
|
+
|
51
51
|
yield self if block_given?
|
52
52
|
|
53
53
|
init_help if @shell and not @help.empty?
|
@@ -56,52 +56,52 @@ class HighLine
|
|
56
56
|
#
|
57
57
|
# An _index_ to append to each menu item in display. See
|
58
58
|
# Menu.index=() for details.
|
59
|
-
#
|
59
|
+
#
|
60
60
|
attr_reader :index
|
61
61
|
#
|
62
62
|
# The String placed between an _index_ and a menu item. Defaults to
|
63
63
|
# ". ". Switches to " ", when _index_ is set to a String (like "-").
|
64
64
|
#
|
65
65
|
attr_accessor :index_suffix
|
66
|
-
#
|
67
|
-
# The _select_by_ attribute controls how the user is allowed to pick a
|
66
|
+
#
|
67
|
+
# The _select_by_ attribute controls how the user is allowed to pick a
|
68
68
|
# menu item. The available choices are:
|
69
|
-
#
|
69
|
+
#
|
70
70
|
# <tt>:index</tt>:: The user is allowed to type the numerical
|
71
|
-
# or
|
71
|
+
# or alphabetical index for their selection.
|
72
72
|
# <tt>:index_or_name</tt>:: Allows both methods from the
|
73
73
|
# <tt>:index</tt> option and the
|
74
74
|
# <tt>:name</tt> option.
|
75
75
|
# <tt>:name</tt>:: Menu items are selected by typing a portion
|
76
76
|
# of the item name that will be
|
77
77
|
# auto-completed.
|
78
|
-
#
|
78
|
+
#
|
79
79
|
attr_accessor :select_by
|
80
|
-
#
|
80
|
+
#
|
81
81
|
# This attribute is passed directly on as the mode to HighLine.list() by
|
82
82
|
# all the preset layouts. See that method for appropriate settings.
|
83
|
-
#
|
83
|
+
#
|
84
84
|
attr_accessor :flow
|
85
85
|
#
|
86
86
|
# This setting is passed on as the third parameter to HighLine.list()
|
87
87
|
# by all the preset layouts. See that method for details of its
|
88
88
|
# effects. Defaults to +nil+.
|
89
|
-
#
|
89
|
+
#
|
90
90
|
attr_accessor :list_option
|
91
91
|
#
|
92
92
|
# Used by all the preset layouts to display title and/or introductory
|
93
93
|
# information, when set. Defaults to +nil+.
|
94
|
-
#
|
94
|
+
#
|
95
95
|
attr_accessor :header
|
96
96
|
#
|
97
97
|
# Used by all the preset layouts to ask the actual question to fetch a
|
98
98
|
# menu selection from the user. Defaults to "? ".
|
99
|
-
#
|
99
|
+
#
|
100
100
|
attr_accessor :prompt
|
101
101
|
#
|
102
102
|
# An ERb _layout_ to use when displaying this Menu object. See
|
103
103
|
# Menu.layout=() for details.
|
104
|
-
#
|
104
|
+
#
|
105
105
|
attr_reader :layout
|
106
106
|
#
|
107
107
|
# When set to +true+, responses are allowed to be an entire line of
|
@@ -109,21 +109,21 @@ class HighLine
|
|
109
109
|
# "word" of input will be matched against the menu choices, but both the
|
110
110
|
# command selected and the rest of the line will be passed to provided
|
111
111
|
# action blocks. Defaults to +false+.
|
112
|
-
#
|
112
|
+
#
|
113
113
|
attr_accessor :shell
|
114
114
|
#
|
115
|
-
# When +true+, any selected item handled by provided action code
|
115
|
+
# When +true+, any selected item handled by provided action code will
|
116
116
|
# return +nil+, instead of the results to the action code. This may
|
117
117
|
# prove handy when dealing with mixed menus where only the names of
|
118
118
|
# items without any code (and +nil+, of course) will be returned.
|
119
119
|
# Defaults to +false+.
|
120
|
-
#
|
120
|
+
#
|
121
121
|
attr_accessor :nil_on_handled
|
122
|
-
|
122
|
+
|
123
123
|
#
|
124
124
|
# Adds _name_ to the list of available menu items. Menu items will be
|
125
125
|
# displayed in the order they are added.
|
126
|
-
#
|
126
|
+
#
|
127
127
|
# An optional _action_ can be associated with this name and if provided,
|
128
128
|
# it will be called if the item is selected. The result of the method
|
129
129
|
# will be returned, unless _nil_on_handled_ is set (when you would get
|
@@ -132,20 +132,20 @@ class HighLine
|
|
132
132
|
# just the command is passed. The <tt>@highline</tt> variable is set to
|
133
133
|
# the current HighLine context before the action code is called and can
|
134
134
|
# thus be used for adding output and the like.
|
135
|
-
#
|
135
|
+
#
|
136
136
|
def choice( name, help = nil, &action )
|
137
137
|
@items << [name, action]
|
138
|
-
|
138
|
+
|
139
139
|
@help[name.to_s.downcase] = help unless help.nil?
|
140
140
|
update_responses # rebuild responses based on our settings
|
141
141
|
end
|
142
|
-
|
142
|
+
|
143
143
|
#
|
144
144
|
# A shortcut for multiple calls to the sister method choice(). <b>Be
|
145
145
|
# warned:</b> An _action_ set here will apply to *all* provided
|
146
146
|
# _names_. This is considered to be a feature, so you can easily
|
147
147
|
# hand-off interface processing to a different chunk of code.
|
148
|
-
#
|
148
|
+
#
|
149
149
|
def choices( *names, &action )
|
150
150
|
names.each { |n| choice(n, &action) }
|
151
151
|
end
|
@@ -153,42 +153,42 @@ class HighLine
|
|
153
153
|
# Identical to choice(), but the item will not be listed for the user.
|
154
154
|
def hidden( name, help = nil, &action )
|
155
155
|
@hidden_items << [name, action]
|
156
|
-
|
156
|
+
|
157
157
|
@help[name.to_s.downcase] = help unless help.nil?
|
158
158
|
end
|
159
|
-
|
160
|
-
#
|
159
|
+
|
160
|
+
#
|
161
161
|
# Sets the indexing style for this Menu object. Indexes are appended to
|
162
162
|
# menu items, when displayed in list form. The available settings are:
|
163
|
-
#
|
163
|
+
#
|
164
164
|
# <tt>:number</tt>:: Menu items will be indexed numerically, starting
|
165
165
|
# with 1. This is the default method of indexing.
|
166
166
|
# <tt>:letter</tt>:: Items will be indexed alphabetically, starting
|
167
167
|
# with a.
|
168
168
|
# <tt>:none</tt>:: No index will be appended to menu items.
|
169
169
|
# <i>any String</i>:: Will be used as the literal _index_.
|
170
|
-
#
|
171
|
-
# Setting the _index_ to <tt>:none</tt> a literal String
|
172
|
-
# _index_suffix_ to a single space and _select_by_ to <tt>:
|
170
|
+
#
|
171
|
+
# Setting the _index_ to <tt>:none</tt> or a literal String also adjusts
|
172
|
+
# _index_suffix_ to a single space and _select_by_ to <tt>:name</tt>.
|
173
173
|
# Because of this, you should make a habit of setting the _index_ first.
|
174
|
-
#
|
174
|
+
#
|
175
175
|
def index=( style )
|
176
176
|
@index = style
|
177
|
-
|
177
|
+
|
178
178
|
# Default settings.
|
179
179
|
if @index == :none or @index.is_a?(::String)
|
180
180
|
@index_suffix = " "
|
181
181
|
@select_by = :name
|
182
182
|
end
|
183
183
|
end
|
184
|
-
|
185
|
-
#
|
184
|
+
|
185
|
+
#
|
186
186
|
# Initializes the help system by adding a <tt>:help</tt> choice, some
|
187
187
|
# action code, and the default help listing.
|
188
|
-
#
|
188
|
+
#
|
189
189
|
def init_help( )
|
190
190
|
return if @items.include?(:help)
|
191
|
-
|
191
|
+
|
192
192
|
topics = @help.keys.sort
|
193
193
|
help_help = @help.include?("help") ? @help["help"] :
|
194
194
|
"This command will display helpful messages about " +
|
@@ -206,21 +206,21 @@ class HighLine
|
|
206
206
|
end
|
207
207
|
end
|
208
208
|
end
|
209
|
-
|
209
|
+
|
210
210
|
#
|
211
211
|
# Used to set help for arbitrary topics. Use the topic <tt>"help"</tt>
|
212
212
|
# to override the default message.
|
213
|
-
#
|
213
|
+
#
|
214
214
|
def help( topic, help )
|
215
215
|
@help[topic] = help
|
216
216
|
end
|
217
|
-
|
218
|
-
#
|
217
|
+
|
218
|
+
#
|
219
219
|
# Setting a _layout_ with this method also adjusts some other attributes
|
220
220
|
# of the Menu object, to ideal defaults for the chosen _layout_. To
|
221
221
|
# account for that, you probably want to set a _layout_ first in your
|
222
222
|
# configuration block, if needed.
|
223
|
-
#
|
223
|
+
#
|
224
224
|
# Accepted settings for _layout_ are:
|
225
225
|
#
|
226
226
|
# <tt>:list</tt>:: The default _layout_. The _header_ if set
|
@@ -228,26 +228,26 @@ class HighLine
|
|
228
228
|
# a trailing colon. Then the list of menu
|
229
229
|
# items will follow. Finally, the _prompt_
|
230
230
|
# will be used as the ask()-like question.
|
231
|
-
# <tt>:one_line</tt>:: A shorter _layout_ that fits on one line.
|
231
|
+
# <tt>:one_line</tt>:: A shorter _layout_ that fits on one line.
|
232
232
|
# The _header_ comes first followed by a
|
233
233
|
# colon and spaces, then the _prompt_ with menu
|
234
234
|
# items between trailing parenthesis.
|
235
235
|
# <tt>:menu_only</tt>:: Just the menu items, followed up by a likely
|
236
236
|
# short _prompt_.
|
237
237
|
# <i>any ERb String</i>:: Will be taken as the literal _layout_. This
|
238
|
-
# String can access <tt>@header</tt>,
|
238
|
+
# String can access <tt>@header</tt>,
|
239
239
|
# <tt>@menu</tt> and <tt>@prompt</tt>, but is
|
240
240
|
# otherwise evaluated in the typical HighLine
|
241
241
|
# context, to provide access to utilities like
|
242
242
|
# HighLine.list() primarily.
|
243
|
-
#
|
243
|
+
#
|
244
244
|
# If set to either <tt>:one_line</tt>, or <tt>:menu_only</tt>, _index_
|
245
245
|
# will default to <tt>:none</tt> and _flow_ will default to
|
246
246
|
# <tt>:inline</tt>.
|
247
|
-
#
|
247
|
+
#
|
248
248
|
def layout=( new_layout )
|
249
249
|
@layout = new_layout
|
250
|
-
|
250
|
+
|
251
251
|
# Default settings.
|
252
252
|
case @layout
|
253
253
|
when :one_line, :menu_only
|
@@ -259,11 +259,11 @@ class HighLine
|
|
259
259
|
#
|
260
260
|
# This method returns all possible options for auto-completion, based
|
261
261
|
# on the settings of _index_ and _select_by_.
|
262
|
-
#
|
262
|
+
#
|
263
263
|
def options( )
|
264
264
|
# add in any hidden menu commands
|
265
265
|
@items.concat(@hidden_items)
|
266
|
-
|
266
|
+
|
267
267
|
by_index = if @index == :letter
|
268
268
|
l_index = "`"
|
269
269
|
@items.map { "#{l_index.succ!}" }
|
@@ -287,13 +287,13 @@ class HighLine
|
|
287
287
|
|
288
288
|
#
|
289
289
|
# This method processes the auto-completed user selection, based on the
|
290
|
-
# rules for this Menu object. If an action was provided for the
|
290
|
+
# rules for this Menu object. If an action was provided for the
|
291
291
|
# selection, it will be executed as described in Menu.choice().
|
292
|
-
#
|
292
|
+
#
|
293
293
|
def select( highline_context, selection, details = nil )
|
294
294
|
# add in any hidden menu commands
|
295
295
|
@items.concat(@hidden_items)
|
296
|
-
|
296
|
+
|
297
297
|
# Find the selected action.
|
298
298
|
name, action = if selection =~ /^\d+$/
|
299
299
|
@items[selection.to_i - 1]
|
@@ -302,7 +302,7 @@ class HighLine
|
|
302
302
|
index = @items.map { "#{l_index.succ!}" }.index(selection)
|
303
303
|
@items.find { |c| c.first == selection } or @items[index]
|
304
304
|
end
|
305
|
-
|
305
|
+
|
306
306
|
# Run or return it.
|
307
307
|
if not action.nil?
|
308
308
|
@highline = highline_context
|
@@ -321,12 +321,12 @@ class HighLine
|
|
321
321
|
# make sure the hidden items are removed, before we return
|
322
322
|
@items.slice!(@items.size - @hidden_items.size, @hidden_items.size)
|
323
323
|
end
|
324
|
-
|
324
|
+
|
325
325
|
#
|
326
326
|
# Allows Menu objects to pass as Arrays, for use with HighLine.list().
|
327
327
|
# This method returns all menu items to be displayed, complete with
|
328
328
|
# indexes.
|
329
|
-
#
|
329
|
+
#
|
330
330
|
def to_ary( )
|
331
331
|
case @index
|
332
332
|
when :number
|
@@ -340,11 +340,11 @@ class HighLine
|
|
340
340
|
@items.map { |c| "#{index}#{@index_suffix}#{c.first}" }
|
341
341
|
end
|
342
342
|
end
|
343
|
-
|
343
|
+
|
344
344
|
#
|
345
345
|
# Allows Menu to behave as a String, just like Question. Returns the
|
346
346
|
# _layout_ to be rendered, which is used by HighLine.say().
|
347
|
-
#
|
347
|
+
#
|
348
348
|
def to_str( )
|
349
349
|
case @layout
|
350
350
|
when :list
|
@@ -364,13 +364,13 @@ class HighLine
|
|
364
364
|
else
|
365
365
|
@layout
|
366
366
|
end
|
367
|
-
end
|
367
|
+
end
|
368
368
|
|
369
369
|
#
|
370
370
|
# This method will update the intelligent responses to account for
|
371
|
-
# Menu specific differences. This overrides the work done by
|
371
|
+
# Menu specific differences. This overrides the work done by
|
372
372
|
# Question.build_responses().
|
373
|
-
#
|
373
|
+
#
|
374
374
|
def update_responses( )
|
375
375
|
append_default unless default.nil?
|
376
376
|
@responses = @responses.merge(
|