1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# coding: utf-8
#--
# terminal.rb
#
# Originally created by James Edward Gray II on 2006-06-14 as
# system_extensions.rb.
# Copyright 2006 Gray Productions. All rights reserved.
#
# This is Free Software. See LICENSE and COPYING for details.
require "highline/compatibility"
class HighLine
# Basic Terminal class which HighLine will direct
# input and output to.
# The specialized Terminals all decend from this HighLine::Terminal class
class Terminal
# Probe for and return a suitable Terminal instance
# @param input [IO] input stream
# @param output [IO] output stream
def self.get_terminal(input, output)
terminal = nil
# First of all, probe for io/console
begin
require "io/console"
require "highline/terminal/io_console"
terminal = HighLine::Terminal::IOConsole.new(input, output)
rescue LoadError
end
# Fall back to UnixStty
unless terminal
require 'highline/terminal/unix_stty'
terminal = HighLine::Terminal::UnixStty.new(input, output)
end
terminal.initialize_system_extensions
terminal
end
# @return [IO] input stream
attr_reader :input
# @return [IO] output stream
attr_reader :output
# Creates a terminal instance based on given input and output streams.
# @param input [IO] input stream
# @param output [IO] output stream
def initialize(input, output)
@input = input
@output = output
end
# An initialization callback.
# It is called by {.get_terminal}.
def initialize_system_extensions
end
# @return [Array<Integer, Integer>] two value terminal
# size like [columns, lines]
def terminal_size
[80, 24]
end
# Enter Raw No Echo mode.
def raw_no_echo_mode
end
# Yieds a block to be executed in Raw No Echo mode and
# then restore the terminal state.
def raw_no_echo_mode_exec
raw_no_echo_mode
yield
ensure
restore_mode
end
# Restore terminal to its default mode
def restore_mode
end
# Get one character from the terminal
# @return [String] one character
def get_character
end
# Get one line from the terminal and format accordling.
# Use readline if question has readline mode set.
# @param question [HighLine::Question]
# @param highline [HighLine]
# @param options [Hash]
def get_line(question, highline, options={})
raw_answer =
if question.readline
get_line_with_readline(question, highline, options={})
else
get_line_default(highline)
end
question.format_answer(raw_answer)
end
# Get one line using #readline_read
# @param (see #get_line)
def get_line_with_readline(question, highline, options={})
require "readline" # load only if needed
question_string = highline.render_statement(question)
raw_answer = readline_read(question_string, question)
if !raw_answer and highline.track_eof?
raise EOFError, "The input stream is exhausted."
end
raw_answer || ""
end
# Use readline to read one line
# @param prompt [String] Readline prompt
# @param question [HighLine::Question] question from where to get
# autocomplete candidate strings
def readline_read(prompt, question)
# prep auto-completion
unless question.selection.empty?
Readline.completion_proc = lambda do |str|
question.selection.grep(/\A#{Regexp.escape(str)}/)
end
end
# work-around ugly readline() warnings
old_verbose = $VERBOSE
$VERBOSE = nil
raw_answer = run_preserving_stty do
Readline.readline(prompt, true)
end
$VERBOSE = old_verbose
raw_answer
end
# Get one line from terminal using default #gets method.
# @param highline (see #get_line)
def get_line_default(highline)
raise EOFError, "The input stream is exhausted." if highline.track_eof? and
highline.input.eof?
highline.input.gets
end
# @!group Enviroment queries
# Running on JRuby?
def jruby?
defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
end
# Running on Rubinius?
def rubinius?
defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
end
# Running on Windows?
def windows?
defined?(RUBY_PLATFORM) && (RUBY_PLATFORM =~ /mswin|mingw|cygwin/)
end
# @!endgroup
# Returns the class name as String. Useful for debuggin.
# @return [String] class name. Ex: "HighLine::Terminal::IOConsole"
def character_mode
self.class.name
end
private
# Yield a block using stty shell commands to preserve the terminal state.
def run_preserving_stty
save_stty
yield
ensure
restore_stty
end
# Saves terminal state using shell stty command.
def save_stty
@stty_save = `stty -g`.chomp rescue nil
end
# Restores terminal state using shell stty command.
def restore_stty
system("stty", @stty_save) if @stty_save
end
end
end
|