natty-ui 0.12.1 → 0.25.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/LICENSE +1 -1
- data/README.md +22 -26
- data/examples/24bit-colors.rb +4 -7
- data/examples/3bit-colors.rb +28 -6
- data/examples/8bit-colors.rb +18 -21
- data/examples/attributes.rb +30 -22
- data/examples/cols.rb +40 -0
- data/examples/elements.rb +31 -0
- data/examples/examples.rb +45 -0
- data/examples/illustration.rb +56 -54
- data/examples/ls.rb +16 -16
- data/examples/named-colors.rb +23 -0
- data/examples/sections.rb +29 -0
- data/examples/tables.rb +62 -0
- data/examples/tasks.rb +52 -0
- data/lib/natty-ui/attributes.rb +604 -0
- data/lib/natty-ui/choice.rb +56 -0
- data/lib/natty-ui/dumb_choice.rb +45 -0
- data/lib/natty-ui/element.rb +78 -0
- data/lib/natty-ui/features.rb +798 -0
- data/lib/natty-ui/framed.rb +51 -0
- data/lib/natty-ui/ls_renderer.rb +93 -0
- data/lib/natty-ui/progress.rb +187 -0
- data/lib/natty-ui/section.rb +69 -0
- data/lib/natty-ui/table.rb +241 -0
- data/lib/natty-ui/table_renderer.rb +147 -0
- data/lib/natty-ui/task.rb +44 -0
- data/lib/natty-ui/temporary.rb +38 -0
- data/lib/natty-ui/theme.rb +303 -0
- data/lib/natty-ui/utils.rb +79 -0
- data/lib/natty-ui/version.rb +1 -1
- data/lib/natty-ui/width_finder.rb +125 -0
- data/lib/natty-ui.rb +89 -147
- metadata +44 -53
- data/examples/animate.rb +0 -42
- data/examples/attributes_list.rb +0 -12
- data/examples/demo.rb +0 -51
- data/examples/message.rb +0 -30
- data/examples/progress.rb +0 -66
- data/examples/query.rb +0 -39
- data/examples/read_key.rb +0 -13
- data/examples/table.rb +0 -39
- data/lib/natty-ui/animation/binary.rb +0 -36
- data/lib/natty-ui/animation/default.rb +0 -38
- data/lib/natty-ui/animation/matrix.rb +0 -51
- data/lib/natty-ui/animation/rainbow.rb +0 -28
- data/lib/natty-ui/animation/type_writer.rb +0 -44
- data/lib/natty-ui/animation.rb +0 -69
- data/lib/natty-ui/ansi/constants.rb +0 -75
- data/lib/natty-ui/ansi.rb +0 -530
- data/lib/natty-ui/ansi_wrapper.rb +0 -232
- data/lib/natty-ui/frame.rb +0 -53
- data/lib/natty-ui/glyph.rb +0 -64
- data/lib/natty-ui/key_map.rb +0 -142
- data/lib/natty-ui/preload.rb +0 -12
- data/lib/natty-ui/spinner.rb +0 -120
- data/lib/natty-ui/text/east_asian_width.rb +0 -2529
- data/lib/natty-ui/text.rb +0 -203
- data/lib/natty-ui/wrapper/animate.rb +0 -17
- data/lib/natty-ui/wrapper/ask.rb +0 -78
- data/lib/natty-ui/wrapper/element.rb +0 -79
- data/lib/natty-ui/wrapper/features.rb +0 -21
- data/lib/natty-ui/wrapper/framed.rb +0 -45
- data/lib/natty-ui/wrapper/heading.rb +0 -64
- data/lib/natty-ui/wrapper/horizontal_rule.rb +0 -37
- data/lib/natty-ui/wrapper/list_in_columns.rb +0 -138
- data/lib/natty-ui/wrapper/message.rb +0 -109
- data/lib/natty-ui/wrapper/mixins.rb +0 -75
- data/lib/natty-ui/wrapper/progress.rb +0 -63
- data/lib/natty-ui/wrapper/query.rb +0 -89
- data/lib/natty-ui/wrapper/quote.rb +0 -25
- data/lib/natty-ui/wrapper/request.rb +0 -54
- data/lib/natty-ui/wrapper/section.rb +0 -118
- data/lib/natty-ui/wrapper/table.rb +0 -550
- data/lib/natty-ui/wrapper/task.rb +0 -55
- data/lib/natty-ui/wrapper.rb +0 -239
@@ -1,232 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'wrapper'
|
4
|
-
|
5
|
-
module NattyUI
|
6
|
-
class AnsiWrapper < Wrapper
|
7
|
-
def ansi? = true
|
8
|
-
|
9
|
-
def cursor=(value)
|
10
|
-
if value
|
11
|
-
(@stream << Ansi::CURSOR_SHOW).flush if @cursor == 1
|
12
|
-
@cursor -= 1 if @cursor.positive?
|
13
|
-
return
|
14
|
-
end
|
15
|
-
(@stream << Ansi::CURSOR_HIDE).flush if @cursor.zero?
|
16
|
-
@cursor += 1
|
17
|
-
end
|
18
|
-
|
19
|
-
def puts(*args, **kwargs)
|
20
|
-
return super if args.empty? || (animation = kwargs[:animation]).nil?
|
21
|
-
animation = Animation[animation].new(wrapper, args, kwargs)
|
22
|
-
self.cursor = false
|
23
|
-
animation.perform(@stream)
|
24
|
-
@lines_written += animation.lines_written
|
25
|
-
self.cursor = true
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def page
|
30
|
-
unless block_given?
|
31
|
-
@stream.flush
|
32
|
-
return self
|
33
|
-
end
|
34
|
-
(@stream << Ansi::SCREEN_BLANK).flush
|
35
|
-
begin
|
36
|
-
yield(self)
|
37
|
-
ensure
|
38
|
-
(@stream << Ansi::SCREEN_UNBLANK).flush
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def cls
|
43
|
-
(@stream << Ansi::CLS).flush
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
protected
|
48
|
-
|
49
|
-
def pprint(strs, opts)
|
50
|
-
prefix = opts[:prefix] and prefix = Text.embellish(prefix)
|
51
|
-
suffix = opts[:suffix] and suffix = Text.embellish(suffix)
|
52
|
-
return yield("#{prefix}#{suffix}") if strs.empty?
|
53
|
-
max_width =
|
54
|
-
opts.fetch(:max_width) do
|
55
|
-
screen_columns - (opts[:prefix_width] || Text.width(prefix)) -
|
56
|
-
(opts[:suffix_width] || Text.width(suffix))
|
57
|
-
end
|
58
|
-
case opts[:align]
|
59
|
-
when :right
|
60
|
-
Text.each_line(strs, max_width) do |line, width|
|
61
|
-
width = max_width - width
|
62
|
-
yield("#{prefix}#{' ' * width}#{line}#{suffix}")
|
63
|
-
end
|
64
|
-
when :center
|
65
|
-
Text.each_line(strs, max_width) do |line, width|
|
66
|
-
width = max_width - width
|
67
|
-
right = width / 2
|
68
|
-
yield(
|
69
|
-
"#{prefix}#{' ' * (width - right)}#{line}#{' ' * right}#{suffix}"
|
70
|
-
)
|
71
|
-
end
|
72
|
-
else
|
73
|
-
Text.each_line(strs, max_width) { yield("#{prefix}#{_1}#{suffix}") }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def temp_func
|
78
|
-
count = @lines_written
|
79
|
-
lambda do
|
80
|
-
if (c = @lines_written - count).nonzero?
|
81
|
-
@stream << Ansi.cursor_prev_line(c) << Ansi.screen_erase(:below) <<
|
82
|
-
Ansi::CURSOR_FIRST_COLUMN
|
83
|
-
@lines_written -= c
|
84
|
-
end
|
85
|
-
@stream.flush
|
86
|
-
self
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class Progress < Element
|
91
|
-
include ProgressAttributes
|
92
|
-
include ValueAttributes
|
93
|
-
|
94
|
-
protected
|
95
|
-
|
96
|
-
def call(title, max_value, spinner)
|
97
|
-
@title = "[b 27]➔[/b] #{title}"
|
98
|
-
@info = nil
|
99
|
-
@final_text = [title]
|
100
|
-
if max_value
|
101
|
-
@max_value = [0, max_value.to_f].max
|
102
|
-
else
|
103
|
-
@spinner = NattyUI::Spinner[spinner]
|
104
|
-
end
|
105
|
-
@value = 0
|
106
|
-
@pos = wrapper.lines_written
|
107
|
-
wrapper.cursor = false
|
108
|
-
@parent.puts(@last_render = render)
|
109
|
-
@height = wrapper.lines_written - @pos
|
110
|
-
self
|
111
|
-
end
|
112
|
-
|
113
|
-
def redraw
|
114
|
-
return if @status
|
115
|
-
current = render
|
116
|
-
return if @last_render == current
|
117
|
-
wrapper.stream << Ansi.cursor_previous_line(@height) << Ansi::LINE_ERASE
|
118
|
-
cl = wrapper.lines_written
|
119
|
-
@parent.puts(@last_render = current)
|
120
|
-
@height = wrapper.lines_written - cl
|
121
|
-
end
|
122
|
-
|
123
|
-
def render
|
124
|
-
return "#{@title} #{@spinner.next}#{" #{@info}" if @info}" if @spinner
|
125
|
-
percent = @max_value.zero? ? 100.0 : @value / @max_value
|
126
|
-
count = [(30 * percent).round, 30].min
|
127
|
-
mv = @max_value.round.to_s
|
128
|
-
"#{@title} [27 on27]#{'█' * count}[ec onec]#{
|
129
|
-
'▁' * (30 - count)
|
130
|
-
}[/bg] [e2 b]#{(percent * 100).round.to_s.rjust(3)}%[/b] [f6](#{
|
131
|
-
@value.round.to_s.rjust(mv.size)
|
132
|
-
}/#{mv})[/]#{" #{@info}" if @info}"
|
133
|
-
end
|
134
|
-
|
135
|
-
def finish
|
136
|
-
wrapper.stream << Ansi.cursor_previous_line(@height) << Ansi::LINE_ERASE
|
137
|
-
wrapper.instance_variable_set(:@lines_written, @pos)
|
138
|
-
wrapper.cursor = true
|
139
|
-
return @parent.failed(*@final_text) if failed?
|
140
|
-
@parent.message(*@final_text, glyph: @status = :completed)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
module Temporary
|
145
|
-
def temporary
|
146
|
-
unless block_given?
|
147
|
-
wrapper.stream.flush
|
148
|
-
return self
|
149
|
-
end
|
150
|
-
count = wrapper.lines_written
|
151
|
-
begin
|
152
|
-
yield(self)
|
153
|
-
ensure
|
154
|
-
count = wrapper.lines_written - count
|
155
|
-
if count.nonzero?
|
156
|
-
wrapper.stream << Ansi.cursor_prev_line(count) <<
|
157
|
-
Ansi.display(:erase_below)
|
158
|
-
end
|
159
|
-
wrapper.stream.flush
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
class Section < Section
|
165
|
-
include Temporary
|
166
|
-
end
|
167
|
-
|
168
|
-
class Quote < Quote
|
169
|
-
include Temporary
|
170
|
-
|
171
|
-
def initialize(...)
|
172
|
-
super
|
173
|
-
@prefix = "#{Ansi[39]}#{@prefix}#{Ansi::RESET}"
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
class Framed < Framed
|
178
|
-
def color(str) = "#{Ansi[39]}#{str}#{Ansi::RESET}"
|
179
|
-
|
180
|
-
def init(type)
|
181
|
-
@prefix = "#{color(type[4])} "
|
182
|
-
@suffix = "#{Ansi.cursor_column(parent.rcol)}#{color(type[4])}"
|
183
|
-
aw = @parent.available_width - 2
|
184
|
-
parent.puts(color("#{type[0]}#{type[5] * aw}#{type[1]}"))
|
185
|
-
@finish = color("#{type[2]}#{type[5] * aw}#{type[3]}")
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
class Message < Section
|
190
|
-
protected
|
191
|
-
|
192
|
-
def initialize(parent, title:, glyph:, **opts)
|
193
|
-
color = COLORS[glyph] || COLORS[:default]
|
194
|
-
glyph = NattyUI::Glyph[glyph]
|
195
|
-
prefix_width = Text.width(glyph) + 1
|
196
|
-
parent.puts(
|
197
|
-
title,
|
198
|
-
prefix: "#{glyph} #{color}",
|
199
|
-
prefix_width: prefix_width,
|
200
|
-
suffix: Ansi::RESET,
|
201
|
-
suffix_width: 0
|
202
|
-
)
|
203
|
-
super(
|
204
|
-
parent,
|
205
|
-
prefix: ' ' * prefix_width,
|
206
|
-
prefix_width: prefix_width,
|
207
|
-
**opts
|
208
|
-
)
|
209
|
-
end
|
210
|
-
|
211
|
-
white = Ansi[255]
|
212
|
-
COLORS = {
|
213
|
-
default: white,
|
214
|
-
point: white,
|
215
|
-
information: white,
|
216
|
-
warning: Ansi[221],
|
217
|
-
error: Ansi[208],
|
218
|
-
completed: Ansi[82],
|
219
|
-
failed: Ansi[196],
|
220
|
-
task: Ansi[39],
|
221
|
-
query: white
|
222
|
-
}.compare_by_identity.freeze
|
223
|
-
end
|
224
|
-
|
225
|
-
class Task < Message
|
226
|
-
include ProgressAttributes
|
227
|
-
include TaskMethods
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
private_constant :AnsiWrapper
|
232
|
-
end
|
data/lib/natty-ui/frame.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
# Helper class to select frame types.
|
5
|
-
# @see Features#framed
|
6
|
-
# @see Features#table
|
7
|
-
module Frame
|
8
|
-
# Define frame type used by default.
|
9
|
-
#
|
10
|
-
# @attribute [w] self.default
|
11
|
-
# @param value [Symbol] type name
|
12
|
-
# @return [Symbol] type name
|
13
|
-
def self.default=(value)
|
14
|
-
@default = self[value.nil? || value == :default ? :rounded : value]
|
15
|
-
end
|
16
|
-
|
17
|
-
# Defined frame type names.
|
18
|
-
# @see []
|
19
|
-
#
|
20
|
-
# @attribute [r] self.names
|
21
|
-
# @return [Array<Symbol>] supported attribute names
|
22
|
-
def self.names = @all.keys
|
23
|
-
|
24
|
-
# @param name [Symbol, String]
|
25
|
-
# defined type name (see {.names})
|
26
|
-
# or frame elements
|
27
|
-
# @return [String] frame definition
|
28
|
-
def self.[](name)
|
29
|
-
return @default if name == :default
|
30
|
-
if name.is_a?(Symbol)
|
31
|
-
ret = @all[name] and return ret
|
32
|
-
elsif name.is_a?(String)
|
33
|
-
return name if name.size == 11
|
34
|
-
return name * 11 if name.size == 1
|
35
|
-
end
|
36
|
-
raise(ArgumentError, "invalid frame type - #{name}")
|
37
|
-
end
|
38
|
-
|
39
|
-
@all = {
|
40
|
-
cols: ' │ │ ',
|
41
|
-
double: '╔╗╚╝║═╬╦╩╠╣',
|
42
|
-
heavy: '┏┓┗┛┃━╋┳┻┣┫',
|
43
|
-
rounded: '╭╮╰╯│─┼┬┴├┤',
|
44
|
-
rows: ' ── ',
|
45
|
-
semi: '╒╕╘╛│═╪╤╧╞╡',
|
46
|
-
semi2: '╓╖╙╜│─╫╥╨╟╢',
|
47
|
-
simple: '┌┐└┘│─┼┬┴├┤',
|
48
|
-
undecorated: ' '
|
49
|
-
}.compare_by_identity
|
50
|
-
|
51
|
-
self.default = nil
|
52
|
-
end
|
53
|
-
end
|
data/lib/natty-ui/glyph.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'text'
|
4
|
-
|
5
|
-
module NattyUI
|
6
|
-
# Helper class to select glyph types.
|
7
|
-
# @see Features#message
|
8
|
-
module Glyph
|
9
|
-
# Define glyph type used by default.
|
10
|
-
# @attribute [w] self.default
|
11
|
-
# @param value [Symbol] type name
|
12
|
-
# @return [Symbol] type name
|
13
|
-
def self.default=(value)
|
14
|
-
@default = self[value.nil? || value == :default ? :point : value]
|
15
|
-
end
|
16
|
-
|
17
|
-
# Defined glyph type names.
|
18
|
-
# @see []
|
19
|
-
#
|
20
|
-
# @attribute [r] self.names
|
21
|
-
# @return [Array<Symbol>] supported attribute names
|
22
|
-
def self.names = @all.keys
|
23
|
-
|
24
|
-
# @param name [Symbol, #to_s]
|
25
|
-
# defined type name (see {.names})
|
26
|
-
# or glyph
|
27
|
-
# @return [String] glyph definition
|
28
|
-
def self.[](name)
|
29
|
-
return @default if name == :default
|
30
|
-
Text.embellish(
|
31
|
-
if name.is_a?(Symbol)
|
32
|
-
@all[name] or raise(ArgumentError, "invalid glyph type - #{name}")
|
33
|
-
else
|
34
|
-
name.to_s
|
35
|
-
end
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
@all = {
|
40
|
-
completed: '[b 52]✓',
|
41
|
-
dot: '[27]•',
|
42
|
-
error: '[b d0]𝙓',
|
43
|
-
failed: '[b c4]𝑭',
|
44
|
-
information: '[b 77]𝒊',
|
45
|
-
point: '[27]◉',
|
46
|
-
query: '[b 27]▸',
|
47
|
-
task: '[b 27]➔',
|
48
|
-
warning: '[b dd]!'
|
49
|
-
}.compare_by_identity
|
50
|
-
|
51
|
-
# GLYPH = {
|
52
|
-
# default: '●',
|
53
|
-
# information: '🅸 ',
|
54
|
-
# warning: '🆆 ',
|
55
|
-
# error: '🅴 ',
|
56
|
-
# completed: '✓',
|
57
|
-
# failed: '🅵 ',
|
58
|
-
# task: '➔',
|
59
|
-
# query: '🆀 '
|
60
|
-
# }.compare_by_identity.freeze
|
61
|
-
|
62
|
-
self.default = nil
|
63
|
-
end
|
64
|
-
end
|
data/lib/natty-ui/key_map.rb
DELETED
@@ -1,142 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module NattyUI
|
4
|
-
KEY_MAP =
|
5
|
-
Module # generator
|
6
|
-
.new do
|
7
|
-
def self.add_modifiers(**keys)
|
8
|
-
@mods.each_pair do |mod, pref|
|
9
|
-
@map.merge!(
|
10
|
-
keys.to_h do |name, code|
|
11
|
-
["\e[1;#{mod}#{code}", "#{pref}+#{name}"]
|
12
|
-
end
|
13
|
-
)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.add_keys(**keys)
|
18
|
-
@map.merge!(keys.to_h { |name, code| ["\e[#{code}", name] })
|
19
|
-
add_modifiers(**keys)
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.add_fkeys(**keys)
|
23
|
-
@map.merge!(keys.to_h { |name, code| ["\e[#{code}~", name] })
|
24
|
-
@mods.each_pair do |mod, prefix|
|
25
|
-
@map.merge!(
|
26
|
-
keys.to_h do |name, code|
|
27
|
-
["\e[#{code};#{mod}~", "#{prefix}+#{name}"]
|
28
|
-
end
|
29
|
-
)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.add_alt_keys(**keys)
|
34
|
-
keys.each_pair do |name, code|
|
35
|
-
@map[code] = name
|
36
|
-
@map["\e#{code}"] = "Alt+#{name}" # kitty
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.to_hash
|
41
|
-
# control codes
|
42
|
-
num = 0
|
43
|
-
@map = ('A'..'Z').to_h { [(num += 1).chr, "Ctrl+#{_1}"] }
|
44
|
-
|
45
|
-
add_modifiers('F1' => 'P', 'F2' => 'Q', 'F3' => 'R', 'F4' => 'S')
|
46
|
-
|
47
|
-
add_keys(
|
48
|
-
'Up' => 'A',
|
49
|
-
'Down' => 'B',
|
50
|
-
'Right' => 'C',
|
51
|
-
'Left' => 'D',
|
52
|
-
'End' => 'F',
|
53
|
-
'Home' => 'H'
|
54
|
-
)
|
55
|
-
|
56
|
-
add_fkeys(
|
57
|
-
'DEL' => '3',
|
58
|
-
'PgUp' => '5',
|
59
|
-
'PgDown' => '6',
|
60
|
-
# -
|
61
|
-
'F1' => 'F1',
|
62
|
-
'F2' => 'F2',
|
63
|
-
'F3' => 'F3',
|
64
|
-
'F4' => 'F4',
|
65
|
-
# -
|
66
|
-
'F5' => '15',
|
67
|
-
'F6' => '17',
|
68
|
-
'F7' => '18',
|
69
|
-
'F8' => '19',
|
70
|
-
'F9' => '20',
|
71
|
-
'F10' => '21',
|
72
|
-
'F11' => '23',
|
73
|
-
'F12' => '24',
|
74
|
-
'F13' => '25',
|
75
|
-
'F14' => '26',
|
76
|
-
'F15' => '28',
|
77
|
-
'F16' => '29',
|
78
|
-
'F17' => '31',
|
79
|
-
'F18' => '32',
|
80
|
-
'F19' => '33',
|
81
|
-
'F20' => '34'
|
82
|
-
)
|
83
|
-
|
84
|
-
add_fkeys('F3' => '13') # kitty
|
85
|
-
|
86
|
-
add_alt_keys(
|
87
|
-
'ESC' => "\e",
|
88
|
-
'ENTER' => "\r",
|
89
|
-
'TAB' => "\t",
|
90
|
-
'BACK' => "\u007F",
|
91
|
-
'Ctrl+BACK' => "\b",
|
92
|
-
'Shift+TAB' => "\e[Z"
|
93
|
-
)
|
94
|
-
|
95
|
-
# overrides and additionals
|
96
|
-
@map.merge!(
|
97
|
-
"\4" => 'DEL',
|
98
|
-
"\e[5" => 'PgUp',
|
99
|
-
"\e[6" => 'PgDown',
|
100
|
-
# SS3 control (VT 100 etc)
|
101
|
-
"\eOA" => 'Up',
|
102
|
-
"\eOB" => 'Down',
|
103
|
-
"\eOC" => 'Right',
|
104
|
-
"\eOD" => 'Left',
|
105
|
-
"\eOP" => 'F1',
|
106
|
-
"\eOQ" => 'F2',
|
107
|
-
"\eOR" => 'F3',
|
108
|
-
"\eOS" => 'F4',
|
109
|
-
"\eO2P" => 'Shift+F1',
|
110
|
-
"\eO2Q" => 'Shift+F2',
|
111
|
-
"\eO2R" => 'Shift+F3',
|
112
|
-
"\eO2S" => 'Shift+F4',
|
113
|
-
"\eOt" => 'F5',
|
114
|
-
"\eOu" => 'F6',
|
115
|
-
"\eOv" => 'F7',
|
116
|
-
"\eOw" => 'F8',
|
117
|
-
"\eOl" => 'F9',
|
118
|
-
"\eOx" => 'F10'
|
119
|
-
)
|
120
|
-
end
|
121
|
-
|
122
|
-
@mods = {
|
123
|
-
2 => 'Shift',
|
124
|
-
3 => 'Alt',
|
125
|
-
4 => 'Alt-Shift',
|
126
|
-
5 => 'Ctrl',
|
127
|
-
6 => 'Ctrl-Shift',
|
128
|
-
7 => 'Ctrl-Alt',
|
129
|
-
8 => 'Ctrl-Alt-Shift',
|
130
|
-
9 => 'Meta',
|
131
|
-
10 => 'Meta-Shift',
|
132
|
-
11 => 'Meta-Alt',
|
133
|
-
12 => 'Meta-Alt-Shift',
|
134
|
-
13 => 'Ctrl-Meta',
|
135
|
-
14 => 'Ctrl-Meta-Shift',
|
136
|
-
15 => 'Ctrl-Meta-Alt',
|
137
|
-
16 => 'Ctrl-Meta-Alt-Shift'
|
138
|
-
}.compare_by_identity
|
139
|
-
end
|
140
|
-
.to_hash
|
141
|
-
.freeze
|
142
|
-
end
|
data/lib/natty-ui/preload.rb
DELETED
data/lib/natty-ui/spinner.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'ansi'
|
4
|
-
|
5
|
-
module NattyUI
|
6
|
-
# Helper class to select spinner types.
|
7
|
-
# @see Features#progress
|
8
|
-
module Spinner
|
9
|
-
class << self
|
10
|
-
# Define spinner type used by default.
|
11
|
-
# @attribute [w] self.default
|
12
|
-
# @param value [Symbol] type name
|
13
|
-
# @return [Symbol] type name
|
14
|
-
def default=(value)
|
15
|
-
@default = self[value.nil? || value == :default ? :pulse : value]
|
16
|
-
end
|
17
|
-
|
18
|
-
# Defined spinner type names.
|
19
|
-
# @see []
|
20
|
-
#
|
21
|
-
# @attribute [r] self.names
|
22
|
-
# @return [Array<Symbol>] supported attribute names
|
23
|
-
def names = @all.keys
|
24
|
-
|
25
|
-
# @param name [Symbol, #to_a, #to_s]
|
26
|
-
# defined type name (see {.names})
|
27
|
-
# or spinner elements
|
28
|
-
# @return [Enumerator] spinner definition
|
29
|
-
def [](name)
|
30
|
-
return @default if name == :default
|
31
|
-
parts =
|
32
|
-
if name.is_a?(Symbol)
|
33
|
-
@all[name] or raise(ArgumentError, "invalid spinner type - #{name}")
|
34
|
-
else
|
35
|
-
name
|
36
|
-
end
|
37
|
-
parts =
|
38
|
-
(parts.respond_to?(:map) ? parts : parts.to_s.chars).map do |part|
|
39
|
-
"#{@style}#{part}#{Ansi::RESET}"
|
40
|
-
end
|
41
|
-
raise(ArgumentError, "invalid spinner type - #{name}") if parts.empty?
|
42
|
-
parts = parts.zip(parts).flatten(1) while parts.size < 6
|
43
|
-
Enumerator.new { |y| parts.each { y << _1 } while true }
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def slide(a, b, size, prefix = nil, suffix = prefix)
|
49
|
-
Enumerator.new do |y|
|
50
|
-
fn =
|
51
|
-
lambda do |i|
|
52
|
-
y << "#{prefix}#{a * (i += 1)}#{b * (size - i)}#{suffix}"
|
53
|
-
end
|
54
|
-
size.times(&fn)
|
55
|
-
a, b = b, a
|
56
|
-
size.times(&fn)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def bounce(a, b, size, prefix = nil, suffix = prefix)
|
61
|
-
Enumerator.new do |y|
|
62
|
-
fn =
|
63
|
-
lambda do |i|
|
64
|
-
y << "#{prefix}#{a * (i += 1)}#{b * (size - i)}#{suffix}"
|
65
|
-
end
|
66
|
-
size.times(&fn)
|
67
|
-
a, b = b, a
|
68
|
-
(size - 1).times(&fn)
|
69
|
-
fn = ->(i) { y << "#{prefix}#{a * i}#{b * (size - i)}#{suffix}" }
|
70
|
-
(size - 2).downto(0, &fn)
|
71
|
-
a, b = b, a
|
72
|
-
(size - 1).downto(0, &fn)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def move(a, b, size, prefix = nil, suffix = prefix)
|
77
|
-
Enumerator.new do |y|
|
78
|
-
size.times do |i|
|
79
|
-
y << "#{prefix}#{b * i}#{a}#{b * (size - i - 1)}#{suffix}"
|
80
|
-
end
|
81
|
-
y << "#{prefix}#{b * size}#{suffix}"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
@style = Ansi[:bold, 220]
|
87
|
-
@all = {
|
88
|
-
bar: '▁▂▃▄▅▆▇█▇▆▅▄▃▂',
|
89
|
-
blink: '■□▪▫',
|
90
|
-
blocks: '▖▘▝▗',
|
91
|
-
bounce: bounce('◼︎', '◻︎', 7),
|
92
|
-
bounce2: bounce('▰', '▱', 7),
|
93
|
-
bounce3: bounce('● ', '◌ ', 7),
|
94
|
-
bounce4: bounce('=', ' ', 5, '[', ']'),
|
95
|
-
circle: '◐◓◑◒',
|
96
|
-
colors: '🟨🟨🟧🟧🟥🟥🟦🟦🟪🟪🟩🟩',
|
97
|
-
dots: '⣷⣯⣟⡿⢿⣻⣽⣾',
|
98
|
-
dots2: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
|
99
|
-
dots3: '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓',
|
100
|
-
dots4: '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆',
|
101
|
-
dots5: '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋',
|
102
|
-
move: move('◼︎', '◻︎', 7),
|
103
|
-
move2: move('▰', '▱', 7),
|
104
|
-
move3: move('● ', '◌ ', 7),
|
105
|
-
move4: move('=', ' ', 5, '[', ']'),
|
106
|
-
pulse: '•✺◉●◉✺',
|
107
|
-
slide: slide('◼︎', '◻︎', 7),
|
108
|
-
slide2: slide('▰', '▱', 7),
|
109
|
-
slide3: slide('● ', '◌ ', 7),
|
110
|
-
slide4: slide('=', ' ', 5, '[', ']'),
|
111
|
-
slide5: slide('.', ' ', 3),
|
112
|
-
snake: '⠁⠉⠙⠸⢰⣠⣄⡆⠇⠃',
|
113
|
-
stod: '⡿⣟⣯⣷⣾⣽⣻⢿',
|
114
|
-
swap: '㊂㊀㊁',
|
115
|
-
vintage: '-\\|/'
|
116
|
-
}.compare_by_identity
|
117
|
-
|
118
|
-
self.default = nil
|
119
|
-
end
|
120
|
-
end
|