rcurses 4.8.3 → 4.9.1

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.
@@ -1,160 +0,0 @@
1
- # string_extensions.rb
2
-
3
- class String
4
- # 256-color or truecolor RGB foregroundbreset only the fg (SGR 39)
5
- def fg(color)
6
- sp, ep = if color.to_s =~ /\A[0-9A-Fa-f]{6}\z/
7
- r, g, b = color.scan(/../).map { |c| c.to_i(16) }
8
- ["\e[38;2;#{r};#{g};#{b}m", "\e[39m"]
9
- else
10
- ["\e[38;5;#{color}m", "\e[39m"]
11
- end
12
- color(self, sp, ep)
13
- end
14
-
15
- # 256-color or truecolor RGB backgroundbreset only the bg (SGR 49)
16
- def bg(color)
17
- sp, ep = if color.to_s =~ /\A[0-9A-Fa-f]{6}\z/
18
- r, g, b = color.scan(/../).map { |c| c.to_i(16) }
19
- ["\e[48;2;#{r};#{g};#{b}m", "\e[49m"]
20
- else
21
- ["\e[48;5;#{color}m", "\e[49m"]
22
- end
23
- color(self, sp, ep)
24
- end
25
-
26
- # Both fg and bg in one go
27
- def fb(fg_color, bg_color)
28
- parts = []
29
- if fg_color.to_s =~ /\A[0-9A-Fa-f]{6}\z/
30
- r, g, b = fg_color.scan(/../).map { |c| c.to_i(16) }
31
- parts << "38;2;#{r};#{g};#{b}"
32
- else
33
- parts << "38;5;#{fg_color}"
34
- end
35
-
36
- if bg_color.to_s =~ /\A[0-9A-Fa-f]{6}\z/
37
- r, g, b = bg_color.scan(/../).map { |c| c.to_i(16) }
38
- parts << "48;2;#{r};#{g};#{b}"
39
- else
40
- parts << "48;5;#{bg_color}"
41
- end
42
-
43
- sp = "\e[#{parts.join(';')}m"
44
- color(self, sp, "\e[39;49m")
45
- end
46
-
47
- # bold, italic, underline, blink, reverse
48
- def b; color(self, "\e[1m", "\e[22m"); end
49
- def i; color(self, "\e[3m", "\e[23m"); end
50
- def u; color(self, "\e[4m", "\e[24m"); end
51
- def l; color(self, "\e[5m", "\e[25m"); end
52
- def r; color(self, "\e[7m", "\e[27m"); end
53
-
54
- # Internal helper - wraps +text+ in start/end sequences,
55
- # and re-applies start on every newline.
56
- def color(text, sp, ep = "\e[0m")
57
- t = text.gsub("\n", "#{ep}\n#{sp}")
58
- "#{sp}#{t}#{ep}"
59
- end
60
-
61
- # Combined code: "foo".c("FF0000,00FF00,bui")
62
- # — 6-hex or decimal for fg, then for bg, then letters b/i/u/l/r
63
- def c(code)
64
- parts = code.split(',')
65
- seq = []
66
-
67
- fg = parts.shift
68
- if fg =~ /\A[0-9A-Fa-f]{6}\z/
69
- r,g,b = fg.scan(/../).map{|c|c.to_i(16)}
70
- seq << "38;2;#{r};#{g};#{b}"
71
- elsif fg =~ /\A\d+\z/
72
- seq << "38;5;#{fg}"
73
- end
74
-
75
- if parts.any?
76
- bg = parts.shift
77
- if bg =~ /\A[0-9A-Fa-f]{6}\z/
78
- r,g,b = bg.scan(/../).map{|c|c.to_i(16)}
79
- seq << "48;2;#{r};#{g};#{b}"
80
- elsif bg =~ /\A\d+\z/
81
- seq << "48;5;#{bg}"
82
- end
83
- end
84
-
85
- seq << '1' if code.include?('b')
86
- seq << '3' if code.include?('i')
87
- seq << '4' if code.include?('u')
88
- seq << '5' if code.include?('l')
89
- seq << '7' if code.include?('r')
90
-
91
- "\e[#{seq.join(';')}m#{self}\e[0m"
92
- end
93
-
94
- # Strip all ANSI SGR sequences
95
- def pure
96
- gsub(/\e\[\d+(?:;\d+)*m/, '')
97
- end
98
-
99
- # Remove stray leading/trailing reset if the string has no other styling
100
- def clean_ansi
101
- gsub(/\A(?:\e\[0m)+/, '').gsub(/\e\[0m\z/, '')
102
- end
103
-
104
- # Truncate the *visible* length to n, but preserve embedded ANSI
105
- def shorten(n)
106
- count = 0
107
- out = ''
108
- i = 0
109
-
110
- while i < length && count < n
111
- if self[i] == "\e" && (m = self[i..-1].match(/\A(\e\[\d+(?:;\d+)*m)/))
112
- out << m[1]
113
- i += m[1].length
114
- else
115
- out << self[i]
116
- i += 1
117
- count += 1
118
- end
119
- end
120
-
121
- out
122
- end
123
-
124
- # Insert +insertion+ at visible position +pos+ (negative → end),
125
- # respecting and re-inserting existing ANSI sequences.
126
- def inject(insertion, pos)
127
- pure_txt = pure
128
- visible_len = pure_txt.length
129
- pos = visible_len if pos < 0
130
-
131
- count, out, i, injected = 0, '', 0, false
132
-
133
- while i < length
134
- if self[i] == "\e" && (m = self[i..-1].match(/\A(\e\[\d+(?:;\d+)*m)/))
135
- out << m[1]
136
- i += m[1].length
137
- else
138
- if count == pos && !injected
139
- out << insertion
140
- injected = true
141
- end
142
- out << self[i]
143
- count += 1
144
- i += 1
145
- end
146
- end
147
-
148
- unless injected
149
- if out =~ /(\e\[\d+(?:;\d+)*m)\z/
150
- trailing = $1
151
- out = out[0...-trailing.length] + insertion + trailing
152
- else
153
- out << insertion
154
- end
155
- end
156
-
157
- out
158
- end
159
- end
160
-