natty-ui 0.5.2 → 0.6.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 -5
- data/examples/attributes.rb +165 -0
- data/examples/basic.rb +8 -9
- data/examples/illustration.png +0 -0
- data/examples/list_in_columns.rb +43 -0
- data/examples/progress.rb +45 -61
- data/examples/query.rb +27 -23
- data/lib/natty-ui/ansi.rb +47 -37
- data/lib/natty-ui/ansi_wrapper.rb +55 -22
- data/lib/natty-ui/features.rb +36 -0
- data/lib/natty-ui/{wrapper/mixins.rb → mixins.rb} +1 -1
- data/lib/natty-ui/version.rb +1 -1
- data/lib/natty-ui/wrapper/ask.rb +5 -3
- data/lib/natty-ui/wrapper/element.rb +6 -4
- data/lib/natty-ui/wrapper/framed.rb +1 -1
- data/lib/natty-ui/wrapper/heading.rb +1 -1
- data/lib/natty-ui/wrapper/list_in_columns.rb +81 -0
- data/lib/natty-ui/wrapper/message.rb +1 -1
- data/lib/natty-ui/wrapper/progress.rb +12 -7
- data/lib/natty-ui/wrapper/query.rb +4 -2
- data/lib/natty-ui/wrapper/request.rb +32 -0
- data/lib/natty-ui/wrapper/section.rb +9 -7
- data/lib/natty-ui/wrapper/task.rb +2 -2
- data/lib/natty-ui/wrapper.rb +19 -13
- data/lib/natty-ui.rb +68 -1
- metadata +10 -7
- data/examples/colors.rb +0 -7
- data/examples/illustration.svg +0 -1
- data/lib/natty-ui/wrapper/features.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 666f2716f2f1d017789bbbfef2d640b7c89af6d006ea051e8575282c806b88f6
|
4
|
+
data.tar.gz: 44922a307f8f62e69d3df00ba656be1164ba20234ac12d621df0eb86fa5ce39e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74d474a1f3876ae3825cadc289250a8f3fb545b4147c26c20861a90b3e9665b249cde0075ae9813a1d668c69671540cb332aaf75cae667fc4a9fe5c0d272a88e
|
7
|
+
data.tar.gz: 4a872db3d8b96ddf6edf42b865eb9dffc8ee87994d6ae6617c842055062eeca4c45f4bac8df644b1e1a0a7b0fd5e4cfd6c53cee88c6a66681657b83879f12c19
|
data/README.md
CHANGED
@@ -44,9 +44,9 @@ or use progression displays like progress bars.
|
|
44
44
|
|
45
45
|
🚀 There are much more [features](https://rubydoc.info/gems/natty-ui/NattyUI/Features)!
|
46
46
|
|
47
|
-
📕 See the [online help](https://rubydoc.info/gems/natty-ui/NattyUI) for more details or have a look at the [examples](./examples/) directory to get an impression of the current feature set
|
47
|
+
📕 See the [online help](https://rubydoc.info/gems/natty-ui/NattyUI) for more details or have a look at the [examples](./examples/) directory to get an impression of the current feature set.
|
48
48
|
|
49
|
-

|
50
50
|
|
51
51
|
## Installation
|
52
52
|
|
@@ -73,13 +73,13 @@ require 'natty-ui'
|
|
73
73
|
You can execute the examples by
|
74
74
|
|
75
75
|
```sh
|
76
|
-
ruby ./examples/basic.rb
|
76
|
+
bundle exec ruby ./examples/basic.rb
|
77
77
|
```
|
78
78
|
|
79
79
|
or see the non-ANSI version
|
80
80
|
|
81
81
|
```sh
|
82
|
-
NO_COLOR=1 ruby ./examples/basic.rb
|
82
|
+
NO_COLOR=1 bundle exec ruby ./examples/basic.rb
|
83
83
|
```
|
84
84
|
|
85
85
|
## NO_COLOR Convention
|
@@ -92,5 +92,4 @@ Since I did not complete the tests and not all my ideas are already implemented
|
|
92
92
|
|
93
93
|
- add more samples to help
|
94
94
|
- add more tests
|
95
|
-
- simple prompt
|
96
95
|
- password prompt
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'natty-ui'
|
4
|
+
|
5
|
+
UI = NattyUI::StdOut
|
6
|
+
|
7
|
+
# helper:
|
8
|
+
def hex(int) = int.to_s(16).rjust(2, '0')
|
9
|
+
|
10
|
+
UI.space
|
11
|
+
UI.h1 'NattyUI ANSI Attributes Demo', <<~TEXT
|
12
|
+
|
13
|
+
This text contains all supported ANSI attrubtes and explains the available
|
14
|
+
colors.
|
15
|
+
|
16
|
+
Please, keep in mind that no all terminals will support of all attributes and
|
17
|
+
color types used in this text. In fact, you can use the output of this text to
|
18
|
+
check the supported ANSI attributes.
|
19
|
+
|
20
|
+
TEXT
|
21
|
+
|
22
|
+
UI.h2 'Attributes', <<~TEXT
|
23
|
+
|
24
|
+
Some attributes are widely supported, such as [[bold]]bold[[/]], [[italic]]italic[[/]], [[underline]]underline[[/]], [[blink]]blink[[/]],
|
25
|
+
[[invert]]invert[[/]] and [[strike]]strike[[/]], while others are rarely complete or correctly implemented,
|
26
|
+
like [[faint]]faint[[/]], [[rapid_blink]]rapid_blink[[/]], [[double_underline]]double_underline[[/]], [[framed]]framed[[/]], [[encircled]]encircled[[/]], [[overlined]]overlined[[/]],
|
27
|
+
[[proportional]]proportional[[/]] and [[spacing]]spacing[[/]].
|
28
|
+
|
29
|
+
Different font types are very rarely displayed:
|
30
|
+
|
31
|
+
- [[primary_font]]primary_font[[/]]
|
32
|
+
- [[font1]]font1[[/]]
|
33
|
+
- [[font2]]font2[[/]]
|
34
|
+
- [[font3]]font3[[/]]
|
35
|
+
- [[font4]]font4[[/]]
|
36
|
+
- [[font5]]font5[[/]]
|
37
|
+
- [[font6]]font6[[/]]
|
38
|
+
- [[font7]]font7[[/]]
|
39
|
+
- [[font8]]font8[[/]]
|
40
|
+
- [[font9]]font9[[/]]
|
41
|
+
- [[fraktur]]fraktur[[/]]
|
42
|
+
|
43
|
+
TEXT
|
44
|
+
|
45
|
+
UI.h2 '3-bit and 4-bit Colors' do |sec|
|
46
|
+
sec.space
|
47
|
+
colors = %w[black red green yellow blue magenta cyan white].freeze
|
48
|
+
(colors + colors.map { |name| "bright_#{name}" }).each do |name|
|
49
|
+
sec.puts " [[#{name}]]#{name.ljust(14)}[[/]] [[on_#{name}]]sample text"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
UI.space
|
53
|
+
|
54
|
+
UI.h2 '8-bit Colors' do |sec|
|
55
|
+
sec.space
|
56
|
+
sec.puts 'There are 256 pre-defined color which can be used by their index:'
|
57
|
+
sec.space
|
58
|
+
|
59
|
+
colors_std = 0.upto(15).map { |i| hex(i) }
|
60
|
+
colors216 = 16.upto(231).lazy.map { |i| hex(i) }
|
61
|
+
colors_gray1 = 232.upto(243).map { |i| hex(i) }
|
62
|
+
colors_gray2 = 244.upto(255).map { |i| hex(i) }
|
63
|
+
|
64
|
+
sec.puts colors_std.map { |i| "[[#{i}]] #{i} [[/]]" }.join
|
65
|
+
colors216.each_slice(18) do |slice|
|
66
|
+
sec.puts slice.map { |i| "[[#{i}]] #{i} [[/]]" }.join
|
67
|
+
end
|
68
|
+
sec.puts colors_gray1.map { |i| "[[#{i}]] #{i} [[/]]" }.join
|
69
|
+
sec.puts colors_gray2.map { |i| "[[#{i}]] #{i} [[/]]" }.join
|
70
|
+
|
71
|
+
sec.space
|
72
|
+
sec.puts colors_std.map { |i| "[[on:#{i}]] #{i} [[/]]" }.join
|
73
|
+
colors216.each_slice(18) do |slice|
|
74
|
+
sec.puts slice.map { |i| "[[on:#{i}]] #{i} [[/]]" }.join
|
75
|
+
end
|
76
|
+
sec.puts colors_gray1.map { |i| "[[on:#{i}]] #{i} [[/]]" }.join
|
77
|
+
sec.puts colors_gray2.map { |i| "[[on:#{i}]] #{i} [[/]]" }.join
|
78
|
+
end
|
79
|
+
|
80
|
+
UI.space
|
81
|
+
UI.h2 '24-bit colors' do |sec|
|
82
|
+
sec.puts <<~TEXT
|
83
|
+
|
84
|
+
Modern terminal applications support 24-bit colors for foreground and background
|
85
|
+
RGB-color values. Here are just some samples:
|
86
|
+
|
87
|
+
TEXT
|
88
|
+
|
89
|
+
some_rgb = DATA.readlines(chomp: true).lazy.each_slice(8)
|
90
|
+
|
91
|
+
some_rgb.each do |slice|
|
92
|
+
sec.puts slice.map { |v| " [[#{v}]]#{v}[[/]] " }.join
|
93
|
+
end
|
94
|
+
sec.space
|
95
|
+
some_rgb.each do |slice|
|
96
|
+
sec.puts slice.map { |v| " [[on:#{v}]]#{v}[[/]] " }.join
|
97
|
+
end
|
98
|
+
end
|
99
|
+
UI.space
|
100
|
+
|
101
|
+
__END__
|
102
|
+
#800000
|
103
|
+
#8b0000
|
104
|
+
#a52a2a
|
105
|
+
#b22222
|
106
|
+
#dc143c
|
107
|
+
#ff0000
|
108
|
+
#ff6347
|
109
|
+
#ff7f50
|
110
|
+
#cd5c5c
|
111
|
+
#f08080
|
112
|
+
#e9967a
|
113
|
+
#fa8072
|
114
|
+
#ffa07a
|
115
|
+
#ff4500
|
116
|
+
#ff8c00
|
117
|
+
#ffa500
|
118
|
+
#ffd700
|
119
|
+
#b8860b
|
120
|
+
#daa520
|
121
|
+
#eee8aa
|
122
|
+
#bdb76b
|
123
|
+
#f0e68c
|
124
|
+
#808000
|
125
|
+
#ffff00
|
126
|
+
#9acd32
|
127
|
+
#556b2f
|
128
|
+
#6b8e23
|
129
|
+
#7cfc00
|
130
|
+
#7fff00
|
131
|
+
#adff2f
|
132
|
+
#006400
|
133
|
+
#008000
|
134
|
+
#228b22
|
135
|
+
#00ff00
|
136
|
+
#32cd32
|
137
|
+
#90ee90
|
138
|
+
#98fb98
|
139
|
+
#8fbc8f
|
140
|
+
#00fa9a
|
141
|
+
#00ff7f
|
142
|
+
#2e8b57
|
143
|
+
#66cdaa
|
144
|
+
#3cb371
|
145
|
+
#20b2aa
|
146
|
+
#2f4f4f
|
147
|
+
#008080
|
148
|
+
#008b8b
|
149
|
+
#00ffff
|
150
|
+
#00ffff
|
151
|
+
#e0ffff
|
152
|
+
#00ced1
|
153
|
+
#40e0d0
|
154
|
+
#48d1cc
|
155
|
+
#afeeee
|
156
|
+
#7fffd4
|
157
|
+
#b0e0e6
|
158
|
+
#5f9ea0
|
159
|
+
#4682b4
|
160
|
+
#6495ed
|
161
|
+
#00bfff
|
162
|
+
#1e90ff
|
163
|
+
#add8e6
|
164
|
+
#87ceeb
|
165
|
+
#87cefa
|
data/examples/basic.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../lib/natty-ui'
|
3
|
+
require 'natty-ui'
|
5
4
|
|
6
5
|
UI = NattyUI::StdOut
|
7
6
|
|
@@ -9,15 +8,15 @@ UI.space
|
|
9
8
|
|
10
9
|
UI.h1 'NattyUI Basic Feature Demo', <<~TEXT
|
11
10
|
|
12
|
-
This is a short demo of the basic features of [[
|
11
|
+
This is a short demo of the basic features of [[75 bold]]NattyUI[[/]].
|
13
12
|
|
14
13
|
TEXT
|
15
14
|
|
16
15
|
UI.h2 'Feature: ANSI Colors and Attributes', <<~TEXT
|
17
16
|
|
18
|
-
Like you might noticed you can [[
|
17
|
+
Like you might noticed you can [[57]]color [[d7]]text[[/]] for terminals supporting this
|
19
18
|
feature. You can enforece the non-ANSI version by setting the environment
|
20
|
-
variable [[
|
19
|
+
variable [[75 italic]]NO_COLOR[[/]] to '[[75]]1[[/]]'. (see also [[underline]]https://no-color.org[[/]])
|
21
20
|
|
22
21
|
You can not only color your text but also [[italic]]modify[[/]], [[underline]]decorate[[/]] and [[strike]]manipulate[[/]]
|
23
22
|
it. The attributes are direct embedded into the text like '[[/bold red]]'
|
@@ -40,14 +39,14 @@ UI.h2 'Feature: Sections' do |sec|
|
|
40
39
|
sec.error 'Error Message'
|
41
40
|
sec.completed 'Completion Message'
|
42
41
|
sec.failed 'Failure Message'
|
43
|
-
sec.msg '[[
|
42
|
+
sec.msg '[[d5]]Customized Message', symbol: '◉'
|
44
43
|
sec.space
|
45
44
|
|
46
45
|
sec.puts 'You can stack all kinds of sections together:'
|
47
46
|
sec.space
|
48
|
-
sec.framed('
|
49
|
-
f1.framed('Heavy Framed
|
50
|
-
f2.framed('
|
47
|
+
sec.framed('Rouned Frame') do |f1|
|
48
|
+
f1.framed('Heavy Framed', type: :heavy) do |f2|
|
49
|
+
f2.framed('Simple Frame', type: :simple) do |f3|
|
51
50
|
f3.framed('Double Framed Section', type: :double) do |f4|
|
52
51
|
f4.message(
|
53
52
|
'[[fff400]]Frames are nice',
|
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'natty-ui'
|
4
|
+
|
5
|
+
UI = NattyUI::StdOut
|
6
|
+
|
7
|
+
LOREM = <<~LOREM
|
8
|
+
Lorem ipsum dolor sit
|
9
|
+
amet, consectetur adipisicing
|
10
|
+
elit, sed do eiusmod tempor
|
11
|
+
incididunt ut labore et
|
12
|
+
dolore [[red]]magna[[/]] aliqua. Ut
|
13
|
+
enim ad minim veniam, quis
|
14
|
+
nostrud exercitation ullamco
|
15
|
+
laboris nisi ut aliquip ex
|
16
|
+
ea commodo [[bold]]consequat[[/]]. Duis
|
17
|
+
aute irure dolor in
|
18
|
+
reprehenderit in voluptate
|
19
|
+
velit [[underline]]esse cillum[[/]] dolore eu
|
20
|
+
fugiat nulla pariatur.
|
21
|
+
Excepteur sint occaecat
|
22
|
+
cupidatat non proident,
|
23
|
+
sunt in culpa qui officia
|
24
|
+
deserunt mollit anim id
|
25
|
+
est laborum.
|
26
|
+
LOREM
|
27
|
+
WORDS = LOREM.split(/\W+/).uniq.sort!.freeze
|
28
|
+
|
29
|
+
UI.space
|
30
|
+
UI.h2 'Print a list in columns'
|
31
|
+
UI.space
|
32
|
+
|
33
|
+
UI.h3 'Lorem ipsum lines'
|
34
|
+
UI.ls LOREM.lines(chomp: true)
|
35
|
+
UI.space
|
36
|
+
|
37
|
+
UI.h3 'Lorem ipsum word list (compact)'
|
38
|
+
UI.ls WORDS
|
39
|
+
UI.space
|
40
|
+
|
41
|
+
UI.h3 'Lorem ipsum word list (row-wise)'
|
42
|
+
UI.ls WORDS, compact: false
|
43
|
+
UI.space
|
data/examples/progress.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../lib/natty-ui'
|
3
|
+
require 'natty-ui'
|
5
4
|
|
6
5
|
UI = NattyUI::StdOut
|
7
6
|
|
@@ -10,75 +9,60 @@ UI.h1 'NattyUI Progress Indication Demo'
|
|
10
9
|
UI.space
|
11
10
|
|
12
11
|
# just simulate some work
|
13
|
-
def something = sleep(0.
|
12
|
+
def something = sleep(0.5)
|
14
13
|
def some = sleep(0.15)
|
15
14
|
|
16
|
-
UI.
|
17
|
-
|
18
|
-
|
19
|
-
progress.step
|
20
|
-
something
|
21
|
-
end
|
22
|
-
progress.done 'Progress ok'
|
23
|
-
|
24
|
-
progress = sec.progress('Simple progress')
|
25
|
-
20.times do
|
26
|
-
progress.step
|
27
|
-
some
|
28
|
-
end
|
29
|
-
progress.done 'All fine'
|
30
|
-
end
|
15
|
+
UI.info 'Tasks are sections to visualize step by step processing.' do |info|
|
16
|
+
info.task 'Assemble assets' do |task|
|
17
|
+
task.task('Initialize') { something }
|
31
18
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
task.task 'Compile files...' do |subtask|
|
37
|
-
%w[readme.txt main.css main.html sub.html].each do |name|
|
38
|
-
subtask.msg "Compile file [[bright_yellow]]./source/#{name}[[/]]..."
|
39
|
-
something
|
19
|
+
progress = task.progress 'Connect to server...'
|
20
|
+
20.times do
|
21
|
+
progress.step
|
22
|
+
some
|
40
23
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
task.msg 'Compressing...'
|
45
|
-
something
|
46
|
-
task.msg 'Signing...'
|
47
|
-
something
|
48
|
-
task.msg 'Store assembled results...'
|
49
|
-
something
|
50
|
-
end
|
24
|
+
progress.ok 'Connected'
|
25
|
+
|
26
|
+
task.task('Collect files...') { something }
|
51
27
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
28
|
+
task.task 'Compile files...' do |subtask|
|
29
|
+
%w[readme.txt main.css main.html sub.html].each do |name|
|
30
|
+
subtask.msg "Compile file [[bright_yellow]]./source/#{name}[[/]]..."
|
31
|
+
something
|
32
|
+
end
|
33
|
+
subtask.done 'Files compiled.'
|
34
|
+
end
|
56
35
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
36
|
+
progress = task.progress('Compress files', max_value: 11)
|
37
|
+
11.times do
|
38
|
+
progress.step
|
39
|
+
something
|
40
|
+
end
|
41
|
+
progress.done 'All compressed'
|
62
42
|
|
63
|
-
|
64
|
-
sec.task('Assemble assets') do |task|
|
65
|
-
assemble(task)
|
66
|
-
task.failed('Unable to store results', <<~ERROR)
|
67
|
-
Server reported Invalid credentials
|
68
|
-
Check your credentials and try again...
|
69
|
-
ERROR
|
43
|
+
task.task('Signing') { something }
|
70
44
|
|
71
|
-
|
45
|
+
task.task('Store assembled results') { something }
|
72
46
|
end
|
73
|
-
|
47
|
+
info.puts(
|
48
|
+
'The details are removed ([[italic]]in ANSI version[[/]]) when the task',
|
49
|
+
'ended sucessfully.'
|
50
|
+
)
|
51
|
+
end
|
74
52
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
task.done('Assets assembled', <<~INFO)
|
79
|
-
Your assets are ready on server now.
|
80
|
-
INFO
|
53
|
+
UI.info 'Details of failed tasks will not be cleaned.' do |info|
|
54
|
+
info.task 'Assemble assets' do |task|
|
55
|
+
task.task('Initialize') { something }
|
81
56
|
|
82
|
-
|
57
|
+
progress = task.progress 'Connect to server...'
|
58
|
+
20.times do
|
59
|
+
progress.step
|
60
|
+
some
|
61
|
+
end
|
62
|
+
progress.failed 'Unable to connect to server'
|
63
|
+
|
64
|
+
task.error 'This code will not be reachd!'
|
83
65
|
end
|
84
66
|
end
|
67
|
+
|
68
|
+
UI.space
|
data/examples/query.rb
CHANGED
@@ -1,32 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../lib/natty-ui'
|
3
|
+
require 'natty-ui'
|
5
4
|
|
6
5
|
UI = NattyUI::StdOut
|
7
6
|
|
8
7
|
UI.space
|
8
|
+
UI.h1 'NattyUI Query Demo'
|
9
|
+
UI.space
|
10
|
+
|
11
|
+
unless UI.ask('Do you like to continute? (Y|n)')
|
12
|
+
UI.failed 'aborted'
|
13
|
+
exit
|
14
|
+
end
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
choice =
|
17
|
+
UI.query(
|
18
|
+
'Which fruits do you prefer?',
|
19
|
+
'Apples',
|
20
|
+
'Bananas',
|
21
|
+
'Cherries',
|
22
|
+
x: 'No fruits',
|
23
|
+
result: :choice
|
24
|
+
)
|
25
|
+
unless choice
|
26
|
+
UI.failed 'aborted'
|
27
|
+
exit false
|
28
|
+
end
|
29
|
+
UI.info "Your choice: #{choice}"
|
16
30
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
'Bananas',
|
22
|
-
'Cherries',
|
23
|
-
x: 'No fruits',
|
24
|
-
result: :choice
|
25
|
-
)
|
26
|
-
unless choice
|
27
|
-
sec.failed('aborted')
|
28
|
-
sec.close
|
29
|
-
exit(false)
|
30
|
-
end
|
31
|
-
sec.info("Your choice: #{choice}")
|
31
|
+
answer = UI.request 'Are you okay?'
|
32
|
+
unless answer
|
33
|
+
UI.failed 'aborted'
|
34
|
+
exit false
|
32
35
|
end
|
36
|
+
UI.info "Your answer: #{answer}"
|
data/lib/natty-ui/ansi.rb
CHANGED
@@ -60,17 +60,23 @@ module NattyUI
|
|
60
60
|
def cursor_left(columns = nil) = "\e[#{columns}D"
|
61
61
|
|
62
62
|
# @param lines [Integer] number of lines
|
63
|
-
# @return [String] ANSI code to move the cursor to beginning of the line
|
63
|
+
# @return [String] ANSI code to move the cursor to beginning of the line
|
64
|
+
# some lines down
|
64
65
|
def cursor_line_down(lines = nil) = "\e[#{lines}E"
|
65
66
|
|
66
67
|
# @param lines [Integer] number of lines
|
67
|
-
# @return [String] ANSI code to move the cursor to beginning of the line
|
68
|
+
# @return [String] ANSI code to move the cursor to beginning of the line
|
69
|
+
# some lines up
|
68
70
|
def cursor_line_up(lines = nil) = "\e[#{lines}F"
|
69
71
|
|
70
72
|
# @param columns [Integer] number of columns
|
71
|
-
# @return [String] ANSI code to move the cursor to
|
73
|
+
# @return [String] ANSI code to move the cursor to given column
|
72
74
|
def cursor_column(columns = nil) = "\e[#{columns}G"
|
73
75
|
|
76
|
+
# @return [String] ANSI code poition the cursor on right hand side of the
|
77
|
+
# terminal
|
78
|
+
def cursor_right_aligned = "\e[9999G\e[D\e[C"
|
79
|
+
|
74
80
|
# @return [String] ANSI code to hide the cursor
|
75
81
|
def cursor_hide = "\e[?25l"
|
76
82
|
|
@@ -107,6 +113,15 @@ module NattyUI
|
|
107
113
|
attributes.empty? ? "#{obj}" : "#{attributes}#{obj}#{"\e[0m" if reset}"
|
108
114
|
end
|
109
115
|
|
116
|
+
# Remove ANSI attribtes from given string.
|
117
|
+
# This will only remove attributes and colors, not other control codes.
|
118
|
+
#
|
119
|
+
# @see embellish
|
120
|
+
#
|
121
|
+
# @param str [#to_s] string to be modified
|
122
|
+
# @return [String] string without ANSI attributes
|
123
|
+
def blemish(str) = str.to_s.gsub(/(\x1b\[(?~m)m)/, '')
|
124
|
+
|
110
125
|
# Combine given ANSI `attributes`.
|
111
126
|
#
|
112
127
|
# ANSI attribute names are:
|
@@ -119,55 +134,57 @@ module NattyUI
|
|
119
134
|
# `fraktur_off`, `underline_off`, `blink_off`, `proportional`, `spacing`,
|
120
135
|
# `invert_off`, `reverse_off`, `reveal`, `strike_off`, `proportional_off`,
|
121
136
|
# `spacing_off`, `framed`, `encircled`, `overlined`, `framed_off`,
|
122
|
-
# `encircled_off`, `overlined_off
|
137
|
+
# `encircled_off`, `overlined_off`.
|
123
138
|
#
|
124
|
-
# Colors can specified by their name for ANSI 4-bit colors:
|
139
|
+
# Colors can specified by their name for ANSI 3-bit and 4-bit colors:
|
125
140
|
# `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`,
|
126
|
-
# `default`, `bright_black`, `bright_red`, `bright_green`,
|
127
|
-
# `bright_blue`, `bright_magenta`, `bright_cyan`,
|
141
|
+
# `default`, `bright_black`, `bright_red`, `bright_green`,
|
142
|
+
# `bright_yellow`, `bright_blue`, `bright_magenta`, `bright_cyan`,
|
143
|
+
# `bright_white`.
|
128
144
|
#
|
129
|
-
# For 8-bit ANSI colors
|
130
|
-
# `i0`...`i255`.
|
145
|
+
# For 8-bit ANSI colors use 2-digit hexadecimal values `00`...`ff`.
|
131
146
|
#
|
132
|
-
# To use RGB ANSI colors
|
133
|
-
#
|
147
|
+
# To use RGB ANSI colors (24-bit colors) specify 3-digit or 6-digit
|
148
|
+
# hexadecimal values `000`...`fff` or `000000`...`ffffff`.
|
149
|
+
# This represent the `RRGGBB` values (or `RGB` for short version) like you
|
150
|
+
# may known from CSS color notation.
|
134
151
|
#
|
135
152
|
# To use a color as background color prefix the color attribute with `bg_`
|
136
153
|
# or `on_`.
|
137
154
|
#
|
138
155
|
# To use a color as underline color prefix the color attribute with `ul_`.
|
139
156
|
#
|
140
|
-
# To make it more clear a color attribute
|
141
|
-
# color the
|
157
|
+
# To make it more clear a color attribute have to be used as foreground
|
158
|
+
# color the color value can be prefixed with `fg_`.
|
142
159
|
#
|
143
160
|
# @example Valid Foreground Color Attributes
|
144
161
|
# Ansi[:yellow]
|
145
|
-
# Ansi[
|
146
|
-
# Ansi[
|
162
|
+
# Ansi['#fab']
|
163
|
+
# Ansi['#00aa00']
|
147
164
|
# Ansi[:fg_fab]
|
148
165
|
# Ansi[:fg_00aa00]
|
149
|
-
# Ansi[:
|
150
|
-
# Ansi[:
|
166
|
+
# Ansi[:af]
|
167
|
+
# Ansi[:fg_af]
|
151
168
|
#
|
152
169
|
# @example Valid Background Color Attributes
|
153
170
|
# Ansi[:bg_yellow]
|
154
171
|
# Ansi[:bg_fab]
|
155
172
|
# Ansi[:bg_00aa00]
|
156
173
|
# Ansi['bg#00aa00']
|
157
|
-
# Ansi[:
|
174
|
+
# Ansi[:bg_af]
|
158
175
|
#
|
159
176
|
# Ansi[:on_yellow]
|
160
177
|
# Ansi[:on_fab]
|
161
178
|
# Ansi[:on_00aa00]
|
162
179
|
# Ansi['on#00aa00']
|
163
|
-
# Ansi[:
|
180
|
+
# Ansi[:on_af]
|
164
181
|
#
|
165
182
|
# @example Valid Underline Color Attributes
|
166
|
-
# Ansi[:underline, :
|
183
|
+
# Ansi[:underline, :ul_yellow]
|
167
184
|
# Ansi[:underline, :ul_fab]
|
168
185
|
# Ansi[:underline, :ul_00aa00]
|
169
186
|
# Ansi[:underline, 'ul#00aa00']
|
170
|
-
# Ansi[:underline, :
|
187
|
+
# Ansi[:underline, :ul_fa]
|
171
188
|
# Ansi[:underline, :ul_bright_yellow]
|
172
189
|
#
|
173
190
|
# @example Combined attributes:
|
@@ -182,7 +199,7 @@ module NattyUI
|
|
182
199
|
.map do |arg|
|
183
200
|
case arg
|
184
201
|
when Symbol, String
|
185
|
-
ATTRIBUTES[arg] ||
|
202
|
+
ATTRIBUTES[arg] || color(arg) || invalid_argument(arg)
|
186
203
|
when (0..255)
|
187
204
|
"38;5;#{arg}"
|
188
205
|
when (256..512)
|
@@ -215,7 +232,7 @@ module NattyUI
|
|
215
232
|
return if attributes.empty?
|
216
233
|
"\e[#{
|
217
234
|
attributes
|
218
|
-
.map { |arg| ATTRIBUTES[arg] ||
|
235
|
+
.map { |arg| ATTRIBUTES[arg] || color(arg) || return }
|
219
236
|
.join(';')
|
220
237
|
}m"
|
221
238
|
end
|
@@ -230,8 +247,14 @@ module NattyUI
|
|
230
247
|
)
|
231
248
|
end
|
232
249
|
|
233
|
-
def
|
250
|
+
def color(value)
|
234
251
|
case value
|
252
|
+
when /\A(fg_|fg:|fg)?([[:xdigit:]]{2})\z/
|
253
|
+
"38;5;#{Regexp.last_match(2).hex}"
|
254
|
+
when /\A(bg_|bg:|bg|on_|on:|on)([[:xdigit:]]{2})\z/
|
255
|
+
"48;5;#{Regexp.last_match(2).hex}"
|
256
|
+
when /\A(ul_|ul:|ul)([[:xdigit:]]{2})\z/
|
257
|
+
"58;5;#{Regexp.last_match(2).hex}"
|
235
258
|
when /\A(fg_|fg:|fg)?#?([[:xdigit:]]{3})\z/
|
236
259
|
hex_rgb_short(38, Regexp.last_match(2))
|
237
260
|
when /\A(fg_|fg:|fg)?#?([[:xdigit:]]{6})\z/
|
@@ -244,20 +267,9 @@ module NattyUI
|
|
244
267
|
hex_rgb_short(58, Regexp.last_match(2))
|
245
268
|
when /\A(ul_|ul:|ul)#?([[:xdigit:]]{6})\z/
|
246
269
|
hex_rgb(58, Regexp.last_match(2))
|
247
|
-
when /\A(fg_|fg:|fg)?i([[:digit:]]{1,3})\z/
|
248
|
-
number(38, Regexp.last_match(2))
|
249
|
-
when /\A(bg_|bg:|bg|on_|on:|on)i([[:digit:]]{1,3})\z/
|
250
|
-
number(48, Regexp.last_match(2))
|
251
|
-
when /\A(ul_|ul:|ul)i([[:digit:]]{1,3})\z/
|
252
|
-
number(58, Regexp.last_match(2))
|
253
270
|
end
|
254
271
|
end
|
255
272
|
|
256
|
-
def number(base, str)
|
257
|
-
index = str.to_i
|
258
|
-
"#{base};5;#{index}" if index >= 0 && index <= 255
|
259
|
-
end
|
260
|
-
|
261
273
|
def hex_rgb_short(base, str)
|
262
274
|
"#{base};2;#{(str[0] * 2).hex};#{(str[1] * 2).hex};#{(str[2] * 2).hex}"
|
263
275
|
end
|
@@ -282,7 +294,6 @@ module NattyUI
|
|
282
294
|
rapid_blink: 6,
|
283
295
|
# ---
|
284
296
|
invert: 7,
|
285
|
-
reverse: 7,
|
286
297
|
# ---
|
287
298
|
conceal: 8,
|
288
299
|
hide: 8,
|
@@ -319,7 +330,6 @@ module NattyUI
|
|
319
330
|
spacing: 26,
|
320
331
|
# ---
|
321
332
|
invert_off: 27,
|
322
|
-
reverse_off: 27,
|
323
333
|
# ---
|
324
334
|
reveal: 28,
|
325
335
|
# ---
|