natty-ui 0.9.0 → 0.9.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05a38cff2c6416d6d7832c3c053d63ebf23977a67abf485e555c35e206fe768b
4
- data.tar.gz: 14363fcea12c6dbb45ce7e7b8dec8d68668f5faa4a8f20793b212e9bb9bd5905
3
+ metadata.gz: 53cd6e051da19fb57efdfe448cfdb6ede5e7bdae3c8d59db5690ea32bb9bcd39
4
+ data.tar.gz: 39a38e0d1c1314e881b72aa7a6d74fdba47225ffadb110a47fd0db305095a564
5
5
  SHA512:
6
- metadata.gz: 5e5031c308e7f63c4f99ba4d6558cf3a3effab04f475f568054c079b6da3908c47df2581259a6c93f661c51e623baafeed61c91e6fe0c025f55bc0adf2b18d17
7
- data.tar.gz: 6275cb88ce6f4822b57debd98a9b8c560198fb3c48028768fd39401320339561b777512d3e0ddbc15a14dd250ef60b592777453f7733156925f525755e4e1678
6
+ metadata.gz: cb080dd1ea872a74f1ad1db42be94020cea77892c1fcab5a4b7850f78c2624d9a5bb9576442b352975644f66de3bc9e2d446e2a73c5dad9390b85b0c187da1ee
7
+ data.tar.gz: c2c5ee5cfbfcc1481ab842470f654176836b962d0ffc6cc3019c5e2e45b3c50cfd0613b9c7c6a82d9800e2b84e3cc26f538a959095101a512d33947be8d8d684
data/lib/natty-ui/ansi.rb CHANGED
@@ -209,9 +209,9 @@ module NattyUI
209
209
  when (0..255)
210
210
  "38;5;#{arg}"
211
211
  when (256..511)
212
- "48;5;#{arg}"
212
+ "48;5;#{arg - 256}"
213
213
  when (512..767)
214
- "58;5;#{arg}"
214
+ "58;5;#{arg - 512}"
215
215
  else
216
216
  invalid_argument(arg)
217
217
  end
@@ -239,7 +239,7 @@ module NattyUI
239
239
  #
240
240
  # @param str [#to_s] string to be modified
241
241
  # @return [String] string without ANSI attributes
