forked from inhere/php-console
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAnsiCode.php
More file actions
230 lines (187 loc) · 6.3 KB
/
Copy pathAnsiCode.php
File metadata and controls
230 lines (187 loc) · 6.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?php
/**
* Created by PhpStorm.
* User: inhere
* Date: 2017-03-08
* Time: 9:35
*/
namespace Inhere\Console\Utils;
/**
* Class AnsiCode terminal
* @package Inhere\Console\Utils
*
* 2K 清除本行
* \x0D = \r = 13 回车,回到行首
* ESC = \x1B = 27
*/
final class AnsiCode
{
const BEGIN_CHAR = "\033[";
const END_CHAR = "\033[0m";
// Control cursor code name list. more @see [[self::$ctrlCursorCodes]]
const CURSOR_HIDE = 'hide';
const CURSOR_SHOW = 'show';
const CURSOR_SAVE_POSITION = 'savePosition';
const CURSOR_RESTORE_POSITION = 'restorePosition';
const CURSOR_UP = 'up';
const CURSOR_DOWN = 'down';
const CURSOR_FORWARD = 'forward';
const CURSOR_BACKWARD = 'backward';
const CURSOR_NEXT_LINE = 'nextLine';
const CURSOR_PREV_LINE = 'prevLine';
const CURSOR_COORDINATE = 'coordinate';
// Control screen code name list. more @see [[self::$ctrlScreenCodes]]
const CLEAR = 'clear';
const CLEAR_BEFORE_CURSOR = 'clearBeforeCursor';
const CLEAR_LINE = 'clearLine';
const CLEAR_LINE_BEFORE_CURSOR = 'clearLineBeforeCursor';
const CLEAR_LINE_AFTER_CURSOR = 'clearLineAfterCursor';
const SCROLL_UP = 'scrollUp';
const SCROLL_DOWN = 'scrollDown';
/**
* current class's instance
* @var self
*/
private static $instance;
/**
* Control cursor code list
* @var array
*/
private static $ctrlCursorCodes = [
// Hides the cursor. Use [show] to bring it back.
'hide' => '?25l',
// Will show a cursor again when it has been hidden by [hide]
'show' => '?25h',
// Saves the current cursor position, Position can then be restored with [restorePosition].
'savePosition' => 's',
// Restores the cursor position saved with [savePosition]
'restorePosition' => 'u',
// Moves the terminal cursor up
'up' => '%dA',
// Moves the terminal cursor down
'down' => '%B',
// Moves the terminal cursor forward - 移动终端光标前进多远
'forward' => '%dC',
// Moves the terminal cursor backward - 移动终端光标后退多远
'backward' => '%dD',
// Moves the terminal cursor to the beginning of the previous line - 移动终端光标到前一行的开始
'prevLine' => '%dF',
// Moves the terminal cursor to the beginning of the next line - 移动终端光标到下一行的开始
'nextLine' => '%dE',
// Moves the cursor to an absolute position given as column and row
// $column 1-based column number, 1 is the left edge of the screen.
// $row 1-based row number, 1 is the top edge of the screen. if not set, will move cursor only in current line.
'coordinate' => '%dG|%d;%dH' // only column: '%dG', column and row: '%d;%dH'.
];
/**
* Control screen code list
* @var array
*/
private static $ctrlScreenCodes = [
// Clears entire screen content
'clear' => '2J', // "\033[2J"
// Clears text from cursor to the beginning of the screen
'clearBeforeCursor' => '1J',
// Clears the line - 清除此行
'clearLine' => '2K',
// Clears text from cursor position to the beginning of the line - 清除此行从光标位置开始到开始的字符
'clearLineBeforeCursor' => '1K',
// Clears text from cursor position to the end of the line - 清除此行从光标位置开始到结束的字符
'clearLineAfterCursor' => '0K',
// Scrolls whole page up. e.g "\033[2S" scroll up 2 line. - 上移多少行
'scrollUp' => '%dS',
// Scrolls whole page down.e.g "\033[2T" scroll down 2 line. - 下移多少行
'scrollDown' => '%dT',
];
public static function make()
{
if (!self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
/**
* build ansi code string
*
* ```
* AnsiCode::build(null, 'u'); // "\033[s" Saves the current cursor position
* AnsiCode::build(0); // "\033[0m" Build end char, Resets any ANSI format
* ```
*
* @param mixed $format
* @param string $type
* @return string
*/
public static function build($format, $type = 'm')
{
$format = null === $format ? '' : implode(';', (array)$format);
return "\033[" . implode(';', (array)$format) . $type;
}
/**
* control cursor
* @param string $typeName
* @param int $arg1
* @param null $arg2
* @return $this
*/
public function cursor($typeName, $arg1 = 1, $arg2 = null)
{
if (!isset(self::$ctrlCursorCodes[$typeName])) {
Show::error("The [$typeName] is not supported cursor control.", __LINE__);
}
$code = self::$ctrlCursorCodes[$typeName];
// allow argument
if (false !== strpos($code, '%')) {
// The special code: ` 'coordinate' => '%dG|%d;%dH' `
if ($typeName === self::CURSOR_COORDINATE) {
$codes = explode('|', $code);
if (null === $arg2) {
$code = sprintf($codes[0], $arg1);
} else {
$code = sprintf($codes[1], $arg1, $arg2);
}
} else {
$code = sprintf($code, $arg1);
}
}
echo self::build($code, '');
return $this;
}
/**
* control screen
* @param $typeName
* @param null $arg
* @return $this
*/
public function screen($typeName, $arg = null)
{
if (!isset(self::$ctrlScreenCodes[$typeName])) {
Show::error("The [$typeName] is not supported cursor control.", __LINE__);
}
$code = self::$ctrlScreenCodes[$typeName];
// allow argument
if (false !== strpos($code, '%')) {
$code = sprintf($code, $arg);
}
echo self::build($code, '');
return $this;
}
public function reset()
{
echo self::END_CHAR;
}
/**
* @return array
*/
public static function supportedCursorCtrl()
{
return array_keys(self::$ctrlCursorCodes);
}
/**
* @return array
*/
public static function supportedScreenCtrl()
{
return array_keys(self::$ctrlScreenCodes);
}
}