terminal_rb 0.19.0 → 1.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 +4 -4
- data/README.md +5 -4
- data/bin/bbcode +25 -21
- data/examples/24bit-colors.rb +11 -12
- data/examples/3bit-colors.rb +9 -9
- data/examples/8bit-colors.rb +18 -18
- data/examples/attributes.rb +24 -10
- data/examples/bbcode.rb +23 -19
- data/examples/info.rb +7 -7
- data/examples/key-codes.rb +4 -7
- data/examples/screen_viewer.rb +82 -0
- data/examples/text.rb +12 -28
- data/lib/terminal/ansi/named_colors.rb +1 -0
- data/lib/terminal/ansi/screen_viewer.rb +224 -0
- data/lib/terminal/ansi.rb +502 -484
- data/lib/terminal/detect.rb +1 -0
- data/lib/terminal/input/ansi.rb +18 -16
- data/lib/terminal/input/dumb.rb +5 -8
- data/lib/terminal/input/key_event.rb +131 -75
- data/lib/terminal/input.rb +55 -44
- data/lib/terminal/output/ansi.rb +44 -6
- data/lib/terminal/output/dumb.rb +33 -0
- data/lib/terminal/output.rb +144 -122
- data/lib/terminal/rspec/helper.rb +30 -1
- data/lib/terminal/shell.rb +10 -6
- data/lib/terminal/text/char_width.rb +178 -176
- data/lib/terminal/text/formatter.rb +619 -0
- data/lib/terminal/text.rb +167 -423
- data/lib/terminal/version.rb +1 -1
- data/lib/terminal.rb +79 -75
- metadata +9 -7
- data/terminal_rb.gemspec +0 -36
data/lib/terminal/output/dumb.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Terminal
|
|
4
|
+
# @private
|
|
4
5
|
module DumbOutput
|
|
5
6
|
def output_mode = :dumb
|
|
6
7
|
def ansi? = false
|
|
@@ -53,6 +54,38 @@ module Terminal
|
|
|
53
54
|
__output_error(nil)
|
|
54
55
|
end
|
|
55
56
|
|
|
57
|
+
def fputs(
|
|
58
|
+
*objects,
|
|
59
|
+
bbcode: true,
|
|
60
|
+
spaces: true,
|
|
61
|
+
eol: true,
|
|
62
|
+
align: nil,
|
|
63
|
+
width: columns,
|
|
64
|
+
height: nil,
|
|
65
|
+
padding: nil,
|
|
66
|
+
prefix: nil,
|
|
67
|
+
suffix: nil
|
|
68
|
+
)
|
|
69
|
+
objects.flatten!
|
|
70
|
+
@out.puts(
|
|
71
|
+
Text::Formatter.format(
|
|
72
|
+
*objects,
|
|
73
|
+
ansi: false,
|
|
74
|
+
bbcode:,
|
|
75
|
+
spaces:,
|
|
76
|
+
eol: eol,
|
|
77
|
+
align:,
|
|
78
|
+
width:,
|
|
79
|
+
height:,
|
|
80
|
+
padding:,
|
|
81
|
+
prefix:,
|
|
82
|
+
suffix:
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
rescue IOError, SystemCallError
|
|
86
|
+
__output_error(nil)
|
|
87
|
+
end
|
|
88
|
+
|
|
56
89
|
private
|
|
57
90
|
|
|
58
91
|
def __output_error(ret)
|
data/lib/terminal/output.rb
CHANGED
|
@@ -2,205 +2,227 @@
|
|
|
2
2
|
|
|
3
3
|
module Terminal
|
|
4
4
|
class << self
|
|
5
|
-
# @!group Attributes
|
|
6
|
-
|
|
7
|
-
# @attribute [r] tui?
|
|
8
5
|
#
|
|
9
|
-
#
|
|
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?
|
|
6
|
+
# @!group Attributes
|
|
18
7
|
#
|
|
19
|
-
# @return [true, false]
|
|
20
|
-
# whether ANSI control codes are supported for input and output
|
|
21
8
|
|
|
22
9
|
# @attribute [r] output_mode
|
|
23
10
|
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
11
|
+
# Current output mode.
|
|
12
|
+
#
|
|
13
|
+
# @return [:ansi]
|
|
14
|
+
# All output methods ({<<}, {print}, {puts}) will forward ANSI control
|
|
15
|
+
# codes to the terminal and translate BBCode (see {Ansi.bbcode}).
|
|
16
|
+
# @return [:dumb]
|
|
17
|
+
# All output methods will not forward ANSI control codes and BBCodes will
|
|
18
|
+
# be removed.
|
|
19
|
+
# The {colors} method will just return 2 (two).
|
|
20
|
+
# @return [:error]
|
|
21
|
+
# When the output device signaled an error or was closed, nothing will
|
|
22
|
+
# be written to the terminal.
|
|
36
23
|
|
|
24
|
+
#
|
|
37
25
|
# @!endgroup
|
|
26
|
+
#
|
|
27
|
+
# @!group Output Attributes
|
|
28
|
+
#
|
|
38
29
|
|
|
39
|
-
# @!
|
|
30
|
+
# @!attribute [r] tui?
|
|
31
|
+
#
|
|
32
|
+
# Whether the terminal supports full TUI interaction (ANSI output
|
|
33
|
+
# with CSI-u or legacy keyboard input).
|
|
34
|
+
#
|
|
35
|
+
# @see .input_mode
|
|
36
|
+
#
|
|
37
|
+
# @return [true, false]
|
|
40
38
|
|
|
41
|
-
#
|
|
39
|
+
# @!attribute [r] ansi?
|
|
42
40
|
#
|
|
43
|
-
#
|
|
44
|
-
# @see tui?
|
|
41
|
+
# Whether ANSI escape codes are supported.
|
|
45
42
|
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
43
|
+
# @see output_mode
|
|
44
|
+
# @see tui?
|
|
45
|
+
#
|
|
46
|
+
# @return [true, false]
|
|
48
47
|
|
|
49
48
|
# @attribute [r] colors
|
|
50
49
|
#
|
|
51
|
-
#
|
|
52
|
-
# The detection checks various conditions to find the correct value. The
|
|
53
|
-
# most common values are
|
|
50
|
+
# Number of colors supported by the terminal.
|
|
54
51
|
#
|
|
55
|
-
#
|
|
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)
|
|
52
|
+
# @see .true_color?
|
|
60
53
|
#
|
|
61
|
-
#
|
|
62
|
-
# number of supported colors
|
|
54
|
+
# @return [Integer] one of 2, 8, 16, 256, or 16777216
|
|
63
55
|
|
|
64
|
-
#
|
|
56
|
+
# Whether the terminal supports true color (24-bit, 16.7 million
|
|
57
|
+
# colors).
|
|
65
58
|
#
|
|
66
|
-
# @see colors
|
|
59
|
+
# @see .colors
|
|
67
60
|
#
|
|
61
|
+
# @attribute [r] true_color?
|
|
68
62
|
# @return [true, false]
|
|
69
|
-
# whether true colors are supported
|
|
70
63
|
def true_color? = (colors == 16_777_216)
|
|
71
64
|
|
|
72
|
-
# @attribute [
|
|
65
|
+
# @attribute [rw] size
|
|
73
66
|
#
|
|
74
|
-
#
|
|
75
|
-
# See {size} for support and detection details.
|
|
67
|
+
# The terminal size.
|
|
76
68
|
#
|
|
69
|
+
# @return [Array<Integer, Integer>] +[rows, columns]+
|
|
70
|
+
|
|
71
|
+
# Terminal width in columns.
|
|
72
|
+
#
|
|
73
|
+
# @see .size
|
|
74
|
+
#
|
|
75
|
+
# @attribute [rw] columns
|
|
77
76
|
# @return [Integer]
|
|
78
|
-
# number of available columns
|
|
79
77
|
def columns = size[1]
|
|
80
|
-
#
|
|
81
|
-
# @attribute [w] columns
|
|
82
78
|
|
|
83
|
-
#
|
|
79
|
+
# Terminal height in rows.
|
|
84
80
|
#
|
|
85
|
-
#
|
|
86
|
-
# See {size} for support and detection details.
|
|
81
|
+
# @see .size
|
|
87
82
|
#
|
|
83
|
+
# @attribute [rw] rows
|
|
88
84
|
# @return [Integer]
|
|
89
|
-
# number of available rows
|
|
90
85
|
def rows = size[0]
|
|
91
|
-
#
|
|
92
|
-
# @attribute [w] rows
|
|
93
86
|
|
|
94
|
-
# @attribute [
|
|
95
|
-
#
|
|
96
|
-
# Current cursor position.
|
|
97
|
-
# This is only available when ANSI is supported ({ansi?} return true).
|
|
87
|
+
# @attribute [rw] pos
|
|
98
88
|
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# @return [nil]
|
|
102
|
-
# for incompatible terminals
|
|
89
|
+
# Current cursor position.
|
|
90
|
+
# This is only available when ANSI is supported ({ansi?} return true).
|
|
103
91
|
#
|
|
104
|
-
#
|
|
92
|
+
# @return [Array<Integer, Integer>, nil] +[row, column]+ or +nil+ if
|
|
93
|
+
# unavailable
|
|
105
94
|
|
|
106
|
-
#
|
|
95
|
+
# Whether the terminal has been resized since the last size query.
|
|
107
96
|
#
|
|
108
|
-
#
|
|
97
|
+
# @see .on_resize
|
|
109
98
|
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
# Setting the terminal size is not widely supported.
|
|
99
|
+
# @attribute [r] resized?
|
|
100
|
+
# @return [true, false]
|
|
101
|
+
def resized? = @size.nil?
|
|
102
|
+
|
|
116
103
|
#
|
|
117
|
-
#
|
|
118
|
-
# @see columns
|
|
104
|
+
# @!endgroup
|
|
119
105
|
#
|
|
120
|
-
#
|
|
121
|
-
# available screen size as rows and columns
|
|
106
|
+
# @!group Output Methods
|
|
122
107
|
#
|
|
123
|
-
# @attribute [w] size
|
|
124
|
-
|
|
125
|
-
# @!endgroup
|
|
126
|
-
|
|
127
|
-
# @!group Output methods
|
|
128
108
|
|
|
129
109
|
# @!method <<(object)
|
|
130
110
|
#
|
|
131
|
-
#
|
|
132
|
-
# Interprets embedded BBCode (see {Ansi.bbcode}).
|
|
111
|
+
# Output an object with BBCode markup processing.
|
|
133
112
|
#
|
|
134
|
-
# @
|
|
135
|
-
#
|
|
113
|
+
# @example
|
|
114
|
+
# Terminal << '[bold]Hello[/bold] World'
|
|
115
|
+
#
|
|
116
|
+
# @param object [#to_s, nil] the object to output; +nil+ is ignored
|
|
117
|
+
# @return [self]
|
|
136
118
|
|
|
137
119
|
# @!method print(*objects, bbcode: true)
|
|
138
120
|
#
|
|
139
|
-
#
|
|
140
|
-
# Optionally interprets embedded BBCode (see {Ansi.bbcode}).
|
|
121
|
+
# Print objects to the terminal.
|
|
141
122
|
#
|
|
142
|
-
# @
|
|
143
|
-
#
|
|
123
|
+
# @example
|
|
124
|
+
# Terminal.print('[green]OK[/]')
|
|
125
|
+
# Terminal.print('press the [red] button', bbcode: false)
|
|
126
|
+
#
|
|
127
|
+
# @param objects [Array<#to_s>] objects to print
|
|
128
|
+
# @param bbcode (see Terminal::Text::Formatter#initialize)
|
|
144
129
|
# @return [nil]
|
|
145
130
|
|
|
146
131
|
# @!method puts(*objects, bbcode: true)
|
|
147
132
|
#
|
|
148
|
-
#
|
|
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.
|
|
133
|
+
# Print objects to the terminal followed by newlines.
|
|
152
134
|
#
|
|
153
|
-
#
|
|
135
|
+
# @example
|
|
136
|
+
# Terminal.puts('[bold]Hello[/bold]', '[italic]World[/italic]')
|
|
154
137
|
#
|
|
155
|
-
# @param objects [Array<#to_s>]
|
|
156
|
-
# @param bbcode
|
|
138
|
+
# @param objects [Array<#to_s>] objects to print
|
|
139
|
+
# @param bbcode (see Terminal::Text::Formatter#initialize)
|
|
157
140
|
# @return [nil]
|
|
158
141
|
|
|
159
|
-
# @!
|
|
142
|
+
# @!method fputs(*objects, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil)
|
|
143
|
+
#
|
|
144
|
+
# Formatted output with word-wrapping, alignment, and padding.
|
|
145
|
+
#
|
|
146
|
+
# @see Terminal::Text::Formatter.format
|
|
147
|
+
#
|
|
148
|
+
# @example
|
|
149
|
+
# Terminal.fputs('Hello World', align: :center, width: 40)
|
|
150
|
+
#
|
|
151
|
+
# @param objects [Array<#to_s>] text to process
|
|
152
|
+
# @param bbcode (see Terminal::Text::Formatter#initialize)
|
|
153
|
+
# @param spaces (see Terminal::Text::Formatter#initialize)
|
|
154
|
+
# @param eol (see Terminal::Text::Formatter#initialize)
|
|
155
|
+
# @param (see Terminal::Text::Formatter#format)
|
|
156
|
+
# @return [nil]
|
|
157
|
+
# @raise (see Terminal::Text::Formatter#format)
|
|
160
158
|
|
|
161
|
-
# @!
|
|
159
|
+
# @!method raw_write(object)
|
|
160
|
+
#
|
|
161
|
+
# Write raw bytes directly to the terminal without BBCode or ANSI
|
|
162
|
+
# processing.
|
|
163
|
+
#
|
|
164
|
+
# @param object [#to_s] object to write
|
|
165
|
+
# @return [Integer, nil] bytes written, or +nil+ on error
|
|
162
166
|
|
|
163
167
|
# @!method hide_cursor
|
|
164
168
|
#
|
|
165
169
|
# Hide the cursor.
|
|
166
|
-
# Will not send the control code if the cursor is already hidden.
|
|
167
170
|
#
|
|
168
|
-
#
|
|
169
|
-
# n-times to show the cursor again.
|
|
171
|
+
# @note Reference-counted; safe for nested use.
|
|
170
172
|
#
|
|
171
|
-
#
|
|
173
|
+
# Calls are reference-counted — nested calls are safe; the cursor
|
|
174
|
+
# is only hidden on the first call and shown when the last matching
|
|
175
|
+
# {show_cursor} is called.
|
|
176
|
+
#
|
|
177
|
+
# @see .show_cursor
|
|
178
|
+
#
|
|
179
|
+
# @return [self]
|
|
172
180
|
|
|
173
181
|
# @!method show_cursor
|
|
174
|
-
#
|
|
175
182
|
# Show the cursor.
|
|
176
|
-
# Will not send the control code if the cursor is not hidden.
|
|
177
183
|
#
|
|
178
|
-
# When you called {hide_cursor} n-times you need to call {show_cursor}
|
|
179
|
-
# n-times to show the cursor again.
|
|
180
184
|
#
|
|
181
|
-
# @
|
|
185
|
+
# @note Reference-counted; safe for nested use.
|
|
186
|
+
#
|
|
187
|
+
# @see .hide_cursor
|
|
188
|
+
#
|
|
189
|
+
# @return [self]
|
|
182
190
|
|
|
183
191
|
# @!method show_alt_screen
|
|
184
192
|
#
|
|
185
|
-
#
|
|
186
|
-
#
|
|
193
|
+
# Switch to the alternate screen buffer.
|
|
194
|
+
#
|
|
195
|
+
# @note Reference-counted; safe for nested use.
|
|
187
196
|
#
|
|
188
|
-
#
|
|
189
|
-
# {hide_alt_screen} n-times to show the default screen again.
|
|
197
|
+
# @see .hide_alt_screen
|
|
190
198
|
#
|
|
191
|
-
# @return [
|
|
199
|
+
# @return [self]
|
|
192
200
|
|
|
193
201
|
# @!method hide_alt_screen
|
|
194
202
|
#
|
|
195
|
-
#
|
|
196
|
-
#
|
|
203
|
+
# Switch back from the alternate screen buffer.
|
|
204
|
+
#
|
|
205
|
+
# @note Reference-counted; safe for nested use.
|
|
197
206
|
#
|
|
198
|
-
#
|
|
199
|
-
# {hide_alt_screen} n-times to show the default screen again.
|
|
207
|
+
# @see .show_alt_screen
|
|
200
208
|
#
|
|
201
|
-
# @return [
|
|
209
|
+
# @return [self]
|
|
202
210
|
|
|
211
|
+
# Register a callback to be invoked when the terminal is resized.
|
|
212
|
+
#
|
|
213
|
+
# @example
|
|
214
|
+
# Terminal.on_resize { puts "New size: #{Terminal.size}" }
|
|
215
|
+
#
|
|
216
|
+
# @yield called on terminal resize
|
|
217
|
+
# @return [self]
|
|
218
|
+
def on_resize(&block)
|
|
219
|
+
@on_resize = block
|
|
220
|
+
self
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
#
|
|
203
224
|
# @!endgroup
|
|
225
|
+
#
|
|
204
226
|
|
|
205
227
|
private
|
|
206
228
|
|
|
@@ -220,18 +242,18 @@ module Terminal
|
|
|
220
242
|
|
|
221
243
|
tty, ansi = __output_modes
|
|
222
244
|
if tty.nil?
|
|
223
|
-
require_relative
|
|
245
|
+
require_relative('output/dumb')
|
|
224
246
|
extend DumbOutput
|
|
225
247
|
__output_error(nil)
|
|
226
248
|
else
|
|
227
249
|
@out = STDOUT
|
|
228
250
|
@out.sync = true if defined?(@out.sync)
|
|
229
251
|
if ansi
|
|
230
|
-
require_relative
|
|
252
|
+
require_relative('output/ansi')
|
|
231
253
|
extend AnsiOutput
|
|
232
254
|
__init_tty if tty
|
|
233
255
|
else
|
|
234
|
-
require_relative
|
|
256
|
+
require_relative('output/dumb')
|
|
235
257
|
extend DumbOutput
|
|
236
258
|
end
|
|
237
259
|
end
|
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# RSpec shared context for testing code that uses Terminal.rb.
|
|
4
|
+
#
|
|
5
|
+
# Stubs all Terminal I/O methods and provides +stdout+, +stdin+, and
|
|
6
|
+
# +stdoutstr+ test helpers. Output is captured into the +stdout+ array;
|
|
7
|
+
# input is read from the +stdin+ array.
|
|
8
|
+
#
|
|
9
|
+
# @example Basic usage
|
|
10
|
+
# RSpec.describe MyClass do
|
|
11
|
+
# include_context 'with Terminal.rb'
|
|
12
|
+
#
|
|
13
|
+
# it 'prints a greeting' do
|
|
14
|
+
# my_object.greet
|
|
15
|
+
# expect(stdoutstr).to include('Hello')
|
|
16
|
+
# end
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# @example Custom terminal settings
|
|
20
|
+
# include_context 'with Terminal.rb', ansi: false, colors: 8,
|
|
21
|
+
# size: [40, 120]
|
|
22
|
+
#
|
|
23
|
+
# @param ansi [true, false] mock ANSI support (default: +true+)
|
|
24
|
+
# @param application [Symbol] mock terminal application
|
|
25
|
+
# (default: +:kitty+)
|
|
26
|
+
# @param colors [Integer, Symbol] mock color depth; use +:true_color+
|
|
27
|
+
# for 16777216 (default: +256+)
|
|
28
|
+
# @param size [Array<Integer, Integer>] mock terminal size as
|
|
29
|
+
# +[rows, columns]+ (default: +[25, 80]+)
|
|
30
|
+
# @param pos [Array<Integer, Integer>] mock cursor position as
|
|
31
|
+
# +[row, column]+ (default: +[1, 1]+)
|
|
3
32
|
RSpec.shared_context 'with Terminal.rb' do |ansi: true, application: :kitty, colors: 256, size: [25, 80], pos: [1, 1]|
|
|
4
33
|
let(:stdout) { [] }
|
|
5
34
|
let(:stdin) { [] }
|
|
@@ -34,7 +63,7 @@ RSpec.shared_context 'with Terminal.rb' do |ansi: true, application: :kitty, col
|
|
|
34
63
|
|
|
35
64
|
allow(Terminal).to receive(:print) do |*objects, bbcode: true|
|
|
36
65
|
bbcode = bbcode_[bbcode]
|
|
37
|
-
objects.flatten.each { stdout.push(bbcode[
|
|
66
|
+
objects.flatten.each { stdout.push(bbcode[it]) unless it.nil? }
|
|
38
67
|
nil
|
|
39
68
|
end
|
|
40
69
|
|
data/lib/terminal/shell.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Terminal
|
|
4
|
+
# @private
|
|
4
5
|
module Shell
|
|
5
6
|
class << self
|
|
6
|
-
def
|
|
7
|
+
def run(*cmd, env: {}, shell: false, input: nil, **options)
|
|
7
8
|
options = options.except(:in, :out, :err)
|
|
8
|
-
cmd = cmd.map! { _escape(
|
|
9
|
+
cmd = cmd.map! { _escape(it) }.join(' ') if shell
|
|
9
10
|
input = Input[input]
|
|
10
11
|
thread = nil
|
|
11
12
|
|
|
@@ -64,19 +65,22 @@ module Terminal
|
|
|
64
65
|
|
|
65
66
|
def _escape(str)
|
|
66
67
|
return "''" if str.empty?
|
|
67
|
-
str.gsub(%r{[^A-Za-z0-9_\-.,:+/@\n]}, "\\\\\\&")
|
|
68
|
+
str = str.gsub(%r{[^A-Za-z0-9_\-.,:+/@\n]}, "\\\\\\&")
|
|
69
|
+
str.gsub!("\n", "'\n'")
|
|
70
|
+
str
|
|
68
71
|
end
|
|
69
72
|
end
|
|
70
73
|
|
|
74
|
+
# @private
|
|
71
75
|
module Input
|
|
72
76
|
def self.[](obj)
|
|
73
77
|
return unless obj
|
|
74
78
|
return copy_writer(obj) if obj.respond_to?(:readpartial)
|
|
75
79
|
return copy_writer(obj.to_io) if obj.respond_to?(:to_io)
|
|
76
|
-
return array_writer(obj) if obj
|
|
80
|
+
return array_writer(obj) if Array === obj
|
|
77
81
|
if obj.respond_to?(:each)
|
|
78
82
|
return enum_writer(obj.enum_for(:each)) if obj.respond_to?(:enum_for)
|
|
79
|
-
return enum_writer(Enumerator.new { |y| obj.each { y <<
|
|
83
|
+
return enum_writer(Enumerator.new { |y| obj.each { y << it } })
|
|
80
84
|
end
|
|
81
85
|
return array_writer(obj.to_a) if obj.respond_to?(:to_a)
|
|
82
86
|
proc do |io|
|
|
@@ -93,7 +97,7 @@ module Terminal
|
|
|
93
97
|
end
|
|
94
98
|
|
|
95
99
|
def self.array_writer(array, idx = -1)
|
|
96
|
-
proc {
|
|
100
|
+
proc { it.write(array[idx += 1] || next) }
|
|
97
101
|
end
|
|
98
102
|
|
|
99
103
|
def self.enum_writer(enum)
|