natty-ui 0.30.0 → 0.31.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 +2 -1
- data/examples/cols.rb +4 -6
- data/examples/hbars.rb +2 -3
- data/examples/illustration.rb +13 -14
- data/examples/info.rb +9 -13
- data/examples/named-colors.rb +3 -5
- data/examples/tables.rb +5 -8
- data/examples/tasks.rb +14 -14
- data/examples/themes.rb +51 -0
- data/lib/natty-ui/attributes.rb +37 -38
- data/lib/natty-ui/features.rb +58 -31
- data/lib/natty-ui/hbars_renderer.rb +51 -43
- data/lib/natty-ui/progress.rb +5 -7
- data/lib/natty-ui/shell_command.rb +132 -0
- data/lib/natty-ui/table.rb +47 -12
- data/lib/natty-ui/table_renderer.rb +3 -2
- data/lib/natty-ui/theme.rb +326 -282
- data/lib/natty-ui/utils.rb +3 -3
- data/lib/natty-ui/vbars_renderer.rb +1 -0
- data/lib/natty-ui/version.rb +1 -1
- data/lib/natty-ui.rb +3 -1
- metadata +4 -2
data/lib/natty-ui/theme.rb
CHANGED
@@ -11,342 +11,386 @@ module NattyUI
|
|
11
11
|
class << self
|
12
12
|
# Currently used theme
|
13
13
|
#
|
14
|
-
# @return [
|
14
|
+
# @return [Theme]
|
15
15
|
attr_reader :current
|
16
16
|
|
17
|
-
#
|
18
|
-
def current=(value)
|
19
|
-
case value
|
20
|
-
when Theme::Compiled
|
21
|
-
@current = value
|
22
|
-
when Theme
|
23
|
-
@current = value.compiled
|
24
|
-
else
|
25
|
-
raise(TypeError, 'Theme expected')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Create a theme.
|
17
|
+
# Name of currently used theme
|
30
18
|
#
|
31
|
-
# @return [
|
32
|
-
|
33
|
-
theme = new
|
34
|
-
yield(theme) if block_given?
|
35
|
-
theme
|
36
|
-
end
|
19
|
+
# @return [Symbol]
|
20
|
+
attr_reader :current_name
|
37
21
|
|
38
|
-
#
|
22
|
+
# Names of all registered themes
|
39
23
|
#
|
40
|
-
# @attribute [r]
|
41
|
-
# @return [
|
42
|
-
def
|
43
|
-
create do |theme|
|
44
|
-
theme.heading_sytle = :bright_blue
|
45
|
-
theme.task_style = %i[bright_green b]
|
46
|
-
# theme.choice_style =
|
47
|
-
theme.choice_current_style = %i[bright_white on_blue b]
|
48
|
-
theme.define_marker(
|
49
|
-
bullet: '[bright_white]•[/fg]',
|
50
|
-
checkmark: '[bright_green]✓[/fg]',
|
51
|
-
quote: '[bright_blue]▍[/fg]',
|
52
|
-
information: '[bright_yellow]𝒊[/fg]',
|
53
|
-
warning: '[bright_yellow]![/fg]',
|
54
|
-
error: '[red]𝙓[/fg]',
|
55
|
-
failed: '[bright_red]𝑭[/fg]',
|
56
|
-
current: '[bright_green]➔[/fg]',
|
57
|
-
choice: '[bright_white]◦[/fg]',
|
58
|
-
current_choice: '[bright_green]➔[/fg]'
|
59
|
-
)
|
60
|
-
theme.define_section(
|
61
|
-
default: :bright_blue,
|
62
|
-
message: :bright_blue,
|
63
|
-
information: :bright_blue,
|
64
|
-
warning: :bright_yellow,
|
65
|
-
error: :red,
|
66
|
-
failed: :bright_red
|
67
|
-
)
|
68
|
-
end
|
69
|
-
end
|
24
|
+
# @attribute [r] names
|
25
|
+
# @return [Array<Symbol>]
|
26
|
+
def names = @ll.keys.sort!
|
70
27
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
quote: '[bright_blue]▍[/fg]',
|
81
|
-
information: '📌',
|
82
|
-
warning: '⚠️',
|
83
|
-
error: '❗️',
|
84
|
-
failed: '‼️',
|
85
|
-
current: '➡️',
|
86
|
-
choice: '[bright_white]•[/fg]',
|
87
|
-
current_choice: '[bright_green]●[/fg]'
|
88
|
-
)
|
89
|
-
theme.define_section(
|
90
|
-
default: :bright_blue,
|
91
|
-
message: :bright_blue,
|
92
|
-
information: :bright_blue,
|
93
|
-
warning: :bright_yellow,
|
94
|
-
error: :red,
|
95
|
-
failed: :bright_red
|
96
|
-
)
|
28
|
+
# Use a theme
|
29
|
+
#
|
30
|
+
# @param name [Symbol]
|
31
|
+
# @return [Symbol] name of used theme
|
32
|
+
def use(name)
|
33
|
+
sel = find(name).last
|
34
|
+
if sel.is_a?(Proc)
|
35
|
+
sel[builder = Builder.new]
|
36
|
+
sel = @ll[name][-1] = builder.build.freeze
|
97
37
|
end
|
38
|
+
@current = sel
|
39
|
+
@current_name = name
|
98
40
|
end
|
99
|
-
end
|
100
41
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
:section_styles,
|
107
|
-
:task_style,
|
108
|
-
:choice_current_style,
|
109
|
-
:choice_style
|
42
|
+
# Get the descrition of a theme.
|
43
|
+
#
|
44
|
+
# @param name [Symbol]
|
45
|
+
# @return [String] description of the theme
|
46
|
+
def description(name) = find(name).first
|
110
47
|
|
111
|
-
|
112
|
-
|
113
|
-
|
48
|
+
# Register a theme
|
49
|
+
#
|
50
|
+
# @param name [Symbol] theme name
|
51
|
+
# @param description [#to_s] theme description
|
52
|
+
# @yieldparam builder [Builder] theme build helper
|
53
|
+
# @return [Theme] itself
|
54
|
+
def register(name, description = nil, &block)
|
55
|
+
raise(ArgumentError, 'block missing') unless block
|
56
|
+
@ll[name.to_sym] = [description&.to_s || name.to_s.capitalize, block]
|
57
|
+
self
|
58
|
+
end
|
114
59
|
|
115
|
-
|
116
|
-
@task_style = Utils.style(value)
|
117
|
-
end
|
60
|
+
private
|
118
61
|
|
119
|
-
|
120
|
-
|
62
|
+
def find(name)
|
63
|
+
@ll.fetch(name) { raise(ArgumentError, "no such theme - #{name}") }
|
64
|
+
end
|
121
65
|
end
|
122
66
|
|
123
|
-
|
124
|
-
|
125
|
-
|
67
|
+
# @todo This chapter needs more documentation.
|
68
|
+
#
|
69
|
+
# Helper class to define a {Theme}.
|
70
|
+
#
|
71
|
+
class Builder
|
72
|
+
attr_accessor :section_border
|
73
|
+
attr_reader :mark,
|
74
|
+
:border,
|
75
|
+
:heading,
|
76
|
+
:heading_sytle,
|
77
|
+
:section_styles,
|
78
|
+
:task_style,
|
79
|
+
:choice_current_style,
|
80
|
+
:choice_style,
|
81
|
+
:sh_out_style,
|
82
|
+
:sh_err_style
|
126
83
|
|
127
|
-
|
84
|
+
def heading_sytle=(value)
|
85
|
+
@heading_sytle = Utils.style(value)
|
86
|
+
end
|
128
87
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
88
|
+
def task_style=(value)
|
89
|
+
@task_style = Utils.style(value)
|
90
|
+
end
|
133
91
|
|
134
|
-
|
135
|
-
|
136
|
-
s = str.to_s
|
137
|
-
case Text.width(s, bbcode: false)
|
138
|
-
when 1
|
139
|
-
@border[name.to_sym] = "#{s * 11} "
|
140
|
-
when 11
|
141
|
-
@border[name.to_sym] = "#{s} "
|
142
|
-
when 13
|
143
|
-
@border[name.to_sym] = s
|
144
|
-
else
|
145
|
-
raise(
|
146
|
-
TypeError,
|
147
|
-
"invalid boder definition for #{name} - #{str.inspect}"
|
148
|
-
)
|
149
|
-
end
|
92
|
+
def choice_current_style=(value)
|
93
|
+
@choice_current_style = Utils.style(value)
|
150
94
|
end
|
151
|
-
self
|
152
|
-
end
|
153
95
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
self
|
158
|
-
end
|
96
|
+
def choice_style=(value)
|
97
|
+
@choice_style = Utils.style(value)
|
98
|
+
end
|
159
99
|
|
160
|
-
|
161
|
-
|
162
|
-
style = Utils.style(style)
|
163
|
-
@section_styles[name.to_sym] = style if style
|
100
|
+
def sh_out_style=(value)
|
101
|
+
@sh_out_style = Utils.style(value)
|
164
102
|
end
|
165
|
-
self
|
166
|
-
end
|
167
103
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
:choice_style,
|
172
|
-
:option_states
|
104
|
+
def sh_err_style=(value)
|
105
|
+
@sh_err_style = Utils.style(value)
|
106
|
+
end
|
173
107
|
|
174
|
-
|
175
|
-
def
|
176
|
-
def heading(index) = @heading[index.to_i.clamp(1, 6) - 1]
|
108
|
+
# @return [Theme] new theme
|
109
|
+
def build = Theme.new(self)
|
177
110
|
|
178
|
-
def
|
179
|
-
|
180
|
-
|
111
|
+
def define_marker(**defs)
|
112
|
+
@mark.merge!(defs)
|
113
|
+
self
|
181
114
|
end
|
182
115
|
|
183
|
-
def
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
116
|
+
def define_border(**defs)
|
117
|
+
defs.each_pair do |name, str|
|
118
|
+
s = str.to_s
|
119
|
+
case Text.width(s, bbcode: false)
|
120
|
+
when 1
|
121
|
+
@border[name.to_sym] = "#{s * 11} "
|
122
|
+
when 11
|
123
|
+
@border[name.to_sym] = "#{s} "
|
124
|
+
when 13
|
125
|
+
@border[name.to_sym] = s
|
126
|
+
else
|
127
|
+
raise(
|
128
|
+
TypeError,
|
129
|
+
"invalid boder definition for #{name} - #{str.inspect}"
|
130
|
+
)
|
131
|
+
end
|
194
132
|
end
|
133
|
+
self
|
195
134
|
end
|
196
135
|
|
197
|
-
def
|
198
|
-
|
136
|
+
def define_heading(*defs)
|
137
|
+
@heading = defs.flatten.take(6)
|
138
|
+
@heading += Array.new(6 - @heading.size, @heading[-1])
|
139
|
+
self
|
199
140
|
end
|
200
141
|
|
201
|
-
def
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
@choice_style = as_style(theme.choice_style)
|
208
|
-
@sections =
|
209
|
-
create_sections(
|
210
|
-
SectionBorder.create(border(theme.section_border)),
|
211
|
-
theme.section_styles.dup.compare_by_identity
|
212
|
-
)
|
213
|
-
@option_states = create_option_states
|
142
|
+
def define_section(**defs)
|
143
|
+
defs.each_pair do |name, style|
|
144
|
+
style = Utils.style(style)
|
145
|
+
@section_styles[name.to_sym] = style if style
|
146
|
+
end
|
147
|
+
self
|
214
148
|
end
|
215
149
|
|
216
150
|
private
|
217
151
|
|
218
|
-
def
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
152
|
+
def initialize
|
153
|
+
define_heading(%w[╸╸╺╸╺━━━ ╴╶╴╶─═══ ╴╶╴╶─── ════ ━━━━ ────])
|
154
|
+
@mark = {
|
155
|
+
default: '•',
|
156
|
+
bullet: '•',
|
157
|
+
checkmark: '✓',
|
158
|
+
quote: '▍',
|
159
|
+
information: '𝒊',
|
160
|
+
warning: '!',
|
161
|
+
error: '𝙓',
|
162
|
+
failed: '𝑭',
|
163
|
+
current: '➔',
|
164
|
+
choice: '◦',
|
165
|
+
current_choice: '◉',
|
166
|
+
sh_out: ':',
|
167
|
+
sh_err: '𝙓'
|
168
|
+
}
|
169
|
+
@border = {
|
170
|
+
######### 0123456789012
|
171
|
+
default: '┌┬┐├┼┤└┴┘│─╶╴',
|
172
|
+
defaulth: '───────── ─╶╴',
|
173
|
+
defaultv: '││││││││││ ',
|
174
|
+
double: '╔╦╗╠╬╣╚╩╝║═',
|
175
|
+
doubleh: '═════════ ═',
|
176
|
+
doublev: '║║║║║║║║║║ ',
|
177
|
+
heavy: '┏┳┓┣╋┫┗┻┛┃━╺╸',
|
178
|
+
heavyh: '━━━━━━━━━ ━╺╸',
|
179
|
+
heavyv: '┃┃┃┃┃┃┃┃┃┃ ',
|
180
|
+
rounded: '╭┬╮├┼┤╰┴╯│─╶╴'
|
181
|
+
}
|
182
|
+
@section_border = :rounded
|
183
|
+
@section_styles = {}
|
230
184
|
end
|
185
|
+
end
|
231
186
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
187
|
+
attr_reader :task_style,
|
188
|
+
:choice_current_style,
|
189
|
+
:choice_style,
|
190
|
+
:sh_out_style,
|
191
|
+
:sh_err_style,
|
192
|
+
:option_states
|
193
|
+
|
194
|
+
def defined_marks = @mark.keys.sort!
|
195
|
+
def defined_borders = @border.keys.sort!
|
196
|
+
def heading(index) = @heading[index.to_i.clamp(1, 6) - 1]
|
197
|
+
|
198
|
+
def mark(value)
|
199
|
+
return @mark[value] if value.is_a?(Symbol)
|
200
|
+
(element = Str.new(value, true)).empty? ? @mark[:default] : element
|
201
|
+
end
|
239
202
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
203
|
+
def border(value)
|
204
|
+
return @border[value] if value.is_a?(Symbol)
|
205
|
+
case Text.width(value = value.to_s, bbcode: false)
|
206
|
+
when 1
|
207
|
+
"#{value * 11} "
|
208
|
+
when 11
|
209
|
+
"#{value} "
|
210
|
+
when 13
|
211
|
+
value
|
212
|
+
else
|
213
|
+
@border[:default]
|
245
214
|
end
|
215
|
+
end
|
246
216
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
end
|
217
|
+
def section_border(kind)
|
218
|
+
kind.is_a?(Symbol) ? @sections[kind] : @sections[:default]
|
219
|
+
end
|
251
220
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
221
|
+
def initialize(theme)
|
222
|
+
@heading = create_heading(theme.heading, theme.heading_sytle).freeze
|
223
|
+
@border = create_border(theme.border).freeze
|
224
|
+
@mark = create_mark(theme.mark).freeze
|
225
|
+
@task_style = as_style(theme.task_style)
|
226
|
+
@choice_current_style = as_style(theme.choice_current_style)
|
227
|
+
@choice_style = as_style(theme.choice_style)
|
228
|
+
@sh_out_style = as_style(theme.sh_out_style)
|
229
|
+
@sh_err_style = as_style(theme.sh_err_style)
|
230
|
+
@sections =
|
231
|
+
create_sections(
|
232
|
+
SectionBorder.create(border(theme.section_border)),
|
233
|
+
theme.section_styles.dup.compare_by_identity
|
234
|
+
)
|
235
|
+
@option_states = create_option_states
|
236
|
+
end
|
259
237
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
238
|
+
private
|
239
|
+
|
240
|
+
def as_style(value) = (Ansi[*value].freeze if value)
|
241
|
+
|
242
|
+
def create_option_states
|
243
|
+
# [current?][selected?]
|
244
|
+
c = @mark[:current_choice]
|
245
|
+
n = @mark[:none]
|
246
|
+
sel = @mark[:checkmark]
|
247
|
+
uns = @mark[:choice]
|
248
|
+
{
|
249
|
+
false => { false => n + uns, true => n + sel }.compare_by_identity,
|
250
|
+
true => { false => c + uns, true => c + sel }.compare_by_identity
|
251
|
+
}.compare_by_identity.freeze
|
252
|
+
end
|
253
|
+
|
254
|
+
def create_sections(template, styles)
|
255
|
+
Hash
|
256
|
+
.new do |h, kind|
|
257
|
+
h[kind] = SectionBorder.new(*template.parts(styles[kind])).freeze
|
267
258
|
end
|
259
|
+
.compare_by_identity
|
260
|
+
end
|
261
|
+
|
262
|
+
def create_mark(mark)
|
263
|
+
return {} if mark.empty?
|
264
|
+
mark = mark.to_h { |n, e| [n.to_sym, Str.new("#{e} ")] }
|
265
|
+
mark[:none] ||= Str.new(' ', 2)
|
266
|
+
with_default(mark)
|
267
|
+
end
|
268
|
+
|
269
|
+
def create_border(border)
|
270
|
+
return {} if border.empty?
|
271
|
+
with_default(border.transform_values { _1.dup.freeze })
|
272
|
+
end
|
273
|
+
|
274
|
+
def create_heading(heading, style)
|
275
|
+
return create_styled_heading(heading, style) if style
|
276
|
+
heading.map do |left|
|
277
|
+
right = " #{left.reverse}"
|
278
|
+
[left = Str.new("#{left} ", true), Str.new(right, left.width)]
|
268
279
|
end
|
280
|
+
end
|
269
281
|
|
270
|
-
|
271
|
-
|
272
|
-
|
282
|
+
def create_styled_heading(heading, style)
|
283
|
+
heading.map do |left|
|
284
|
+
right = Ansi.decorate(left.reverse, *style)
|
285
|
+
[
|
286
|
+
left = Str.new("#{Ansi.decorate(left, *style)} ", true),
|
287
|
+
Str.new(" #{right}", left.width)
|
288
|
+
]
|
273
289
|
end
|
290
|
+
end
|
274
291
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
mid2 = mid * 2
|
280
|
-
right = "#{border[11]}#{border[12] * 2}"
|
281
|
-
new(
|
282
|
-
border[0] + mid2 + right,
|
283
|
-
border[0] + mid,
|
284
|
-
mid + right,
|
285
|
-
border[6] + mid2 + right,
|
286
|
-
border[9]
|
287
|
-
)
|
288
|
-
end
|
292
|
+
def with_default(map)
|
293
|
+
map.default = (map[:default] ||= map[map.first.first])
|
294
|
+
map.compare_by_identity
|
295
|
+
end
|
289
296
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
297
|
+
SectionBorder =
|
298
|
+
Struct.new(:top, :top_left, :top_right, :bottom, :prefix) do
|
299
|
+
def self.create(border)
|
300
|
+
mid = border[10] * 2
|
301
|
+
mid2 = mid * 2
|
302
|
+
right = "#{border[11]}#{border[12] * 2}"
|
303
|
+
new(
|
304
|
+
border[0] + mid2 + right,
|
305
|
+
border[0] + mid,
|
306
|
+
mid + right,
|
307
|
+
border[6] + mid2 + right,
|
308
|
+
border[9]
|
309
|
+
)
|
310
|
+
end
|
311
|
+
|
312
|
+
def parts(style)
|
313
|
+
if style
|
300
314
|
style = Ansi[*style]
|
301
|
-
|
302
|
-
# TODO: use rather [/fg]
|
303
|
-
Str.new("#{style}#{top}#{Ansi::RESET}", 6),
|
304
|
-
Str.new("#{style}#{top_left}#{Ansi::RESET} ", 4),
|
305
|
-
Str.new(" #{style}#{top_right}#{Ansi::RESET}", 6),
|
306
|
-
Str.new("#{style}#{bottom}#{Ansi::RESET}", 6),
|
307
|
-
Str.new("#{style}#{prefix}#{Ansi::RESET} ", 2)
|
308
|
-
]
|
315
|
+
reset = Ansi::RESET
|
309
316
|
end
|
317
|
+
[
|
318
|
+
Str.new("#{style}#{top}#{reset}", 6),
|
319
|
+
Str.new("#{style}#{top_left}#{reset} ", 4),
|
320
|
+
Str.new(" #{style}#{top_right}#{reset}", 6),
|
321
|
+
Str.new("#{style}#{bottom}#{reset}", 6),
|
322
|
+
Str.new("#{style}#{prefix}#{reset} ", 2)
|
323
|
+
]
|
310
324
|
end
|
311
|
-
|
312
|
-
|
325
|
+
end
|
326
|
+
private_constant :SectionBorder
|
327
|
+
|
328
|
+
@ll = {}
|
329
|
+
|
330
|
+
register(:mono, 'Monochrome – Non-ANSI fallback', &:itself)
|
331
|
+
|
332
|
+
register(:default, 'Default – uses default colors') do |theme|
|
333
|
+
theme.heading_sytle = :bright_blue
|
334
|
+
theme.task_style = %i[bright_green b]
|
335
|
+
# theme.choice_style =
|
336
|
+
theme.sh_out_style = :default
|
337
|
+
theme.sh_err_style = :bright_yellow
|
338
|
+
theme.choice_current_style = %i[bright_white on_blue b]
|
339
|
+
theme.define_marker(
|
340
|
+
bullet: '[bright_white]•[/fg]',
|
341
|
+
checkmark: '[bright_green]✓[/fg]',
|
342
|
+
quote: '[bright_blue]▍[/fg]',
|
343
|
+
information: '[bright_yellow]𝒊[/fg]',
|
344
|
+
warning: '[bright_yellow]![/fg]',
|
345
|
+
error: '[red]𝙓[/fg]',
|
346
|
+
failed: '[bright_red]𝑭[/fg]',
|
347
|
+
current: '[bright_green]➔[/fg]',
|
348
|
+
choice: '[bright_white]◦[/fg]',
|
349
|
+
current_choice: '[bright_green]➔[/fg]',
|
350
|
+
sh_out: '[bright_white]:[/fg]',
|
351
|
+
sh_err: '[red]𝙓[/fg]'
|
352
|
+
)
|
353
|
+
theme.define_section(
|
354
|
+
default: :bright_blue,
|
355
|
+
message: :bright_blue,
|
356
|
+
information: :bright_blue,
|
357
|
+
warning: :bright_yellow,
|
358
|
+
error: :red,
|
359
|
+
failed: :bright_red
|
360
|
+
)
|
313
361
|
end
|
314
|
-
# private_constant :Compiled
|
315
|
-
|
316
|
-
private
|
317
362
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
@section_styles = {}
|
363
|
+
register(:emoji, 'Emoji – emoticons and default colors') do |theme|
|
364
|
+
theme.heading_sytle = :bright_blue
|
365
|
+
theme.task_style = %i[bright_green b]
|
366
|
+
# theme.choice_style =
|
367
|
+
theme.sh_out_style = :default
|
368
|
+
theme.sh_err_style = :bright_red
|
369
|
+
theme.choice_current_style = %i[bright_white on_blue b]
|
370
|
+
theme.define_marker(
|
371
|
+
bullet: '▫️',
|
372
|
+
checkmark: '✅',
|
373
|
+
quote: '[bright_blue]▍[/fg]',
|
374
|
+
information: '📌',
|
375
|
+
warning: '⚠️',
|
376
|
+
error: '❗️',
|
377
|
+
failed: '‼️',
|
378
|
+
current: '➡️',
|
379
|
+
choice: '[bright_white]•[/fg]',
|
380
|
+
current_choice: '[bright_green]●[/fg]',
|
381
|
+
sh_out: '[white b]:[/]',
|
382
|
+
sh_err: '❗️'
|
383
|
+
)
|
384
|
+
theme.define_section(
|
385
|
+
default: :bright_blue,
|
386
|
+
message: :bright_blue,
|
387
|
+
information: :bright_blue,
|
388
|
+
warning: :bright_yellow,
|
389
|
+
error: :red,
|
390
|
+
failed: :bright_red
|
391
|
+
)
|
348
392
|
end
|
349
393
|
|
350
|
-
|
394
|
+
use(Terminal.colors == 2 ? :mono : :default)
|
351
395
|
end
|
352
396
|
end
|