highline 1.7.10 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|