natty-ui 0.7.0 → 0.9.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/.yardopts +7 -3
- data/README.md +25 -47
- data/examples/24bit-colors.rb +27 -0
- data/examples/3bit-colors.rb +14 -0
- data/examples/8bit-colors.rb +31 -0
- data/examples/animate.rb +24 -0
- data/examples/attributes.rb +25 -159
- data/examples/demo.rb +53 -0
- data/examples/illustration.png +0 -0
- data/examples/illustration.rb +29 -0
- data/examples/{list_in_columns.rb → ls.rb} +13 -20
- data/examples/message.rb +30 -0
- data/examples/progress.rb +25 -30
- data/examples/query.rb +26 -28
- data/examples/read_key.rb +13 -0
- data/examples/table.rb +36 -0
- data/lib/natty-ui/ansi.rb +351 -305
- data/lib/natty-ui/ansi_constants.rb +73 -0
- data/lib/natty-ui/ansi_wrapper.rb +136 -162
- data/lib/natty-ui/features.rb +11 -18
- data/lib/natty-ui/key_map.rb +119 -0
- data/lib/natty-ui/line_animation/default.rb +35 -0
- data/lib/natty-ui/line_animation/matrix.rb +28 -0
- data/lib/natty-ui/line_animation/rainbow.rb +30 -0
- data/lib/natty-ui/line_animation/test.rb +29 -0
- data/lib/natty-ui/line_animation/type_writer.rb +64 -0
- data/lib/natty-ui/line_animation.rb +54 -0
- data/lib/natty-ui/version.rb +2 -2
- data/lib/natty-ui/wrapper/animate.rb +17 -0
- data/lib/natty-ui/wrapper/ask.rb +21 -21
- data/lib/natty-ui/wrapper/element.rb +19 -23
- data/lib/natty-ui/wrapper/framed.rb +29 -19
- data/lib/natty-ui/wrapper/heading.rb +26 -53
- data/lib/natty-ui/wrapper/horizontal_rule.rb +37 -0
- data/lib/natty-ui/wrapper/list_in_columns.rb +71 -12
- data/lib/natty-ui/wrapper/message.rb +20 -27
- data/lib/natty-ui/wrapper/progress.rb +40 -13
- data/lib/natty-ui/wrapper/query.rb +34 -31
- data/lib/natty-ui/wrapper/quote.rb +25 -0
- data/lib/natty-ui/wrapper/request.rb +21 -10
- data/lib/natty-ui/wrapper/section.rb +55 -39
- data/lib/natty-ui/wrapper/table.rb +298 -0
- data/lib/natty-ui/wrapper/task.rb +6 -7
- data/lib/natty-ui/wrapper.rb +123 -41
- data/lib/natty-ui.rb +65 -40
- metadata +28 -9
- data/examples/basic.rb +0 -62
@@ -0,0 +1,298 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'element'
|
4
|
+
|
5
|
+
module NattyUI
|
6
|
+
module Features
|
7
|
+
#
|
8
|
+
# Table view of data.
|
9
|
+
#
|
10
|
+
# @note Tables do not support text attributes yet and are still under
|
11
|
+
# construction. This means table features are not complete defined and
|
12
|
+
# may change in near future.
|
13
|
+
#
|
14
|
+
# Defined values for `type` are
|
15
|
+
# :double, :heavy, :semi, :simple
|
16
|
+
#
|
17
|
+
# @overload table(type: simple)
|
18
|
+
# Construct and display a table.
|
19
|
+
#
|
20
|
+
# @param [Symbol] type frame type
|
21
|
+
# @yieldparam [Table] table construction helper
|
22
|
+
# @return [Wrapper::Section, Wrapper] it's parent object
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# ui.table do |table|
|
26
|
+
# table.add('name', 'price', 'origin')
|
27
|
+
# table.add('apple', '1$', 'California')
|
28
|
+
# table.add('banana', '2$', 'Brasil')
|
29
|
+
# table.add('kiwi', '1.5$', 'Newzeeland')
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # output:
|
33
|
+
# # name │ price │ origin
|
34
|
+
# # ───────┼───────┼───────────
|
35
|
+
# # apple │ 1$ │ California
|
36
|
+
# # ───────┼───────┼───────────
|
37
|
+
# # banana │ 2$ │ Brasil
|
38
|
+
# # ───────┼───────┼───────────
|
39
|
+
# # kiwi │ 1.5$ │ Newzeeland
|
40
|
+
#
|
41
|
+
# @overload table(*args, type: simple)
|
42
|
+
# Display the given arrays as rows of a table.
|
43
|
+
#
|
44
|
+
# @param [Array<#to_s>] args one or more arrays representing rows of the table
|
45
|
+
# @param [Symbol] type frame type
|
46
|
+
# @return [Wrapper::Section, Wrapper] it's parent object
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# ui.table(
|
50
|
+
# %w[name price origin],
|
51
|
+
# %w[apple 1$ California],
|
52
|
+
# %w[banana 2$ Brasil],
|
53
|
+
# %w[kiwi 1.5$ Newzeeland]
|
54
|
+
# )
|
55
|
+
def table(*table, type: :simple)
|
56
|
+
table = Table.new(*table)
|
57
|
+
yield(table) if block_given?
|
58
|
+
_element(:Table, table.rows, type)
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Table-like display of key/value pairs.
|
63
|
+
#
|
64
|
+
# @param [#to_s] seperator
|
65
|
+
# @param [Hash<#to_s,#to_s>] kwargs
|
66
|
+
# @return [Wrapper::Section, Wrapper] it's parent object
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
# ui.pairs(apple: '1$', banana: '2$', kiwi: '1.5$')
|
70
|
+
#
|
71
|
+
# # output:
|
72
|
+
# # apple: 1$
|
73
|
+
# # banana: 2$
|
74
|
+
# # kiwi: 1.5$
|
75
|
+
#
|
76
|
+
def pairs(seperator = ': ', **kwargs)
|
77
|
+
_element(:Pairs, Table.new(**kwargs).rows, seperator)
|
78
|
+
end
|
79
|
+
|
80
|
+
class Table
|
81
|
+
attr_reader :rows
|
82
|
+
|
83
|
+
def add_row(*columns)
|
84
|
+
@rows << columns
|
85
|
+
self
|
86
|
+
end
|
87
|
+
alias add add_row
|
88
|
+
|
89
|
+
def add_col(*columns)
|
90
|
+
columns.each_with_index do |col, row_idx|
|
91
|
+
(@rows[row_idx] ||= []) << col
|
92
|
+
end
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
def initialize(*args, **kwargs)
|
97
|
+
@rows = []
|
98
|
+
args.each { add_row(*_1) }
|
99
|
+
kwargs.each_pair { add_row(*_1) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
private_constant :Table
|
103
|
+
end
|
104
|
+
|
105
|
+
class Wrapper
|
106
|
+
# An {Element} to print a table.
|
107
|
+
#
|
108
|
+
# @see Features#table
|
109
|
+
class Table < Element
|
110
|
+
protected
|
111
|
+
|
112
|
+
def call(rows, type)
|
113
|
+
TableGenerator.each_line(
|
114
|
+
rows,
|
115
|
+
@parent.available_width - 1,
|
116
|
+
ORNAMENTS[type] ||
|
117
|
+
raise(ArgumentError, "invalid table type - #{type.inspect}"),
|
118
|
+
Ansi[39],
|
119
|
+
Ansi::RESET
|
120
|
+
) { @parent.puts(_1) }
|
121
|
+
@parent
|
122
|
+
end
|
123
|
+
|
124
|
+
def coloring = [nil, nil]
|
125
|
+
|
126
|
+
ORNAMENTS = {
|
127
|
+
rounded: '│─┼',
|
128
|
+
simple: '│─┼',
|
129
|
+
heavy: '┃━╋',
|
130
|
+
double: '║═╬',
|
131
|
+
semi: '║╴╫'
|
132
|
+
}.compare_by_identity.freeze
|
133
|
+
end
|
134
|
+
|
135
|
+
# An {Element} to print key/value pairs.
|
136
|
+
#
|
137
|
+
# @see Features#pairs
|
138
|
+
class Pairs < Element
|
139
|
+
protected
|
140
|
+
|
141
|
+
def call(rows, seperator)
|
142
|
+
TableGenerator.each_simple_line(
|
143
|
+
rows,
|
144
|
+
@parent.available_width - 1,
|
145
|
+
seperator,
|
146
|
+
NattyUI.plain(seperator, ansi: false)[-1] == ' '
|
147
|
+
) { @parent.puts(_1) }
|
148
|
+
@parent
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class TableGenerator
|
153
|
+
def self.each_line(rows, max_width, ornament, opref, osuff)
|
154
|
+
return if rows.empty?
|
155
|
+
gen = new(rows, max_width, 3)
|
156
|
+
return unless gen.ok?
|
157
|
+
last_row = 0
|
158
|
+
col_div = " #{opref}#{ornament[0]}#{osuff} "
|
159
|
+
row_div = "#{ornament[1]}#{ornament[2]}#{ornament[1]}"
|
160
|
+
row_div =
|
161
|
+
"#{opref}#{gen.widths.map { ornament[1] * _1 }.join(row_div)}#{osuff}"
|
162
|
+
gen.each do |line, number|
|
163
|
+
if last_row != number
|
164
|
+
last_row = number
|
165
|
+
yield(row_div)
|
166
|
+
end
|
167
|
+
yield(line.join(col_div))
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.each_simple_line(rows, max_width, col_div, first_right)
|
172
|
+
return if rows.empty?
|
173
|
+
gen = new(rows, max_width, NattyUI.display_width(col_div))
|
174
|
+
return unless gen.ok?
|
175
|
+
gen.aligns[0] = :right if first_right
|
176
|
+
gen.each { yield(_1.join(col_div)) }
|
177
|
+
end
|
178
|
+
|
179
|
+
attr_reader :widths, :aligns
|
180
|
+
|
181
|
+
def initialize(rows, max_width, col_div_size)
|
182
|
+
@rows =
|
183
|
+
rows.map do |row|
|
184
|
+
row.map do |col|
|
185
|
+
col = NattyUI.embellish(col).each_line(chomp: true).to_a
|
186
|
+
col.empty? ? col << '' : col
|
187
|
+
end
|
188
|
+
end
|
189
|
+
@max_width = max_width
|
190
|
+
@col_div_size = col_div_size
|
191
|
+
@widths = create_widths.freeze
|
192
|
+
@aligns = Array.new(@widths.size, :left)
|
193
|
+
end
|
194
|
+
|
195
|
+
def ok? = (@widths != nil)
|
196
|
+
|
197
|
+
def each
|
198
|
+
return unless @widths
|
199
|
+
col_empty = @widths.map { ' ' * _1 }
|
200
|
+
@rows.each_with_index do |row, row_idx|
|
201
|
+
row
|
202
|
+
.max_by(&:size)
|
203
|
+
.size
|
204
|
+
.times do |line_nr|
|
205
|
+
col_idx = -1
|
206
|
+
yield(
|
207
|
+
@widths.map do |col_width|
|
208
|
+
cell = row[col_idx += 1] or next col_empty[col_idx]
|
209
|
+
next col_empty[col_idx] if (line = cell[line_nr]).nil?
|
210
|
+
align(line.to_s, col_width, @aligns[col_idx])
|
211
|
+
end,
|
212
|
+
row_idx
|
213
|
+
)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
|
220
|
+
def align(str, width, alignment)
|
221
|
+
return str unless (width -= NattyUI.display_width(str)).positive?
|
222
|
+
return str + (' ' * width) if alignment == :left
|
223
|
+
(' ' * width) << str
|
224
|
+
end
|
225
|
+
|
226
|
+
def create_widths
|
227
|
+
matrix = create_matrix
|
228
|
+
col_widths = find_col_widths(matrix)
|
229
|
+
adjusted = adjusted_widths(col_widths)
|
230
|
+
return if adjusted.empty? # nothing to draw
|
231
|
+
return adjusted if col_widths == adjusted # all fine
|
232
|
+
if (size = adjusted.size) != col_widths.size
|
233
|
+
@rows.map! { _1.take(size) }
|
234
|
+
matrix.map! { _1.take(size) }
|
235
|
+
col_widths = col_widths.take(size)
|
236
|
+
end
|
237
|
+
diff = diff(col_widths, adjusted)
|
238
|
+
@rows.each_with_index do |row, row_idx|
|
239
|
+
diff.each do |col_idx|
|
240
|
+
adjust_to = adjusted[col_idx]
|
241
|
+
next if matrix[row_idx][col_idx] <= adjust_to
|
242
|
+
ary = NattyUI.each_line(*row[col_idx], max_width: adjust_to).to_a
|
243
|
+
ary.pop if ary.last.empty?
|
244
|
+
row[col_idx] = ary
|
245
|
+
end
|
246
|
+
end
|
247
|
+
adjusted
|
248
|
+
end
|
249
|
+
|
250
|
+
def create_matrix
|
251
|
+
ret =
|
252
|
+
@rows.map do |row|
|
253
|
+
row.map { |col| col.map { NattyUI.display_width(_1) }.max }
|
254
|
+
end
|
255
|
+
cc = ret.max_by(&:size).size
|
256
|
+
ret.each { (add = cc - _1.size).nonzero? and _1.fill(0, _1.size, add) }
|
257
|
+
end
|
258
|
+
|
259
|
+
def find_col_widths(matrix)
|
260
|
+
ret = nil
|
261
|
+
matrix.each do |row|
|
262
|
+
next ret = row.dup unless ret
|
263
|
+
row.each_with_index do |size, idx|
|
264
|
+
hs = ret[idx]
|
265
|
+
ret[idx] = size if hs < size
|
266
|
+
end
|
267
|
+
end
|
268
|
+
ret
|
269
|
+
end
|
270
|
+
|
271
|
+
def adjusted_widths(col_widths)
|
272
|
+
ret = col_widths.dup
|
273
|
+
left = @max_width - (@col_div_size * (col_widths.size - 1))
|
274
|
+
return ret if ret.sum <= left
|
275
|
+
indexed = ret.each_with_index.to_a
|
276
|
+
# TODO: optimize this!
|
277
|
+
until ret.sum <= left
|
278
|
+
indexed.sort! { |b, a| (a[0] <=> b[0]).nonzero? || (a[1] <=> b[1]) }
|
279
|
+
pair = indexed[0]
|
280
|
+
next ret[pair[1]] = pair[0] if (pair[0] -= 1).nonzero?
|
281
|
+
indexed.shift
|
282
|
+
return [] if indexed.empty?
|
283
|
+
ret.pop
|
284
|
+
end
|
285
|
+
ret
|
286
|
+
end
|
287
|
+
|
288
|
+
def diff(col_widths, adjusted)
|
289
|
+
ret = []
|
290
|
+
col_widths.each_with_index do |val, idx|
|
291
|
+
ret << idx if val != adjusted[idx]
|
292
|
+
end
|
293
|
+
ret
|
294
|
+
end
|
295
|
+
end
|
296
|
+
private_constant :TableGenerator
|
297
|
+
end
|
298
|
+
end
|
@@ -15,29 +15,28 @@ module NattyUI
|
|
15
15
|
# @return [Object] the result of the code block
|
16
16
|
# @return [Wrapper::Task] itself, when no code block is given
|
17
17
|
def task(title, *args, &block)
|
18
|
-
_section(
|
18
|
+
_section(:Task, args, title: title, &block)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
module TaskMethods
|
23
23
|
protected
|
24
24
|
|
25
|
-
def initialize(parent, title
|
26
|
-
@
|
27
|
-
@temp = wrapper.temporary
|
25
|
+
def initialize(parent, title:)
|
26
|
+
@temp = parent.wrapper.temporary
|
28
27
|
@final_text = [title]
|
29
|
-
super(parent, title: title,
|
28
|
+
super(parent, title: title, glyph: :task)
|
30
29
|
end
|
31
30
|
|
32
31
|
def finish
|
33
32
|
return @parent.failed(*@final_text) if failed?
|
34
33
|
@temp.call
|
35
34
|
_section(
|
36
|
-
@parent,
|
37
35
|
:Message,
|
38
36
|
@final_text,
|
37
|
+
owner: @parent,
|
39
38
|
title: @final_text.shift,
|
40
|
-
|
39
|
+
glyph: @status = :completed
|
41
40
|
)
|
42
41
|
end
|
43
42
|
end
|
data/lib/natty-ui/wrapper.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'io/console'
|
4
|
+
require_relative 'ansi'
|
5
|
+
require_relative 'wrapper/animate'
|
4
6
|
require_relative 'wrapper/ask'
|
5
7
|
require_relative 'wrapper/framed'
|
6
8
|
require_relative 'wrapper/heading'
|
9
|
+
require_relative 'wrapper/horizontal_rule'
|
7
10
|
require_relative 'wrapper/list_in_columns'
|
8
11
|
require_relative 'wrapper/message'
|
9
12
|
require_relative 'wrapper/progress'
|
10
13
|
require_relative 'wrapper/query'
|
14
|
+
require_relative 'wrapper/quote'
|
11
15
|
require_relative 'wrapper/request'
|
12
16
|
require_relative 'wrapper/section'
|
17
|
+
require_relative 'wrapper/table'
|
13
18
|
require_relative 'wrapper/task'
|
14
19
|
|
15
20
|
module NattyUI
|
@@ -28,60 +33,60 @@ module NattyUI
|
|
28
33
|
|
29
34
|
# @attribute [r] screen_size
|
30
35
|
# @return [[Integer, Integer]] screen size as rows and columns
|
31
|
-
def screen_size
|
32
|
-
return @stream.winsize if @ws
|
33
|
-
[ENV['LINES'].to_i.nonzero? || 24, ENV['COLUMNS'].to_i.nonzero? || 80]
|
34
|
-
end
|
36
|
+
def screen_size = (@screen_size ||= determine_screen_size)
|
35
37
|
|
36
38
|
# @attribute [r] screen_rows
|
37
39
|
# @return [Integer] number of screen rows
|
38
|
-
def screen_rows
|
39
|
-
@ws ? @stream.winsize[0] : (ENV['LINES'].to_i.nonzero? || 24)
|
40
|
-
end
|
40
|
+
def screen_rows = screen_size[0]
|
41
41
|
|
42
42
|
# @attribute [r] screen_columns
|
43
43
|
# @return [Integer] number of screen columns
|
44
|
-
def screen_columns
|
45
|
-
@ws ? @stream.winsize[-1] : (ENV['COLUMNS'].to_i.nonzero? || 80)
|
46
|
-
end
|
44
|
+
def screen_columns = screen_size[1]
|
47
45
|
|
48
46
|
# @!group Tool functions
|
49
47
|
|
50
|
-
# Print given arguments
|
51
|
-
# Optionally limit the line width to given `max_width`.
|
48
|
+
# Print given arguments line-wise to the output stream.
|
52
49
|
#
|
53
|
-
# @overload puts(
|
50
|
+
# @overload puts(...)
|
54
51
|
# @param [#to_s] ... objects to print
|
55
|
-
# @param [Integer, nil] max_width maximum line width
|
56
|
-
# @comment @param [#to_s, nil] prefix line prefix
|
57
|
-
# @comment @param [#to_s, nil] suffix line suffix
|
58
52
|
# @return [Wrapper] itself
|
59
|
-
def puts(*args,
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
53
|
+
def puts(*args, **kwargs)
|
54
|
+
args = prepare_print(args, kwargs)
|
55
|
+
@lines_written += args.size
|
56
|
+
@stream.puts(args)
|
57
|
+
@stream.flush
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
# Print given arguments to the output stream.
|
62
|
+
#
|
63
|
+
# @overload print(...)
|
64
|
+
# @param [#to_s] ... objects to print
|
65
|
+
# @return [Wrapper] itself
|
66
|
+
def print(*args, **kwargs)
|
67
|
+
args = prepare_print(args, kwargs).to_a
|
68
|
+
@lines_written += args.size - 1
|
69
|
+
@stream.print(*args)
|
69
70
|
@stream.flush
|
70
71
|
self
|
71
72
|
end
|
72
|
-
alias add puts
|
73
73
|
|
74
74
|
# Add at least one empty line
|
75
75
|
#
|
76
76
|
# @param [#to_i] lines count of lines
|
77
77
|
# @return [Wrapper] itself
|
78
78
|
def space(lines = 1)
|
79
|
-
lines = [lines.to_i
|
80
|
-
@lines_written += lines
|
79
|
+
lines = [1, lines.to_i].max
|
81
80
|
(@stream << ("\n" * lines)).flush
|
81
|
+
@lines_written += lines
|
82
82
|
self
|
83
83
|
end
|
84
84
|
|
85
|
+
# Clear Screen
|
86
|
+
#
|
87
|
+
# @return [Wrapper] itself
|
88
|
+
def cls = self
|
89
|
+
|
85
90
|
# @note The screen manipulation is only available in ANSI mode see {#ansi?}
|
86
91
|
#
|
87
92
|
# Saves current screen, deletes all screen content and moves the cursor
|
@@ -136,8 +141,53 @@ module NattyUI
|
|
136
141
|
# @!visibility private
|
137
142
|
alias inspect to_s
|
138
143
|
|
144
|
+
# @attribute [r] wrapper
|
145
|
+
# @return [Wrapper] self
|
146
|
+
alias wrapper itself
|
147
|
+
|
148
|
+
# @!visibility private
|
149
|
+
alias available_width screen_columns
|
150
|
+
|
151
|
+
# @!visibility private
|
152
|
+
alias rcol screen_columns
|
153
|
+
|
154
|
+
# @!visibility private
|
155
|
+
def prefix = nil
|
156
|
+
|
157
|
+
# @return [Array<Symbol>] available glyph names
|
158
|
+
def glyph_names = GLYPHS.keys
|
159
|
+
|
160
|
+
#
|
161
|
+
# Get a pre-defined glyph
|
162
|
+
#
|
163
|
+
# @param [Symbol] name glyph name
|
164
|
+
# @return [String] the named glyph
|
165
|
+
# @return [nil] when glyph is not defined
|
166
|
+
def glyph(name) = GLYPHS[name]
|
167
|
+
|
139
168
|
protected
|
140
169
|
|
170
|
+
def prepare_print(args, kwargs)
|
171
|
+
_prepare_print(args, kwargs) { NattyUI.plain(_1, ansi: false) }
|
172
|
+
end
|
173
|
+
|
174
|
+
def _prepare_print(args, kwargs, &cvt)
|
175
|
+
prefix = kwargs[:prefix] and prefix = prefix.empty? ? '' : cvt[prefix]
|
176
|
+
suffix = kwargs[:suffix] and suffix = suffix.empty? ? '' : cvt[suffix]
|
177
|
+
return ["#{prefix}#{suffix}"] if args.empty?
|
178
|
+
NattyUI
|
179
|
+
.each_line(
|
180
|
+
*args.map!(&cvt),
|
181
|
+
max_width:
|
182
|
+
kwargs.fetch(:max_width) do
|
183
|
+
screen_columns -
|
184
|
+
kwargs.fetch(:prefix_width) { NattyUI.display_width(prefix) } -
|
185
|
+
kwargs.fetch(:suffix_width) { NattyUI.display_width(suffix) }
|
186
|
+
end
|
187
|
+
)
|
188
|
+
.map { "#{prefix}#{_1}#{suffix}" }
|
189
|
+
end
|
190
|
+
|
141
191
|
def temp_func
|
142
192
|
lambda do
|
143
193
|
@stream.flush
|
@@ -148,23 +198,55 @@ module NattyUI
|
|
148
198
|
def initialize(stream)
|
149
199
|
@stream = stream
|
150
200
|
@lines_written = 0
|
151
|
-
@ws = stream.respond_to?(:winsize) && stream.winsize&.all?(&:positive?)
|
152
|
-
rescue Errno::ENOTTY
|
153
|
-
@ws = false
|
154
201
|
end
|
155
202
|
|
156
|
-
|
203
|
+
private_class_method :new
|
157
204
|
|
158
|
-
|
159
|
-
def prefix = nil
|
160
|
-
alias suffix prefix
|
205
|
+
private
|
161
206
|
|
162
|
-
def
|
163
|
-
|
164
|
-
|
207
|
+
def determine_screen_size
|
208
|
+
return @stream.winsize if @ws
|
209
|
+
if @ws.nil?
|
210
|
+
ret = try_fetch_winsize
|
211
|
+
if ret
|
212
|
+
@ws = true
|
213
|
+
Signal.trap('WINCH') { @screen_size = nil }
|
214
|
+
return ret
|
215
|
+
end
|
216
|
+
@ws = false
|
217
|
+
end
|
218
|
+
[ENV['LINES'].to_i.nonzero? || 24, ENV['COLUMNS'].to_i.nonzero? || 80]
|
219
|
+
end
|
165
220
|
|
166
|
-
|
221
|
+
def try_fetch_winsize
|
222
|
+
return unless @stream.respond_to?(:winsize)
|
223
|
+
ret = @stream.winsize
|
224
|
+
ret&.all?(&:positive?) ? ret : nil
|
225
|
+
rescue SystemCallError
|
226
|
+
nil
|
227
|
+
end
|
167
228
|
|
168
|
-
|
229
|
+
GLYPHS = {
|
230
|
+
default: "#{Ansi[:bold, 255]}•#{Ansi::RESET}",
|
231
|
+
information: "#{Ansi[:bold, 119]}𝒊#{Ansi::RESET}",
|
232
|
+
warning: "#{Ansi[:bold, 221]}!#{Ansi::RESET}",
|
233
|
+
error: "#{Ansi[:bold, 208]}𝙓#{Ansi::RESET}",
|
234
|
+
completed: "#{Ansi[:bold, 82]}✓#{Ansi::RESET}",
|
235
|
+
failed: "#{Ansi[:bold, 196]}𝑭#{Ansi::RESET}",
|
236
|
+
task: "#{Ansi[:bold, 39]}➔#{Ansi::RESET}",
|
237
|
+
query: "#{Ansi[:bold, 39]}▸#{Ansi::RESET}"
|
238
|
+
}.compare_by_identity.freeze
|
239
|
+
|
240
|
+
# GLYPHS = {
|
241
|
+
# default: '●',
|
242
|
+
# information: '🅸 ',
|
243
|
+
# warning: '🆆 ',
|
244
|
+
# error: '🅴 ',
|
245
|
+
# completed: '✓',
|
246
|
+
# failed: '🅵 ',
|
247
|
+
# task: '➔',
|
248
|
+
# query: '🆀 '
|
249
|
+
# }.compare_by_identity.freeze
|
250
|
+
private_constant :GLYPHS
|
169
251
|
end
|
170
252
|
end
|