natty-ui 0.8.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 +3 -2
- data/examples/24bit-colors.rb +11 -7
- data/examples/3bit-colors.rb +3 -2
- data/examples/8bit-colors.rb +2 -2
- data/examples/animate.rb +24 -0
- data/examples/attributes.rb +20 -65
- data/examples/demo.rb +39 -203
- data/examples/illustration.png +0 -0
- data/examples/illustration.rb +26 -23
- data/examples/{list_in_columns.rb → ls.rb} +11 -11
- data/examples/message.rb +30 -0
- data/examples/progress.rb +2 -2
- data/examples/query.rb +6 -2
- data/examples/read_key.rb +13 -0
- data/examples/table.rb +26 -8
- data/lib/natty-ui/ansi.rb +354 -328
- data/lib/natty-ui/ansi_constants.rb +73 -0
- data/lib/natty-ui/ansi_wrapper.rb +68 -23
- 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 +1 -1
- data/lib/natty-ui/wrapper/animate.rb +17 -0
- data/lib/natty-ui/wrapper/ask.rb +2 -8
- data/lib/natty-ui/wrapper/framed.rb +26 -21
- data/lib/natty-ui/wrapper/heading.rb +1 -1
- data/lib/natty-ui/wrapper/horizontal_rule.rb +3 -3
- data/lib/natty-ui/wrapper/list_in_columns.rb +7 -4
- data/lib/natty-ui/wrapper/message.rb +4 -4
- data/lib/natty-ui/wrapper/progress.rb +33 -8
- data/lib/natty-ui/wrapper/query.rb +9 -13
- data/lib/natty-ui/wrapper/request.rb +2 -2
- data/lib/natty-ui/wrapper/section.rb +25 -11
- data/lib/natty-ui/wrapper/table.rb +11 -11
- data/lib/natty-ui/wrapper.rb +19 -14
- data/lib/natty-ui.rb +33 -12
- metadata +16 -4
@@ -11,8 +11,7 @@ module NattyUI
|
|
11
11
|
# {Wrapper::Element#close}.
|
12
12
|
#
|
13
13
|
# @param [Array<#to_s>] args more objects to print
|
14
|
-
# @param [
|
15
|
-
# valid types are `:rounded`, `:simple`, `:heavy`, `:semi`, `:double`
|
14
|
+
# @param [:block, :double, :heavy, :rounded, :semi, :simple] type frame type
|
16
15
|
# @yieldparam [Wrapper::Framed] framed the created section
|
17
16
|
# @return [Object] the result of the code block
|
18
17
|
# @return [Wrapper::Framed] itself, when no code block is given
|
@@ -30,30 +29,36 @@ module NattyUI
|
|
30
29
|
protected
|
31
30
|
|
32
31
|
def initialize(parent, type:)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
color("#{@type[0]}#{@type[1] * (parent.available_width - 2)}")
|
37
|
-
)
|
38
|
-
super(parent, prefix: "#{color(@type[4])} ", prefix_width: 2)
|
39
|
-
@suffix = ' '
|
40
|
-
@suffix_width = 1
|
32
|
+
deco = as_deco(type)
|
33
|
+
super(parent, prefix: "#{deco[0]} ", prefix_width: 2, suffix_width: 2)
|
34
|
+
init(deco)
|
41
35
|
end
|
42
36
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
)
|
37
|
+
def as_deco(type)
|
38
|
+
if type.is_a?(Symbol)
|
39
|
+
ret = DECO[type] and return ret
|
40
|
+
elsif type.is_a?(String)
|
41
|
+
return type if type.size == 8
|
42
|
+
return type * 8 if type.size == 1
|
43
|
+
end
|
44
|
+
raise(ArgumentError, "invalid frame type - #{type.inspect}")
|
47
45
|
end
|
48
46
|
|
49
|
-
def
|
47
|
+
def init(deco)
|
48
|
+
aw = @parent.available_width - 1
|
49
|
+
parent.puts("#{deco[1]}#{deco[2] * aw}")
|
50
|
+
@finish = "#{deco[5]}#{deco[6] * aw}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def finish = @parent.puts(@finish)
|
50
54
|
|
51
|
-
|
52
|
-
rounded: '
|
53
|
-
simple: '
|
54
|
-
heavy: '
|
55
|
-
double: '
|
56
|
-
semi: '
|
55
|
+
DECO = {
|
56
|
+
rounded: '│╭─╮│╰─╯',
|
57
|
+
simple: '│┌─┐│└─┘',
|
58
|
+
heavy: '┃┏━┓┃┗━┛',
|
59
|
+
double: '║╔═╗║╚═╝',
|
60
|
+
semi: '│╒═╕│╘═╛',
|
61
|
+
block: '▌▛▀▜▐▙▄▟'
|
57
62
|
}.compare_by_identity.freeze
|
58
63
|
end
|
59
64
|
end
|
@@ -51,7 +51,7 @@ module NattyUI
|
|
51
51
|
@parent.puts(
|
52
52
|
title,
|
53
53
|
prefix: "#{Ansi[39]}#{enclose} #{Ansi[:bold, 255]}",
|
54
|
-
suffix: " #{Ansi[:
|
54
|
+
suffix: " #{Ansi[:bold_off, 39]}#{enclose}#{Ansi::RESET}",
|
55
55
|
max_width: available_width - 2 - (enclose.size * 2)
|
56
56
|
)
|
57
57
|
end
|
@@ -8,7 +8,7 @@ module NattyUI
|
|
8
8
|
#
|
9
9
|
# @param [#to_s] symbol string to build the horizontal rule
|
10
10
|
# @return [Wrapper::Section, Wrapper] it's parent object
|
11
|
-
def hr(symbol = '
|
11
|
+
def hr(symbol = '─') = _element(:HorizontalRule, symbol)
|
12
12
|
end
|
13
13
|
|
14
14
|
class Wrapper
|
@@ -23,8 +23,8 @@ module NattyUI
|
|
23
23
|
size = NattyUI.display_width(symbol = symbol.to_s)
|
24
24
|
return @parent.puts if size == 0
|
25
25
|
max_width = available_width
|
26
|
-
@parent.
|
27
|
-
symbol * ((max_width / size)
|
26
|
+
@parent.print(
|
27
|
+
symbol * ((max_width / size)),
|
28
28
|
max_width: max_width,
|
29
29
|
prefix: Ansi[39],
|
30
30
|
prefix_width: 0,
|
@@ -25,7 +25,7 @@ module NattyUI
|
|
25
25
|
#
|
26
26
|
# @example ordered list, start at 100
|
27
27
|
# ui.ls('apple', 'banana', 'blueberry', 'pineapple', 'strawberry', glyph: 100)
|
28
|
-
# # =>
|
28
|
+
# # => 100 apple 101 banana 102 blueberry 103 pineapple 104 strawberry
|
29
29
|
#
|
30
30
|
# @example ordered list using, uppercase characters
|
31
31
|
# ui.ls('apple', 'banana', 'blueberry', 'pineapple', 'strawberry', glyph: :A)
|
@@ -84,7 +84,11 @@ module NattyUI
|
|
84
84
|
->(s) { "#{(glyph += 1).to_s.rjust(pad)} #{NattyUI.embellish(s)}" }
|
85
85
|
when Symbol
|
86
86
|
lambda do |s|
|
87
|
-
"#{
|
87
|
+
"#{
|
88
|
+
t = glyph
|
89
|
+
glyph = glyph.succ
|
90
|
+
t
|
91
|
+
} #{NattyUI.embellish(s)}"
|
88
92
|
end
|
89
93
|
else
|
90
94
|
->(s) { "#{glyph} #{NattyUI.embellish(s)}" }
|
@@ -122,8 +126,7 @@ module NattyUI
|
|
122
126
|
end
|
123
127
|
|
124
128
|
def fill(ary, size)
|
125
|
-
diff = size - ary.size
|
126
|
-
ary.fill(nil, ary.size, diff) if diff.positive?
|
129
|
+
(diff = size - ary.size).positive? && ary.fill(nil, ary.size, diff)
|
127
130
|
end
|
128
131
|
|
129
132
|
Item =
|
@@ -96,13 +96,13 @@ module NattyUI
|
|
96
96
|
def initialize(parent, title:, glyph:)
|
97
97
|
glyph = parent.wrapper.glyph(glyph) || glyph
|
98
98
|
prefix_width = NattyUI.display_width(glyph) + 1
|
99
|
-
|
100
|
-
|
101
|
-
prefix:
|
99
|
+
super(
|
100
|
+
parent,
|
101
|
+
prefix: ' ' * prefix_width,
|
102
102
|
prefix_width: prefix_width,
|
103
103
|
suffix_width: 0
|
104
104
|
)
|
105
|
-
|
105
|
+
parent.puts(title, prefix: "#{glyph} ", prefix_width: prefix_width)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -7,14 +7,23 @@ module NattyUI
|
|
7
7
|
module Features
|
8
8
|
# Creates progress element implementing additional {ProgressAttributes}.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# When a `max_value` is given, the progress will by displayed as a bar.
|
11
|
+
# Otherwise the `spinner` is used for a little animation.
|
12
|
+
#
|
13
|
+
# When no pre-defined spinner is specified then spinner will be
|
14
|
+
# used char-wise as a string for the progress animation.
|
15
|
+
#
|
16
|
+
# A progress element has additional states and can be closed with
|
17
|
+
# {#completed} or {#failed}.
|
12
18
|
#
|
13
19
|
# @param [#to_s] title object to print as progress title
|
14
|
-
# @param [
|
20
|
+
# @param [#to_f] max_value maximum value of the progress
|
21
|
+
# @param [:bar, :blink, :blocks, :braile, :circle, :colors, :pulse,
|
22
|
+
# :snake, :swap, :triangles, :vintage, #to_s] spinner type of spinner or
|
23
|
+
# spinner elements
|
15
24
|
# @return [Wrapper::Progress] the created progress element
|
16
|
-
def progress(title, max_value: nil)
|
17
|
-
_element(:Progress, title, max_value)
|
25
|
+
def progress(title, max_value: nil, spinner: :pulse)
|
26
|
+
_element(:Progress, title, max_value, spinner)
|
18
27
|
end
|
19
28
|
end
|
20
29
|
|
@@ -29,15 +38,31 @@ module NattyUI
|
|
29
38
|
|
30
39
|
protected
|
31
40
|
|
32
|
-
def call(title, max_value)
|
41
|
+
def call(title, max_value, spinner)
|
33
42
|
@final_text = [title]
|
34
43
|
@max_value = [0, max_value.to_f].max if max_value
|
35
44
|
@value = @progress = 0
|
36
|
-
draw(title)
|
45
|
+
draw(title, SPINNER[spinner] || spinner.to_s)
|
37
46
|
self
|
38
47
|
end
|
39
48
|
|
40
|
-
|
49
|
+
SPINNER = {
|
50
|
+
bar: '▁▂▃▄▅▆▇█▇▆▅▄▃▂',
|
51
|
+
blink: '■□▪▫',
|
52
|
+
blocks: '▖▘▝▗',
|
53
|
+
braile: '⣷⣯⣟⡿⢿⣻⣽⣾',
|
54
|
+
braile_reverse: '⡿⣟⣯⣷⣾⣽⣻⢿',
|
55
|
+
circle: '◐◓◑◒',
|
56
|
+
colors: '🟨🟧🟥🟦🟪🟩',
|
57
|
+
pulse: '•✺◉●◉✺',
|
58
|
+
snake: '⠁⠉⠙⠸⢰⣠⣄⡆⠇⠃',
|
59
|
+
swap: '㊂㊀㊁',
|
60
|
+
triangles: '◢◣◤◥',
|
61
|
+
vintage: '-\\|/'
|
62
|
+
}.compare_by_identity.freeze
|
63
|
+
private_constant :SPINNER
|
64
|
+
|
65
|
+
def draw(title, _spinner)
|
41
66
|
(wrapper.stream << @parent.prefix << "➔ #{title} ").flush
|
42
67
|
end
|
43
68
|
|
@@ -63,28 +63,24 @@ module NattyUI
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def as_choices(choices, kw_choices)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
.transform_values! { _1.to_s.tr("\r\n\t", ' ') }
|
74
|
-
)
|
66
|
+
choices
|
67
|
+
.take(9)
|
68
|
+
.each_with_index
|
69
|
+
.to_h { |str, i| [i + 1, str] }
|
70
|
+
.merge!(kw_choices)
|
71
|
+
.transform_keys!(&:to_s)
|
72
|
+
.transform_values! { _1.to_s.gsub(/[[:space:]]/, ' ') }
|
75
73
|
end
|
76
74
|
|
77
75
|
def read(choices, result)
|
78
76
|
while true
|
79
|
-
char = NattyUI.
|
80
|
-
return if
|
77
|
+
char = NattyUI.read_key
|
78
|
+
return if char == 'Ctrl+C'
|
81
79
|
next unless choices.key?(char)
|
82
80
|
return char if result == :char
|
83
81
|
return choices[char] if result == :title
|
84
82
|
return char, choices[char]
|
85
83
|
end
|
86
|
-
rescue Interrupt, SystemCallError
|
87
|
-
nil
|
88
84
|
end
|
89
85
|
|
90
86
|
CHOICE_MARK = Ansi[:bold, 34]
|
@@ -46,8 +46,8 @@ module NattyUI
|
|
46
46
|
(wrapper.stream << ANSI_PREFIX).flush if wrapper.ansi?
|
47
47
|
end
|
48
48
|
|
49
|
-
ANSI_PREFIX = Ansi::RESET + Ansi
|
50
|
-
ANSI_FINISH = Ansi::RESET + Ansi::
|
49
|
+
ANSI_PREFIX = Ansi::RESET + Ansi::ITALIC
|
50
|
+
ANSI_FINISH = Ansi::RESET + Ansi::LINE_PREVIOUS + Ansi::LINE_ERASE
|
51
51
|
private_constant :ANSI_PREFIX, :ANSI_FINISH
|
52
52
|
end
|
53
53
|
end
|
@@ -8,10 +8,14 @@ module NattyUI
|
|
8
8
|
# into the section.
|
9
9
|
#
|
10
10
|
# @param [Array<#to_s>] args optional objects to print
|
11
|
+
# @param [String] prefix used for each printed line
|
12
|
+
# @param [String] suffix used for each printed line
|
11
13
|
# @yieldparam [Wrapper::Section] section the created section
|
12
14
|
# @return [Object] the result of the code block
|
13
15
|
# @return [Wrapper::Section] itself, when no code block is given
|
14
|
-
def section(*args,
|
16
|
+
def section(*args, prefix: ' ', suffix: ' ', &block)
|
17
|
+
_section(:Section, args, prefix: prefix, suffix: suffix, &block)
|
18
|
+
end
|
15
19
|
alias sec section
|
16
20
|
end
|
17
21
|
|
@@ -38,10 +42,12 @@ module NattyUI
|
|
38
42
|
return self if @status
|
39
43
|
@parent.puts(
|
40
44
|
*args,
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
+
**kwargs.merge!(
|
46
|
+
prefix: "#{@prefix}#{kwargs[:prefix]}",
|
47
|
+
prefix_width: @prefix_width + kwargs[:prefix_width].to_i,
|
48
|
+
suffix: "#{kwargs[:suffix]}#{@suffix}",
|
49
|
+
suffix_width: @suffix_width + kwargs[:suffix_width].to_i
|
50
|
+
)
|
45
51
|
)
|
46
52
|
self
|
47
53
|
end
|
@@ -55,10 +61,12 @@ module NattyUI
|
|
55
61
|
return self if @status
|
56
62
|
@parent.print(
|
57
63
|
*args,
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
**kwargs.merge!(
|
65
|
+
prefix: "#{@prefix}#{kwargs[:prefix]}",
|
66
|
+
prefix_width: @prefix_width + kwargs[:prefix_width].to_i,
|
67
|
+
suffix: "#{kwargs[:suffix]}#{@suffix}",
|
68
|
+
suffix_width: @suffix_width + kwargs[:suffix_width].to_i
|
69
|
+
)
|
62
70
|
)
|
63
71
|
self
|
64
72
|
end
|
@@ -87,17 +95,23 @@ module NattyUI
|
|
87
95
|
# @!visibility private
|
88
96
|
def inspect = @status ? "#{_to_s[..-2]} status=#{@status}>" : _to_s
|
89
97
|
|
98
|
+
# @!visibility private
|
99
|
+
def rcol = @parent.rcol - @suffix_width
|
100
|
+
|
90
101
|
protected
|
91
102
|
|
92
103
|
def initialize(
|
93
104
|
parent,
|
94
105
|
prefix:,
|
95
|
-
prefix_width: NattyUI.display_width(prefix)
|
106
|
+
prefix_width: NattyUI.display_width(prefix),
|
107
|
+
suffix: nil,
|
108
|
+
suffix_width: NattyUI.display_width(suffix)
|
96
109
|
)
|
97
110
|
super(parent)
|
98
111
|
@prefix = prefix
|
112
|
+
@suffix = suffix
|
99
113
|
@prefix_width = prefix_width
|
100
|
-
@suffix_width =
|
114
|
+
@suffix_width = suffix_width
|
101
115
|
end
|
102
116
|
end
|
103
117
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'element'
|
3
4
|
|
4
5
|
module NattyUI
|
@@ -10,11 +11,13 @@ module NattyUI
|
|
10
11
|
# construction. This means table features are not complete defined and
|
11
12
|
# may change in near future.
|
12
13
|
#
|
14
|
+
# Defined values for `type` are
|
15
|
+
# :double, :heavy, :semi, :simple
|
16
|
+
#
|
13
17
|
# @overload table(type: simple)
|
14
18
|
# Construct and display a table.
|
15
19
|
#
|
16
|
-
# @param [Symbol] type frame type
|
17
|
-
# valid types are `:simple`, `:heavy`, `:semi`, `:double`
|
20
|
+
# @param [Symbol] type frame type
|
18
21
|
# @yieldparam [Table] table construction helper
|
19
22
|
# @return [Wrapper::Section, Wrapper] it's parent object
|
20
23
|
#
|
@@ -39,8 +42,7 @@ module NattyUI
|
|
39
42
|
# Display the given arrays as rows of a table.
|
40
43
|
#
|
41
44
|
# @param [Array<#to_s>] args one or more arrays representing rows of the table
|
42
|
-
# @param [Symbol] type frame type
|
43
|
-
# valid types are `:simple`, `:heavy`, `:semi`, `:double`
|
45
|
+
# @param [Symbol] type frame type
|
44
46
|
# @return [Wrapper::Section, Wrapper] it's parent object
|
45
47
|
#
|
46
48
|
# @example
|
@@ -115,7 +117,7 @@ module NattyUI
|
|
115
117
|
raise(ArgumentError, "invalid table type - #{type.inspect}"),
|
116
118
|
Ansi[39],
|
117
119
|
Ansi::RESET
|
118
|
-
) {
|
120
|
+
) { @parent.puts(_1) }
|
119
121
|
@parent
|
120
122
|
end
|
121
123
|
|
@@ -142,7 +144,7 @@ module NattyUI
|
|
142
144
|
@parent.available_width - 1,
|
143
145
|
seperator,
|
144
146
|
NattyUI.plain(seperator, ansi: false)[-1] == ' '
|
145
|
-
) {
|
147
|
+
) { @parent.puts(_1) }
|
146
148
|
@parent
|
147
149
|
end
|
148
150
|
end
|
@@ -217,7 +219,7 @@ module NattyUI
|
|
217
219
|
|
218
220
|
def align(str, width, alignment)
|
219
221
|
return str unless (width -= NattyUI.display_width(str)).positive?
|
220
|
-
return str
|
222
|
+
return str + (' ' * width) if alignment == :left
|
221
223
|
(' ' * width) << str
|
222
224
|
end
|
223
225
|
|
@@ -268,10 +270,8 @@ module NattyUI
|
|
268
270
|
|
269
271
|
def adjusted_widths(col_widths)
|
270
272
|
ret = col_widths.dup
|
271
|
-
|
272
|
-
|
273
|
-
return ret
|
274
|
-
end
|
273
|
+
left = @max_width - (@col_div_size * (col_widths.size - 1))
|
274
|
+
return ret if ret.sum <= left
|
275
275
|
indexed = ret.each_with_index.to_a
|
276
276
|
# TODO: optimize this!
|
277
277
|
until ret.sum <= left
|
data/lib/natty-ui/wrapper.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'io/console'
|
4
4
|
require_relative 'ansi'
|
5
|
+
require_relative 'wrapper/animate'
|
5
6
|
require_relative 'wrapper/ask'
|
6
7
|
require_relative 'wrapper/framed'
|
7
8
|
require_relative 'wrapper/heading'
|
@@ -65,7 +66,7 @@ module NattyUI
|
|
65
66
|
def print(*args, **kwargs)
|
66
67
|
args = prepare_print(args, kwargs).to_a
|
67
68
|
@lines_written += args.size - 1
|
68
|
-
@stream.print(args
|
69
|
+
@stream.print(*args)
|
69
70
|
@stream.flush
|
70
71
|
self
|
71
72
|
end
|
@@ -148,7 +149,10 @@ module NattyUI
|
|
148
149
|
alias available_width screen_columns
|
149
150
|
|
150
151
|
# @!visibility private
|
151
|
-
|
152
|
+
alias rcol screen_columns
|
153
|
+
|
154
|
+
# @!visibility private
|
155
|
+
def prefix = nil
|
152
156
|
|
153
157
|
# @return [Array<Symbol>] available glyph names
|
154
158
|
def glyph_names = GLYPHS.keys
|
@@ -164,25 +168,26 @@ module NattyUI
|
|
164
168
|
protected
|
165
169
|
|
166
170
|
def prepare_print(args, kwargs)
|
167
|
-
|
168
|
-
|
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]
|
169
177
|
return ["#{prefix}#{suffix}"] if args.empty?
|
170
178
|
NattyUI
|
171
179
|
.each_line(
|
172
|
-
*args.map!
|
173
|
-
max_width:
|
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
|
174
187
|
)
|
175
188
|
.map { "#{prefix}#{_1}#{suffix}" }
|
176
189
|
end
|
177
190
|
|
178
|
-
def max_with(prefix, suffix, kwargs)
|
179
|
-
mw = kwargs[:max_width] and return mw
|
180
|
-
mw = screen_columns
|
181
|
-
mw -= kwargs[:prefix_width] || NattyUI.display_width(prefix) if prefix
|
182
|
-
mw -= kwargs[:suffix_width] || NattyUI.display_width(suffix) if suffix
|
183
|
-
mw
|
184
|
-
end
|
185
|
-
|
186
191
|
def temp_func
|
187
192
|
lambda do
|
188
193
|
@stream.flush
|
data/lib/natty-ui.rb
CHANGED
@@ -149,9 +149,12 @@ module NattyUI
|
|
149
149
|
str
|
150
150
|
.to_s
|
151
151
|
.each_line(chomp: true) do |line|
|
152
|
-
|
153
|
-
|
154
|
-
|
152
|
+
next yield(line) if line.empty?
|
153
|
+
lines, _height = Reline::Unicode.split_by_width(line, max_width)
|
154
|
+
lines.compact!
|
155
|
+
next if lines.empty?
|
156
|
+
lines.pop if lines[-1].empty?
|
157
|
+
lines.each(&block)
|
155
158
|
end
|
156
159
|
end
|
157
160
|
nil
|
@@ -159,23 +162,35 @@ module NattyUI
|
|
159
162
|
|
160
163
|
# Read next raw key (keyboard input) from {in_stream}.
|
161
164
|
#
|
165
|
+
# The input will be returned as named key codes like "Ctrl+C" by default.
|
166
|
+
# This can be changed by the `mode` parameter:
|
167
|
+
#
|
168
|
+
# - `:named` - name if available (fallback to raw)
|
169
|
+
# - `:raw` - key code "as is"
|
170
|
+
# - `:both` - key code and name if available
|
171
|
+
#
|
172
|
+
# @param [:named, :raw, :both] mode modfies the result
|
162
173
|
# @return [String] read key
|
163
|
-
def read_key
|
174
|
+
def read_key(mode: :named)
|
164
175
|
return @in_stream.getch unless defined?(@in_stream.getc)
|
165
176
|
return @in_stream.getc unless defined?(@in_stream.raw)
|
166
|
-
@in_stream.raw do |
|
167
|
-
key =
|
168
|
-
while (nc =
|
177
|
+
@in_stream.raw do |raw_stream|
|
178
|
+
key = raw_stream.getc
|
179
|
+
while (nc = raw_stream.read_nonblock(1, exception: false))
|
169
180
|
nc.is_a?(String) ? key += nc : break
|
170
181
|
end
|
171
|
-
key
|
182
|
+
return key if mode == :raw
|
183
|
+
return key, KEY_MAP[key]&.dup if mode == :both
|
184
|
+
KEY_MAP[key]&.dup || key
|
172
185
|
end
|
186
|
+
rescue Interrupt, SystemCallError
|
187
|
+
nil
|
173
188
|
end
|
174
189
|
|
175
190
|
private
|
176
191
|
|
177
192
|
def wrapper_class(stream, ansi)
|
178
|
-
return AnsiWrapper if ansi == true
|
193
|
+
return AnsiWrapper if ansi == true || ENV['ANSI'] == '1'
|
179
194
|
if ansi == false || ENV.key?('NO_COLOR') || ENV['TERM'] == 'dumb'
|
180
195
|
return Wrapper
|
181
196
|
end
|
@@ -197,8 +212,14 @@ module NattyUI
|
|
197
212
|
|
198
213
|
@element = StdOut
|
199
214
|
self.in_stream = STDIN
|
215
|
+
|
216
|
+
autoload(:KEY_MAP, File.join(__dir__, 'natty-ui', 'key_map'))
|
217
|
+
private_constant :KEY_MAP
|
200
218
|
end
|
201
219
|
|
202
|
-
#
|
203
|
-
|
204
|
-
|
220
|
+
# @!visibility private
|
221
|
+
module Kernel
|
222
|
+
# @see NattyUI.element
|
223
|
+
# @return [NattyUI::Wrapper, NattyUI::Wrapper::Element] active UI element
|
224
|
+
def ui = NattyUI.element unless defined?(ui)
|
225
|
+
end
|
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.9.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-
|
11
|
+
date: 2024-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely,
|
@@ -28,20 +28,32 @@ files:
|
|
28
28
|
- examples/24bit-colors.rb
|
29
29
|
- examples/3bit-colors.rb
|
30
30
|
- examples/8bit-colors.rb
|
31
|
+
- examples/animate.rb
|
31
32
|
- examples/attributes.rb
|
32
33
|
- examples/demo.rb
|
33
34
|
- examples/illustration.png
|
34
35
|
- examples/illustration.rb
|
35
|
-
- examples/
|
36
|
+
- examples/ls.rb
|
37
|
+
- examples/message.rb
|
36
38
|
- examples/progress.rb
|
37
39
|
- examples/query.rb
|
40
|
+
- examples/read_key.rb
|
38
41
|
- examples/table.rb
|
39
42
|
- lib/natty-ui.rb
|
40
43
|
- lib/natty-ui/ansi.rb
|
44
|
+
- lib/natty-ui/ansi_constants.rb
|
41
45
|
- lib/natty-ui/ansi_wrapper.rb
|
42
46
|
- lib/natty-ui/features.rb
|
47
|
+
- lib/natty-ui/key_map.rb
|
48
|
+
- lib/natty-ui/line_animation.rb
|
49
|
+
- lib/natty-ui/line_animation/default.rb
|
50
|
+
- lib/natty-ui/line_animation/matrix.rb
|
51
|
+
- lib/natty-ui/line_animation/rainbow.rb
|
52
|
+
- lib/natty-ui/line_animation/test.rb
|
53
|
+
- lib/natty-ui/line_animation/type_writer.rb
|
43
54
|
- lib/natty-ui/version.rb
|
44
55
|
- lib/natty-ui/wrapper.rb
|
56
|
+
- lib/natty-ui/wrapper/animate.rb
|
45
57
|
- lib/natty-ui/wrapper/ask.rb
|
46
58
|
- lib/natty-ui/wrapper/element.rb
|
47
59
|
- lib/natty-ui/wrapper/framed.rb
|
@@ -81,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
93
|
- !ruby/object:Gem::Version
|
82
94
|
version: '0'
|
83
95
|
requirements: []
|
84
|
-
rubygems_version: 3.5.
|
96
|
+
rubygems_version: 3.5.14
|
85
97
|
signing_key:
|
86
98
|
specification_version: 4
|
87
99
|
summary: This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely, natty
|