highline 1.6.15 → 1.6.16
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.
- 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
data/CHANGELOG
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
Below is a complete listing of changes for each revision of HighLine.
|
4
4
|
|
5
|
+
== 1.6.16
|
6
|
+
|
7
|
+
* Added the new indention feature (by davispuh).
|
8
|
+
* Separated auto-completion from the answer type (by davispuh).
|
9
|
+
* Improved JRuby support (by rsutphin).
|
10
|
+
* General code clean up (by stomar).
|
11
|
+
* Made HighLine#say() a little smarter with regard to color escapes (by Kenneth Murphy).
|
12
|
+
|
5
13
|
== 1.6.15
|
6
14
|
|
7
15
|
* Added support for nil arguments in lists (by Eric Saxby).
|
@@ -88,12 +96,12 @@ Below is a complete listing of changes for each revision of HighLine.
|
|
88
96
|
* Fixed raw_no_echo_mode so that it uses stty -icanon rather than cbreak
|
89
97
|
as cbreak does not appear to be the posixly correct argument. It fails
|
90
98
|
on Solaris if cbreak is used.
|
91
|
-
* Fixed an issue that kept Menu from showing the correct choices for
|
99
|
+
* Fixed an issue that kept Menu from showing the correct choices for
|
92
100
|
disambiguation.
|
93
101
|
* Removed a circular require that kept Ruby 1.9.2 from loading HighLine.
|
94
102
|
* Fixed a bug that caused infinite looping when wrapping text without spaces.
|
95
103
|
* Fixed it so that :auto paging accounts for the two lines it adds.
|
96
|
-
* On JRuby, improved error message about ffi-ncurses. Before 1.5.3,
|
104
|
+
* On JRuby, improved error message about ffi-ncurses. Before 1.5.3,
|
97
105
|
HighLine was silently swallowing error messages when ffi-ncurses gem
|
98
106
|
was installed without ncurses present on the system.
|
99
107
|
* Reverted Aaron Simmons's patch to allow redirecting STDIN on Windows. This
|
@@ -261,7 +269,7 @@ Patch by Jeremy Hinegardner:
|
|
261
269
|
make fetching passwords trivial.
|
262
270
|
* Fixed an auto-complete bug that could cause a crash when the user gave an
|
263
271
|
answer that didn't complete to any valid choice.
|
264
|
-
* Implemented +case+ for HighLine::Question objects to provide character case
|
272
|
+
* Implemented +case+ for HighLine::Question objects to provide character case
|
265
273
|
conversions on given answers. Can be set to <tt>:up</tt>, <tt>:down</tt>, or
|
266
274
|
<tt>:capitalize</tt>.
|
267
275
|
* Exposed <tt>@answer</tt> to the response system, to allow response that are
|
data/INSTALL
CHANGED
@@ -35,7 +35,7 @@ without a working ncurses installation. First, ensure that you have
|
|
35
35
|
ncurses installed and then install the ffi-ncurses gem.
|
36
36
|
|
37
37
|
If ffi-ncurses fails to find your ncurses library, you may need to set the
|
38
|
-
RUBY_FFI_NCURSES envirionment variable, i.e:
|
38
|
+
RUBY_FFI_NCURSES envirionment variable, i.e:
|
39
39
|
|
40
40
|
RUBY_FFI_NCURSES_LIB=ncursesw ruby examples/hello.rb
|
41
41
|
|
data/README.rdoc
CHANGED
@@ -46,11 +46,11 @@ Menus:
|
|
46
46
|
|
47
47
|
choose do |menu|
|
48
48
|
menu.prompt = "Please choose your favorite programming language? "
|
49
|
-
|
49
|
+
|
50
50
|
menu.choice(:ruby) { say("Good choice!") }
|
51
51
|
menu.choices(:python, :perl) { say("Not from around here, are you?") }
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
For more examples see the examples/ directory of this project.
|
55
55
|
|
56
56
|
== Installing
|
data/Rakefile
CHANGED
@@ -39,8 +39,8 @@ end
|
|
39
39
|
desc "Show library's code statistics"
|
40
40
|
task :stats do
|
41
41
|
require 'code_statistics'
|
42
|
-
CodeStatistics.new( ["HighLine", "lib"],
|
43
|
-
["Functionals", "examples"],
|
42
|
+
CodeStatistics.new( ["HighLine", "lib"],
|
43
|
+
["Functionals", "examples"],
|
44
44
|
["Units", "test"] ).to_s
|
45
45
|
end
|
46
46
|
|
data/examples/basic_usage.rb
CHANGED
data/examples/color_scheme.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
2
|
|
3
3
|
# color_scheme.rb
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Created by Jeremy Hinegardner on 2007-01-24
|
6
|
-
# Copyright 2007 Jeremy Hinegardner. All rights reserved
|
6
|
+
# Copyright 2007 Jeremy Hinegardner. All rights reserved
|
7
7
|
|
8
8
|
require 'rubygems'
|
9
9
|
require 'highline/import'
|
data/examples/limit.rb
CHANGED
data/examples/menus.rb
CHANGED
data/examples/overwrite.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
# overwrite.rb
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Created by Jeremy Hinegardner on 2007-01-24
|
6
|
-
# Copyright 2007 Jeremy Hinegardner. All rights reserved
|
6
|
+
# Copyright 2007 Jeremy Hinegardner. All rights reserved
|
7
7
|
|
8
8
|
require 'rubygems'
|
9
9
|
require 'highline/import'
|
data/examples/page_and_wrap.rb
CHANGED
@@ -249,14 +249,14 @@ Delaware
|
|
249
249
|
|
250
250
|
Geo: Read
|
251
251
|
Gunning Bedford jun
|
252
|
-
John Dickinson
|
253
|
-
Richard Bassett
|
254
|
-
Jaco: Broom
|
252
|
+
John Dickinson
|
253
|
+
Richard Bassett
|
254
|
+
Jaco: Broom
|
255
255
|
|
256
256
|
Maryland
|
257
257
|
|
258
258
|
James MCHenry
|
259
|
-
Dan of ST ThoS. Jenifer
|
259
|
+
Dan of ST ThoS. Jenifer
|
260
260
|
DanL Carroll.
|
261
261
|
|
262
262
|
Virginia
|
@@ -268,7 +268,7 @@ North Carolina
|
|
268
268
|
|
269
269
|
WM Blount
|
270
270
|
RichD. Dobbs Spaight.
|
271
|
-
Hu Williamson
|
271
|
+
Hu Williamson
|
272
272
|
|
273
273
|
South Carolina
|
274
274
|
|
@@ -290,7 +290,7 @@ Nicholas Gilman
|
|
290
290
|
Massachusetts
|
291
291
|
|
292
292
|
Nathaniel Gorham
|
293
|
-
Rufus King
|
293
|
+
Rufus King
|
294
294
|
|
295
295
|
Connecticut
|
296
296
|
WM. SamL. Johnson
|
@@ -304,8 +304,8 @@ New Jersey
|
|
304
304
|
|
305
305
|
Wil: Livingston
|
306
306
|
David Brearley.
|
307
|
-
WM. Paterson.
|
308
|
-
Jona: Dayton
|
307
|
+
WM. Paterson.
|
308
|
+
Jona: Dayton
|
309
309
|
|
310
310
|
Pennsylvania
|
311
311
|
|
@@ -313,9 +313,9 @@ B Franklin
|
|
313
313
|
Thomas Mifflin
|
314
314
|
RobT Morris
|
315
315
|
Geo. Clymer
|
316
|
-
ThoS. FitzSimons
|
317
|
-
Jared Ingersoll
|
318
|
-
James Wilson.
|
316
|
+
ThoS. FitzSimons
|
317
|
+
Jared Ingersoll
|
318
|
+
James Wilson.
|
319
319
|
Gouv Morris
|
320
320
|
|
321
321
|
Attest William Jackson Secretary
|
data/highline.gemspec
CHANGED
@@ -27,6 +27,7 @@ SPEC = Gem::Specification.new do |spec|
|
|
27
27
|
spec.email = "james@graysoftinc.com"
|
28
28
|
spec.rubyforge_project = "highline"
|
29
29
|
spec.homepage = "http://highline.rubyforge.org"
|
30
|
+
spec.license = "Ruby"
|
30
31
|
spec.description = <<END_DESC
|
31
32
|
A high-level IO library that provides validation, type conversion, and more for
|
32
33
|
command-line interfaces. HighLine also includes a complete menu system that can
|
data/lib/highline.rb
CHANGED
@@ -18,7 +18,7 @@ require "highline/color_scheme"
|
|
18
18
|
require "highline/style"
|
19
19
|
|
20
20
|
#
|
21
|
-
# A HighLine object is a "high-level line oriented" shell over an input and an
|
21
|
+
# A HighLine object is a "high-level line oriented" shell over an input and an
|
22
22
|
# output stream. HighLine simplifies common console interaction, effectively
|
23
23
|
# replacing puts() and gets(). User code can simply specify the question to ask
|
24
24
|
# and any details about user interaction, then leave the rest of the work to
|
@@ -28,41 +28,41 @@ require "highline/style"
|
|
28
28
|
#
|
29
29
|
class HighLine
|
30
30
|
# The version of the installed library.
|
31
|
-
VERSION = "1.6.
|
32
|
-
|
31
|
+
VERSION = "1.6.16".freeze
|
32
|
+
|
33
33
|
# An internal HighLine error. User code does not need to trap this.
|
34
34
|
class QuestionError < StandardError
|
35
35
|
# do nothing, just creating a unique error type
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
# The setting used to disable color output.
|
39
39
|
@@use_color = true
|
40
|
-
|
40
|
+
|
41
41
|
# Pass +false+ to _setting_ to turn off HighLine's color escapes.
|
42
42
|
def self.use_color=( setting )
|
43
43
|
@@use_color = setting
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# Returns true if HighLine is currently using color escapes.
|
47
47
|
def self.use_color?
|
48
48
|
@@use_color
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
# For checking if the current version of HighLine supports RGB colors
|
52
52
|
# Usage: HighLine.supports_rgb_color? rescue false # rescue for compatibility with older versions
|
53
53
|
# Note: color usage also depends on HighLine.use_color being set
|
54
54
|
def self.supports_rgb_color?
|
55
55
|
true
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
# The setting used to disable EOF tracking.
|
59
59
|
@@track_eof = true
|
60
|
-
|
60
|
+
|
61
61
|
# Pass +false+ to _setting_ to turn off HighLine's EOF tracking.
|
62
62
|
def self.track_eof=( setting )
|
63
63
|
@@track_eof = setting
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
# Returns true if HighLine is currently tracking EOF for input.
|
67
67
|
def self.track_eof?
|
68
68
|
@@track_eof
|
@@ -71,7 +71,7 @@ class HighLine
|
|
71
71
|
# The setting used to control color schemes.
|
72
72
|
@@color_scheme = nil
|
73
73
|
|
74
|
-
# Pass ColorScheme to _setting_ to
|
74
|
+
# Pass ColorScheme to _setting_ to set a HighLine color scheme.
|
75
75
|
def self.color_scheme=( setting )
|
76
76
|
@@color_scheme = setting
|
77
77
|
end
|
@@ -87,13 +87,13 @@ class HighLine
|
|
87
87
|
end
|
88
88
|
|
89
89
|
#
|
90
|
-
# Embed in a String to clear all previous ANSI sequences. This *MUST* be
|
90
|
+
# Embed in a String to clear all previous ANSI sequences. This *MUST* be
|
91
91
|
# done before the program exits!
|
92
92
|
#
|
93
|
-
|
93
|
+
|
94
94
|
ERASE_LINE_STYLE = Style.new(:name=>:erase_line, :builtin=>true, :code=>"\e[K") # Erase the current line of terminal output
|
95
95
|
ERASE_CHAR_STYLE = Style.new(:name=>:erase_char, :builtin=>true, :code=>"\e[P") # Erase the character under the cursor.
|
96
|
-
CLEAR_STYLE = Style.new(:name=>:clear, :builtin=>true, :code=>"\e[0m") # Clear color settings
|
96
|
+
CLEAR_STYLE = Style.new(:name=>:clear, :builtin=>true, :code=>"\e[0m") # Clear color settings
|
97
97
|
RESET_STYLE = Style.new(:name=>:reset, :builtin=>true, :code=>"\e[0m") # Alias for CLEAR.
|
98
98
|
BOLD_STYLE = Style.new(:name=>:bold, :builtin=>true, :code=>"\e[1m") # Bold; Note: bold + a color works as you'd expect,
|
99
99
|
# for example bold black. Bold without a color displays
|
@@ -104,7 +104,7 @@ class HighLine
|
|
104
104
|
BLINK_STYLE = Style.new(:name=>:blink, :builtin=>true, :code=>"\e[5m") # Blink; support uncommon
|
105
105
|
REVERSE_STYLE = Style.new(:name=>:reverse, :builtin=>true, :code=>"\e[7m") # Reverse foreground and background
|
106
106
|
CONCEALED_STYLE = Style.new(:name=>:concealed, :builtin=>true, :code=>"\e[8m") # Concealed; support uncommon
|
107
|
-
|
107
|
+
|
108
108
|
STYLES = %w{CLEAR RESET BOLD DARK UNDERLINE UNDERSCORE BLINK REVERSE CONCEALED}
|
109
109
|
|
110
110
|
# These RGB colors are approximate; see http://en.wikipedia.org/wiki/ANSI_escape_code
|
@@ -116,15 +116,15 @@ class HighLine
|
|
116
116
|
MAGENTA_STYLE = Style.new(:name=>:magenta, :builtin=>true, :code=>"\e[35m", :rgb=>[128, 0,128])
|
117
117
|
CYAN_STYLE = Style.new(:name=>:cyan, :builtin=>true, :code=>"\e[36m", :rgb=>[ 0,128,128])
|
118
118
|
# On Mac OSX Terminal, white is actually gray
|
119
|
-
WHITE_STYLE = Style.new(:name=>:white, :builtin=>true, :code=>"\e[37m", :rgb=>[192,192,192])
|
119
|
+
WHITE_STYLE = Style.new(:name=>:white, :builtin=>true, :code=>"\e[37m", :rgb=>[192,192,192])
|
120
120
|
# Alias for WHITE, since WHITE is actually a light gray on Macs
|
121
121
|
GRAY_STYLE = Style.new(:name=>:gray, :builtin=>true, :code=>"\e[37m", :rgb=>[192,192,192])
|
122
|
-
# On Mac OSX Terminal, this is black foreground, or bright white background.
|
122
|
+
# On Mac OSX Terminal, this is black foreground, or bright white background.
|
123
123
|
# Also used as base for RGB colors, if available
|
124
|
-
NONE_STYLE = Style.new(:name=>:none, :builtin=>true, :code=>"\e[38m", :rgb=>[ 0, 0, 0])
|
125
|
-
|
124
|
+
NONE_STYLE = Style.new(:name=>:none, :builtin=>true, :code=>"\e[38m", :rgb=>[ 0, 0, 0])
|
125
|
+
|
126
126
|
BASIC_COLORS = %w{BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE GRAY NONE}
|
127
|
-
|
127
|
+
|
128
128
|
colors = BASIC_COLORS.dup
|
129
129
|
BASIC_COLORS.each do |color|
|
130
130
|
bright_color = "BRIGHT_#{color}"
|
@@ -132,18 +132,18 @@ class HighLine
|
|
132
132
|
const_set bright_color+'_STYLE', const_get(color + '_STYLE').bright
|
133
133
|
end
|
134
134
|
COLORS = colors
|
135
|
-
|
135
|
+
|
136
136
|
colors.each do |color|
|
137
137
|
const_set color, const_get("#{color}_STYLE").code
|
138
138
|
const_set "ON_#{color}_STYLE", const_get("#{color}_STYLE").on
|
139
139
|
const_set "ON_#{color}", const_get("ON_#{color}_STYLE").code
|
140
140
|
end
|
141
141
|
ON_NONE_STYLE.rgb = [255,255,255] # Override; white background
|
142
|
-
|
142
|
+
|
143
143
|
STYLES.each do |style|
|
144
144
|
const_set style, const_get("#{style}_STYLE").code
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
# For RGB colors:
|
148
148
|
def self.const_missing(name)
|
149
149
|
if name.to_s =~ /^(ON_)?(RGB_)([A-F0-9]{6})(_STYLE)?$/ # RGB color
|
@@ -174,14 +174,17 @@ class HighLine
|
|
174
174
|
# and _output_.
|
175
175
|
#
|
176
176
|
def initialize( input = $stdin, output = $stdout,
|
177
|
-
wrap_at = nil, page_at = nil )
|
178
|
-
super()
|
177
|
+
wrap_at = nil, page_at = nil, indent_size=3, indent_level=0 )
|
179
178
|
@input = input
|
180
179
|
@output = output
|
181
|
-
|
180
|
+
|
181
|
+
@multi_indent = true
|
182
|
+
@indent_size = indent_size
|
183
|
+
@indent_level = indent_level
|
184
|
+
|
182
185
|
self.wrap_at = wrap_at
|
183
186
|
self.page_at = page_at
|
184
|
-
|
187
|
+
|
185
188
|
@question = nil
|
186
189
|
@answer = nil
|
187
190
|
@menu = nil
|
@@ -190,22 +193,30 @@ class HighLine
|
|
190
193
|
@gather = nil
|
191
194
|
@answers = nil
|
192
195
|
@key = nil
|
196
|
+
|
197
|
+
initialize_system_extensions if respond_to?(:initialize_system_extensions)
|
193
198
|
end
|
194
|
-
|
199
|
+
|
195
200
|
include HighLine::SystemExtensions
|
196
|
-
|
201
|
+
|
197
202
|
# The current column setting for wrapping output.
|
198
203
|
attr_reader :wrap_at
|
199
204
|
# The current row setting for paging output.
|
200
205
|
attr_reader :page_at
|
201
|
-
|
206
|
+
# Indentation over multiple lines
|
207
|
+
attr_accessor :multi_indent
|
208
|
+
# The indentation size
|
209
|
+
attr_accessor :indent_size
|
210
|
+
# The indentation level
|
211
|
+
attr_accessor :indent_level
|
212
|
+
|
202
213
|
#
|
203
214
|
# A shortcut to HighLine.ask() a question that only accepts "yes" or "no"
|
204
215
|
# answers ("y" and "n" are allowed) and returns +true+ or +false+
|
205
216
|
# (+true+ for "yes"). If provided a +true+ value, _character_ will cause
|
206
217
|
# HighLine to fetch a single character response. A block can be provided
|
207
218
|
# to further configure the question as in HighLine.ask()
|
208
|
-
#
|
219
|
+
#
|
209
220
|
# Raises EOFError if input is exhausted.
|
210
221
|
#
|
211
222
|
def agree( yes_or_no_question, character = nil )
|
@@ -214,11 +225,11 @@ class HighLine
|
|
214
225
|
q.responses[:not_valid] = 'Please enter "yes" or "no".'
|
215
226
|
q.responses[:ask_on_error] = :question
|
216
227
|
q.character = character
|
217
|
-
|
228
|
+
|
218
229
|
yield q if block_given?
|
219
230
|
end
|
220
231
|
end
|
221
|
-
|
232
|
+
|
222
233
|
#
|
223
234
|
# This method is the primary interface for user input. Just provide a
|
224
235
|
# _question_ to ask the user, the _answer_type_ you want returned, and
|
@@ -226,20 +237,20 @@ class HighLine
|
|
226
237
|
# handled. See HighLine.say() for details on the format of _question_, and
|
227
238
|
# HighLine::Question for more information about _answer_type_ and what's
|
228
239
|
# valid in the code block.
|
229
|
-
#
|
240
|
+
#
|
230
241
|
# If <tt>@question</tt> is set before ask() is called, parameters are
|
231
242
|
# ignored and that object (must be a HighLine::Question) is used to drive
|
232
243
|
# the process instead.
|
233
|
-
#
|
244
|
+
#
|
234
245
|
# Raises EOFError if input is exhausted.
|
235
246
|
#
|
236
247
|
def ask( question, answer_type = String, &details ) # :yields: question
|
237
248
|
@question ||= Question.new(question, answer_type, &details)
|
238
|
-
|
249
|
+
|
239
250
|
return gather if @question.gather
|
240
|
-
|
241
|
-
# readline() needs to handle
|
242
|
-
# full line reading. Therefore if @question.echo is anything but true,
|
251
|
+
|
252
|
+
# readline() needs to handle its own output, but readline only supports
|
253
|
+
# full line reading. Therefore if @question.echo is anything but true,
|
243
254
|
# the prompt will not be issued. And we have to account for that now.
|
244
255
|
# Also, JRuby-1.7's ConsoleReader.readLine() needs to be passed the prompt
|
245
256
|
# to handle line editing properly.
|
@@ -250,14 +261,14 @@ class HighLine
|
|
250
261
|
explain_error(:not_valid)
|
251
262
|
raise QuestionError
|
252
263
|
end
|
253
|
-
|
264
|
+
|
254
265
|
@answer = @question.convert(@answer)
|
255
|
-
|
266
|
+
|
256
267
|
if @question.in_range?(@answer)
|
257
268
|
if @question.confirm
|
258
269
|
# need to add a layer of scope to ask a question inside a
|
259
270
|
# question, without destroying instance data
|
260
|
-
context_change = self.class.new(@input, @output, @wrap_at, @page_at)
|
271
|
+
context_change = self.class.new(@input, @output, @wrap_at, @page_at, @indent_size, @indent_level)
|
261
272
|
if @question.confirm == true
|
262
273
|
confirm_question = "Are you sure? "
|
263
274
|
else
|
@@ -271,7 +282,7 @@ class HighLine
|
|
271
282
|
raise QuestionError
|
272
283
|
end
|
273
284
|
end
|
274
|
-
|
285
|
+
|
275
286
|
@answer
|
276
287
|
else
|
277
288
|
explain_error(:not_in_range)
|
@@ -283,7 +294,7 @@ class HighLine
|
|
283
294
|
raise if error.is_a?(NoMethodError)
|
284
295
|
if error.message =~ /ambiguous/
|
285
296
|
# the assumption here is that OptionParser::Completion#complete
|
286
|
-
# (used for ambiguity resolution) throws exceptions containing
|
297
|
+
# (used for ambiguity resolution) throws exceptions containing
|
287
298
|
# the word 'ambiguous' whenever resolution fails
|
288
299
|
explain_error(:ambiguous_completion)
|
289
300
|
else
|
@@ -302,21 +313,23 @@ class HighLine
|
|
302
313
|
# This method is HighLine's menu handler. For simple usage, you can just
|
303
314
|
# pass all the menu items you wish to display. At that point, choose() will
|
304
315
|
# build and display a menu, walk the user through selection, and return
|
305
|
-
# their choice
|
316
|
+
# their choice among the provided items. You might use this in a case
|
306
317
|
# statement for quick and dirty menus.
|
307
|
-
#
|
318
|
+
#
|
308
319
|
# However, choose() is capable of much more. If provided, a block will be
|
309
320
|
# passed a HighLine::Menu object to configure. Using this method, you can
|
310
321
|
# customize all the details of menu handling from index display, to building
|
311
322
|
# a complete shell-like menuing system. See HighLine::Menu for all the
|
312
323
|
# methods it responds to.
|
313
|
-
#
|
324
|
+
#
|
314
325
|
# Raises EOFError if input is exhausted.
|
315
|
-
#
|
326
|
+
#
|
316
327
|
def choose( *items, &details )
|
317
328
|
@menu = @question = Menu.new(&details)
|
318
329
|
@menu.choices(*items) unless items.empty?
|
319
|
-
|
330
|
+
|
331
|
+
# Set auto-completion
|
332
|
+
@menu.completion = @menu.options
|
320
333
|
# Set _answer_type_ so we can double as the Question for ask().
|
321
334
|
@menu.answer_type = if @menu.shell
|
322
335
|
lambda do |command| # shell-style selection
|
@@ -335,11 +348,11 @@ class HighLine
|
|
335
348
|
else
|
336
349
|
@menu.options # normal menu selection, by index or name
|
337
350
|
end
|
338
|
-
|
351
|
+
|
339
352
|
# Provide hooks for ERb layouts.
|
340
353
|
@header = @menu.header
|
341
354
|
@prompt = @menu.prompt
|
342
|
-
|
355
|
+
|
343
356
|
if @menu.shell
|
344
357
|
selected = ask("Ignored", @menu.answer_type)
|
345
358
|
@menu.select(self, *selected)
|
@@ -353,11 +366,11 @@ class HighLine
|
|
353
366
|
# This method provides easy access to ANSI color sequences, without the user
|
354
367
|
# needing to remember to CLEAR at the end of each sequence. Just pass the
|
355
368
|
# _string_ to color, followed by a list of _colors_ you would like it to be
|
356
|
-
# affected by. The _colors_ can be HighLine class constants, or symbols
|
369
|
+
# affected by. The _colors_ can be HighLine class constants, or symbols
|
357
370
|
# (:blue for BLUE, for example). A CLEAR will automatically be embedded to
|
358
371
|
# the end of the returned String.
|
359
|
-
#
|
360
|
-
# This method returns the original _string_ unchanged if HighLine::use_color?
|
372
|
+
#
|
373
|
+
# This method returns the original _string_ unchanged if HighLine::use_color?
|
361
374
|
# is +false+.
|
362
375
|
#
|
363
376
|
def self.color( string, *colors )
|
@@ -369,28 +382,28 @@ class HighLine
|
|
369
382
|
def self.color_code(*colors)
|
370
383
|
Style(*colors).code
|
371
384
|
end
|
372
|
-
|
385
|
+
|
373
386
|
# Works as an instance method, same as the class method
|
374
387
|
def color_code(*colors)
|
375
388
|
self.class.color_code(*colors)
|
376
389
|
end
|
377
|
-
|
390
|
+
|
378
391
|
# Works as an instance method, same as the class method
|
379
392
|
def color(*args)
|
380
393
|
self.class.color(*args)
|
381
394
|
end
|
382
|
-
|
395
|
+
|
383
396
|
# Remove color codes from a string
|
384
397
|
def self.uncolor(string)
|
385
398
|
Style.uncolor(string)
|
386
399
|
end
|
387
|
-
|
400
|
+
|
388
401
|
# Works as an instance method, same as the class method
|
389
402
|
def uncolor(string)
|
390
403
|
self.class.uncolor(string)
|
391
404
|
end
|
392
|
-
|
393
|
-
#
|
405
|
+
|
406
|
+
#
|
394
407
|
# This method is a utility for quickly and easily laying out lists. It can
|
395
408
|
# be accessed within ERb replacements of any text that will be sent to the
|
396
409
|
# user.
|
@@ -416,13 +429,13 @@ class HighLine
|
|
416
429
|
# _option_ or a default of " or ". All
|
417
430
|
# other _items_ are separated by ", ".
|
418
431
|
# <tt>:rows</tt>:: The default mode. Each of the _items_ is
|
419
|
-
# placed on
|
432
|
+
# placed on its own line. The _option_
|
420
433
|
# parameter is ignored in this mode.
|
421
|
-
#
|
434
|
+
#
|
422
435
|
# Each member of the _items_ Array is passed through ERb and thus can contain
|
423
|
-
# their own expansions. Color escape expansions do not contribute to the
|
436
|
+
# their own expansions. Color escape expansions do not contribute to the
|
424
437
|
# final field width.
|
425
|
-
#
|
438
|
+
#
|
426
439
|
def list( items, mode = :rows, option = nil )
|
427
440
|
items = items.to_ary.map do |item|
|
428
441
|
if item.nil?
|
@@ -431,14 +444,14 @@ class HighLine
|
|
431
444
|
ERB.new(item, nil, "%").result(binding)
|
432
445
|
end
|
433
446
|
end
|
434
|
-
|
447
|
+
|
435
448
|
if items.empty?
|
436
449
|
""
|
437
450
|
else
|
438
451
|
case mode
|
439
452
|
when :inline
|
440
453
|
option = " or " if option.nil?
|
441
|
-
|
454
|
+
|
442
455
|
if items.size == 1
|
443
456
|
items.first
|
444
457
|
else
|
@@ -459,7 +472,7 @@ class HighLine
|
|
459
472
|
"%-#{pad}s" % item
|
460
473
|
end
|
461
474
|
row_count = (items.size / option.to_f).ceil
|
462
|
-
|
475
|
+
|
463
476
|
if mode == :columns_across
|
464
477
|
rows = Array.new(row_count) { Array.new }
|
465
478
|
items.each_with_index do |item, index|
|
@@ -472,7 +485,7 @@ class HighLine
|
|
472
485
|
items.each_with_index do |item, index|
|
473
486
|
columns[index / row_count] << item
|
474
487
|
end
|
475
|
-
|
488
|
+
|
476
489
|
list = ""
|
477
490
|
columns.first.size.times do |index|
|
478
491
|
list << columns.map { |column| column[index] }.
|
@@ -588,79 +601,113 @@ class HighLine
|
|
588
601
|
end
|
589
602
|
end
|
590
603
|
end
|
591
|
-
|
604
|
+
|
592
605
|
#
|
593
606
|
# The basic output method for HighLine objects. If the provided _statement_
|
594
607
|
# ends with a space or tab character, a newline will not be appended (output
|
595
608
|
# will be flush()ed). All other cases are passed straight to Kernel.puts().
|
596
609
|
#
|
597
610
|
# The _statement_ parameter is processed as an ERb template, supporting
|
598
|
-
# embedded Ruby code. The template is evaluated with a binding inside
|
611
|
+
# embedded Ruby code. The template is evaluated with a binding inside
|
599
612
|
# the HighLine instance, providing easy access to the ANSI color constants
|
600
613
|
# and the HighLine.color() method.
|
601
614
|
#
|
602
615
|
def say( statement )
|
603
616
|
statement = statement.to_str
|
604
617
|
return unless statement.length > 0
|
605
|
-
|
618
|
+
|
606
619
|
template = ERB.new(statement, nil, "%")
|
607
620
|
statement = template.result(binding)
|
608
|
-
|
621
|
+
|
609
622
|
statement = wrap(statement) unless @wrap_at.nil?
|
610
623
|
statement = page_print(statement) unless @page_at.nil?
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
624
|
+
|
625
|
+
statement = statement.gsub(/\n(?!$)/,"\n#{indentation}") if @multi_indent
|
626
|
+
|
627
|
+
# Don't add a newline if statement ends with whitespace, OR
|
628
|
+
# if statement ends with whitespace before a color escape code.
|
629
|
+
if /[ \t](\e\[\d+(;\d+)*m)?\Z/ =~ statement
|
630
|
+
@output.print(indentation+statement)
|
631
|
+
@output.flush
|
615
632
|
else
|
616
|
-
@output.puts(statement)
|
633
|
+
@output.puts(indentation+statement)
|
617
634
|
end
|
618
635
|
end
|
619
|
-
|
636
|
+
|
620
637
|
#
|
621
638
|
# Set to an integer value to cause HighLine to wrap output lines at the
|
622
639
|
# indicated character limit. When +nil+, the default, no wrapping occurs. If
|
623
|
-
# set to <tt>:auto</tt>, HighLine will attempt to
|
640
|
+
# set to <tt>:auto</tt>, HighLine will attempt to determine the columns
|
624
641
|
# available for the <tt>@output</tt> or use a sensible default.
|
625
642
|
#
|
626
643
|
def wrap_at=( setting )
|
627
644
|
@wrap_at = setting == :auto ? output_cols : setting
|
628
645
|
end
|
629
|
-
|
646
|
+
|
630
647
|
#
|
631
648
|
# Set to an integer value to cause HighLine to page output lines over the
|
632
649
|
# indicated line limit. When +nil+, the default, no paging occurs. If
|
633
|
-
# set to <tt>:auto</tt>, HighLine will attempt to
|
650
|
+
# set to <tt>:auto</tt>, HighLine will attempt to determine the rows available
|
634
651
|
# for the <tt>@output</tt> or use a sensible default.
|
635
652
|
#
|
636
653
|
def page_at=( setting )
|
637
654
|
@page_at = setting == :auto ? output_rows - 2 : setting
|
638
655
|
end
|
639
|
-
|
640
|
-
#
|
656
|
+
|
657
|
+
#
|
658
|
+
# Outputs indentation with current settings
|
659
|
+
#
|
660
|
+
def indentation
|
661
|
+
return ' '*@indent_size*@indent_level
|
662
|
+
end
|
663
|
+
|
664
|
+
#
|
665
|
+
# Executes block or outputs statement with indentation
|
666
|
+
#
|
667
|
+
def indent(increase=1, statement=nil, multiline=nil)
|
668
|
+
@indent_level += increase
|
669
|
+
multi = @multi_indent
|
670
|
+
@multi_indent = multiline unless multiline.nil?
|
671
|
+
if block_given?
|
672
|
+
yield self
|
673
|
+
else
|
674
|
+
say(statement)
|
675
|
+
end
|
676
|
+
@multi_indent = multi
|
677
|
+
@indent_level -= increase
|
678
|
+
end
|
679
|
+
|
680
|
+
#
|
681
|
+
# Outputs newline
|
682
|
+
#
|
683
|
+
def newline
|
684
|
+
@output.puts
|
685
|
+
end
|
686
|
+
|
687
|
+
#
|
641
688
|
# Returns the number of columns for the console, or a default it they cannot
|
642
689
|
# be determined.
|
643
|
-
#
|
690
|
+
#
|
644
691
|
def output_cols
|
645
692
|
return 80 unless @output.tty?
|
646
693
|
terminal_size.first
|
647
694
|
rescue
|
648
695
|
return 80
|
649
696
|
end
|
650
|
-
|
651
|
-
#
|
697
|
+
|
698
|
+
#
|
652
699
|
# Returns the number of rows for the console, or a default if they cannot be
|
653
700
|
# determined.
|
654
|
-
#
|
701
|
+
#
|
655
702
|
def output_rows
|
656
703
|
return 24 unless @output.tty?
|
657
704
|
terminal_size.last
|
658
705
|
rescue
|
659
706
|
return 24
|
660
707
|
end
|
661
|
-
|
708
|
+
|
662
709
|
private
|
663
|
-
|
710
|
+
|
664
711
|
#
|
665
712
|
# A helper method for sending the output stream and error and repeat
|
666
713
|
# of the question.
|
@@ -673,13 +720,13 @@ class HighLine
|
|
673
720
|
say(@question.responses[:ask_on_error])
|
674
721
|
end
|
675
722
|
end
|
676
|
-
|
723
|
+
|
677
724
|
#
|
678
|
-
# Collects an Array/Hash full of answers as described in
|
725
|
+
# Collects an Array/Hash full of answers as described in
|
679
726
|
# HighLine::Question.gather().
|
680
|
-
#
|
727
|
+
#
|
681
728
|
# Raises EOFError if input is exhausted.
|
682
|
-
#
|
729
|
+
#
|
683
730
|
def gather( )
|
684
731
|
original_question = @question
|
685
732
|
original_question_string = @question.question
|
@@ -748,10 +795,10 @@ class HighLine
|
|
748
795
|
#
|
749
796
|
# Read a line of input from the input stream and process whitespace as
|
750
797
|
# requested by the Question object.
|
751
|
-
#
|
798
|
+
#
|
752
799
|
# If Question's _readline_ property is set, that library will be used to
|
753
800
|
# fetch input. *WARNING*: This ignores the currently set input stream.
|
754
|
-
#
|
801
|
+
#
|
755
802
|
# Raises EOFError if input is exhausted.
|
756
803
|
#
|
757
804
|
def get_line( )
|
@@ -764,12 +811,12 @@ class HighLine
|
|
764
811
|
say(@question)
|
765
812
|
question = @output.string
|
766
813
|
@output = old_output
|
767
|
-
|
814
|
+
|
768
815
|
# prep auto-completion
|
769
816
|
Readline.completion_proc = lambda do |string|
|
770
817
|
@question.selection.grep(/\A#{Regexp.escape(string)}/)
|
771
818
|
end
|
772
|
-
|
819
|
+
|
773
820
|
# work-around ugly readline() warnings
|
774
821
|
old_verbose = $VERBOSE
|
775
822
|
$VERBOSE = nil
|
@@ -803,16 +850,14 @@ class HighLine
|
|
803
850
|
# Return a line or character of input, as requested for this question.
|
804
851
|
# Character input will be returned as a single character String,
|
805
852
|
# not an Integer.
|
806
|
-
#
|
853
|
+
#
|
807
854
|
# This question's _first_answer_ will be returned instead of input, if set.
|
808
|
-
#
|
855
|
+
#
|
809
856
|
# Raises EOFError if input is exhausted.
|
810
857
|
#
|
811
858
|
def get_response( )
|
812
859
|
return @question.first_answer if @question.first_answer?
|
813
860
|
|
814
|
-
stty = (CHARACTER_MODE == "stty")
|
815
|
-
|
816
861
|
if @question.character.nil?
|
817
862
|
if @question.echo == true and @question.limit.nil?
|
818
863
|
get_line
|
@@ -894,15 +939,15 @@ class HighLine
|
|
894
939
|
@question.change_case(response)
|
895
940
|
end
|
896
941
|
end
|
897
|
-
|
898
|
-
#
|
942
|
+
|
943
|
+
#
|
899
944
|
# Page print a series of at most _page_at_ lines for _output_. After each
|
900
945
|
# page is printed, HighLine will pause until the user presses enter/return
|
901
946
|
# then display the next page of data.
|
902
947
|
#
|
903
948
|
# Note that the final page of _output_ is *not* printed, but returned
|
904
949
|
# instead. This is to support any special handling for the final sequence.
|
905
|
-
#
|
950
|
+
#
|
906
951
|
def page_print( output )
|
907
952
|
lines = output.scan(/[^\n]*\n?/)
|
908
953
|
while lines.size > @page_at
|
@@ -913,18 +958,18 @@ class HighLine
|
|
913
958
|
end
|
914
959
|
return lines.join
|
915
960
|
end
|
916
|
-
|
917
|
-
#
|
961
|
+
|
962
|
+
#
|
918
963
|
# Ask user if they wish to continue paging output. Allows them to type "q" to
|
919
964
|
# cancel the paging process.
|
920
|
-
#
|
965
|
+
#
|
921
966
|
def continue_paging?
|
922
967
|
command = HighLine.new(@input, @output).ask(
|
923
968
|
"-- press enter/return to continue or q to stop -- "
|
924
969
|
) { |q| q.character = true }
|
925
970
|
command !~ /\A[qQ]\Z/ # Only continue paging if Q was not hit.
|
926
971
|
end
|
927
|
-
|
972
|
+
|
928
973
|
#
|
929
974
|
# Wrap a sequence of _lines_ at _wrap_at_ characters per line. Existing
|
930
975
|
# newlines will not be affected by this process, but additional newlines
|
@@ -950,15 +995,14 @@ class HighLine
|
|
950
995
|
end
|
951
996
|
return wrapped.join
|
952
997
|
end
|
953
|
-
|
954
|
-
#
|
998
|
+
|
999
|
+
#
|
955
1000
|
# Returns the length of the passed +string_with_escapes+, minus and color
|
956
1001
|
# sequence escapes.
|
957
|
-
#
|
1002
|
+
#
|
958
1003
|
def actual_length( string_with_escapes )
|
959
1004
|
string_with_escapes.to_s.gsub(/\e\[\d{1,2}m/, "").length
|
960
1005
|
end
|
961
1006
|
end
|
962
1007
|
|
963
1008
|
require "highline/string_extensions"
|
964
|
-
|