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.
- checksums.yaml +4 -4
- data/README.md +565 -237
- metadata +4 -13
- data/examples/basic_panes.rb +0 -43
- data/examples/focus_panes.rb +0 -42
- data/lib/rcurses/cursor.rb +0 -48
- data/lib/rcurses/general.rb +0 -6
- data/lib/rcurses/input.rb +0 -127
- data/lib/rcurses/pane.rb +0 -662
- data/lib/rcurses.rb +0 -61
- data/lib/string_extensions.rb +0 -160
data/lib/string_extensions.rb
DELETED
@@ -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
|
-
|