highline 1.5.2 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +17 -0
- data/INSTALL +14 -0
- data/lib/highline.rb +3 -5
- data/lib/highline/color_scheme.rb +0 -2
- data/lib/highline/compatibility.rb +2 -3
- data/lib/highline/menu.rb +5 -3
- data/lib/highline/question.rb +4 -5
- data/lib/highline/system_extensions.rb +42 -98
- metadata +17 -5
data/CHANGELOG
CHANGED
@@ -2,6 +2,23 @@
|
|
2
2
|
|
3
3
|
Below is a complete listing of changes for each revision of HighLine.
|
4
4
|
|
5
|
+
== 1.6.1
|
6
|
+
|
7
|
+
* Fixed raw_no_echo_mode so that it uses stty -icanon rather than cbreak
|
8
|
+
as cbreak does not appear to be the posixly correct argument. It fails
|
9
|
+
on Solaris if cbreak is used.
|
10
|
+
* Fixed an issue that kept Menu from showing the correct choices for
|
11
|
+
disambiguation.
|
12
|
+
* Removed a circular require that kept Ruby 1.9.2 from loading HighLine.
|
13
|
+
* Fixed a bug that caused infinite looping when wrapping text without spaces.
|
14
|
+
* Fixed it so that :auto paging accounts for the two lines it adds.
|
15
|
+
* On JRuby, improved error message about ffi-ncurses. Before 1.5.3,
|
16
|
+
HighLine was silently swallowing error messages when ffi-ncurses gem
|
17
|
+
was installed without ncurses present on the system.
|
18
|
+
* Reverted Aaron Simmons's patch to allow redirecting STDIN on Windows. This
|
19
|
+
is the only way we could find to restore HighLine's character reading to
|
20
|
+
working order.
|
21
|
+
|
5
22
|
== 1.5.2
|
6
23
|
|
7
24
|
* Added support for using the ffi-ncurses gem which is supported in JRuby.
|
data/INSTALL
CHANGED
@@ -28,6 +28,20 @@ the root project directory and enter:
|
|
28
28
|
|
29
29
|
$ sudo ruby setup.rb
|
30
30
|
|
31
|
+
== Installing HighLine on JRuby
|
32
|
+
|
33
|
+
If you are using HighLine on JRuby, many features will not work properly
|
34
|
+
without a working ncurses installation. First, ensure that you have
|
35
|
+
ncurses installed and then install the ffi-ncurses gem.
|
36
|
+
|
37
|
+
If ffi-ncurses fails to find your ncurses library, you may need to set the
|
38
|
+
RUBY_FFI_NCURSES envirionment variable, i.e:
|
39
|
+
|
40
|
+
RUBY_FFI_NCURSES_LIB=ncursesw ruby examples/hello.rb
|
41
|
+
|
42
|
+
For details, see the ffi-ncurses documentation at:
|
43
|
+
http://github.com/seanohalpin/ffi-ncurses
|
44
|
+
|
31
45
|
== Using termios
|
32
46
|
|
33
47
|
While not a requirement, HighLine will take advantage of the termios library if
|
data/lib/highline.rb
CHANGED
@@ -13,13 +13,11 @@ require "erb"
|
|
13
13
|
require "optparse"
|
14
14
|
require "stringio"
|
15
15
|
require "abbrev"
|
16
|
-
require "highline/compatibility"
|
17
16
|
require "highline/system_extensions"
|
18
17
|
require "highline/question"
|
19
18
|
require "highline/menu"
|
20
19
|
require "highline/color_scheme"
|
21
20
|
|
22
|
-
|
23
21
|
#
|
24
22
|
# A HighLine object is a "high-level line oriented" shell over an input and an
|
25
23
|
# output stream. HighLine simplifies common console interaction, effectively
|
@@ -31,7 +29,7 @@ require "highline/color_scheme"
|
|
31
29
|
#
|
32
30
|
class HighLine
|
33
31
|
# The version of the installed library.
|
34
|
-
VERSION = "1.
|
32
|
+
VERSION = "1.6.1".freeze
|
35
33
|
|
36
34
|
# An internal HighLine error. User code does not need to trap this.
|
37
35
|
class QuestionError < StandardError
|
@@ -478,7 +476,7 @@ class HighLine
|
|
478
476
|
# for the <tt>@output</tt> or use a sensible default.
|
479
477
|
#
|
480
478
|
def page_at=( setting )
|
481
|
-
@page_at = setting == :auto ? output_rows : setting
|
479
|
+
@page_at = setting == :auto ? output_rows - 2 : setting
|
482
480
|
end
|
483
481
|
|
484
482
|
#
|
@@ -740,7 +738,7 @@ class HighLine
|
|
740
738
|
replace.sub!(/\n[ \t]+/, "\n")
|
741
739
|
line.sub!(search, replace)
|
742
740
|
else
|
743
|
-
line[@wrap_at, 0] = "\n"
|
741
|
+
line[$~.begin(1) + @wrap_at, 0] = "\n"
|
744
742
|
end
|
745
743
|
end
|
746
744
|
wrapped << line
|
@@ -1,4 +1,4 @@
|
|
1
|
-
unless STDIN.respond_to?
|
1
|
+
unless STDIN.respond_to? :getbyte
|
2
2
|
class IO
|
3
3
|
alias_method :getbyte, :getc
|
4
4
|
end
|
@@ -8,8 +8,7 @@ unless STDIN.respond_to?(:getbyte)
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
unless "".respond_to?
|
12
|
-
|
11
|
+
unless "".respond_to? :each_line
|
13
12
|
# Not a perfect translation, but sufficient for our needs.
|
14
13
|
class String
|
15
14
|
alias_method :each_line, :each
|
data/lib/highline/menu.rb
CHANGED
@@ -53,7 +53,6 @@ class HighLine
|
|
53
53
|
yield self if block_given?
|
54
54
|
|
55
55
|
init_help if @shell and not @help.empty?
|
56
|
-
update_responses # rebuild responses based on our settings
|
57
56
|
end
|
58
57
|
|
59
58
|
#
|
@@ -140,6 +139,7 @@ class HighLine
|
|
140
139
|
@items << [name, action]
|
141
140
|
|
142
141
|
@help[name.to_s.downcase] = help unless help.nil?
|
142
|
+
update_responses # rebuild responses based on our settings
|
143
143
|
end
|
144
144
|
|
145
145
|
#
|
@@ -374,7 +374,8 @@ class HighLine
|
|
374
374
|
#
|
375
375
|
def update_responses( )
|
376
376
|
append_default unless default.nil?
|
377
|
-
@responses =
|
377
|
+
@responses = @responses.merge(
|
378
|
+
:ambiguous_completion =>
|
378
379
|
"Ambiguous choice. " +
|
379
380
|
"Please choose one of #{options.inspect}.",
|
380
381
|
:ask_on_error =>
|
@@ -389,7 +390,8 @@ class HighLine
|
|
389
390
|
"(#{expected_range}).",
|
390
391
|
:not_valid =>
|
391
392
|
"Your answer isn't valid (must match " +
|
392
|
-
"#{@validate.inspect})."
|
393
|
+
"#{@validate.inspect})."
|
394
|
+
)
|
393
395
|
end
|
394
396
|
end
|
395
397
|
end
|
data/lib/highline/question.rb
CHANGED
@@ -27,7 +27,7 @@ class HighLine
|
|
27
27
|
#
|
28
28
|
# Create an instance of HighLine::Question. Expects a _question_ to ask
|
29
29
|
# (can be <tt>""</tt>) and an _answer_type_ to convert the answer to.
|
30
|
-
# The _answer_type_ parameter must be a type
|
30
|
+
# The _answer_type_ parameter must be a type recognized by
|
31
31
|
# Question.convert(). If given, a block is yeilded the new Question
|
32
32
|
# object to allow custom initializaion.
|
33
33
|
#
|
@@ -68,10 +68,9 @@ class HighLine
|
|
68
68
|
attr_accessor :answer_type
|
69
69
|
#
|
70
70
|
# Can be set to +true+ to use HighLine's cross-platform character reader
|
71
|
-
# instead of fetching an entire line of input. (Note: HighLine's
|
72
|
-
#
|
73
|
-
#
|
74
|
-
# to use that method on the input stream.
|
71
|
+
# instead of fetching an entire line of input. (Note: HighLine's character
|
72
|
+
# reader *ONLY* supports STDIN on Windows and Unix.) Can also be set to
|
73
|
+
# <tt>:getc</tt> to use that method on the input stream.
|
75
74
|
#
|
76
75
|
# *WARNING*: The _echo_ and _overwrite_ attributes for a question are
|
77
76
|
# ignored when using the <tt>:getc</tt> method.
|
@@ -7,12 +7,14 @@
|
|
7
7
|
#
|
8
8
|
# This is Free Software. See LICENSE and COPYING for details.
|
9
9
|
|
10
|
+
require "highline/compatibility"
|
11
|
+
|
10
12
|
class HighLine
|
11
13
|
module SystemExtensions
|
12
14
|
module_function
|
13
15
|
|
14
16
|
JRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
15
|
-
|
17
|
+
|
16
18
|
#
|
17
19
|
# This section builds character reading and terminal size functions
|
18
20
|
# to suit the proper platform we're running on. Be warned: Here be
|
@@ -29,106 +31,44 @@ class HighLine
|
|
29
31
|
#
|
30
32
|
# Windows savvy getc().
|
31
33
|
#
|
34
|
+
# *WARNING*: This method ignores <tt>input</tt> and reads one
|
35
|
+
# character from +STDIN+!
|
32
36
|
#
|
33
37
|
def get_character( input = STDIN )
|
34
|
-
|
35
|
-
|
36
|
-
begin
|
37
|
-
SetConsoleEcho(@stdin_handle, false)
|
38
|
-
input.getbyte
|
39
|
-
ensure
|
40
|
-
SetConsoleEcho(@stdin_handle, true)
|
41
|
-
end
|
38
|
+
Win32API.new("crtdll", "_getch", [ ], "L").Call
|
42
39
|
end
|
43
40
|
|
44
41
|
# A Windows savvy method to fetch the console columns, and rows.
|
45
42
|
def terminal_size
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
m_GetStdHandle = Win32API.new( 'kernel32',
|
44
|
+
'GetStdHandle',
|
45
|
+
['L'],
|
46
|
+
'L' )
|
47
|
+
m_GetConsoleScreenBufferInfo = Win32API.new(
|
48
|
+
'kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L'
|
49
|
+
)
|
50
|
+
|
51
|
+
format = 'SSSSSssssSS'
|
52
|
+
buf = ([0] * format.size).pack(format)
|
53
|
+
stdout_handle = m_GetStdHandle.call(0xFFFFFFF5)
|
54
|
+
|
55
|
+
m_GetConsoleScreenBufferInfo.call(stdout_handle, buf)
|
56
|
+
bufx, bufy, curx, cury, wattr,
|
57
|
+
left, top, right, bottom, maxx, maxy = buf.unpack(format)
|
50
58
|
return right - left + 1, bottom - top + 1
|
51
59
|
end
|
52
|
-
|
53
|
-
# windows savvy console echo toggler
|
54
|
-
def SetConsoleEcho( console_handle, on )
|
55
|
-
mode = GetConsoleMode(console_handle)
|
56
|
-
|
57
|
-
# toggle the console echo bit
|
58
|
-
if on
|
59
|
-
mode |= ENABLE_ECHO_INPUT
|
60
|
-
else
|
61
|
-
mode &= ~ENABLE_ECHO_INPUT
|
62
|
-
end
|
63
|
-
|
64
|
-
ok = SetConsoleMode(console_handle, mode)
|
65
|
-
end
|
66
|
-
|
67
|
-
# win32 console APIs
|
68
|
-
|
69
|
-
STD_INPUT_HANDLE = -10
|
70
|
-
STD_OUTPUT_HANDLE = -11
|
71
|
-
STD_ERROR_HANDLE = -12
|
72
|
-
|
73
|
-
ENABLE_PROCESSED_INPUT = 0x0001
|
74
|
-
ENABLE_LINE_INPUT = 0x0002
|
75
|
-
ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
|
76
|
-
ENABLE_ECHO_INPUT = 0x0004
|
77
|
-
ENABLE_WINDOW_INPUT = 0x0008
|
78
|
-
ENABLE_MOUSE_INPUT = 0x0010
|
79
|
-
ENABLE_INSERT_MODE = 0x0020
|
80
|
-
ENABLE_QUICK_EDIT_MODE = 0x0040
|
81
|
-
|
82
|
-
@@apiGetStdHandle = nil
|
83
|
-
@@apiGetConsoleMode = nil
|
84
|
-
@@apiSetConsoleMode = nil
|
85
|
-
@@apiGetConsoleScreenBufferInfo = nil
|
86
|
-
|
87
|
-
def GetStdHandle( handle_type )
|
88
|
-
@@apiGetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle",
|
89
|
-
['L'], 'L' )
|
90
|
-
|
91
|
-
@@apiGetStdHandle.call( handle_type )
|
92
|
-
end
|
93
|
-
|
94
|
-
def GetConsoleMode( console_handle )
|
95
|
-
@@apiGetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode",
|
96
|
-
['L', 'P'], 'I' )
|
97
|
-
|
98
|
-
mode = ' ' * 4
|
99
|
-
@@apiGetConsoleMode.call(console_handle, mode)
|
100
|
-
mode.unpack('L')[0]
|
101
|
-
end
|
102
|
-
|
103
|
-
def SetConsoleMode( console_handle, mode )
|
104
|
-
@@apiSetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode",
|
105
|
-
['L', 'L'], 'I' )
|
106
|
-
|
107
|
-
@@apiSetConsoleMode.call(console_handle, mode) != 0
|
108
|
-
end
|
109
|
-
|
110
|
-
def GetConsoleScreenBufferInfo( console_handle )
|
111
|
-
@@apiGetConsoleScreenBufferInfo ||=
|
112
|
-
Win32API.new( "kernel32", "GetConsoleScreenBufferInfo",
|
113
|
-
['L', 'P'], 'L' )
|
114
|
-
|
115
|
-
format = 'SSSSSssssSS'
|
116
|
-
buf = ([0] * format.size).pack(format)
|
117
|
-
@@apiGetConsoleScreenBufferInfo.call(console_handle, buf)
|
118
|
-
buf.unpack(format)
|
119
|
-
end
|
120
|
-
|
121
60
|
rescue LoadError # If we're not on Windows try...
|
122
61
|
begin
|
62
|
+
raise LoadError
|
123
63
|
require "termios" # Unix, first choice termios.
|
124
64
|
|
125
65
|
CHARACTER_MODE = "termios" # For Debugging purposes only.
|
126
66
|
|
127
67
|
#
|
128
68
|
# Unix savvy getc(). (First choice.)
|
129
|
-
#
|
69
|
+
#
|
130
70
|
# *WARNING*: This method requires the "termios" library!
|
131
|
-
#
|
71
|
+
#
|
132
72
|
def get_character( input = STDIN )
|
133
73
|
old_settings = Termios.getattr(input)
|
134
74
|
|
@@ -144,10 +84,10 @@ class HighLine
|
|
144
84
|
end
|
145
85
|
end
|
146
86
|
rescue LoadError # If our first choice fails, try using ffi-ncurses.
|
147
|
-
begin
|
87
|
+
begin
|
148
88
|
require 'ffi-ncurses' # The ffi gem is builtin to JRUBY and because stty does not
|
149
89
|
# work correctly in JRuby manually installing the ffi-ncurses
|
150
|
-
# gem is the only way to get highline to operate correctly in
|
90
|
+
# gem is the only way to get highline to operate correctly in
|
151
91
|
# JRuby. The ncurses library is only present on unix platforms
|
152
92
|
# so this is not a solution for using highline in JRuby on
|
153
93
|
# windows.
|
@@ -156,29 +96,33 @@ class HighLine
|
|
156
96
|
|
157
97
|
#
|
158
98
|
# ncurses savvy getc(). (JRuby choice.)
|
159
|
-
#
|
99
|
+
#
|
160
100
|
def get_character( input = STDIN )
|
161
101
|
FFI::NCurses.initscr
|
162
102
|
FFI::NCurses.cbreak
|
163
103
|
begin
|
164
104
|
FFI::NCurses.curs_set 0
|
165
|
-
input.
|
105
|
+
input.getbyte
|
166
106
|
ensure
|
167
107
|
FFI::NCurses.endwin
|
168
108
|
end
|
169
109
|
end
|
170
110
|
|
171
|
-
rescue LoadError
|
111
|
+
rescue LoadError => e # If the ffi-ncurses choice fails, try using stty
|
172
112
|
if JRUBY
|
173
|
-
|
174
|
-
|
113
|
+
if e.message =~ /^no such file to load/
|
114
|
+
STDERR.puts "\n*** Using highline effectively in JRuby requires manually installing the ffi-ncurses gem.\n*** jruby -S gem install ffi-ncurses"
|
115
|
+
else
|
116
|
+
raise
|
117
|
+
end
|
118
|
+
end
|
175
119
|
CHARACTER_MODE = "stty" # For Debugging purposes only.
|
176
120
|
|
177
121
|
#
|
178
122
|
# Unix savvy getc(). (Second choice.)
|
179
|
-
#
|
123
|
+
#
|
180
124
|
# *WARNING*: This method requires the external "stty" program!
|
181
|
-
#
|
125
|
+
#
|
182
126
|
def get_character( input = STDIN )
|
183
127
|
raw_no_echo_mode
|
184
128
|
|
@@ -191,19 +135,19 @@ class HighLine
|
|
191
135
|
|
192
136
|
#
|
193
137
|
# Switched the input mode to raw and disables echo.
|
194
|
-
#
|
138
|
+
#
|
195
139
|
# *WARNING*: This method requires the external "stty" program!
|
196
|
-
#
|
140
|
+
#
|
197
141
|
def raw_no_echo_mode
|
198
142
|
@state = `stty -g`
|
199
|
-
system "stty raw -echo
|
143
|
+
system "stty raw -echo -icanon isig"
|
200
144
|
end
|
201
145
|
|
202
146
|
#
|
203
147
|
# Restores a previously saved input mode.
|
204
|
-
#
|
148
|
+
#
|
205
149
|
# *WARNING*: This method requires the external "stty" program!
|
206
|
-
#
|
150
|
+
#
|
207
151
|
def restore_mode
|
208
152
|
system "stty #{@state}"
|
209
153
|
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: highline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 13
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 6
|
9
|
+
- 1
|
10
|
+
version: 1.6.1
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- James Edward Gray II
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-07-15 00:00:00 -05:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -74,21 +80,27 @@ rdoc_options:
|
|
74
80
|
require_paths:
|
75
81
|
- lib
|
76
82
|
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
77
84
|
requirements:
|
78
85
|
- - ">="
|
79
86
|
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
80
90
|
version: "0"
|
81
|
-
version:
|
82
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
83
93
|
requirements:
|
84
94
|
- - ">="
|
85
95
|
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
86
99
|
version: "0"
|
87
|
-
version:
|
88
100
|
requirements: []
|
89
101
|
|
90
102
|
rubyforge_project: highline
|
91
|
-
rubygems_version: 1.3.
|
103
|
+
rubygems_version: 1.3.7
|
92
104
|
signing_key:
|
93
105
|
specification_version: 3
|
94
106
|
summary: HighLine is a high-level command-line IO library.
|