rich-ruby 1.0.1 → 1.0.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 +4 -4
- data/CHANGELOG.md +80 -0
- data/LICENSE +21 -21
- data/README.md +547 -547
- data/docs/architecture.md +43 -0
- data/docs/cheat-sheet.md +52 -0
- data/docs/customization.md +53 -0
- data/docs/how-to-use.md +96 -0
- data/docs/test-report.md +112 -0
- data/docs/troubleshooting.md +36 -0
- data/docs/windows-notes.md +30 -0
- data/examples/demo.rb +106 -106
- data/examples/showcase.rb +420 -420
- data/examples/smoke_test.rb +41 -41
- data/examples/stress_test.rb +604 -604
- data/examples/syntax_markdown_demo.rb +166 -166
- data/examples/verify.rb +216 -215
- data/examples/visual_demo.rb +145 -145
- data/lib/rich/_palettes.rb +148 -148
- data/lib/rich/box.rb +342 -342
- data/lib/rich/cells.rb +524 -512
- data/lib/rich/color.rb +631 -628
- data/lib/rich/color_triplet.rb +227 -220
- data/lib/rich/console.rb +604 -549
- data/lib/rich/control.rb +332 -332
- data/lib/rich/json.rb +260 -254
- data/lib/rich/layout.rb +314 -314
- data/lib/rich/markdown.rb +531 -509
- data/lib/rich/markup.rb +186 -175
- data/lib/rich/panel.rb +318 -311
- data/lib/rich/progress.rb +430 -430
- data/lib/rich/segment.rb +387 -387
- data/lib/rich/style.rb +464 -433
- data/lib/rich/syntax.rb +1220 -1145
- data/lib/rich/table.rb +547 -525
- data/lib/rich/terminal_theme.rb +126 -126
- data/lib/rich/text.rb +460 -433
- data/lib/rich/tree.rb +220 -220
- data/lib/rich/version.rb +5 -5
- data/lib/rich/win32_console.rb +620 -582
- data/lib/rich.rb +108 -108
- metadata +15 -5
data/lib/rich/control.rb
CHANGED
|
@@ -1,332 +1,332 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Rich
|
|
4
|
-
# Terminal control codes and escape sequences.
|
|
5
|
-
# Provides constants and methods for cursor movement, screen clearing,
|
|
6
|
-
# and other terminal control operations.
|
|
7
|
-
module Control
|
|
8
|
-
# Control code types for segment rendering
|
|
9
|
-
module ControlType
|
|
10
|
-
BELL = :bell
|
|
11
|
-
CARRIAGE_RETURN = :carriage_return
|
|
12
|
-
HOME = :home
|
|
13
|
-
CLEAR = :clear
|
|
14
|
-
SHOW_CURSOR = :show_cursor
|
|
15
|
-
HIDE_CURSOR = :hide_cursor
|
|
16
|
-
ENABLE_ALT_SCREEN = :enable_alt_screen
|
|
17
|
-
DISABLE_ALT_SCREEN = :disable_alt_screen
|
|
18
|
-
CURSOR_UP = :cursor_up
|
|
19
|
-
CURSOR_DOWN = :cursor_down
|
|
20
|
-
CURSOR_FORWARD = :cursor_forward
|
|
21
|
-
CURSOR_BACKWARD = :cursor_backward
|
|
22
|
-
CURSOR_MOVE_TO_COLUMN = :cursor_move_to_column
|
|
23
|
-
CURSOR_MOVE_TO = :cursor_move_to
|
|
24
|
-
ERASE_IN_LINE = :erase_in_line
|
|
25
|
-
SET_WINDOW_TITLE = :set_window_title
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# ESC character for ANSI sequences
|
|
29
|
-
ESC = "\e"
|
|
30
|
-
|
|
31
|
-
# Control Sequence Introducer
|
|
32
|
-
CSI = "\e["
|
|
33
|
-
|
|
34
|
-
# Operating System Command
|
|
35
|
-
OSC = "\e]"
|
|
36
|
-
|
|
37
|
-
# String Terminator
|
|
38
|
-
ST = "\e\\"
|
|
39
|
-
|
|
40
|
-
# Bell character
|
|
41
|
-
BEL = "\a"
|
|
42
|
-
|
|
43
|
-
class << self
|
|
44
|
-
# Generate bell/alert
|
|
45
|
-
# @return [String]
|
|
46
|
-
def bell
|
|
47
|
-
BEL
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Carriage return (move to column 0)
|
|
51
|
-
# @return [String]
|
|
52
|
-
def carriage_return
|
|
53
|
-
"\r"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Move cursor to home position (1,1)
|
|
57
|
-
# @return [String]
|
|
58
|
-
def home
|
|
59
|
-
"#{CSI}H"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Clear the screen
|
|
63
|
-
# @param mode [Integer] 0=cursor to end, 1=start to cursor, 2=entire screen
|
|
64
|
-
# @return [String]
|
|
65
|
-
def clear(mode = 2)
|
|
66
|
-
"#{CSI}#{mode}J"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Clear entire screen and move to home
|
|
70
|
-
# @return [String]
|
|
71
|
-
def clear_screen
|
|
72
|
-
"#{CSI}2J#{CSI}H"
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Show the cursor
|
|
76
|
-
# @return [String]
|
|
77
|
-
def show_cursor
|
|
78
|
-
"#{CSI}?25h"
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Hide the cursor
|
|
82
|
-
# @return [String]
|
|
83
|
-
def hide_cursor
|
|
84
|
-
"#{CSI}?25l"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Enable alternative screen buffer
|
|
88
|
-
# @return [String]
|
|
89
|
-
def enable_alt_screen
|
|
90
|
-
"#{CSI}?1049h"
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Disable alternative screen buffer
|
|
94
|
-
# @return [String]
|
|
95
|
-
def disable_alt_screen
|
|
96
|
-
"#{CSI}?1049l"
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Move cursor up
|
|
100
|
-
# @param count [Integer] Number of rows
|
|
101
|
-
# @return [String]
|
|
102
|
-
def cursor_up(count = 1)
|
|
103
|
-
return "" if count < 1
|
|
104
|
-
|
|
105
|
-
"#{CSI}#{count}A"
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Move cursor down
|
|
109
|
-
# @param count [Integer] Number of rows
|
|
110
|
-
# @return [String]
|
|
111
|
-
def cursor_down(count = 1)
|
|
112
|
-
return "" if count < 1
|
|
113
|
-
|
|
114
|
-
"#{CSI}#{count}B"
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Move cursor forward (right)
|
|
118
|
-
# @param count [Integer] Number of columns
|
|
119
|
-
# @return [String]
|
|
120
|
-
def cursor_forward(count = 1)
|
|
121
|
-
return "" if count < 1
|
|
122
|
-
|
|
123
|
-
"#{CSI}#{count}C"
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Move cursor backward (left)
|
|
127
|
-
# @param count [Integer] Number of columns
|
|
128
|
-
# @return [String]
|
|
129
|
-
def cursor_backward(count = 1)
|
|
130
|
-
return "" if count < 1
|
|
131
|
-
|
|
132
|
-
"#{CSI}#{count}D"
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Move cursor to next line
|
|
136
|
-
# @param count [Integer] Number of lines
|
|
137
|
-
# @return [String]
|
|
138
|
-
def cursor_next_line(count = 1)
|
|
139
|
-
return "" if count < 1
|
|
140
|
-
|
|
141
|
-
"#{CSI}#{count}E"
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
# Move cursor to previous line
|
|
145
|
-
# @param count [Integer] Number of lines
|
|
146
|
-
# @return [String]
|
|
147
|
-
def cursor_prev_line(count = 1)
|
|
148
|
-
return "" if count < 1
|
|
149
|
-
|
|
150
|
-
"#{CSI}#{count}F"
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# Move cursor to column (1-based)
|
|
154
|
-
# @param column [Integer] Column number (1-based)
|
|
155
|
-
# @return [String]
|
|
156
|
-
def cursor_move_to_column(column)
|
|
157
|
-
"#{CSI}#{column}G"
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
# Move cursor to position (1-based coordinates)
|
|
161
|
-
# @param row [Integer] Row (1-based)
|
|
162
|
-
# @param column [Integer] Column (1-based)
|
|
163
|
-
# @return [String]
|
|
164
|
-
def cursor_move_to(row, column)
|
|
165
|
-
"#{CSI}#{row};#{column}H"
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Save cursor position
|
|
169
|
-
# @return [String]
|
|
170
|
-
def save_cursor
|
|
171
|
-
"#{CSI}s"
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# Restore cursor position
|
|
175
|
-
# @return [String]
|
|
176
|
-
def restore_cursor
|
|
177
|
-
"#{CSI}u"
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
# Erase in line
|
|
181
|
-
# @param mode [Integer] 0=cursor to end, 1=start to cursor, 2=entire line
|
|
182
|
-
# @return [String]
|
|
183
|
-
def erase_line(mode = 2)
|
|
184
|
-
"#{CSI}#{mode}K"
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
# Erase from cursor to end of line
|
|
188
|
-
# @return [String]
|
|
189
|
-
def erase_end_of_line
|
|
190
|
-
"#{CSI}0K"
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Erase from start of line to cursor
|
|
194
|
-
# @return [String]
|
|
195
|
-
def erase_start_of_line
|
|
196
|
-
"#{CSI}1K"
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
# Set window title
|
|
200
|
-
# @param title [String] Window title
|
|
201
|
-
# @return [String]
|
|
202
|
-
def set_title(title)
|
|
203
|
-
"#{OSC}2;#{title}#{ST}"
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
# Set icon name (some terminals)
|
|
207
|
-
# @param name [String] Icon name
|
|
208
|
-
# @return [String]
|
|
209
|
-
def set_icon_name(name)
|
|
210
|
-
"#{OSC}1;#{name}#{ST}"
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# Set both icon name and window title
|
|
214
|
-
# @param title [String] Title/name
|
|
215
|
-
# @return [String]
|
|
216
|
-
def set_icon_and_title(title)
|
|
217
|
-
"#{OSC}0;#{title}#{ST}"
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
# Request cursor position (terminal will respond)
|
|
221
|
-
# @return [String]
|
|
222
|
-
def request_cursor_position
|
|
223
|
-
"#{CSI}6n"
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
# Scroll up
|
|
227
|
-
# @param count [Integer] Number of lines
|
|
228
|
-
# @return [String]
|
|
229
|
-
def scroll_up(count = 1)
|
|
230
|
-
"#{CSI}#{count}S"
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
# Scroll down
|
|
234
|
-
# @param count [Integer] Number of lines
|
|
235
|
-
# @return [String]
|
|
236
|
-
def scroll_down(count = 1)
|
|
237
|
-
"#{CSI}#{count}T"
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# Reset all attributes
|
|
241
|
-
# @return [String]
|
|
242
|
-
def reset
|
|
243
|
-
"#{CSI}0m"
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
# Create a hyperlink
|
|
247
|
-
# @param url [String] URL
|
|
248
|
-
# @param text [String] Link text
|
|
249
|
-
# @param id [String, nil] Optional link ID
|
|
250
|
-
# @return [String]
|
|
251
|
-
def hyperlink(url, text, id: nil)
|
|
252
|
-
params = id ? "id=#{id}" : ""
|
|
253
|
-
"#{OSC}8;#{params};#{url}#{ST}#{text}#{OSC}8;;#{ST}"
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
# Start hyperlink
|
|
257
|
-
# @param url [String] URL
|
|
258
|
-
# @param id [String, nil] Optional link ID
|
|
259
|
-
# @return [String]
|
|
260
|
-
def hyperlink_start(url, id: nil)
|
|
261
|
-
params = id ? "id=#{id}" : ""
|
|
262
|
-
"#{OSC}8;#{params};#{url}#{ST}"
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
# End hyperlink
|
|
266
|
-
# @return [String]
|
|
267
|
-
def hyperlink_end
|
|
268
|
-
"#{OSC}8;;#{ST}"
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
# Strip ANSI escape sequences from text
|
|
272
|
-
# @param text [String] Text to strip
|
|
273
|
-
# @return [String] Text without ANSI sequences
|
|
274
|
-
def strip_ansi(text)
|
|
275
|
-
text.gsub(/\e\[[0-9;]*[A-Za-z]/, "")
|
|
276
|
-
.gsub(/\e\][^\a\e]*(?:\a|\e\\)/, "")
|
|
277
|
-
.gsub(/\e[()][\dAB]/, "")
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
# Check if text contains ANSI escape sequences
|
|
281
|
-
# @param text [String] Text to check
|
|
282
|
-
# @return [Boolean]
|
|
283
|
-
def contains_ansi?(text)
|
|
284
|
-
text.match?(/\e[\[\]()][^\a\e]*/)
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
# Generate control code for a control type
|
|
288
|
-
# @param control_type [Symbol] Control type
|
|
289
|
-
# @param param1 [Object] First parameter
|
|
290
|
-
# @param param2 [Object] Second parameter
|
|
291
|
-
# @return [String]
|
|
292
|
-
def generate(control_type, param1 = nil, param2 = nil)
|
|
293
|
-
case control_type
|
|
294
|
-
when ControlType::BELL
|
|
295
|
-
bell
|
|
296
|
-
when ControlType::CARRIAGE_RETURN
|
|
297
|
-
carriage_return
|
|
298
|
-
when ControlType::HOME
|
|
299
|
-
home
|
|
300
|
-
when ControlType::CLEAR
|
|
301
|
-
clear
|
|
302
|
-
when ControlType::SHOW_CURSOR
|
|
303
|
-
show_cursor
|
|
304
|
-
when ControlType::HIDE_CURSOR
|
|
305
|
-
hide_cursor
|
|
306
|
-
when ControlType::ENABLE_ALT_SCREEN
|
|
307
|
-
enable_alt_screen
|
|
308
|
-
when ControlType::DISABLE_ALT_SCREEN
|
|
309
|
-
disable_alt_screen
|
|
310
|
-
when ControlType::CURSOR_UP
|
|
311
|
-
cursor_up(param1 || 1)
|
|
312
|
-
when ControlType::CURSOR_DOWN
|
|
313
|
-
cursor_down(param1 || 1)
|
|
314
|
-
when ControlType::CURSOR_FORWARD
|
|
315
|
-
cursor_forward(param1 || 1)
|
|
316
|
-
when ControlType::CURSOR_BACKWARD
|
|
317
|
-
cursor_backward(param1 || 1)
|
|
318
|
-
when ControlType::CURSOR_MOVE_TO_COLUMN
|
|
319
|
-
cursor_move_to_column(param1 || 1)
|
|
320
|
-
when ControlType::CURSOR_MOVE_TO
|
|
321
|
-
cursor_move_to(param1 || 1, param2 || 1)
|
|
322
|
-
when ControlType::ERASE_IN_LINE
|
|
323
|
-
erase_line(param1 || 2)
|
|
324
|
-
when ControlType::SET_WINDOW_TITLE
|
|
325
|
-
set_title(param1.to_s)
|
|
326
|
-
else
|
|
327
|
-
""
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rich
|
|
4
|
+
# Terminal control codes and escape sequences.
|
|
5
|
+
# Provides constants and methods for cursor movement, screen clearing,
|
|
6
|
+
# and other terminal control operations.
|
|
7
|
+
module Control
|
|
8
|
+
# Control code types for segment rendering
|
|
9
|
+
module ControlType
|
|
10
|
+
BELL = :bell
|
|
11
|
+
CARRIAGE_RETURN = :carriage_return
|
|
12
|
+
HOME = :home
|
|
13
|
+
CLEAR = :clear
|
|
14
|
+
SHOW_CURSOR = :show_cursor
|
|
15
|
+
HIDE_CURSOR = :hide_cursor
|
|
16
|
+
ENABLE_ALT_SCREEN = :enable_alt_screen
|
|
17
|
+
DISABLE_ALT_SCREEN = :disable_alt_screen
|
|
18
|
+
CURSOR_UP = :cursor_up
|
|
19
|
+
CURSOR_DOWN = :cursor_down
|
|
20
|
+
CURSOR_FORWARD = :cursor_forward
|
|
21
|
+
CURSOR_BACKWARD = :cursor_backward
|
|
22
|
+
CURSOR_MOVE_TO_COLUMN = :cursor_move_to_column
|
|
23
|
+
CURSOR_MOVE_TO = :cursor_move_to
|
|
24
|
+
ERASE_IN_LINE = :erase_in_line
|
|
25
|
+
SET_WINDOW_TITLE = :set_window_title
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# ESC character for ANSI sequences
|
|
29
|
+
ESC = "\e"
|
|
30
|
+
|
|
31
|
+
# Control Sequence Introducer
|
|
32
|
+
CSI = "\e["
|
|
33
|
+
|
|
34
|
+
# Operating System Command
|
|
35
|
+
OSC = "\e]"
|
|
36
|
+
|
|
37
|
+
# String Terminator
|
|
38
|
+
ST = "\e\\"
|
|
39
|
+
|
|
40
|
+
# Bell character
|
|
41
|
+
BEL = "\a"
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
# Generate bell/alert
|
|
45
|
+
# @return [String]
|
|
46
|
+
def bell
|
|
47
|
+
BEL
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Carriage return (move to column 0)
|
|
51
|
+
# @return [String]
|
|
52
|
+
def carriage_return
|
|
53
|
+
"\r"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Move cursor to home position (1,1)
|
|
57
|
+
# @return [String]
|
|
58
|
+
def home
|
|
59
|
+
"#{CSI}H"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Clear the screen
|
|
63
|
+
# @param mode [Integer] 0=cursor to end, 1=start to cursor, 2=entire screen
|
|
64
|
+
# @return [String]
|
|
65
|
+
def clear(mode = 2)
|
|
66
|
+
"#{CSI}#{mode}J"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Clear entire screen and move to home
|
|
70
|
+
# @return [String]
|
|
71
|
+
def clear_screen
|
|
72
|
+
"#{CSI}2J#{CSI}H"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Show the cursor
|
|
76
|
+
# @return [String]
|
|
77
|
+
def show_cursor
|
|
78
|
+
"#{CSI}?25h"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Hide the cursor
|
|
82
|
+
# @return [String]
|
|
83
|
+
def hide_cursor
|
|
84
|
+
"#{CSI}?25l"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Enable alternative screen buffer
|
|
88
|
+
# @return [String]
|
|
89
|
+
def enable_alt_screen
|
|
90
|
+
"#{CSI}?1049h"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Disable alternative screen buffer
|
|
94
|
+
# @return [String]
|
|
95
|
+
def disable_alt_screen
|
|
96
|
+
"#{CSI}?1049l"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Move cursor up
|
|
100
|
+
# @param count [Integer] Number of rows
|
|
101
|
+
# @return [String]
|
|
102
|
+
def cursor_up(count = 1)
|
|
103
|
+
return "" if count < 1
|
|
104
|
+
|
|
105
|
+
"#{CSI}#{count}A"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Move cursor down
|
|
109
|
+
# @param count [Integer] Number of rows
|
|
110
|
+
# @return [String]
|
|
111
|
+
def cursor_down(count = 1)
|
|
112
|
+
return "" if count < 1
|
|
113
|
+
|
|
114
|
+
"#{CSI}#{count}B"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Move cursor forward (right)
|
|
118
|
+
# @param count [Integer] Number of columns
|
|
119
|
+
# @return [String]
|
|
120
|
+
def cursor_forward(count = 1)
|
|
121
|
+
return "" if count < 1
|
|
122
|
+
|
|
123
|
+
"#{CSI}#{count}C"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Move cursor backward (left)
|
|
127
|
+
# @param count [Integer] Number of columns
|
|
128
|
+
# @return [String]
|
|
129
|
+
def cursor_backward(count = 1)
|
|
130
|
+
return "" if count < 1
|
|
131
|
+
|
|
132
|
+
"#{CSI}#{count}D"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Move cursor to next line
|
|
136
|
+
# @param count [Integer] Number of lines
|
|
137
|
+
# @return [String]
|
|
138
|
+
def cursor_next_line(count = 1)
|
|
139
|
+
return "" if count < 1
|
|
140
|
+
|
|
141
|
+
"#{CSI}#{count}E"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Move cursor to previous line
|
|
145
|
+
# @param count [Integer] Number of lines
|
|
146
|
+
# @return [String]
|
|
147
|
+
def cursor_prev_line(count = 1)
|
|
148
|
+
return "" if count < 1
|
|
149
|
+
|
|
150
|
+
"#{CSI}#{count}F"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Move cursor to column (1-based)
|
|
154
|
+
# @param column [Integer] Column number (1-based)
|
|
155
|
+
# @return [String]
|
|
156
|
+
def cursor_move_to_column(column)
|
|
157
|
+
"#{CSI}#{column}G"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Move cursor to position (1-based coordinates)
|
|
161
|
+
# @param row [Integer] Row (1-based)
|
|
162
|
+
# @param column [Integer] Column (1-based)
|
|
163
|
+
# @return [String]
|
|
164
|
+
def cursor_move_to(row, column)
|
|
165
|
+
"#{CSI}#{row};#{column}H"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Save cursor position
|
|
169
|
+
# @return [String]
|
|
170
|
+
def save_cursor
|
|
171
|
+
"#{CSI}s"
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Restore cursor position
|
|
175
|
+
# @return [String]
|
|
176
|
+
def restore_cursor
|
|
177
|
+
"#{CSI}u"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Erase in line
|
|
181
|
+
# @param mode [Integer] 0=cursor to end, 1=start to cursor, 2=entire line
|
|
182
|
+
# @return [String]
|
|
183
|
+
def erase_line(mode = 2)
|
|
184
|
+
"#{CSI}#{mode}K"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Erase from cursor to end of line
|
|
188
|
+
# @return [String]
|
|
189
|
+
def erase_end_of_line
|
|
190
|
+
"#{CSI}0K"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Erase from start of line to cursor
|
|
194
|
+
# @return [String]
|
|
195
|
+
def erase_start_of_line
|
|
196
|
+
"#{CSI}1K"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Set window title
|
|
200
|
+
# @param title [String] Window title
|
|
201
|
+
# @return [String]
|
|
202
|
+
def set_title(title)
|
|
203
|
+
"#{OSC}2;#{title}#{ST}"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Set icon name (some terminals)
|
|
207
|
+
# @param name [String] Icon name
|
|
208
|
+
# @return [String]
|
|
209
|
+
def set_icon_name(name)
|
|
210
|
+
"#{OSC}1;#{name}#{ST}"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Set both icon name and window title
|
|
214
|
+
# @param title [String] Title/name
|
|
215
|
+
# @return [String]
|
|
216
|
+
def set_icon_and_title(title)
|
|
217
|
+
"#{OSC}0;#{title}#{ST}"
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Request cursor position (terminal will respond)
|
|
221
|
+
# @return [String]
|
|
222
|
+
def request_cursor_position
|
|
223
|
+
"#{CSI}6n"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Scroll up
|
|
227
|
+
# @param count [Integer] Number of lines
|
|
228
|
+
# @return [String]
|
|
229
|
+
def scroll_up(count = 1)
|
|
230
|
+
"#{CSI}#{count}S"
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Scroll down
|
|
234
|
+
# @param count [Integer] Number of lines
|
|
235
|
+
# @return [String]
|
|
236
|
+
def scroll_down(count = 1)
|
|
237
|
+
"#{CSI}#{count}T"
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Reset all attributes
|
|
241
|
+
# @return [String]
|
|
242
|
+
def reset
|
|
243
|
+
"#{CSI}0m"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Create a hyperlink
|
|
247
|
+
# @param url [String] URL
|
|
248
|
+
# @param text [String] Link text
|
|
249
|
+
# @param id [String, nil] Optional link ID
|
|
250
|
+
# @return [String]
|
|
251
|
+
def hyperlink(url, text, id: nil)
|
|
252
|
+
params = id ? "id=#{id}" : ""
|
|
253
|
+
"#{OSC}8;#{params};#{url}#{ST}#{text}#{OSC}8;;#{ST}"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Start hyperlink
|
|
257
|
+
# @param url [String] URL
|
|
258
|
+
# @param id [String, nil] Optional link ID
|
|
259
|
+
# @return [String]
|
|
260
|
+
def hyperlink_start(url, id: nil)
|
|
261
|
+
params = id ? "id=#{id}" : ""
|
|
262
|
+
"#{OSC}8;#{params};#{url}#{ST}"
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# End hyperlink
|
|
266
|
+
# @return [String]
|
|
267
|
+
def hyperlink_end
|
|
268
|
+
"#{OSC}8;;#{ST}"
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Strip ANSI escape sequences from text
|
|
272
|
+
# @param text [String] Text to strip
|
|
273
|
+
# @return [String] Text without ANSI sequences
|
|
274
|
+
def strip_ansi(text)
|
|
275
|
+
text.gsub(/\e\[[0-9;]*[A-Za-z]/, "")
|
|
276
|
+
.gsub(/\e\][^\a\e]*(?:\a|\e\\)/, "")
|
|
277
|
+
.gsub(/\e[()][\dAB]/, "")
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Check if text contains ANSI escape sequences
|
|
281
|
+
# @param text [String] Text to check
|
|
282
|
+
# @return [Boolean]
|
|
283
|
+
def contains_ansi?(text)
|
|
284
|
+
text.match?(/\e[\[\]()][^\a\e]*/)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Generate control code for a control type
|
|
288
|
+
# @param control_type [Symbol] Control type
|
|
289
|
+
# @param param1 [Object] First parameter
|
|
290
|
+
# @param param2 [Object] Second parameter
|
|
291
|
+
# @return [String]
|
|
292
|
+
def generate(control_type, param1 = nil, param2 = nil)
|
|
293
|
+
case control_type
|
|
294
|
+
when ControlType::BELL
|
|
295
|
+
bell
|
|
296
|
+
when ControlType::CARRIAGE_RETURN
|
|
297
|
+
carriage_return
|
|
298
|
+
when ControlType::HOME
|
|
299
|
+
home
|
|
300
|
+
when ControlType::CLEAR
|
|
301
|
+
clear
|
|
302
|
+
when ControlType::SHOW_CURSOR
|
|
303
|
+
show_cursor
|
|
304
|
+
when ControlType::HIDE_CURSOR
|
|
305
|
+
hide_cursor
|
|
306
|
+
when ControlType::ENABLE_ALT_SCREEN
|
|
307
|
+
enable_alt_screen
|
|
308
|
+
when ControlType::DISABLE_ALT_SCREEN
|
|
309
|
+
disable_alt_screen
|
|
310
|
+
when ControlType::CURSOR_UP
|
|
311
|
+
cursor_up(param1 || 1)
|
|
312
|
+
when ControlType::CURSOR_DOWN
|
|
313
|
+
cursor_down(param1 || 1)
|
|
314
|
+
when ControlType::CURSOR_FORWARD
|
|
315
|
+
cursor_forward(param1 || 1)
|
|
316
|
+
when ControlType::CURSOR_BACKWARD
|
|
317
|
+
cursor_backward(param1 || 1)
|
|
318
|
+
when ControlType::CURSOR_MOVE_TO_COLUMN
|
|
319
|
+
cursor_move_to_column(param1 || 1)
|
|
320
|
+
when ControlType::CURSOR_MOVE_TO
|
|
321
|
+
cursor_move_to(param1 || 1, param2 || 1)
|
|
322
|
+
when ControlType::ERASE_IN_LINE
|
|
323
|
+
erase_line(param1 || 2)
|
|
324
|
+
when ControlType::SET_WINDOW_TITLE
|
|
325
|
+
set_title(param1.to_s)
|
|
326
|
+
else
|
|
327
|
+
""
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|