natty-ui 0.7.0 → 0.8.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.
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.reset
95
+ Ansi::RESET
94
96
  end
95
- reset ? "#{ret}#{Ansi.reset}" : ret
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
- # @return ]String] edited string
102
- def plain(str)
103
- str
104
- .to_s
105
- .gsub(/(\[\[((?~\]\]))\]\])/) do
106
- match = Regexp.last_match[2]
107
- next match.empty? ? nil : "[[#{match}]]" if match.delete_prefix!('/')
108
- Ansi.try_convert(match) ? nil : "[[#{match}]]"
109
- end
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? ? 0 : Reline::Unicode.calculate_width(str)
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 { |str| str.to_s.each_line(chomp: true, &block) }
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
@@ -149,37 +157,28 @@ module NattyUI
149
157
  nil
150
158
  end
151
159
 
152
- # Read user input line from {.in_stream}.
160
+ # Read next raw key (keyboard input) from {in_stream}.
153
161
  #
154
- # This method uses Ruby's Readline implementation (default gem). See there
155
- # for more information.
156
- #
157
- # @see .valid_out?
158
- #
159
- # @param [#to_s] prompt input prompt
160
- # @param [false, nil, #call] completion disable autocompletion, use default
161
- # autocompletion or use given completion proc
162
- # @param [IO] stream writeable IO used to display output
163
- # @return [String] user input line
164
- # @return [nil] when user interrupted input with `^C` or `^D`
165
- def readline(prompt = nil, completion: false, stream: StdOut.stream)
166
- cp = Readline.completion_proc
167
- Readline.completion_proc = completion == false ? ->(*_) {} : completion
168
- Readline.output = stream
169
- Readline.input = @in_stream
170
- Readline.readline(prompt.to_s)
171
- rescue Interrupt
172
- stream.puts
173
- nil
174
- ensure
175
- Readline.completion_proc = cp
162
+ # @return [String] read key
163
+ def read_key
164
+ return @in_stream.getch unless defined?(@in_stream.getc)
165
+ return @in_stream.getc unless defined?(@in_stream.raw)
166
+ @in_stream.raw do |raw|
167
+ key = raw.getc
168
+ while (nc = raw.read_nonblock(1, exception: false))
169
+ nc.is_a?(String) ? key += nc : break
170
+ end
171
+ key
172
+ end
176
173
  end
177
174
 
178
175
  private
179
176
 
180
177
  def wrapper_class(stream, ansi)
181
178
  return AnsiWrapper if ansi == true
182
- return Wrapper if ansi == false || ENV.key?('NO_COLOR')
179
+ if ansi == false || ENV.key?('NO_COLOR') || ENV['TERM'] == 'dumb'
180
+ return Wrapper
181
+ end
183
182
  stream.tty? ? AnsiWrapper : Wrapper
184
183
  end
185
184
 
@@ -196,5 +195,10 @@ module NattyUI
196
195
  # Instance for standard error output.
197
196
  StdErr = stderr_is_stdout? ? StdOut : new(STDERR)
198
197
 
198
+ @element = StdOut
199
199
  self.in_stream = STDIN
200
200
  end
201
+
202
+ # @see NattyUI.element
203
+ # @return [NattyUI::Wrapper, NattyUI::Wrapper::Element] active UI element
204
+ def ui = NattyUI.element unless defined?(ui)
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.7.0
4
+ version: 0.8.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: 2023-11-29 00:00:00.000000000 Z
11
+ date: 2024-06-18 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 interfaces
16
- (CLI).
17
- Here you find elegant, simple and beautiful tools that enhance your
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,12 +25,17 @@ 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
29
31
  - examples/attributes.rb
30
- - examples/basic.rb
32
+ - examples/demo.rb
31
33
  - examples/illustration.png
34
+ - examples/illustration.rb
32
35
  - examples/list_in_columns.rb
33
36
  - examples/progress.rb
34
37
  - examples/query.rb
38
+ - examples/table.rb
35
39
  - lib/natty-ui.rb
36
40
  - lib/natty-ui/ansi.rb
37
41
  - lib/natty-ui/ansi_wrapper.rb
@@ -42,13 +46,16 @@ files:
42
46
  - lib/natty-ui/wrapper/element.rb
43
47
  - lib/natty-ui/wrapper/framed.rb
44
48
  - lib/natty-ui/wrapper/heading.rb
49
+ - lib/natty-ui/wrapper/horizontal_rule.rb
45
50
  - lib/natty-ui/wrapper/list_in_columns.rb
46
51
  - lib/natty-ui/wrapper/message.rb
47
52
  - lib/natty-ui/wrapper/mixins.rb
48
53
  - lib/natty-ui/wrapper/progress.rb
49
54
  - lib/natty-ui/wrapper/query.rb
55
+ - lib/natty-ui/wrapper/quote.rb
50
56
  - lib/natty-ui/wrapper/request.rb
51
57
  - lib/natty-ui/wrapper/section.rb
58
+ - lib/natty-ui/wrapper/table.rb
52
59
  - lib/natty-ui/wrapper/task.rb
53
60
  - lib/natty_ui.rb
54
61
  homepage: https://github.com/mblumtritt/natty-ui
@@ -74,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
81
  - !ruby/object:Gem::Version
75
82
  version: '0'
76
83
  requirements: []
77
- rubygems_version: 3.4.22
84
+ rubygems_version: 3.5.13
78
85
  signing_key:
79
86
  specification_version: 4
80
87
  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