highline 1.7.10 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +5 -0
- data/.rubocop.yml +84 -0
- data/.simplecov +5 -0
- data/.travis.yml +35 -9
- data/Changelog.md +214 -15
- data/Gemfile +16 -5
- data/README.md +202 -0
- data/Rakefile +8 -20
- data/appveyor.yml +37 -0
- data/examples/ansi_colors.rb +6 -11
- data/examples/asking_for_arrays.rb +6 -2
- data/examples/basic_usage.rb +31 -21
- data/examples/color_scheme.rb +11 -10
- data/examples/get_character.rb +8 -4
- data/examples/limit.rb +4 -0
- data/examples/menus.rb +16 -10
- data/examples/overwrite.rb +9 -5
- data/examples/page_and_wrap.rb +5 -4
- data/examples/password.rb +4 -0
- data/examples/repeat_entry.rb +10 -5
- data/examples/trapping_eof.rb +2 -1
- data/examples/using_readline.rb +2 -1
- data/highline.gemspec +25 -27
- data/lib/highline/builtin_styles.rb +129 -0
- data/lib/highline/color_scheme.rb +49 -32
- data/lib/highline/compatibility.rb +11 -4
- data/lib/highline/custom_errors.rb +57 -0
- data/lib/highline/import.rb +19 -12
- data/lib/highline/io_console_compatible.rb +37 -0
- data/lib/highline/list.rb +177 -0
- data/lib/highline/list_renderer.rb +261 -0
- data/lib/highline/menu/item.rb +32 -0
- data/lib/highline/menu.rb +306 -111
- data/lib/highline/paginator.rb +52 -0
- data/lib/highline/question/answer_converter.rb +103 -0
- data/lib/highline/question.rb +281 -131
- data/lib/highline/question_asker.rb +150 -0
- data/lib/highline/simulate.rb +24 -13
- data/lib/highline/statement.rb +88 -0
- data/lib/highline/string.rb +36 -0
- data/lib/highline/string_extensions.rb +83 -64
- data/lib/highline/style.rb +196 -63
- data/lib/highline/template_renderer.rb +62 -0
- data/lib/highline/terminal/io_console.rb +36 -0
- data/lib/highline/terminal/ncurses.rb +38 -0
- data/lib/highline/terminal/unix_stty.rb +51 -0
- data/lib/highline/terminal.rb +190 -0
- data/lib/highline/version.rb +3 -1
- data/lib/highline/wrapper.rb +53 -0
- data/lib/highline.rb +390 -788
- metadata +56 -35
- data/INSTALL +0 -59
- data/README.rdoc +0 -74
- data/lib/highline/system_extensions.rb +0 -254
- data/setup.rb +0 -1360
- data/test/string_methods.rb +0 -32
- data/test/tc_color_scheme.rb +0 -96
- data/test/tc_highline.rb +0 -1402
- data/test/tc_import.rb +0 -52
- data/test/tc_menu.rb +0 -439
- data/test/tc_simulator.rb +0 -33
- data/test/tc_string_extension.rb +0 -33
- data/test/tc_string_highline.rb +0 -38
- data/test/tc_style.rb +0 -578
@@ -0,0 +1,190 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# terminal.rb
|
5
|
+
#
|
6
|
+
# Originally created by James Edward Gray II on 2006-06-14 as
|
7
|
+
# system_extensions.rb.
|
8
|
+
# Copyright 2006 Gray Productions. All rights reserved.
|
9
|
+
#
|
10
|
+
# This is Free Software. See LICENSE and COPYING for details.
|
11
|
+
|
12
|
+
require "highline/compatibility"
|
13
|
+
|
14
|
+
class HighLine
|
15
|
+
# Basic Terminal class which HighLine will direct
|
16
|
+
# input and output to.
|
17
|
+
# The specialized Terminals all decend from this HighLine::Terminal class
|
18
|
+
class Terminal
|
19
|
+
# Probe for and return a suitable Terminal instance
|
20
|
+
# @param input [IO] input stream
|
21
|
+
# @param output [IO] output stream
|
22
|
+
def self.get_terminal(input, output)
|
23
|
+
# First of all, probe for io/console
|
24
|
+
begin
|
25
|
+
require "io/console"
|
26
|
+
require "highline/terminal/io_console"
|
27
|
+
terminal = HighLine::Terminal::IOConsole.new(input, output)
|
28
|
+
rescue LoadError
|
29
|
+
require "highline/terminal/unix_stty"
|
30
|
+
terminal = HighLine::Terminal::UnixStty.new(input, output)
|
31
|
+
end
|
32
|
+
|
33
|
+
terminal.initialize_system_extensions
|
34
|
+
terminal
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [IO] input stream
|
38
|
+
attr_reader :input
|
39
|
+
|
40
|
+
# @return [IO] output stream
|
41
|
+
attr_reader :output
|
42
|
+
|
43
|
+
# Creates a terminal instance based on given input and output streams.
|
44
|
+
# @param input [IO] input stream
|
45
|
+
# @param output [IO] output stream
|
46
|
+
def initialize(input, output)
|
47
|
+
@input = input
|
48
|
+
@output = output
|
49
|
+
end
|
50
|
+
|
51
|
+
# An initialization callback.
|
52
|
+
# It is called by {.get_terminal}.
|
53
|
+
def initialize_system_extensions; end
|
54
|
+
|
55
|
+
# @return [Array<Integer, Integer>] two value terminal
|
56
|
+
# size like [columns, lines]
|
57
|
+
def terminal_size
|
58
|
+
[80, 24]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Enter Raw No Echo mode.
|
62
|
+
def raw_no_echo_mode; end
|
63
|
+
|
64
|
+
# Yieds a block to be executed in Raw No Echo mode and
|
65
|
+
# then restore the terminal state.
|
66
|
+
def raw_no_echo_mode_exec
|
67
|
+
raw_no_echo_mode
|
68
|
+
yield
|
69
|
+
ensure
|
70
|
+
restore_mode
|
71
|
+
end
|
72
|
+
|
73
|
+
# Restore terminal to its default mode
|
74
|
+
def restore_mode; end
|
75
|
+
|
76
|
+
# Get one character from the terminal
|
77
|
+
# @return [String] one character
|
78
|
+
def get_character; end # rubocop:disable Naming/AccessorMethodName
|
79
|
+
|
80
|
+
# Get one line from the terminal and format accordling.
|
81
|
+
# Use readline if question has readline mode set.
|
82
|
+
# @param question [HighLine::Question]
|
83
|
+
# @param highline [HighLine]
|
84
|
+
def get_line(question, highline)
|
85
|
+
raw_answer =
|
86
|
+
if question.readline
|
87
|
+
get_line_with_readline(question, highline)
|
88
|
+
else
|
89
|
+
get_line_default(highline)
|
90
|
+
end
|
91
|
+
|
92
|
+
question.format_answer(raw_answer)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get one line using #readline_read
|
96
|
+
# @param (see #get_line)
|
97
|
+
def get_line_with_readline(question, highline)
|
98
|
+
require "readline" # load only if needed
|
99
|
+
|
100
|
+
raw_answer = readline_read(question)
|
101
|
+
|
102
|
+
if !raw_answer && highline.track_eof?
|
103
|
+
raise EOFError, "The input stream is exhausted."
|
104
|
+
end
|
105
|
+
|
106
|
+
raw_answer || ""
|
107
|
+
end
|
108
|
+
|
109
|
+
# Use readline to read one line
|
110
|
+
# @param question [HighLine::Question] question from where to get
|
111
|
+
# autocomplete candidate strings
|
112
|
+
def readline_read(question)
|
113
|
+
# prep auto-completion
|
114
|
+
unless question.selection.empty?
|
115
|
+
Readline.completion_proc = lambda do |str|
|
116
|
+
question.selection.grep(/\A#{Regexp.escape(str)}/)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# work-around ugly readline() warnings
|
121
|
+
old_verbose = $VERBOSE
|
122
|
+
$VERBOSE = nil
|
123
|
+
|
124
|
+
raw_answer = run_preserving_stty do
|
125
|
+
Readline.readline("", true)
|
126
|
+
end
|
127
|
+
|
128
|
+
$VERBOSE = old_verbose
|
129
|
+
|
130
|
+
raw_answer
|
131
|
+
end
|
132
|
+
|
133
|
+
# Get one line from terminal using default #gets method.
|
134
|
+
# @param highline (see #get_line)
|
135
|
+
def get_line_default(highline)
|
136
|
+
raise EOFError, "The input stream is exhausted." if highline.track_eof? &&
|
137
|
+
highline.input.eof?
|
138
|
+
highline.input.gets
|
139
|
+
end
|
140
|
+
|
141
|
+
# @!group Enviroment queries
|
142
|
+
|
143
|
+
# Running on JRuby?
|
144
|
+
def jruby?
|
145
|
+
defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
146
|
+
end
|
147
|
+
|
148
|
+
# Running on Rubinius?
|
149
|
+
def rubinius?
|
150
|
+
defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
|
151
|
+
end
|
152
|
+
|
153
|
+
# Running on Windows?
|
154
|
+
def windows?
|
155
|
+
defined?(RUBY_PLATFORM) && (RUBY_PLATFORM =~ /mswin|mingw|cygwin/)
|
156
|
+
end
|
157
|
+
|
158
|
+
# @!endgroup
|
159
|
+
|
160
|
+
# Returns the class name as String. Useful for debuggin.
|
161
|
+
# @return [String] class name. Ex: "HighLine::Terminal::IOConsole"
|
162
|
+
def character_mode
|
163
|
+
self.class.name
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
# Yield a block using stty shell commands to preserve the terminal state.
|
169
|
+
def run_preserving_stty
|
170
|
+
save_stty
|
171
|
+
yield
|
172
|
+
ensure
|
173
|
+
restore_stty
|
174
|
+
end
|
175
|
+
|
176
|
+
# Saves terminal state using shell stty command.
|
177
|
+
def save_stty
|
178
|
+
@stty_save = begin
|
179
|
+
`stty -g`.chomp
|
180
|
+
rescue StandardError
|
181
|
+
nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Restores terminal state using shell stty command.
|
186
|
+
def restore_stty
|
187
|
+
system("stty", @stty_save) if @stty_save
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
data/lib/highline/version.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
|
5
|
+
class HighLine
|
6
|
+
# A simple Wrapper module that is aware of ANSI escape codes.
|
7
|
+
# It compensates for the ANSI escape codes so it works on the
|
8
|
+
# actual (visual) line length.
|
9
|
+
module Wrapper
|
10
|
+
#
|
11
|
+
# Wrap a sequence of _lines_ at _wrap_at_ characters per line. Existing
|
12
|
+
# newlines will not be affected by this process, but additional newlines
|
13
|
+
# may be added.
|
14
|
+
#
|
15
|
+
# @param text [String] text to be wrapped
|
16
|
+
# @param wrap_at [#to_i] column count to wrap the text into
|
17
|
+
def self.wrap(text, wrap_at)
|
18
|
+
return text unless wrap_at
|
19
|
+
wrap_at = Integer(wrap_at)
|
20
|
+
|
21
|
+
wrapped = []
|
22
|
+
text.each_line do |line|
|
23
|
+
# take into account color escape sequences when wrapping
|
24
|
+
wrap_at += (line.length - actual_length(line))
|
25
|
+
while line =~ /([^\n]{#{wrap_at + 1},})/
|
26
|
+
search = Regexp.last_match(1).dup
|
27
|
+
replace = Regexp.last_match(1).dup
|
28
|
+
index = replace.rindex(" ", wrap_at)
|
29
|
+
if index
|
30
|
+
replace[index, 1] = "\n"
|
31
|
+
replace.sub!(/\n[ \t]+/, "\n")
|
32
|
+
line.sub!(search, replace)
|
33
|
+
else
|
34
|
+
line[$LAST_MATCH_INFO.begin(1) + wrap_at, 0] = "\n"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
wrapped << line
|
38
|
+
end
|
39
|
+
wrapped.join
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Returns the length of the passed +string_with_escapes+, minus and color
|
44
|
+
# sequence escapes.
|
45
|
+
#
|
46
|
+
# @param string_with_escapes [String] any ANSI colored String
|
47
|
+
# @return [Integer] length based on the visual size of the String
|
48
|
+
# (without the escape codes)
|
49
|
+
def self.actual_length(string_with_escapes)
|
50
|
+
string_with_escapes.to_s.gsub(/\e\[\d{1,2}m/, "").length
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|