natty-ui 0.5.1 → 0.5.3
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 +13 -33
- data/examples/basic.rb +2 -0
- data/examples/colors.rb +2 -0
- data/lib/natty-ui/ansi_wrapper.rb +15 -15
- data/lib/natty-ui/version.rb +1 -1
- data/lib/natty-ui/wrapper/ask.rb +2 -0
- data/lib/natty-ui/wrapper/element.rb +3 -8
- data/lib/natty-ui/wrapper/features.rb +1 -5
- data/lib/natty-ui/wrapper/framed.rb +4 -3
- data/lib/natty-ui/wrapper/heading.rb +6 -6
- data/lib/natty-ui/wrapper/message.rb +7 -7
- data/lib/natty-ui/wrapper/progress.rb +1 -1
- data/lib/natty-ui/wrapper/query.rb +3 -1
- data/lib/natty-ui/wrapper/section.rb +11 -11
- data/lib/natty-ui/wrapper/task.rb +3 -3
- data/lib/natty-ui/wrapper.rb +11 -14
- data/lib/natty-ui.rb +60 -23
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a717eec681b358c4979684881f16d5217dea7ebacca3baf46f84edfc318d39b
|
4
|
+
data.tar.gz: 2829903b6bf15aa81d33259bf77633d6ed6b9e5f88a598bc858b881be94da4cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 274f008deb82e73ba4a6c0b93d2a4e4cea3afdd60284d8fdc8e462e56cf04f6e5bda8a25af1c1707cd5a8c92612d48f445f5d127fb5c6531d183b3b8ac424279
|
7
|
+
data.tar.gz: 770c07b0085ac1efd565b141fae6f704899a89b7e8b648fd27e687166a13676edd3a38039d8f4aeae7c490849cf39a5d2d22daed25d6a1c0b9540340b21483f4
|
data/README.md
CHANGED
@@ -40,29 +40,13 @@ UI.framed 'Text Below In Frame' do |framed|
|
|
40
40
|
end
|
41
41
|
```
|
42
42
|
|
43
|
-
or use progression displays like progress bars
|
43
|
+
or use progression displays like progress bars.
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
### But there is more!
|
48
|
-
|
49
|
-
Have a look at the [examples](./examples/) directory to get an impression of the current feature set.
|
50
|
-
|
51
|
-
```sh
|
52
|
-
ruby ./examples/basic.rb
|
53
|
-
```
|
54
|
-
|
55
|
-
or see the non-ANSI version
|
56
|
-
|
57
|
-
```sh
|
58
|
-
NO_COLOR=1 ruby ./examples/basic.rb
|
59
|
-
```
|
45
|
+
🚀 There are much more [features](https://rubydoc.info/gems/natty-ui/NattyUI/Features)!
|
60
46
|
|
61
|
-
|
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.
|
62
48
|
|
63
|
-
|
64
|
-
|
65
|
-
NattyUI follows the [NO_COLOR convention](https://no-color.org).
|
49
|
+

|
66
50
|
|
67
51
|
## Installation
|
68
52
|
|
@@ -84,32 +68,28 @@ After that you only need one line of code to have everything together
|
|
84
68
|
require 'natty-ui'
|
85
69
|
```
|
86
70
|
|
87
|
-
##
|
88
|
-
|
89
|
-
Unicode is generally supported. This means that for the calculation of screen outputs the different width of characters is considered. For this the wonderful Gem [unicode/display_width](https://github.com/janlelis/unicode-display_width) is used.
|
71
|
+
## Run Examples
|
90
72
|
|
91
|
-
|
73
|
+
You can execute the examples by
|
92
74
|
|
93
|
-
|
94
|
-
|
95
|
-
```ruby
|
96
|
-
require 'unicode/emoji'
|
97
|
-
require 'natty-ui'
|
75
|
+
```sh
|
76
|
+
ruby ./examples/basic.rb
|
98
77
|
```
|
99
78
|
|
100
|
-
|
79
|
+
or see the non-ANSI version
|
101
80
|
|
102
81
|
```sh
|
103
|
-
|
82
|
+
NO_COLOR=1 ruby ./examples/basic.rb
|
104
83
|
```
|
105
84
|
|
106
|
-
|
85
|
+
## NO_COLOR Convention
|
86
|
+
|
87
|
+
NattyUI follows the [NO_COLOR convention](https://no-color.org).
|
107
88
|
|
108
89
|
## TODO
|
109
90
|
|
110
91
|
Since I did not complete the tests and not all my ideas are already implemented I have this Todo list:
|
111
92
|
|
112
|
-
- add samples to README
|
113
93
|
- add more samples to help
|
114
94
|
- add more tests
|
115
95
|
- simple prompt
|
data/examples/basic.rb
CHANGED
data/examples/colors.rb
CHANGED
@@ -46,16 +46,16 @@ module NattyUI
|
|
46
46
|
|
47
47
|
def title_attr(str, symbol)
|
48
48
|
color = COLORS[symbol]
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
{
|
50
|
+
prefix:
|
51
|
+
if color
|
52
52
|
"#{Ansi[:bold, :italic, color]}#{str}" \
|
53
|
-
"#{Ansi[:reset, :bold, color]} "
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
"#{Ansi[:reset, :bold, color]} "
|
54
|
+
else
|
55
|
+
"#{Ansi[:bold, 231]}#{str} "
|
56
|
+
end,
|
57
|
+
suffix: Ansi.reset
|
58
|
+
}
|
59
59
|
end
|
60
60
|
|
61
61
|
COLORS = {
|
@@ -167,12 +167,6 @@ module NattyUI
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
TITLE_PREFIX = "#{Ansi[:bold, :italic, 117]}➔#{Ansi[:reset, 117]} ".freeze
|
171
|
-
INDICATOR_ATTRIBUTE = Ansi[:bold, 220].freeze
|
172
|
-
BAR_COLOR = Ansi[39, 295].freeze
|
173
|
-
BAR_BACK = Ansi[236, 492].freeze
|
174
|
-
BAR_INK = Ansi[:bold, 255, :on_default].freeze
|
175
|
-
|
176
170
|
def draw_final = (wrapper.stream << Ansi.line_clear).flush
|
177
171
|
|
178
172
|
def redraw
|
@@ -194,6 +188,12 @@ module NattyUI
|
|
194
188
|
)
|
195
189
|
}"
|
196
190
|
end
|
191
|
+
|
192
|
+
TITLE_PREFIX = "#{Ansi[:bold, :italic, 117]}➔#{Ansi[:reset, 117]} ".freeze
|
193
|
+
INDICATOR_ATTRIBUTE = Ansi[:bold, 220].freeze
|
194
|
+
BAR_COLOR = Ansi[39, 295].freeze
|
195
|
+
BAR_BACK = Ansi[236, 492].freeze
|
196
|
+
BAR_INK = Ansi[:bold, 255, :on_default].freeze
|
197
197
|
end
|
198
198
|
|
199
199
|
PAGE_BEGIN =
|
data/lib/natty-ui/version.rb
CHANGED
data/lib/natty-ui/wrapper/ask.rb
CHANGED
@@ -22,6 +22,8 @@ module NattyUI
|
|
22
22
|
# sec.failed('You should have an opinion!')
|
23
23
|
# end
|
24
24
|
#
|
25
|
+
# @see NattyUI.in_stream
|
26
|
+
#
|
25
27
|
# @param question [#to_s] Question to display
|
26
28
|
# @param yes [#to_s] chars which will be used to answer 'Yes'
|
27
29
|
# @param no [#to_s] chars which will be used to answer 'No'
|
@@ -24,17 +24,14 @@ module NattyUI
|
|
24
24
|
|
25
25
|
# Close the element.
|
26
26
|
#
|
27
|
-
# @return [Element] itself
|
28
|
-
# @return [nil] when used with a code block
|
27
|
+
# @return [Element] itself
|
29
28
|
def close = _close(:closed)
|
30
29
|
|
31
30
|
alias _to_s to_s
|
32
31
|
private :_to_s
|
33
32
|
|
34
33
|
# @!visibility private
|
35
|
-
def inspect
|
36
|
-
"#{_to_s[..-2]} status=#{@status}}}>"
|
37
|
-
end
|
34
|
+
def inspect = "#{_to_s[..-2]} status=#{@status}}}>"
|
38
35
|
|
39
36
|
protected
|
40
37
|
|
@@ -49,9 +46,7 @@ module NattyUI
|
|
49
46
|
@wrapper
|
50
47
|
end
|
51
48
|
|
52
|
-
def initialize(parent)
|
53
|
-
@parent = parent
|
54
|
-
end
|
49
|
+
def initialize(parent) = (@parent = parent)
|
55
50
|
|
56
51
|
def _close(state)
|
57
52
|
return self if @status
|
@@ -11,11 +11,7 @@ module NattyUI
|
|
11
11
|
wrapper.class.const_get(type).__send__(:new, self).__send__(:_call, *args)
|
12
12
|
end
|
13
13
|
|
14
|
-
def _section(type, args, **opts, &block)
|
15
|
-
__section(self, type, args, **opts, &block)
|
16
|
-
end
|
17
|
-
|
18
|
-
def __section(owner, type, args, **opts, &block)
|
14
|
+
def _section(owner, type, args, **opts, &block)
|
19
15
|
sec = wrapper.class.const_get(type).__send__(:new, owner, **opts)
|
20
16
|
sec.puts(*args) if args && !args.empty?
|
21
17
|
block ? sec.__send__(:_call, &block) : sec
|
@@ -7,17 +7,18 @@ module NattyUI
|
|
7
7
|
# Creates frame-enclosed section with a highlighted `title` and
|
8
8
|
# prints given additional arguments as lines into the section.
|
9
9
|
#
|
10
|
-
# When no block is given, the section must be closed, see
|
10
|
+
# When no block is given, the section must be closed, see
|
11
|
+
# {Wrapper::Element#close}.
|
11
12
|
#
|
12
13
|
# @param [#to_s] title object to print as section title
|
13
14
|
# @param [Array<#to_s>] args more objects to print
|
14
15
|
# @param [Symbol] type frame type;
|
15
16
|
# valid types are `:rounded`, `:simple`, `:heavy`, `:semi`, `:double`
|
16
|
-
# @yieldparam [Wrapper::Framed]
|
17
|
+
# @yieldparam [Wrapper::Framed] framed the created section
|
17
18
|
# @return [Object] the result of the code block
|
18
19
|
# @return [Wrapper::Framed] itself, when no code block is given
|
19
20
|
def framed(title, *args, type: :rounded, &block)
|
20
|
-
_section(:Framed, args, title: title, type: type, &block)
|
21
|
+
_section(self, :Framed, args, title: title, type: type, &block)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -7,11 +7,11 @@ module NattyUI
|
|
7
7
|
# Creates section with a H1 title.
|
8
8
|
#
|
9
9
|
# @param (see #information)
|
10
|
-
# @yieldparam [Wrapper::Heading]
|
10
|
+
# @yieldparam [Wrapper::Heading] heading the created section
|
11
11
|
# @return [Object] the result of the code block
|
12
12
|
# @return [Wrapper::Heading] itself, when no code block is given
|
13
13
|
def h1(title, *args, &block)
|
14
|
-
_section(:Heading, args, title: title, weight: 1, &block)
|
14
|
+
_section(self, :Heading, args, title: title, weight: 1, &block)
|
15
15
|
end
|
16
16
|
|
17
17
|
# Creates section with a H2 title.
|
@@ -20,7 +20,7 @@ module NattyUI
|
|
20
20
|
# @yieldparam (see #h1)
|
21
21
|
# @return (see #h1)
|
22
22
|
def h2(title, *args, &block)
|
23
|
-
_section(:Heading, args, title: title, weight: 2, &block)
|
23
|
+
_section(self, :Heading, args, title: title, weight: 2, &block)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Creates section with a H3 title.
|
@@ -29,7 +29,7 @@ module NattyUI
|
|
29
29
|
# @yieldparam (see #h1)
|
30
30
|
# @return (see #h1)
|
31
31
|
def h3(title, *args, &block)
|
32
|
-
_section(:Heading, args, title: title, weight: 3, &block)
|
32
|
+
_section(self, :Heading, args, title: title, weight: 3, &block)
|
33
33
|
end
|
34
34
|
|
35
35
|
# Creates section with a H4 title.
|
@@ -38,7 +38,7 @@ module NattyUI
|
|
38
38
|
# @yieldparam (see #h1)
|
39
39
|
# @return (see #h1)
|
40
40
|
def h4(title, *args, &block)
|
41
|
-
_section(:Heading, args, title: title, weight: 4, &block)
|
41
|
+
_section(self, :Heading, args, title: title, weight: 4, &block)
|
42
42
|
end
|
43
43
|
|
44
44
|
# Creates section with a H5 title.
|
@@ -47,7 +47,7 @@ module NattyUI
|
|
47
47
|
# @yieldparam (see #h1)
|
48
48
|
# @return (see #h1)
|
49
49
|
def h5(title, *args, &block)
|
50
|
-
_section(:Heading, args, title: title, weight: 5, &block)
|
50
|
+
_section(self, :Heading, args, title: title, weight: 5, &block)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -10,11 +10,11 @@ module NattyUI
|
|
10
10
|
# @param [#to_s] title object to print as section title
|
11
11
|
# @param [Array<#to_s>] args more objects to print
|
12
12
|
# @param [#to_s] symbol symbol/prefix used for the title
|
13
|
-
# @yieldparam [Wrapper::Message]
|
13
|
+
# @yieldparam [Wrapper::Message] message the created section
|
14
14
|
# @return [Object] the result of the code block
|
15
15
|
# @return [Wrapper::Message] itself, when no code block is given
|
16
16
|
def message(title, *args, symbol: :default, &block)
|
17
|
-
_section(:Message, args, title: title, symbol: symbol, &block)
|
17
|
+
_section(self, :Message, args, title: title, symbol: symbol, &block)
|
18
18
|
end
|
19
19
|
alias msg message
|
20
20
|
|
@@ -26,7 +26,7 @@ module NattyUI
|
|
26
26
|
# @yieldparam (see #message)
|
27
27
|
# @return (see #message)
|
28
28
|
def information(title, *args, &block)
|
29
|
-
_section(:Message, args, title: title, symbol: :information, &block)
|
29
|
+
_section(self, :Message, args, title: title, symbol: :information, &block)
|
30
30
|
end
|
31
31
|
alias info information
|
32
32
|
|
@@ -37,7 +37,7 @@ module NattyUI
|
|
37
37
|
# @yieldparam (see #message)
|
38
38
|
# @return (see #message)
|
39
39
|
def warning(title, *args, &block)
|
40
|
-
_section(:Message, args, title: title, symbol: :warning, &block)
|
40
|
+
_section(self, :Message, args, title: title, symbol: :warning, &block)
|
41
41
|
end
|
42
42
|
alias warn warning
|
43
43
|
|
@@ -48,7 +48,7 @@ module NattyUI
|
|
48
48
|
# @yieldparam (see #message)
|
49
49
|
# @return (see #message)
|
50
50
|
def error(title, *args, &block)
|
51
|
-
_section(:Message, args, title: title, symbol: :error, &block)
|
51
|
+
_section(self, :Message, args, title: title, symbol: :error, &block)
|
52
52
|
end
|
53
53
|
alias err error
|
54
54
|
|
@@ -61,7 +61,7 @@ module NattyUI
|
|
61
61
|
# @yieldparam (see #message)
|
62
62
|
# @return (see #message)
|
63
63
|
def completed(title, *args, &block)
|
64
|
-
_section(:Message, args, title: title, symbol: :completed, &block)
|
64
|
+
_section(self, :Message, args, title: title, symbol: :completed, &block)
|
65
65
|
end
|
66
66
|
alias done completed
|
67
67
|
alias ok completed
|
@@ -76,7 +76,7 @@ module NattyUI
|
|
76
76
|
# @yieldparam (see #message)
|
77
77
|
# @return (see #message)
|
78
78
|
def failed(title, *args, &block)
|
79
|
-
_section(:Message, args, title: title, symbol: :failed, &block)
|
79
|
+
_section(self, :Message, args, title: title, symbol: :failed, &block)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -14,7 +14,7 @@ module NattyUI
|
|
14
14
|
# @param [##to_f] max_value maximum value of the progress
|
15
15
|
# @return [Wrapper::Progress] the created progress element
|
16
16
|
def progress(title, max_value: nil)
|
17
|
-
_section(:Progress, nil, title: title, max_value: max_value)
|
17
|
+
_section(self, :Progress, nil, title: title, max_value: max_value)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -24,6 +24,8 @@ module NattyUI
|
|
24
24
|
# )
|
25
25
|
# # => 'a' or 'b' or 'c' or nil if user aborted
|
26
26
|
#
|
27
|
+
# @see NattyUI.in_stream
|
28
|
+
#
|
27
29
|
# @param question [#to_s] Question to display
|
28
30
|
# @param choices [#to_s] choices selectable via index (0..9)
|
29
31
|
# @param result [Symbol] defines how the result ist returned
|
@@ -49,7 +51,7 @@ module NattyUI
|
|
49
51
|
choices = grab(choices, kw_choices)
|
50
52
|
return if choices.empty?
|
51
53
|
wrapper.temporary do
|
52
|
-
|
54
|
+
_section(
|
53
55
|
@parent,
|
54
56
|
:Message,
|
55
57
|
choices.map { |k, v| "#{k} #{v}" },
|
@@ -12,7 +12,7 @@ module NattyUI
|
|
12
12
|
# @return [Object] the result of the code block
|
13
13
|
# @return [Wrapper::Section] itself, when no code block is given
|
14
14
|
def section(*args, &block)
|
15
|
-
_section(:Section, args, prefix: ' ', suffix: ' ', &block)
|
15
|
+
_section(self, :Section, args, prefix: ' ', suffix: ' ', &block)
|
16
16
|
end
|
17
17
|
alias sec section
|
18
18
|
|
@@ -23,13 +23,13 @@ module NattyUI
|
|
23
23
|
# @yieldparam (see #section)
|
24
24
|
# @return (see #section)
|
25
25
|
def quote(*args, &block)
|
26
|
-
_section(:Section, args, prefix: '▍ ', prefix_attr: 39, &block)
|
26
|
+
_section(self, :Section, args, prefix: '▍ ', prefix_attr: 39, &block)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
class Wrapper
|
31
31
|
#
|
32
|
-
# Visual
|
32
|
+
# Visual {Element} to keep text lines together.
|
33
33
|
#
|
34
34
|
# A section can contain other elements and sections.
|
35
35
|
#
|
@@ -38,21 +38,23 @@ module NattyUI
|
|
38
38
|
class Section < Element
|
39
39
|
# Close the section.
|
40
40
|
#
|
41
|
-
# @return [Section] itself
|
42
|
-
# @return [nil] when used with a code block
|
41
|
+
# @return [Section] itself
|
43
42
|
def close = _close(:closed)
|
44
43
|
|
45
44
|
# Print given arguments as lines into the section.
|
45
|
+
# Optionally limit the line width to given `max_width`.
|
46
46
|
#
|
47
|
-
# @overload puts(
|
47
|
+
# @overload puts(..., max_width: nil)
|
48
48
|
# @param [#to_s] ... objects to print
|
49
|
+
# @param [Integer, nil] max_width maximum line width
|
49
50
|
# @comment @param [#to_s, nil] prefix line prefix
|
50
51
|
# @comment @param [#to_s, nil] suffix line suffix
|
51
52
|
# @return [Section] itself
|
52
|
-
def puts(*args, prefix: nil, suffix: nil)
|
53
|
+
def puts(*args, max_width: nil, prefix: nil, suffix: nil)
|
53
54
|
return self if @status
|
54
55
|
@parent.puts(
|
55
56
|
*args,
|
57
|
+
max_width: max_width,
|
56
58
|
prefix: prefix ? "#{@prefix}#{prefix}" : @prefix,
|
57
59
|
suffix: suffix ? "#{@suffix}#{suffix}" : @suffix
|
58
60
|
)
|
@@ -66,7 +68,7 @@ module NattyUI
|
|
66
68
|
# @return [Section] itself
|
67
69
|
def space(lines = 1)
|
68
70
|
@parent.puts(
|
69
|
-
*
|
71
|
+
"\n" * ([lines.to_i, 1].max - 1),
|
70
72
|
prefix: @prefix,
|
71
73
|
suffix: @suffix
|
72
74
|
)
|
@@ -86,9 +88,7 @@ module NattyUI
|
|
86
88
|
#
|
87
89
|
# @yield [Section] itself
|
88
90
|
# @return [Object] block result
|
89
|
-
def temporary
|
90
|
-
block_given? ? yield(self) : self
|
91
|
-
end
|
91
|
+
def temporary = block_given? ? yield(self) : self
|
92
92
|
|
93
93
|
protected
|
94
94
|
|
@@ -11,11 +11,11 @@ module NattyUI
|
|
11
11
|
# or {#failed}.
|
12
12
|
#
|
13
13
|
# @param (see #information)
|
14
|
-
# @yieldparam [Wrapper::Task]
|
14
|
+
# @yieldparam [Wrapper::Task] task the created section
|
15
15
|
# @return [Object] the result of the code block
|
16
16
|
# @return [Wrapper::Task] itself, when no code block is given
|
17
17
|
def task(title, *args, &block)
|
18
|
-
_section(:Task, args, title: title, &block)
|
18
|
+
_section(self, :Task, args, title: title, &block)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -34,7 +34,7 @@ module NattyUI
|
|
34
34
|
@status = :completed if @status == :closed
|
35
35
|
@temp.call
|
36
36
|
end
|
37
|
-
|
37
|
+
_section(
|
38
38
|
@parent,
|
39
39
|
:Message,
|
40
40
|
@final_text,
|
data/lib/natty-ui/wrapper.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'stringio'
|
4
3
|
require_relative 'wrapper/ask'
|
5
4
|
require_relative 'wrapper/framed'
|
6
5
|
require_relative 'wrapper/heading'
|
@@ -28,13 +27,13 @@ module NattyUI
|
|
28
27
|
# @return [[Integer, Integer]] screen size as rows and columns
|
29
28
|
def screen_size
|
30
29
|
return @stream.winsize if @ws
|
31
|
-
[ENV['LINES'].to_i.nonzero? ||
|
30
|
+
[ENV['LINES'].to_i.nonzero? || 24, ENV['COLUMNS'].to_i.nonzero? || 80]
|
32
31
|
end
|
33
32
|
|
34
33
|
# @attribute [r] screen_rows
|
35
34
|
# @return [Integer] number of screen rows
|
36
35
|
def screen_rows
|
37
|
-
@ws ? @stream.winsize[0] : (ENV['LINES'].to_i.nonzero? ||
|
36
|
+
@ws ? @stream.winsize[0] : (ENV['LINES'].to_i.nonzero? || 24)
|
38
37
|
end
|
39
38
|
|
40
39
|
# @attribute [r] screen_columns
|
@@ -46,24 +45,22 @@ module NattyUI
|
|
46
45
|
# @!group Tool functions
|
47
46
|
|
48
47
|
# Print given arguments as lines to the output stream.
|
48
|
+
# Optionally limit the line width to given `max_width`.
|
49
49
|
#
|
50
|
-
# @overload puts(
|
50
|
+
# @overload puts(..., max_width: nil)
|
51
51
|
# @param [#to_s] ... objects to print
|
52
|
+
# @param [Integer, nil] max_width maximum line width
|
52
53
|
# @comment @param [#to_s, nil] prefix line prefix
|
53
54
|
# @comment @param [#to_s, nil] suffix line suffix
|
54
55
|
# @return [Wrapper] itself
|
55
|
-
def puts(*args, prefix: nil, suffix: nil)
|
56
|
+
def puts(*args, max_width: nil, prefix: nil, suffix: nil)
|
56
57
|
if args.empty?
|
57
58
|
@stream.puts(embellish("#{prefix}#{suffix}"))
|
58
59
|
@lines_written += 1
|
59
60
|
else
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
io.each(chomp: true) do |line|
|
64
|
-
@stream.puts(embellish("#{prefix}#{line}#{suffix}"))
|
65
|
-
@lines_written += 1
|
66
|
-
end
|
61
|
+
NattyUI.each_line(*args, max_width: max_width) do |line|
|
62
|
+
@stream.puts(embellish("#{prefix}#{line}#{suffix}"))
|
63
|
+
@lines_written += 1
|
67
64
|
end
|
68
65
|
end
|
69
66
|
@stream.flush
|
@@ -77,7 +74,7 @@ module NattyUI
|
|
77
74
|
# @return [Wrapper] itself
|
78
75
|
def space(lines = 1)
|
79
76
|
lines = [lines.to_i, 1].max
|
80
|
-
@stream
|
77
|
+
@stream << ("\n" * lines)
|
81
78
|
@lines_written += lines
|
82
79
|
@stream.flush
|
83
80
|
self
|
@@ -154,7 +151,7 @@ module NattyUI
|
|
154
151
|
def initialize(stream)
|
155
152
|
@stream = stream
|
156
153
|
@lines_written = 0
|
157
|
-
@ws = stream.respond_to?(:winsize) && stream.winsize&.
|
154
|
+
@ws = stream.respond_to?(:winsize) && stream.winsize&.all?(&:positive?)
|
158
155
|
rescue Errno::ENOTTY
|
159
156
|
@ws = false
|
160
157
|
end
|
data/lib/natty-ui.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'readline'
|
4
|
+
unless defined?(Reline)
|
5
|
+
# only load the Reline::Unicode part
|
6
|
+
# @!visibility private
|
7
|
+
module Reline
|
8
|
+
def self.ambiguous_width = 1
|
9
|
+
end
|
10
|
+
require 'reline/unicode'
|
11
|
+
end
|
4
12
|
require_relative 'natty-ui/wrapper'
|
5
13
|
require_relative 'natty-ui/ansi_wrapper'
|
6
14
|
|
@@ -71,7 +79,7 @@ module NattyUI
|
|
71
79
|
# @return ]String] edited string
|
72
80
|
def embellish(str)
|
73
81
|
str = str.to_s
|
74
|
-
return '' if str.empty?
|
82
|
+
return +'' if str.empty?
|
75
83
|
reset = false
|
76
84
|
ret =
|
77
85
|
str.gsub(/(\[\[((?~\]\]))\]\])/) do
|
@@ -111,10 +119,56 @@ module NattyUI
|
|
111
119
|
# @return [Integer] the display size
|
112
120
|
def display_width(str)
|
113
121
|
str = str.to_s
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
122
|
+
str.empty? ? 0 : Reline::Unicode.calculate_width(str)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Convert given arguments into strings and yield each line.
|
126
|
+
# Optionally limit the line width to given `max_width`.
|
127
|
+
#
|
128
|
+
# @overload each_line(..., max_width: nil)
|
129
|
+
# @param [#to_s] ... objects to print
|
130
|
+
# @param [#to_i, nil] max_width maximum line width
|
131
|
+
# @yieldparam [String] line string line
|
132
|
+
# @return [nil]
|
133
|
+
# @overload each_line(..., max_width: nil)
|
134
|
+
# @param [#to_s] ... objects to print
|
135
|
+
# @param [#to_i, nil] max_width maximum line width
|
136
|
+
# @return [Enumerator] line enumerator
|
137
|
+
def each_line(*strs, max_width: nil, &block)
|
138
|
+
return to_enum(__method__, *strs, max_width: max_width) unless block
|
139
|
+
unless max_width
|
140
|
+
strs.each { |str| str.to_s.each_line(chomp: true, &block) }
|
141
|
+
return nil
|
142
|
+
end
|
143
|
+
max_width = max_width.to_i
|
144
|
+
return if max_width <= 0
|
145
|
+
strs.each do |str|
|
146
|
+
str
|
147
|
+
.to_s
|
148
|
+
.each_line(chomp: true) do |line|
|
149
|
+
Reline::Unicode.split_by_width(line, max_width)[0].each do |part|
|
150
|
+
yield(part) if part
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
|
157
|
+
# Read user input line from {.in_stream}.
|
158
|
+
#
|
159
|
+
# @see .valid_out?
|
160
|
+
#
|
161
|
+
# @param [#to_s] prompt input prompt
|
162
|
+
# @param [IO] stream writeable IO used to display output
|
163
|
+
# @return [String] user input line
|
164
|
+
# @return [nil] when user interrputed input with `^C` or `^D`
|
165
|
+
def readline(prompt = nil, stream: StdOut.stream)
|
166
|
+
Readline.output = stream
|
167
|
+
Readline.input = @in_stream
|
168
|
+
Readline.readline(prompt.to_s)
|
169
|
+
rescue Interrupt
|
170
|
+
stream.puts
|
171
|
+
nil
|
118
172
|
end
|
119
173
|
|
120
174
|
private
|
@@ -125,17 +179,6 @@ module NattyUI
|
|
125
179
|
stream.tty? ? AnsiWrapper : Wrapper
|
126
180
|
end
|
127
181
|
|
128
|
-
def emoji_extra_width_of(string)
|
129
|
-
ret = 0
|
130
|
-
string.scan(Unicode::Emoji::REGEX) do |emoji|
|
131
|
-
ret += 2 * emoji.scan(EMOJI_MODIFIER_REGEX).size
|
132
|
-
emoji.scan(EMOKI_ZWJ_REGEX) do |zwj_succ|
|
133
|
-
ret += Unicode::DisplayWidth.of(zwj_succ, 1, {})
|
134
|
-
end
|
135
|
-
end
|
136
|
-
ret
|
137
|
-
end
|
138
|
-
|
139
182
|
def stderr_is_stdout?
|
140
183
|
STDOUT.tty? && STDERR.tty? && STDOUT.pos == STDERR.pos
|
141
184
|
rescue IOError, SystemCallError
|
@@ -143,12 +186,6 @@ module NattyUI
|
|
143
186
|
end
|
144
187
|
end
|
145
188
|
|
146
|
-
if defined?(Unicode::Emoji)
|
147
|
-
EMOJI_MODIFIER_REGEX = /[#{Unicode::Emoji::EMOJI_MODIFIERS.pack('U*')}]/
|
148
|
-
EMOKI_ZWJ_REGEX = /(?<=#{[Unicode::Emoji::ZWJ].pack('U')})./
|
149
|
-
private_constant :EMOJI_MODIFIER_REGEX, :EMOKI_ZWJ_REGEX
|
150
|
-
end
|
151
|
-
|
152
189
|
# Instance for standard output.
|
153
190
|
StdOut = new(STDOUT)
|
154
191
|
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: natty-ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: unicode-display_width
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2.5'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2.5'
|
11
|
+
date: 2023-11-11 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
27
13
|
description: |
|
28
14
|
This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely,
|
29
15
|
natty user interface you like to have for your command line interfaces
|