natty-ui 0.7.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 +7 -3
- data/README.md +25 -47
- data/examples/24bit-colors.rb +27 -0
- data/examples/3bit-colors.rb +14 -0
- data/examples/8bit-colors.rb +31 -0
- data/examples/animate.rb +24 -0
- data/examples/attributes.rb +25 -159
- data/examples/demo.rb +53 -0
- data/examples/illustration.png +0 -0
- data/examples/illustration.rb +29 -0
- data/examples/{list_in_columns.rb → ls.rb} +13 -20
- data/examples/message.rb +30 -0
- data/examples/progress.rb +25 -30
- data/examples/query.rb +26 -28
- data/examples/read_key.rb +13 -0
- data/examples/table.rb +36 -0
- data/lib/natty-ui/ansi.rb +351 -305
- data/lib/natty-ui/ansi_constants.rb +73 -0
- data/lib/natty-ui/ansi_wrapper.rb +136 -162
- data/lib/natty-ui/features.rb +11 -18
- 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 +2 -2
- data/lib/natty-ui/wrapper/animate.rb +17 -0
- data/lib/natty-ui/wrapper/ask.rb +21 -21
- data/lib/natty-ui/wrapper/element.rb +19 -23
- data/lib/natty-ui/wrapper/framed.rb +29 -19
- data/lib/natty-ui/wrapper/heading.rb +26 -53
- data/lib/natty-ui/wrapper/horizontal_rule.rb +37 -0
- data/lib/natty-ui/wrapper/list_in_columns.rb +71 -12
- data/lib/natty-ui/wrapper/message.rb +20 -27
- data/lib/natty-ui/wrapper/progress.rb +40 -13
- data/lib/natty-ui/wrapper/query.rb +34 -31
- data/lib/natty-ui/wrapper/quote.rb +25 -0
- data/lib/natty-ui/wrapper/request.rb +21 -10
- data/lib/natty-ui/wrapper/section.rb +55 -39
- data/lib/natty-ui/wrapper/table.rb +298 -0
- data/lib/natty-ui/wrapper/task.rb +6 -7
- data/lib/natty-ui/wrapper.rb +123 -41
- data/lib/natty-ui.rb +65 -40
- metadata +28 -9
- data/examples/basic.rb +0 -62
data/lib/natty-ui.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'readline'
|
4
3
|
unless defined?(Reline)
|
5
4
|
# load the Reline::Unicode part only
|
6
5
|
# @!visibility private
|
@@ -15,7 +14,7 @@ require_relative 'natty-ui/ansi_wrapper'
|
|
15
14
|
|
16
15
|
#
|
17
16
|
# Module to create beautiful, nice, nifty, fancy, neat, pretty, cool, lovely,
|
18
|
-
# natty user interfaces for your CLI.
|
17
|
+
# natty user interfaces for your CLI application.
|
19
18
|
#
|
20
19
|
# It creates {Wrapper} instances which can optionally support ANSI. The UI
|
21
20
|
# consists of {Wrapper::Element}s and {Wrapper::Section}s for different
|
@@ -28,6 +27,9 @@ module NattyUI
|
|
28
27
|
# @raise [TypeError] when a non-readable stream will be assigned
|
29
28
|
attr_reader :in_stream
|
30
29
|
|
30
|
+
# @return [Wrapper, Wrapper::Element] active UI element
|
31
|
+
attr_reader :element
|
32
|
+
|
31
33
|
# @param [IO] stream to read input
|
32
34
|
def in_stream=(stream)
|
33
35
|
unless valid_in?(stream)
|
@@ -90,23 +92,28 @@ module NattyUI
|
|
90
92
|
end
|
91
93
|
match.empty? or next "[[#{match}]]"
|
92
94
|
reset = false
|
93
|
-
Ansi
|
95
|
+
Ansi::RESET
|
94
96
|
end
|
95
|
-
reset ? "#{ret}#{Ansi
|
97
|
+
reset ? "#{ret}#{Ansi::RESET}" : ret
|
96
98
|
end
|
97
99
|
|
98
100
|
# Remove embedded attribute descriptions from given string.
|
99
101
|
#
|
100
102
|
# @param [#to_s] str string to edit
|
101
|
-
# @
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
103
|
+
# @param [:keep,:remove] ansi keep or remove ANSI codes too
|
104
|
+
# @return [String] edited string
|
105
|
+
def plain(str, ansi: :keep)
|
106
|
+
str =
|
107
|
+
str
|
108
|
+
.to_s
|
109
|
+
.gsub(/(\[\[((?~\]\]))\]\])/) do
|
110
|
+
match = Regexp.last_match[2]
|
111
|
+
if match.delete_prefix!('/')
|
112
|
+
next match.empty? ? nil : "[[#{match}]]"
|
113
|
+
end
|
114
|
+
Ansi.try_convert(match) ? nil : "[[#{match}]]"
|
115
|
+
end
|
116
|
+
ansi == :keep ? str : Ansi.blemish(str)
|
110
117
|
end
|
111
118
|
|
112
119
|
# Calculate monospace (display) width of given String.
|
@@ -115,7 +122,8 @@ module NattyUI
|
|
115
122
|
# @param [#to_s] str string to calculate
|
116
123
|
# @return [Integer] the display size
|
117
124
|
def display_width(str)
|
118
|
-
(str = str.to_s).empty?
|
125
|
+
return 0 if (str = str.to_s).empty?
|
126
|
+
Reline::Unicode.calculate_width(plain(str), true)
|
119
127
|
end
|
120
128
|
|
121
129
|
# Convert given arguments into strings and yield each line.
|
@@ -133,7 +141,7 @@ module NattyUI
|
|
133
141
|
def each_line(*strs, max_width: nil, &block)
|
134
142
|
return to_enum(__method__, *strs, max_width: max_width) unless block
|
135
143
|
if max_width.nil?
|
136
|
-
strs.each {
|
144
|
+
strs.each { _1.to_s.each_line(chomp: true, &block) }
|
137
145
|
return nil
|
138
146
|
end
|
139
147
|
return if (max_width = max_width.to_i) <= 0
|
@@ -141,45 +149,51 @@ module NattyUI
|
|
141
149
|
str
|
142
150
|
.to_s
|
143
151
|
.each_line(chomp: true) do |line|
|
144
|
-
|
145
|
-
|
146
|
-
|
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)
|
147
158
|
end
|
148
159
|
end
|
149
160
|
nil
|
150
161
|
end
|
151
162
|
|
152
|
-
# Read
|
163
|
+
# Read next raw key (keyboard input) from {in_stream}.
|
153
164
|
#
|
154
|
-
#
|
155
|
-
#
|
165
|
+
# The input will be returned as named key codes like "Ctrl+C" by default.
|
166
|
+
# This can be changed by the `mode` parameter:
|
156
167
|
#
|
157
|
-
#
|
168
|
+
# - `:named` - name if available (fallback to raw)
|
169
|
+
# - `:raw` - key code "as is"
|
170
|
+
# - `:both` - key code and name if available
|
158
171
|
#
|
159
|
-
# @param [
|
160
|
-
# @
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
172
|
+
# @param [:named, :raw, :both] mode modfies the result
|
173
|
+
# @return [String] read key
|
174
|
+
def read_key(mode: :named)
|
175
|
+
return @in_stream.getch unless defined?(@in_stream.getc)
|
176
|
+
return @in_stream.getc unless defined?(@in_stream.raw)
|
177
|
+
@in_stream.raw do |raw_stream|
|
178
|
+
key = raw_stream.getc
|
179
|
+
while (nc = raw_stream.read_nonblock(1, exception: false))
|
180
|
+
nc.is_a?(String) ? key += nc : break
|
181
|
+
end
|
182
|
+
return key if mode == :raw
|
183
|
+
return key, KEY_MAP[key]&.dup if mode == :both
|
184
|
+
KEY_MAP[key]&.dup || key
|
185
|
+
end
|
186
|
+
rescue Interrupt, SystemCallError
|
173
187
|
nil
|
174
|
-
ensure
|
175
|
-
Readline.completion_proc = cp
|
176
188
|
end
|
177
189
|
|
178
190
|
private
|
179
191
|
|
180
192
|
def wrapper_class(stream, ansi)
|
181
|
-
return AnsiWrapper if ansi == true
|
182
|
-
|
193
|
+
return AnsiWrapper if ansi == true || ENV['ANSI'] == '1'
|
194
|
+
if ansi == false || ENV.key?('NO_COLOR') || ENV['TERM'] == 'dumb'
|
195
|
+
return Wrapper
|
196
|
+
end
|
183
197
|
stream.tty? ? AnsiWrapper : Wrapper
|
184
198
|
end
|
185
199
|
|
@@ -196,5 +210,16 @@ module NattyUI
|
|
196
210
|
# Instance for standard error output.
|
197
211
|
StdErr = stderr_is_stdout? ? StdOut : new(STDERR)
|
198
212
|
|
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
|
218
|
+
end
|
219
|
+
|
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)
|
200
225
|
end
|
metadata
CHANGED
@@ -1,21 +1,20 @@
|
|
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:
|
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,
|
15
|
-
natty user interface you like to have for your command line
|
16
|
-
|
17
|
-
|
18
|
-
command line application functionally and aesthetically.
|
15
|
+
natty user interface tool you like to have for your command line applications.
|
16
|
+
It contains elegant, simple and beautiful features that enhance your
|
17
|
+
command line interfaces functionally and aesthetically.
|
19
18
|
email:
|
20
19
|
executables: []
|
21
20
|
extensions: []
|
@@ -26,29 +25,49 @@ files:
|
|
26
25
|
- ".yardopts"
|
27
26
|
- LICENSE
|
28
27
|
- README.md
|
28
|
+
- examples/24bit-colors.rb
|
29
|
+
- examples/3bit-colors.rb
|
30
|
+
- examples/8bit-colors.rb
|
31
|
+
- examples/animate.rb
|
29
32
|
- examples/attributes.rb
|
30
|
-
- examples/
|
33
|
+
- examples/demo.rb
|
31
34
|
- examples/illustration.png
|
32
|
-
- examples/
|
35
|
+
- examples/illustration.rb
|
36
|
+
- examples/ls.rb
|
37
|
+
- examples/message.rb
|
33
38
|
- examples/progress.rb
|
34
39
|
- examples/query.rb
|
40
|
+
- examples/read_key.rb
|
41
|
+
- examples/table.rb
|
35
42
|
- lib/natty-ui.rb
|
36
43
|
- lib/natty-ui/ansi.rb
|
44
|
+
- lib/natty-ui/ansi_constants.rb
|
37
45
|
- lib/natty-ui/ansi_wrapper.rb
|
38
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
|
39
54
|
- lib/natty-ui/version.rb
|
40
55
|
- lib/natty-ui/wrapper.rb
|
56
|
+
- lib/natty-ui/wrapper/animate.rb
|
41
57
|
- lib/natty-ui/wrapper/ask.rb
|
42
58
|
- lib/natty-ui/wrapper/element.rb
|
43
59
|
- lib/natty-ui/wrapper/framed.rb
|
44
60
|
- lib/natty-ui/wrapper/heading.rb
|
61
|
+
- lib/natty-ui/wrapper/horizontal_rule.rb
|
45
62
|
- lib/natty-ui/wrapper/list_in_columns.rb
|
46
63
|
- lib/natty-ui/wrapper/message.rb
|
47
64
|
- lib/natty-ui/wrapper/mixins.rb
|
48
65
|
- lib/natty-ui/wrapper/progress.rb
|
49
66
|
- lib/natty-ui/wrapper/query.rb
|
67
|
+
- lib/natty-ui/wrapper/quote.rb
|
50
68
|
- lib/natty-ui/wrapper/request.rb
|
51
69
|
- lib/natty-ui/wrapper/section.rb
|
70
|
+
- lib/natty-ui/wrapper/table.rb
|
52
71
|
- lib/natty-ui/wrapper/task.rb
|
53
72
|
- lib/natty_ui.rb
|
54
73
|
homepage: https://github.com/mblumtritt/natty-ui
|
@@ -74,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
93
|
- !ruby/object:Gem::Version
|
75
94
|
version: '0'
|
76
95
|
requirements: []
|
77
|
-
rubygems_version: 3.
|
96
|
+
rubygems_version: 3.5.14
|
78
97
|
signing_key:
|
79
98
|
specification_version: 4
|
80
99
|
summary: This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely, natty
|
data/examples/basic.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'natty-ui'
|
4
|
-
|
5
|
-
UI = NattyUI::StdOut
|
6
|
-
|
7
|
-
UI.space
|
8
|
-
|
9
|
-
UI.h1 'NattyUI Basic Feature Demo', <<~TEXT
|
10
|
-
|
11
|
-
This is a short demo of the basic features of [[75 bold]]NattyUI[[/]].
|
12
|
-
|
13
|
-
TEXT
|
14
|
-
|
15
|
-
UI.h2 'Feature: ANSI Colors and Attributes', <<~TEXT
|
16
|
-
|
17
|
-
Like you might noticed you can [[57]]color [[d7]]text[[/]] for terminals supporting this
|
18
|
-
feature. You can enforece the non-ANSI version by setting the environment
|
19
|
-
variable [[75 italic]]NO_COLOR[[/]] to '[[75]]1[[/]]'. (see also [[underline]]https://no-color.org[[/]])
|
20
|
-
|
21
|
-
You can not only color your text but also [[italic]]modify[[/]], [[underline]]decorate[[/]] and [[strike]]manipulate[[/]]
|
22
|
-
it. The attributes are direct embedded into the text like '[[/bold red]]'
|
23
|
-
and can be resetted with '[[//]]' or at the line end.
|
24
|
-
|
25
|
-
TEXT
|
26
|
-
|
27
|
-
UI.h2 'Feature: Sections' do |sec|
|
28
|
-
sec.puts <<~TEXT
|
29
|
-
|
30
|
-
Sections group text lines together and/or define their style. There are
|
31
|
-
several section types which all can be stacked.
|
32
|
-
|
33
|
-
Have a look at the different types of sections:
|
34
|
-
|
35
|
-
TEXT
|
36
|
-
sec.message 'Generic Message'
|
37
|
-
sec.information 'Informational Message'
|
38
|
-
sec.warning 'Warning Message'
|
39
|
-
sec.error 'Error Message'
|
40
|
-
sec.completed 'Completion Message'
|
41
|
-
sec.failed 'Failure Message'
|
42
|
-
sec.msg '[[d5]]Customized Message', symbol: '◉'
|
43
|
-
sec.space
|
44
|
-
|
45
|
-
sec.puts 'You can stack all kinds of sections together:'
|
46
|
-
sec.space
|
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|
|
50
|
-
f3.framed('Double Framed Section', type: :double) do |f4|
|
51
|
-
f4.message(
|
52
|
-
'[[fff400]]Frames are nice',
|
53
|
-
"Just to show you that all sections\ncan be stacked...",
|
54
|
-
symbol: '💛'
|
55
|
-
)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
UI.space
|