terminal_rb 0.17.2 → 0.19.0
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 +4 -4
- data/README.md +3 -3
- data/bin/bbcode +1 -1
- data/lib/terminal/input/ansi.rb +47 -0
- data/lib/terminal/input/dumb.rb +42 -0
- data/lib/terminal/input.rb +88 -179
- data/lib/terminal/output/ansi.rb +114 -0
- data/lib/terminal/output/dumb.rb +76 -0
- data/lib/terminal/output.rb +238 -0
- data/lib/terminal/rspec/helper.rb +7 -3
- data/lib/terminal/text/char_width.rb +166 -31
- data/lib/terminal/text.rb +90 -66
- data/lib/terminal/version.rb +1 -1
- data/lib/terminal.rb +6 -288
- data/terminal_rb.gemspec +3 -1
- metadata +8 -3
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Terminal
|
|
4
|
+
class << self
|
|
5
|
+
# @!group Attributes
|
|
6
|
+
|
|
7
|
+
# @attribute [r] tui?
|
|
8
|
+
#
|
|
9
|
+
# Return `true` if the current terminal supports ANSI control codes for
|
|
10
|
+
# input _and_ output.
|
|
11
|
+
# In this case not only all output methods ({<<}, {print}, {puts}) will
|
|
12
|
+
# forward ANSI control codes to the terminal and translate BBCode
|
|
13
|
+
# (see {Ansi.bbcode}). But also the input methods {read_key_event} and
|
|
14
|
+
# {on_key_event} will support extended key codes, mouse and focus events.
|
|
15
|
+
#
|
|
16
|
+
# @see output_mode
|
|
17
|
+
# @see ansi?
|
|
18
|
+
#
|
|
19
|
+
# @return [true, false]
|
|
20
|
+
# whether ANSI control codes are supported for input and output
|
|
21
|
+
|
|
22
|
+
# @attribute [r] output_mode
|
|
23
|
+
#
|
|
24
|
+
# Supported output mode.
|
|
25
|
+
#
|
|
26
|
+
# @return [:ansi]
|
|
27
|
+
# All output methods ({<<}, {print}, {puts}) will forward ANSI control
|
|
28
|
+
# codes to the terminal and translate BBCode (see {Ansi.bbcode}).
|
|
29
|
+
# @return [:dumb]
|
|
30
|
+
# All output methods will not forward ANSI control codes and BBCodes will
|
|
31
|
+
# be removed.
|
|
32
|
+
# The {colors} method will just return 2 (two).
|
|
33
|
+
# @return [:error]
|
|
34
|
+
# When the output device signaled an error or was closed, nothing will
|
|
35
|
+
# be written to the terminal.
|
|
36
|
+
|
|
37
|
+
# @!endgroup
|
|
38
|
+
|
|
39
|
+
# @!group Output attributes
|
|
40
|
+
|
|
41
|
+
# @attribute [r] ansi?
|
|
42
|
+
#
|
|
43
|
+
# @see output_mode
|
|
44
|
+
# @see tui?
|
|
45
|
+
#
|
|
46
|
+
# @return [true, false]
|
|
47
|
+
# whether ANSI control codes are supported for output
|
|
48
|
+
|
|
49
|
+
# @attribute [r] colors
|
|
50
|
+
#
|
|
51
|
+
# Number of supported colors.
|
|
52
|
+
# The detection checks various conditions to find the correct value. The
|
|
53
|
+
# most common values are
|
|
54
|
+
#
|
|
55
|
+
# - `16_777_216` for 24-bit encoding ({true_color?} return true)
|
|
56
|
+
# - `256` for 8-Bit encoding
|
|
57
|
+
# - `52` for some Unix terminals with an extended color palette
|
|
58
|
+
# - `8` for 3-/4-bit encoding
|
|
59
|
+
# - `2` if ANSI is not supported in general ({ansi?} return false)
|
|
60
|
+
#
|
|
61
|
+
# @return [Integer]
|
|
62
|
+
# number of supported colors
|
|
63
|
+
|
|
64
|
+
# @attribute [r] true_color?
|
|
65
|
+
#
|
|
66
|
+
# @see colors
|
|
67
|
+
#
|
|
68
|
+
# @return [true, false]
|
|
69
|
+
# whether true colors are supported
|
|
70
|
+
def true_color? = (colors == 16_777_216)
|
|
71
|
+
|
|
72
|
+
# @attribute [r] columns
|
|
73
|
+
#
|
|
74
|
+
# Screen column count.
|
|
75
|
+
# See {size} for support and detection details.
|
|
76
|
+
#
|
|
77
|
+
# @return [Integer]
|
|
78
|
+
# number of available columns
|
|
79
|
+
def columns = size[1]
|
|
80
|
+
#
|
|
81
|
+
# @attribute [w] columns
|
|
82
|
+
|
|
83
|
+
# @attribute [r] rows
|
|
84
|
+
#
|
|
85
|
+
# Screen row count.
|
|
86
|
+
# See {size} for support and detection details.
|
|
87
|
+
#
|
|
88
|
+
# @return [Integer]
|
|
89
|
+
# number of available rows
|
|
90
|
+
def rows = size[0]
|
|
91
|
+
#
|
|
92
|
+
# @attribute [w] rows
|
|
93
|
+
|
|
94
|
+
# @attribute [r] pos
|
|
95
|
+
#
|
|
96
|
+
# Current cursor position.
|
|
97
|
+
# This is only available when ANSI is supported ({ansi?} return true).
|
|
98
|
+
#
|
|
99
|
+
# @return [[Integer, Integer]]
|
|
100
|
+
# cursor position as rows and columns
|
|
101
|
+
# @return [nil]
|
|
102
|
+
# for incompatible terminals
|
|
103
|
+
#
|
|
104
|
+
# @attribute [w] pos
|
|
105
|
+
|
|
106
|
+
# @attribute [r] size
|
|
107
|
+
#
|
|
108
|
+
# Screen size as a tuple of {rows} and {columns}.
|
|
109
|
+
#
|
|
110
|
+
# If the terminal does not support the report of it's dimension or ANSI
|
|
111
|
+
# is not supported in general then environment variables `COLUMNS` and
|
|
112
|
+
# `LINES` will be used.
|
|
113
|
+
# If this failed `[25, 80]` will be returned as default.
|
|
114
|
+
#
|
|
115
|
+
# Setting the terminal size is not widely supported.
|
|
116
|
+
#
|
|
117
|
+
# @see rows
|
|
118
|
+
# @see columns
|
|
119
|
+
#
|
|
120
|
+
# @return [[Integer, Integer]]
|
|
121
|
+
# available screen size as rows and columns
|
|
122
|
+
#
|
|
123
|
+
# @attribute [w] size
|
|
124
|
+
|
|
125
|
+
# @!endgroup
|
|
126
|
+
|
|
127
|
+
# @!group Output methods
|
|
128
|
+
|
|
129
|
+
# @!method <<(object)
|
|
130
|
+
#
|
|
131
|
+
# Writes the given object to the terminal.
|
|
132
|
+
# Interprets embedded BBCode (see {Ansi.bbcode}).
|
|
133
|
+
#
|
|
134
|
+
# @param object [#to_s] object to write
|
|
135
|
+
# @return [Terminal] itself
|
|
136
|
+
|
|
137
|
+
# @!method print(*objects, bbcode: true)
|
|
138
|
+
#
|
|
139
|
+
# Writes the given objects to the terminal.
|
|
140
|
+
# Optionally interprets embedded BBCode (see {Ansi.bbcode}).
|
|
141
|
+
#
|
|
142
|
+
# @param objects [Array<#to_s>] any number of objects to write
|
|
143
|
+
# @param bbcode [true|false] whether to interpret embedded BBCode
|
|
144
|
+
# @return [nil]
|
|
145
|
+
|
|
146
|
+
# @!method puts(*objects, bbcode: true)
|
|
147
|
+
#
|
|
148
|
+
# Writes the given objects to the terminal.
|
|
149
|
+
# Writes a newline after each object that does not already end with a
|
|
150
|
+
# newline sequence in it's String represenation.
|
|
151
|
+
# If called without any arguments, writes a newline only.
|
|
152
|
+
#
|
|
153
|
+
# Optionally interprets embedded BBCode (see {Ansi.bbcode}).
|
|
154
|
+
#
|
|
155
|
+
# @param objects [Array<#to_s>] any number of objects to write
|
|
156
|
+
# @param bbcode [true|false] whether to interpret embedded BBCode
|
|
157
|
+
# @return [nil]
|
|
158
|
+
|
|
159
|
+
# @!endgroup
|
|
160
|
+
|
|
161
|
+
# @!group Output helper methods
|
|
162
|
+
|
|
163
|
+
# @!method hide_cursor
|
|
164
|
+
#
|
|
165
|
+
# Hide the cursor.
|
|
166
|
+
# Will not send the control code if the cursor is already hidden.
|
|
167
|
+
#
|
|
168
|
+
# When you called {hide_cursor} n-times you need to call {show_cursor}
|
|
169
|
+
# n-times to show the cursor again.
|
|
170
|
+
#
|
|
171
|
+
# @return [Terminal] itself
|
|
172
|
+
|
|
173
|
+
# @!method show_cursor
|
|
174
|
+
#
|
|
175
|
+
# Show the cursor.
|
|
176
|
+
# Will not send the control code if the cursor is not hidden.
|
|
177
|
+
#
|
|
178
|
+
# When you called {hide_cursor} n-times you need to call {show_cursor}
|
|
179
|
+
# n-times to show the cursor again.
|
|
180
|
+
#
|
|
181
|
+
# @return [Terminal] itself
|
|
182
|
+
|
|
183
|
+
# @!method show_alt_screen
|
|
184
|
+
#
|
|
185
|
+
# Show the alternate screen.
|
|
186
|
+
# Will not send the control code if the alternate screen is already used.
|
|
187
|
+
#
|
|
188
|
+
# When you called {show_alt_screen} n-times you need to call
|
|
189
|
+
# {hide_alt_screen} n-times to show the default screen again.
|
|
190
|
+
#
|
|
191
|
+
# @return [Terminal] itself
|
|
192
|
+
|
|
193
|
+
# @!method hide_alt_screen
|
|
194
|
+
#
|
|
195
|
+
# Hide the alternate screen.
|
|
196
|
+
# Will not send the control code if the alternate screen is not used.
|
|
197
|
+
#
|
|
198
|
+
# When you called {show_alt_screen} n-times you need to call
|
|
199
|
+
# {hide_alt_screen} n-times to show the default screen again.
|
|
200
|
+
#
|
|
201
|
+
# @return [Terminal] itself
|
|
202
|
+
|
|
203
|
+
# @!endgroup
|
|
204
|
+
|
|
205
|
+
private
|
|
206
|
+
|
|
207
|
+
def __default_size
|
|
208
|
+
rows = ENV['LINES'].to_i
|
|
209
|
+
columns = ENV['COLUMNS'].to_i
|
|
210
|
+
[rows > 0 ? rows : 25, columns > 0 ? columns : 80]
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def __output_modes
|
|
214
|
+
return false if ENV.key?('NO_COLOR') || ENV['TERM'] == 'dumb'
|
|
215
|
+
[tty = STDOUT.tty?, ENV['ANSI'] == 'force' || tty]
|
|
216
|
+
rescue IOError, SystemCallError
|
|
217
|
+
nil
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
tty, ansi = __output_modes
|
|
222
|
+
if tty.nil?
|
|
223
|
+
require_relative 'output/dumb'
|
|
224
|
+
extend DumbOutput
|
|
225
|
+
__output_error(nil)
|
|
226
|
+
else
|
|
227
|
+
@out = STDOUT
|
|
228
|
+
@out.sync = true if defined?(@out.sync)
|
|
229
|
+
if ansi
|
|
230
|
+
require_relative 'output/ansi'
|
|
231
|
+
extend AnsiOutput
|
|
232
|
+
__init_tty if tty
|
|
233
|
+
else
|
|
234
|
+
require_relative 'output/dumb'
|
|
235
|
+
extend DumbOutput
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
@@ -53,9 +53,13 @@ RSpec.shared_context 'with Terminal.rb' do |ansi: true, application: :kitty, col
|
|
|
53
53
|
nil
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if ansi
|
|
57
|
+
allow(Terminal).to receive(:raw_write) do |object|
|
|
58
|
+
stdout.push(object = object.to_s)
|
|
59
|
+
object.bytesize
|
|
60
|
+
end
|
|
61
|
+
else
|
|
62
|
+
allow(Terminal).to receive(:raw_write).and_return(nil)
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
allow(Terminal).to receive(:read_key_event) do
|