242
- def blemish(str) = str.to_s.gsub(/(\e\[(?~[a-zA-Z])[a-zA-Z])/, '')
242
+ def blemish(str) = str.to_s.gsub(ESC, '')
243
243
 
244
244
  # Try to combine given ANSI attributes and colors.
245
245
  # The attributes and colors have to be seperated by space char (" ").
@@ -331,6 +331,13 @@ module NattyUI
331
331
  end
332
332
  end
333
333
 
334
+ CSI = /\e\[[\d;:]*[ABCDEFGHJKSTfminsuhl]/
335
+ OSC = /\e\]\d+(?:;[^;\a\e]+)*(?:\a|\e\\)/
336
+ ESC = /(#{CSI})|(#{OSC})/
337
+
338
+ # @!visibility private
339
+ WIDTH_SCANNER = /\G(?:(\1)|(\2)|(#{CSI})|(#{OSC})|(\X))/
340
+
334
341
  CLR_PREFIX = {
335
342
  'fg' => '38',
336
343
  'bg' => '48',
@@ -338,8 +345,8 @@ module NattyUI
338
345
  'on' => '48'
339
346
  }.freeze
340
347
 
341
- PI2_THIRD = 2 * Math::PI / 3.0
342
- PI4_THIRD = 4 * Math::PI / 3.0
348
+ PI2_THIRD = 2 * Math::PI / 3
349
+ PI4_THIRD = 4 * Math::PI / 3
343
350
 
344
351
  SATTR =
345
352
  Module
@@ -347,6 +354,7 @@ module NattyUI
347
354
  def self.to_hash
348
355
  map = {
349
356
  # alternative names
357
+ reset: '',
350
358
  slow_blink: 5,
351
359
  conceal: 8,
352
360
  default_font: 10,
@@ -368,9 +376,8 @@ module NattyUI
368
376
  }
369
377
  add = ->(s, n) { n.each_with_index { |a, idx| map[a] = s + idx } }
370
378
  add[
371
- 0,
379
+ 1,
372
380
  %i[
373
- reset
374
381
  bold
375
382
  faint
376
383
  italic
@@ -477,8 +484,18 @@ module NattyUI
477
484
  ATTR = SATTR.transform_keys(&:to_s).freeze
478
485
  SCLR = CLR.transform_keys(&:to_sym).compare_by_identity.freeze
479
486
 
480
- private_constant :CLR_PREFIX, :PI2_THIRD, :PI4_THIRD
481
- private_constant :SATTR, :SCLR, :ATTR, :CLR
487
+ private_constant(
488
+ :CSI,
489
+ :OSC,
490
+ :ESC,
491
+ :CLR_PREFIX,
492
+ :PI2_THIRD,
493
+ :PI4_THIRD,
494
+ :SATTR,
495
+ :CLR,
496
+ :ATTR,
497
+ :SCLR
498
+ )
482
499
  end
483
500
  end
484
501
 
@@ -4,42 +4,31 @@ module NattyUI
4
4
  module Ansi
5
5
  CURSOR_SHOW = "\e[?25h"
6
6
  CURSOR_HIDE = "\e[?25l"
7
+
7
8
  CURSOR_HOME = cursor_pos(nil, nil)
8
9
  CURSOR_FIRST_ROW = cursor_pos(1).freeze
9
10
  CURSOR_FIRST_COLUMN = cursor_column(1).freeze
11
+
10
12
  CURSOR_SAFE_POS_SCO = "\e[s"
11
- CURSOR_RESTORE_POS_SCO = "\e[u"
12
13
  CURSOR_SAFE_POS_DEC = "\e7"
13
- CURSOR_RESTORE_POS_DEC = "\e8"
14
14
  CURSOR_SAFE_POS = CURSOR_SAFE_POS_DEC
15
- CURSOR_RESTORE_POS = CURSOR_RESTORE_POS_DEC
16
15
 
17
- CURSOR_ALIGN_RIGHT = "\e[9999G\e[1D\e[1C" # @!visibility private
16
+ CURSOR_RESTORE_POS_SCO = "\e[u"
17
+ CURSOR_RESTORE_POS_DEC = "\e8"
18
+ CURSOR_RESTORE_POS = CURSOR_RESTORE_POS_DEC
18
19
 
19
20
  SCREEN_ERASE = screen_erase(:entire)
21
+
20
22
  SCREEN_SAVE = "\e[?47h"
21
23
  SCREEN_RESTORE = "\e[?47l"
24
+
22
25
  SCREEN_ALTERNATE = "\e[?1049h"
23
26
  SCREEN_ALTERNATE_OFF = "\e[?1049l"
24
- SCREEN_SAVE_ATTRIBUTES = '\e[#{'
25
- SCREEN_RESTORE_ATTRIBUTES = '\e[#}'
26
-
27
- SCREEN_BLANK = "\e[0m\e[s\e[?47h\e[H\e[2J" # @!visibility private
28
- SCREEN_UNBLANK = "\e[?47l\e[u\e[0m" # @!visibility private
29
27
 
30
28
  LINE_PREVIOUS = cursor_previous_line(1).freeze
31
29
  LINE_NEXT = cursor_next_line(1).freeze
32
30
  LINE_ERASE = line_erase(:entire)
33
31
 
34
- # ANSI control code sequence to erase the screen and set cursor position on
35
- # upper left corner.
36
- CLS = (CURSOR_HOME + SCREEN_ERASE).freeze
37
-
38
- # ANSI control code sequence to erase current line and position to first
39
- # column.
40
- CLL = (LINE_ERASE + CURSOR_FIRST_COLUMN).freeze
41
-
42
- # ANSI control code to reset all attributes.
43
32
  RESET = self[:reset].freeze
44
33
 
45
34
  BOLD = self[:bold].freeze
@@ -69,5 +58,20 @@ module NattyUI
69
58
 
70
59
  HIDE = self[:hide].freeze
71
60
  REVEAL = self[:reveal].freeze
61
+
62
+ # @!visibility private
63
+ CLS = (CURSOR_HOME + SCREEN_ERASE).freeze
64
+
65
+ # @!visibility private
66
+ CLL = (CURSOR_FIRST_COLUMN + LINE_ERASE).freeze
67
+
68
+ # @!visibility private
69
+ SCREEN_BLANK =
70
+ (
71
+ CURSOR_SAFE_POS + SCREEN_ALTERNATE + CURSOR_HOME + SCREEN_ERASE + RESET
72
+ ).freeze
73
+
74
+ # @!visibility private
75
+ SCREEN_UNBLANK = (RESET + SCREEN_ALTERNATE_OFF + CURSOR_RESTORE_POS).freeze
72
76
  end
73
77
  end
@@ -80,7 +80,7 @@ module NattyUI
80
80
  lambda do
81
81
  count = @lines_written - count
82
82
  if count.nonzero?
83
- @stream << Ansi.cursor_prev_line(count) << Ansi.display(:erase_below)
83
+ @stream << Ansi.cursor_prev_line(count) << Ansi.screen_erase(:below)
84
84
  @lines_written -= count
85
85
  end
86
86
  @stream.flush
@@ -2,5 +2,5 @@
2
2
 
3
3
  module NattyUI
4
4
  # The version number of the gem.
5
- VERSION = '0.9.0'
5
+ VERSION = '0.9.2'
6
6
  end
data/lib/natty-ui.rb CHANGED
@@ -83,18 +83,19 @@ module NattyUI
83
83
  def embellish(str)
84
84
  return +'' if (str = str.to_s).empty?
85
85
  reset = false
86
- ret =
86
+ str =
87
87
  str.gsub(/(\[\[((?~\]\]))\]\])/) do
88
88
  match = Regexp.last_match[2]
89
- unless match.delete_prefix!('/')
89
+ if match[0] == '/'
90
+ next "[[#{match[1..]}]]" if match.size > 1
91
+ reset = false
92
+ Ansi::RESET
93
+ else
90
94
  ansi = Ansi.try_convert(match)
91
- next ansi ? reset = ansi : "[[#{match}]]"
95
+ ansi ? reset = ansi : "[[#{match}]]"
92
96
  end
93
- match.empty? or next "[[#{match}]]"
94
- reset = false
95
- Ansi::RESET
96
97
  end
97
- reset ? "#{ret}#{Ansi::RESET}" : ret
98
+ reset ? "#{str}#{Ansi::RESET}" : str
98
99
  end
99
100
 
100
101
  # Remove embedded attribute descriptions from given string.
@@ -103,16 +104,13 @@ module NattyUI
103
104
  # @param [:keep,:remove] ansi keep or remove ANSI codes too
104
105
  # @return [String] edited string
105
106
  def plain(str, ansi: :keep)
107
+ return +'' if (str = str.to_s).empty?
106
108
  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
109
+ str.gsub(/(\[\[((?~\]\]))\]\])/) do
110
+ match = Regexp.last_match[2]
111
+ next match.size == 1 ? nil : "[[#{match[1..]}]]" if match[0] == '/'
112
+ Ansi.try_convert(match) ? nil : "[[#{match}]]"
113
+ end
116
114
  ansi == :keep ? str : Ansi.blemish(str)
117
115
  end
118
116
 
@@ -122,8 +120,19 @@ module NattyUI
122
120
  # @param [#to_s] str string to calculate
123
121
  # @return [Integer] the display size
124
122
  def display_width(str)
125
- return 0 if (str = str.to_s).empty?
126
- Reline::Unicode.calculate_width(plain(str), true)
123
+ str = plain(str).encode(Encoding::UTF_8)
124
+ return 0 if str.empty?
125
+ width = 0
126
+ in_zero_width = false
127
+ str.scan(Ansi::WIDTH_SCANNER) do |np_start, np_end, _csi, _osc, gc|
128
+ if in_zero_width
129
+ in_zero_width = false if np_end
130
+ next
131
+ end
132
+ next in_zero_width = true if np_start
133
+ width += Reline::Unicode.get_mbchar_width(gc) if gc
134
+ end
135
+ width
127
136
  end
128
137
 
129
138
  # Convert given arguments into strings and yield each line.
@@ -190,10 +199,10 @@ module NattyUI
190
199
  private
191
200
 
192
201
  def wrapper_class(stream, ansi)
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
202
+ return AnsiWrapper if ansi == true
203
+ return Wrapper if ansi == false || ENV.key?('NO_COLOR')
204
+ return AnsiWrapper if ENV['ANSI'] == '1'
205
+ return Wrapper if ENV['TERM'] == 'dumb'
197
206
  stream.tty? ? AnsiWrapper : Wrapper
198
207
  end
199
208
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: natty-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-07 00:00:00.000000000 Z
11
+ date: 2024-07-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  This is the beautiful, nice, nifty, fancy, neat, pretty, cool, lovely,
@@ -31,7 +31,6 @@ files:
31
31
  - examples/animate.rb
32
32
  - examples/attributes.rb
33
33
  - examples/demo.rb
34
- - examples/illustration.png
35
34
  - examples/illustration.rb
36
35
  - examples/ls.rb
37
36
  - examples/message.rb
Binary file