natty-ui 0.9.4 → 0.11.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 +4 -11
- data/examples/24bit-colors.rb +8 -16
- data/examples/3bit-colors.rb +1 -1
- data/examples/8bit-colors.rb +15 -11
- data/examples/animate.rb +31 -11
- data/examples/attributes.rb +16 -14
- data/examples/attributes_list.rb +14 -0
- data/examples/demo.rb +4 -4
- data/examples/illustration.rb +52 -24
- data/examples/ls.rb +4 -4
- data/examples/message.rb +11 -9
- data/examples/progress.rb +2 -2
- data/examples/query.rb +1 -1
- data/examples/table.rb +23 -23
- data/lib/natty-ui/animation/binary.rb +37 -0
- data/lib/natty-ui/animation/default.rb +42 -0
- data/lib/natty-ui/animation/matrix.rb +55 -0
- data/lib/natty-ui/animation/rainbow.rb +28 -0
- data/lib/natty-ui/animation/type_writer.rb +44 -0
- data/lib/natty-ui/animation.rb +69 -0
- data/lib/natty-ui/ansi/constants.rb +1 -1
- data/lib/natty-ui/ansi.rb +46 -26
- data/lib/natty-ui/ansi_wrapper.rb +47 -51
- data/lib/natty-ui/key_map.rb +72 -49
- data/lib/natty-ui/preload.rb +1 -1
- data/lib/natty-ui/text.rb +75 -85
- data/lib/natty-ui/version.rb +1 -1
- data/lib/natty-ui/wrapper/animate.rb +1 -1
- data/lib/natty-ui/wrapper/ask.rb +1 -1
- data/lib/natty-ui/wrapper/element.rb +18 -10
- data/lib/natty-ui/wrapper/features.rb +0 -8
- data/lib/natty-ui/wrapper/framed.rb +7 -27
- data/lib/natty-ui/wrapper/message.rb +1 -1
- data/lib/natty-ui/wrapper/request.rb +1 -1
- data/lib/natty-ui/wrapper/section.rb +18 -18
- data/lib/natty-ui/wrapper/table.rb +432 -168
- data/lib/natty-ui/wrapper.rb +45 -48
- data/lib/natty-ui.rb +65 -2
- metadata +10 -8
- data/lib/natty-ui/line_animation/default.rb +0 -35
- data/lib/natty-ui/line_animation/matrix.rb +0 -28
- data/lib/natty-ui/line_animation/rainbow.rb +0 -30
- data/lib/natty-ui/line_animation/type_writer.rb +0 -44
- data/lib/natty-ui/line_animation.rb +0 -48
data/lib/natty-ui/wrapper.rb
CHANGED
@@ -47,24 +47,29 @@ module NattyUI
|
|
47
47
|
|
48
48
|
# Print given arguments line-wise to the output stream.
|
49
49
|
#
|
50
|
-
# @
|
51
|
-
#
|
52
|
-
#
|
53
|
-
def puts(*args, **
|
54
|
-
|
55
|
-
|
50
|
+
# @param [#to_s] args objects to print
|
51
|
+
# @option options [:left, :right, :center] :align text alignment
|
52
|
+
# @return [Wrapper] itself
|
53
|
+
def puts(*args, **options)
|
54
|
+
pprint(args, options) do |line|
|
55
|
+
@stream.puts(line)
|
56
|
+
@lines_written += 1
|
57
|
+
end
|
56
58
|
@stream.flush
|
57
59
|
self
|
58
60
|
end
|
59
61
|
|
60
62
|
# Print given arguments to the output stream.
|
61
63
|
#
|
62
|
-
# @
|
63
|
-
#
|
64
|
-
#
|
65
|
-
def print(*args, **
|
66
|
-
|
67
|
-
|
64
|
+
# @param [#to_s] args objects to print
|
65
|
+
# @option options [:left, :right, :center] :align text alignment
|
66
|
+
# @return [Wrapper] itself
|
67
|
+
def print(*args, **options)
|
68
|
+
pprint(args, options) do |line|
|
69
|
+
@stream.print(line)
|
70
|
+
@lines_written += 1
|
71
|
+
end
|
72
|
+
@lines_written -= 1
|
68
73
|
@stream.flush
|
69
74
|
self
|
70
75
|
end
|
@@ -152,21 +157,36 @@ module NattyUI
|
|
152
157
|
# @!visibility private
|
153
158
|
def prefix = nil
|
154
159
|
|
155
|
-
# @return [Array<Symbol>] available glyph names
|
156
|
-
def glyph_names = GLYPHS.keys
|
157
|
-
|
158
|
-
#
|
159
|
-
# Get a pre-defined glyph
|
160
|
-
#
|
161
|
-
# @param [Symbol] name glyph name
|
162
|
-
# @return [String] the named glyph
|
163
|
-
# @return [nil] when glyph is not defined
|
164
|
-
def glyph(name) = GLYPHS[name]
|
165
|
-
|
166
160
|
protected
|
167
161
|
|
168
|
-
def
|
169
|
-
|
162
|
+
def pprint(strs, opts)
|
163
|
+
prefix = opts[:prefix] and prefix = Text.plain(prefix)
|
164
|
+
suffix = opts[:suffix] and suffix = Text.plain(suffix)
|
165
|
+
return yield("#{prefix}#{suffix}") if strs.empty?
|
166
|
+
max_width =
|
167
|
+
opts.fetch(:max_width) do
|
168
|
+
screen_columns - (opts[:prefix_width] || Text.width(prefix)) -
|
169
|
+
(opts[:suffix_width] || Text.width(suffix))
|
170
|
+
end
|
171
|
+
case opts[:align]
|
172
|
+
when :right
|
173
|
+
Text.each_line_plain(strs, max_width) do |line, width|
|
174
|
+
width = max_width - width
|
175
|
+
yield("#{prefix}#{' ' * width}#{line}#{suffix}")
|
176
|
+
end
|
177
|
+
when :center
|
178
|
+
Text.each_line_plain(strs, max_width) do |line, width|
|
179
|
+
width = max_width - width
|
180
|
+
right = width / 2
|
181
|
+
yield(
|
182
|
+
"#{prefix}#{' ' * (width - right)}#{line}#{' ' * right}#{suffix}"
|
183
|
+
)
|
184
|
+
end
|
185
|
+
else
|
186
|
+
Text.each_line_plain(strs, max_width) do |line|
|
187
|
+
yield("#{prefix}#{line}#{suffix}")
|
188
|
+
end
|
189
|
+
end
|
170
190
|
end
|
171
191
|
|
172
192
|
def temp_func
|
@@ -206,28 +226,5 @@ module NattyUI
|
|
206
226
|
rescue SystemCallError
|
207
227
|
nil
|
208
228
|
end
|
209
|
-
|
210
|
-
GLYPHS = {
|
211
|
-
default: "#{Ansi[:bold, 255]}•#{Ansi::RESET}",
|
212
|
-
information: "#{Ansi[:bold, 119]}𝒊#{Ansi::RESET}",
|
213
|
-
warning: "#{Ansi[:bold, 221]}!#{Ansi::RESET}",
|
214
|
-
error: "#{Ansi[:bold, 208]}𝙓#{Ansi::RESET}",
|
215
|
-
completed: "#{Ansi[:bold, 82]}✓#{Ansi::RESET}",
|
216
|
-
failed: "#{Ansi[:bold, 196]}𝑭#{Ansi::RESET}",
|
217
|
-
task: "#{Ansi[:bold, 39]}➔#{Ansi::RESET}",
|
218
|
-
query: "#{Ansi[:bold, 39]}▸#{Ansi::RESET}"
|
219
|
-
}.compare_by_identity.freeze
|
220
|
-
|
221
|
-
# GLYPHS = {
|
222
|
-
# default: '●',
|
223
|
-
# information: '🅸 ',
|
224
|
-
# warning: '🆆 ',
|
225
|
-
# error: '🅴 ',
|
226
|
-
# completed: '✓',
|
227
|
-
# failed: '🅵 ',
|
228
|
-
# task: '➔',
|
229
|
-
# query: '🆀 '
|
230
|
-
# }.compare_by_identity.freeze
|
231
|
-
private_constant :GLYPHS
|
232
229
|
end
|
233
230
|
end
|
data/lib/natty-ui.rb
CHANGED
@@ -135,6 +135,34 @@ module NattyUI
|
|
135
135
|
nil
|
136
136
|
end
|
137
137
|
|
138
|
+
# @return [Array<Symbol>] available glyph names
|
139
|
+
def glyph_names = GLYPH.keys
|
140
|
+
|
141
|
+
# Get a pre-defined glyph.
|
142
|
+
#
|
143
|
+
# @param [Symbol] name glyph name
|
144
|
+
# @return [String] the glyph
|
145
|
+
# @return [nil] when glyph is not defined
|
146
|
+
def glyph(name) = GLYPH[name]
|
147
|
+
|
148
|
+
# @return [Array<Symbol>] available frame names
|
149
|
+
def frame_names = FRAME.keys
|
150
|
+
|
151
|
+
# Get a frame definition.
|
152
|
+
#
|
153
|
+
# @param [Symbol] name frame type name
|
154
|
+
# @return [String] the frame definition
|
155
|
+
# @raise [ArgumentError] when an invalid name is specified
|
156
|
+
def frame(name)
|
157
|
+
if name.is_a?(Symbol)
|
158
|
+
ret = FRAME[name] and return ret
|
159
|
+
elsif name.is_a?(String)
|
160
|
+
return name if name.size == 11
|
161
|
+
return name * 11 if name.size == 1
|
162
|
+
end
|
163
|
+
raise(ArgumentError, "invalid frame type - #{name.inspect}")
|
164
|
+
end
|
165
|
+
|
138
166
|
private
|
139
167
|
|
140
168
|
def wrapper_class(stream, ansi)
|
@@ -159,10 +187,45 @@ module NattyUI
|
|
159
187
|
StdErr = stderr_is_stdout? ? StdOut : new(STDERR)
|
160
188
|
|
161
189
|
dir = __dir__
|
162
|
-
autoload(:
|
190
|
+
autoload(:Animation, File.join(dir, 'natty-ui', 'animation'))
|
163
191
|
autoload(:KEY_MAP, File.join(dir, 'natty-ui', 'key_map'))
|
164
192
|
|
165
|
-
|
193
|
+
GLYPH = {
|
194
|
+
default: "#{Ansi[:bold, 255]}•#{Ansi::RESET}",
|
195
|
+
point: "#{Ansi[0x27]}◉#{Ansi::RESET}",
|
196
|
+
information: "#{Ansi[:bold, 119]}𝒊#{Ansi::RESET}",
|
197
|
+
warning: "#{Ansi[:bold, 221]}!#{Ansi::RESET}",
|
198
|
+
error: "#{Ansi[:bold, 208]}𝙓#{Ansi::RESET}",
|
199
|
+
completed: "#{Ansi[:bold, 82]}✓#{Ansi::RESET}",
|
200
|
+
failed: "#{Ansi[:bold, 196]}𝑭#{Ansi::RESET}",
|
201
|
+
task: "#{Ansi[:bold, 39]}➔#{Ansi::RESET}",
|
202
|
+
query: "#{Ansi[:bold, 39]}▸#{Ansi::RESET}"
|
203
|
+
}.compare_by_identity.freeze
|
204
|
+
|
205
|
+
# GLYPH = {
|
206
|
+
# default: '●',
|
207
|
+
# information: '🅸 ',
|
208
|
+
# warning: '🆆 ',
|
209
|
+
# error: '🅴 ',
|
210
|
+
# completed: '✓',
|
211
|
+
# failed: '🅵 ',
|
212
|
+
# task: '➔',
|
213
|
+
# query: '🆀 '
|
214
|
+
# }.compare_by_identity.freeze
|
215
|
+
|
216
|
+
FRAME = {
|
217
|
+
rounded: '╭╮╰╯│─┼┬┴├┤',
|
218
|
+
simple: '┌┐└┘│─┼┬┴├┤',
|
219
|
+
heavy: '┏┓┗┛┃━╋┳┻┣┫',
|
220
|
+
double: '╔╗╚╝║═╬╦╩╠╣',
|
221
|
+
semi: '╒╕╘╛│═╪╤╧╞╡',
|
222
|
+
semi2: '╓╖╙╜│─╫╥╨╟╢',
|
223
|
+
rows: ' ── ',
|
224
|
+
cols: ' │ │ ',
|
225
|
+
undecorated: ' '
|
226
|
+
}.compare_by_identity.freeze
|
227
|
+
|
228
|
+
private_constant :Animation, :KEY_MAP, :GLYPH, :FRAME
|
166
229
|
|
167
230
|
@element = StdOut
|
168
231
|
self.in_stream = STDIN
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: natty-ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely,
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- examples/8bit-colors.rb
|
31
31
|
- examples/animate.rb
|
32
32
|
- examples/attributes.rb
|
33
|
+
- examples/attributes_list.rb
|
33
34
|
- examples/demo.rb
|
34
35
|
- examples/illustration.rb
|
35
36
|
- examples/ls.rb
|
@@ -39,15 +40,16 @@ files:
|
|
39
40
|
- examples/read_key.rb
|
40
41
|
- examples/table.rb
|
41
42
|
- lib/natty-ui.rb
|
43
|
+
- lib/natty-ui/animation.rb
|
44
|
+
- lib/natty-ui/animation/binary.rb
|
45
|
+
- lib/natty-ui/animation/default.rb
|
46
|
+
- lib/natty-ui/animation/matrix.rb
|
47
|
+
- lib/natty-ui/animation/rainbow.rb
|
48
|
+
- lib/natty-ui/animation/type_writer.rb
|
42
49
|
- lib/natty-ui/ansi.rb
|
43
50
|
- lib/natty-ui/ansi/constants.rb
|
44
51
|
- lib/natty-ui/ansi_wrapper.rb
|
45
52
|
- lib/natty-ui/key_map.rb
|
46
|
-
- lib/natty-ui/line_animation.rb
|
47
|
-
- lib/natty-ui/line_animation/default.rb
|
48
|
-
- lib/natty-ui/line_animation/matrix.rb
|
49
|
-
- lib/natty-ui/line_animation/rainbow.rb
|
50
|
-
- lib/natty-ui/line_animation/type_writer.rb
|
51
53
|
- lib/natty-ui/preload.rb
|
52
54
|
- lib/natty-ui/text.rb
|
53
55
|
- lib/natty-ui/text/east_asian_width.rb
|
@@ -94,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
96
|
- !ruby/object:Gem::Version
|
95
97
|
version: '0'
|
96
98
|
requirements: []
|
97
|
-
rubygems_version: 3.5.
|
99
|
+
rubygems_version: 3.5.16
|
98
100
|
signing_key:
|
99
101
|
specification_version: 4
|
100
102
|
summary: This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely, natty
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
module LineAnimation
|
5
|
-
class Default < None
|
6
|
-
def initialize(*_)
|
7
|
-
super
|
8
|
-
@column = @options[:prefix_width] + 1
|
9
|
-
@color = color
|
10
|
-
@num = 0
|
11
|
-
end
|
12
|
-
|
13
|
-
def print(line)
|
14
|
-
line = Text.plain(line)
|
15
|
-
time = 0.5 / line.size
|
16
|
-
@stream << @color
|
17
|
-
if (@num += 1).odd?
|
18
|
-
line.each_char do |char|
|
19
|
-
(@stream << char).flush
|
20
|
-
sleep(time)
|
21
|
-
end
|
22
|
-
else
|
23
|
-
pos = @column + line.size
|
24
|
-
line.reverse!
|
25
|
-
line.each_char do |char|
|
26
|
-
(@stream << Ansi.cursor_column(pos -= 1) << char).flush
|
27
|
-
sleep(time)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
define default: Default
|
34
|
-
end
|
35
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
module LineAnimation
|
5
|
-
class Matrix < None
|
6
|
-
def initialize(*_)
|
7
|
-
super
|
8
|
-
@prefix = "#{to_column}#{color}"
|
9
|
-
end
|
10
|
-
|
11
|
-
def print(line)
|
12
|
-
line = Text.plain(line)
|
13
|
-
str = Array.new(line.size) { CHARS.sample }.join
|
14
|
-
pos = Array.new(line.size, &:itself).shuffle
|
15
|
-
until pos.size < 4
|
16
|
-
pos.shift(pos.size / 4).each { str[_1] = line[_1] }
|
17
|
-
pos.sample(pos.size / 2).each { str[_1] = CHARS.sample }
|
18
|
-
(@stream << "#{@prefix}#{str}").flush
|
19
|
-
sleep(0.08)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
CHARS = '2598Z*):.\=+-¦|_ヲアウエオカキケコサシスセソタツテナニヌネハヒホマミムメモヤユラリワ'.chars
|
24
|
-
end
|
25
|
-
|
26
|
-
define matrix: Matrix
|
27
|
-
end
|
28
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
module LineAnimation
|
5
|
-
class Rainbow < None
|
6
|
-
def initialize(*_)
|
7
|
-
super
|
8
|
-
@prefix = to_column
|
9
|
-
end
|
10
|
-
|
11
|
-
def print(line)
|
12
|
-
line = Text.plain(line)
|
13
|
-
11.upto(200) do |spread|
|
14
|
-
(
|
15
|
-
@stream << @prefix <<
|
16
|
-
Ansi.rainbow(
|
17
|
-
line,
|
18
|
-
frequence: 0.1,
|
19
|
-
spread: spread / 100.0,
|
20
|
-
seed: 0
|
21
|
-
)
|
22
|
-
).flush
|
23
|
-
sleep(0.01)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
define rainbow: Rainbow
|
29
|
-
end
|
30
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
module LineAnimation
|
5
|
-
class TypeWriter < None
|
6
|
-
def initialize(*_)
|
7
|
-
super
|
8
|
-
@color = color
|
9
|
-
@cursor_color = attribute(:cursor_color, 0x2e)
|
10
|
-
@column = @options[:prefix_width] + 1
|
11
|
-
@num = 0
|
12
|
-
end
|
13
|
-
|
14
|
-
def print(line)
|
15
|
-
line = Text.plain(line)
|
16
|
-
if (@num += 1).odd?
|
17
|
-
line.each_char { (@stream << cursor(_1)).flush }
|
18
|
-
else
|
19
|
-
pos = @column + line.size
|
20
|
-
line.reverse!
|
21
|
-
line.each_char do |char|
|
22
|
-
@stream << Ansi.cursor_column(pos -= 1)
|
23
|
-
(@stream << cursor(char)).flush
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def cursor(char)
|
29
|
-
@stream << @cursor_color
|
30
|
-
(SPACE.match?(char) ? '▁' : '▁▂▃▄▅▆▇█').each_char do |cursor|
|
31
|
-
(@stream << cursor).flush
|
32
|
-
sleep(0.002)
|
33
|
-
@stream << CURSOR_BACK
|
34
|
-
end
|
35
|
-
@stream << @color
|
36
|
-
char
|
37
|
-
end
|
38
|
-
|
39
|
-
CURSOR_BACK = Ansi.cursor_back(1)
|
40
|
-
end
|
41
|
-
|
42
|
-
define type_writer: TypeWriter
|
43
|
-
end
|
44
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
module LineAnimation
|
5
|
-
def self.defined = @defined.keys
|
6
|
-
def self.defined?(name) = @defined.key?(name)
|
7
|
-
def self.define(**kwargs) = @defined.merge!(kwargs)
|
8
|
-
|
9
|
-
def self.[](name)
|
10
|
-
return if name.nil?
|
11
|
-
klass = @defined[name] || @defined[:default]
|
12
|
-
return klass unless klass.is_a?(String)
|
13
|
-
require(klass)
|
14
|
-
klass = @defined[name] and return klass
|
15
|
-
raise(LoadError, "unknown animation - #{name}")
|
16
|
-
end
|
17
|
-
|
18
|
-
class None
|
19
|
-
def initialize(stream, options)
|
20
|
-
@stream = stream
|
21
|
-
@options = options
|
22
|
-
end
|
23
|
-
|
24
|
-
def print(_line) = raise(NotImplementedError)
|
25
|
-
|
26
|
-
protected
|
27
|
-
|
28
|
-
def to_column = Ansi.cursor_column(@options[:prefix_width] + 1)
|
29
|
-
def color = attribute(:color, :default)
|
30
|
-
|
31
|
-
def attribute(name, *default)
|
32
|
-
att = @options[name] or return Ansi[*default]
|
33
|
-
return Ansi[*att] if att.is_a?(Enumerable)
|
34
|
-
Ansi.try_convert(att.to_s) || Ansi[*default]
|
35
|
-
end
|
36
|
-
|
37
|
-
SPACE = /[[:space:]]/
|
38
|
-
end
|
39
|
-
|
40
|
-
dir = __dir__
|
41
|
-
@defined = {
|
42
|
-
default: "#{dir}/line_animation/default",
|
43
|
-
matrix: "#{dir}/line_animation/matrix",
|
44
|
-
rainbow: "#{dir}/line_animation/rainbow",
|
45
|
-
type_writer: "#{dir}/line_animation/type_writer"
|
46
|
-
}.compare_by_identity
|
47
|
-
end
|
48
|
-
end
|